Skip to content

KernelCompilation

Adam Boardman edited this page Nov 24, 2018 · 12 revisions

Building Gemian kernel for Gemini PDA used to be done outside of Debian packaging system. Here are the instructions to compile it (loosely based on https://github.com/bq/aquaris-M10-FHD) on that basis.

We have now also got a 'packaging' and 'native' branches for two versions of the kernel source that let you compile the kernel on an amd64 (packaging branch) or arm64 (native branch). So you can ignore the following and just do a regular 'debuild -b -uc -us' after pulling down the relevant branch and dependencies.

Compiling the kernel common steps

First, you should clone the kernel repository:

$ git clone https://github.com/gemian/gemini-linux-kernel-3.18 kernel-3.18

Create KERNEL_OUT dir:

$ mkdir KERNEL_OUT   

Cross-compiling the kernel (on an x86 machine)

At the same level of the "kernel-3.18" directory:

Download a prebuilt gcc:

$ git clone https://android.googlesource.com/platform/prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9 -b nougat-release --depth 1

Your directory tree should look like this:

  • kernel-3.18
  • aarch64-linux-android-4.9
  • KERNEL_OUT

Create kernel config based on aeon6797_6m_n_halium_defconfig, then, finally, build the kernel. You can specify "-jCORES" argument based on the number of your CPUs to speed-up compilation.

$ make O=../KERNEL_OUT -C kernel-3.18 ARCH=arm64 aeon6797_6m_n_halium_defconfig
$ make O=../KERNEL_OUT -C kernel-3.18 ARCH=arm64  CROSS_COMPILE=../aarch64-linux-android-4.9/bin/aarch64-linux-android- -j8

Cross compiling with debian provided compiler

You can simplify the above and use the debian provided compiler on stretch:

$ sudo apt-get install gcc-aarch64-linux-gnu
$ cd kernel-3.18
$ make O=../KERNEL_OUT ARCH=arm64 aeon6797_6m_n_halium_defconfig
$ make O=../KERNEL_OUT ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu-

Compiling the kernel directly on your Gemini PDA (arm64)

If you want to build the kernel on your Gemini, you will need to install the build dependencies. I will update this wiki entry when I do a fresh re-build. It definitely required the following:

$sudo apt-get install gcc libncurses5-dev bc make

You will need to disable a bunch of compiler warnings about indentations etc. the simple way is just to disable all warnings by editing the kernel Makefile

$ vi ./kernel-3.18/Makefile 

and adding '-Wall' to the KBUILD_CFLAGS so it looks like

KBUILD_CFLAGS   := -w -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs 
                   -fno-strict-aliasing -fno-common 
                   -Werror-implicit-function-declaration 
                   -Wno-format-security 
                   -std=gnu89

You can get the current kernel configuration from your running kernel using the following commands

$ cat /proc/config.gz | gunzip > running.config 

You should copy that to your KERNEL_OUT folder to make that the current config for the build

$ cp running.config KERNEL_OUT/.config 

And then customize from there with Make option 'menuconfig' before making the kernel

$ make O=../KERNEL_OUT -C kernel-3.18 menuconfig -j8
$ make O=../KERNEL_OUT -C kernel-3.18 -j8

If you are doing this from a kernel that was originally cross-compiled you will need to go into 'General Setup->Cross-compiler tool prefix' and delete the string 'aarch64-linux-android-4.9/bin/aarch64-linux-android-'. Suggest that is the only change you make initially as this should build and help you confirm you have all the build dependencies. Errors thrown will help you identify which libs/dependencies you need to install.

Creating bootable image

Gemini PDA bootloader requires kernel to be in Android Boot Image format, which includes kernel itself, ramdisk and parameters/cmdline in single file which is then flashed onto boot/boot2/boot3 partition.

mkbootimg comes from Android Open Source Project, but no Makefile is provided to build it on Linux, so use forked version:

$ git clone https://github.com/osm0sis/mkbootimg.git
$ make -C mkbootimg

Download pre-made ramdisk (includes Busybox and init script forked from hybris-boot, which is currently configured to boot system from /dev/mmcblk0p29 partition):

$ curl -O https://gemian.thinkglobally.org/ramdisk.cpio.gz

Finally, use mkbootimg to combine kernel and ramdisk into boot.img-format file:

./mkbootimg/mkbootimg \
    --kernel KERNEL_OUT/arch/arm64/boot/Image.gz-dtb \
    --ramdisk ramdisk.cpio.gz \
    --base 0x40080000 \
    --second_offset 0x00e80000 \
    --cmdline "bootopt=64S3,32N2,64N2 log_buf_len=4M" \
    --kernel_offset 0x00000000 \
    --ramdisk_offset 0x04f80000 \
    --tags_offset 0x03f80000 \
    --pagesize 2048 \
    -o linux_boot.img

Resulting linux_boot.img can be flashed onto device using FlashTool or any other method.

Updating to an experimental kernel

If you want to just try a one off version of a new kernel and you don't know if its going to work or not its best to pop it over the recovery partition, then boot holding the escape key (or whatever your boot loader normally gives you a dead android for)

sudo dd if=my-custom-linux-boot.img of=/dev/disk/by-partlabel/recovery

Note: This is only useful for 'smoke' testing a new kernel, the lk bootloader doesn't init the modem for recovery. Ideally we'd have another boot partition available as per Bootloader for experimenting or another OS. If it fails then you want to boot back to (~ recovery | a known good kernel ~) and check /proc/last_kmsg for any useful info.