Building generic kernels

Even if kernel sources are not provided by the vendor, it's still possible to package kernel and make the phone boot.

Find generic kernel for the device
To find a needed kernel, you have to:
 * 1) Find out the information about the SoC/board used in the device. One SoC may have multiple boards. For example, Spreadtrum SC7731C has 2 boards: sc7731cea and sc7731ceb.
 * 2) Try to search for kernels on the internet. Use different queries to find as much kernels as possible. Kernel is considered matching if it has files for your board, such as device tree source (located at  ). Some downstream kernels (up to 3.10.x) may have support in board files instead. They are located at   or  (e.g. mach-sc, mach-qcom, mach-mt6582).

Add device support
Depending on the way of describing the hardware in kernel, you should choose one of these methods

Add vendor dts in kernel

 * 1) Get dts from stock boot.img
 * 2) Copy dts to linux-device-codename folder and add its filename to   list in APKBUILD
 * 3) Add a copy command for dts file on prepare step, like
 * 4) Patch related Makefile (usually in  ) to build device tree blob

Board files
If the found kernel uses board files for your SoC, then you have to change kernel config to enable/disable support for specific hardware and patch the board file if implementation of additional devices is needed (e.g. hardware keyboard).

Adapt kernel config
This step is needed to make a proper kernel config which works for the device. You have to find detailed information about the hardware. Possible ways to do it are: After one of these steps write down all information you've found and use it to adjust kernel config. Run  and use built-in search (press / key) to find options related to found hardware.
 * 1) Get dts from stock boot.img
 * 2) Follow instructions from tuning sysfs page to get contents of sysfs. It is recommended to do it on a rooted phone in Android, since dump made from recovery will probably have less details about hardware.
 * 3) Use   to dump all possible function names and find out which kernel options should be enabled to add these functions in kernel during building.
 * 4) Find photos of device's internals on the web. If there are none, disassemble the device yourself or ask someone to do it.

There is no driver for X in the kernel. What to do?

 * 1) Check if driver is available in other generic kernels you have found for the device. If driver is available, check step 6 and further.
 * 2) Try to find this driver in other kernels that don't match your device. It will be helpful to understand how it works, though you'll most likely have to rewrite(port) it.
 * 3) Find datasheet to have more information for porting the driver.
 * 4) Find a dummy driver for the driver's group(e.g. lcd_dummy.c for LCD panel drivers) in your kernel. Read it as well as other drivers for devices similar to yours.
 * 5) Use drivers and datasheet to make a new driver.
 * 6) Patch the kernel with driver, Makefile and Kconfig files related to your drivers group to add support. Give a proper name to driver option in Kconfig.
 * 7) Add a line to linux-device-codename's config to make the driver option appear in menuconfig. Example:
 * 8) Run   and enable the option. Tap / on the keyboard to search for it.

Getting a list of input devices and keycodes
For Android devices, you may run  to get detailed information about the input devices and related keycodes. You'll get output similar to: It's possible to use  flag to replace keycodes with key names from. Do note that some keys may not exist. For example, the output given above has F3 and F4 keycodes, but device doesn't have these keys. If you're unsure about the relations of physical keys and keycodes, you may start  and press buttons one by one to understand. You should also record data from, it may help later.

Add and modify input devices in board file
This task will be reviewed on the previous example. As can be seen, the phone has an input device for headset with one button, matrix keypad device with 9 keys (remember that F3 button doesn't exist) and GPIO keys device. The board file used as the base is arch/arm/mach-sc/board-sp7715ga.c. This board has headset and matrix keypad devices set, but the GPIO keys device is missing and matrix data doesn't fit the device. So, the steps needed are: The matrix data looks like this As there should be 9 matrix keys, we assume that the matrix has 3 rows and 3 columns. So, the first step is to replace existing entries with ones related to your keys. If you have access to dmesg, then you may find out the proper row and column for every key, otherwise you'll have to guess them. After that, change amount of rows and columns, patch, build and flash the kernel. Then boot to postmarketOS and run. Choose the keypad device and press buttons one by one. If the keycode doesn't fit the key, then you have to make changes in board file. The final result for the device in example is:
 * 1) Change matrix data to fit the device
 * 2) Add gpio keys device to the list of devices
 * 3) Create gpio keys device description

The second step is to add the missing GPIO keys device. There is no template for it in this exact board file, so you have to find it. It is recommended to search for it in the same path where the board file for your device is located ( in this case). It doesn't mean you're limited by the kernel you're using though. It's possible to search in another kernels as well, just be sure they don't differ much. Example: The final step is to add description of all GPIO keys to the device. In this example, we define GPIOs for keys and change the contents of  and test the changes. It is recommended to use debug-shell hook for initramfs so you get access to dmesg as fast as possible. In dmesg you may find details of GPIO keys initialization. If it failed, there will be a wrong GPIO mentioned. Then, if everything's alright, run  again and choose GPIO keys device. Test and edit the board file till it works.