Qemu for arm64 android kernel version 6.1

A way to run the latest android kernel

Posted by half cup coffee on July 17, 2024

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)

Run poweroff command to exit from the Qemu.