Before start
Before you start to follow this guide. You might need to read this link first.
Fetch the android kernel version 6.1
From this Google link we can get to know the branch inforamtion of android kernel.
mkdir android-kernel && cd android-kernel
repo init -u https://android.googlesource.com/kernel/manifest -b common-android14-6.1-lts
repo sync -c -d -j8
Necessary change need be done before build
For the folder common which is the kernel source code location. Please do following change:
--- a/arch/arm64/configs/gki_defconfig
+++ b/arch/arm64/configs/gki_defconfig
@@ -744,3 +744,17 @@ CONFIG_KUNIT=y
CONFIG_KUNIT_DEBUGFS=y
# CONFIG_KUNIT_DEFAULT_ENABLED is not set
# CONFIG_RUNTIME_TESTING_MENU is not set
+
+CONFIG_INITRAMFS_SOURCE="/media/nvme1/temp/rootfs/rfs"
+CONFIG_VIRTIO_PCI=y
+CONFIG_VIRTIO_BALLOON=y
+CONFIG_VIRTIO_BLK=y
+CONFIG_VIRTIO_NET=y
+CONFIG_9P_FS_SECURITY=y
+CONFIG_NET_9P=y
+CONFIG_NET_9P_VIRTIO=y
+CONFIG_NET_9P_DEBUG=y
+CONFIG_9P_FS=y
+CONFIG_9P_FS_POSIX_ACL=y
--- a/build.config.gki
+++ b/build.config.gki
@@ -1,2 +1,2 @@
DEFCONFIG=gki_defconfig
-POST_DEFCONFIG_CMDS="check_defconfig"
+###POST_DEFCONFIG_CMDS="check_defconfig"
Build commands
Execute below commands to build kernel and modules:
tools/bazel run //common:kernel_aarch64_dist -- --dist_dir=/media/nvme1/play_android_kernel/out-new
tools/bazel run //common-modules/virtual-device:virtual_device_aarch64_dist -- --dist_dir=/media/nvme1/play_android_kernel/out-new
Adding a kernel module example
The kernel build currently is using the Bazel. You can see the document about it from [here] (https://android.googlesource.com/kernel/build/+/refs/heads/main/kleaf/docs/impl.md). So there is a differnet way for us to add a kernel module.
For example, we have 2 new kernel module to be add. We create the source code folder under common-modules/virtual-device. The folder device_test1 and hello-world-module is the 2 modules we are going to add.
To compile these 2 kernel modules we need do following change :
--- a/BUILD.bazel
+++ b/BUILD.bazel
@@ -92,6 +92,20 @@ filegroup(
],
)
+filegroup(
+ name = "hello_world_sources",
+ srcs = [
+ "hello-world-module/hello-world-module.c"
+ ],
+)
+
+filegroup(
+ name = "device_test1_sources",
+ srcs = [
+ "device_test1/main.c"
+ ],
+)
+
filegroup(
name = "v4l2loopback_sources",
srcs = [
@@ -517,6 +531,24 @@ ddk_module(
deps = [":common_headers_aarch64"],
)
+ddk_module(
+ name = "aarch64/hello_world",
+ srcs = [":hello_world_sources"],
+ out = "hello_world.ko",
+ kernel_build = ":virtual_device_aarch64",
+ local_defines = ["DRIVER_VERSION=\"android14-6.1\""],
+ deps = [":common_headers_aarch64"],
+)
+
+ddk_module(
+ name = "aarch64/device_test1",
+ srcs = [":device_test1_sources"],
+ out = "device_test1.ko",
+ kernel_build = ":virtual_device_aarch64",
+ local_defines = ["DRIVER_VERSION=\"android14-6.1\""],
+ deps = [":common_headers_aarch64"],
+)
+
ddk_module(
name = "aarch64/v4l2loopback",
srcs = [":v4l2loopback_sources"],
@@ -534,6 +566,8 @@ kernel_module_group(
":aarch64/goldfish_drivers/goldfish_sync",
":aarch64/v4l2loopback",
":aarch64/virtio_video",
+ ":aarch64/hello_world",
+ ":aarch64/device_test1",
],
)
Then run the build command again. Then you will see the device_test1.ko and hello_world.ko in the folder /media/nvme1/play_android_kernel/out-new.
Launch the kernel
Basically the command is like the command from this link.
export OUT_FOLDER="/media/nvme1/play_android_kernel/out-new"
qemu-system-aarch64 -machine virt -cpu cortex-a57 -machine type=virt -m 1024 -smp 4 -kernel $OUT_FOLDER/Image --append "rdinit=/linuxrc root=/dev/vda rw console=ttyAMA0 loglevel=8" -nographic -fsdev local,security_model=passthrough,id=fsdev0,path=$OUT_FOLDER -device virtio-9p-pci,id=fs0,fsdev=fsdev0,mount_tag=kmod_mount -drive format=raw,file=/media/nvme1/temp/rootfs/hd1 -net nic,model=virtio,macaddr=DE:AD:BE:EF:28:05
Load the modules
The folder play_android_kernel/out-new is passed to the qemu VM by the option -fsdev local,security_model=passthrough,id=fsdev0,path=$OUT_FOLDER -device virtio-9p-pci,id=fs0,fsdev=fsdev0,mount_tag=kmod_mount. So all the files under the play_android_kernel/out-new can be seen in the guest VM after we launch it. It is mounted in the folder /mnt.
To load the kernel module we created:
[root@weller mnt]# insmod hello_world.ko
[ 28.894159][ T90] hello_world: loading out-of-tree module taints kernel.
[ 28.894707][ T90] hello_world: module license 'MIT' taints kernel.
[ 28.894816][ T90] Disabling lock debugging due to kernel taint
[ 28.896604][ T90] hello_world: module verification failed: signature and/or required key missing - tainting kernel
[ 28.902241][ T90] [hello-world-module] Kernel Module Inserted Successfully...
[root@weller mnt]# insmod device_test1.ko
[ 35.515065][ T91] ========mynull_device_init: In init
[ 35.515318][ T91] mynull_device_init: Major Number:503 Minor Number:0
[root@weller mnt]#
[root@weller mnt]# lsmod
device_test1 20480 0 - Live 0xffffffc001026000 (OE)
hello_world 20480 0 - Live 0xffffffc001020000 (POE)