AOSP分支:android-13.0.0_r1
Kernel分支:common-android13-5.15-2022-09
以上两个分支内核版本是相同的,如果版本不同,会报disagree错误,common-android13-5.15 分支在最新一次合入中的改动导致了内核使用模拟器加载的时候打不开,所以先用2022-09这个月的分支。
-------------------------
进行Android内核开发的第一步,实现一个输出Hello World的内核模块。
首先进行编码:
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
static int __init hello_init(void){
printk(KERN_INFO "Hello world zhaojun! \n");
return 0;
}
static void __exit hello_exit(void){
printk(KERN_INFO "Good bye zhaojun! \n");
return;
}
module_init(hello_init);
module_exit(hello_exit);
MODULE_LICENSE("GPL");
代码逻辑就是在加载的时候输出一句Hello world zhaojun!
然后将它作为驱动,放置到Android Kernel源码目录下,由于我们需要将我们新写的模块与内核一起编译,我们选择的内核编译选项是common:kernel_x86_64,因此,我们需要将它放置到common路径下面,common路径下有一个driver文件夹,里面存放着各种各样的内核驱动。
这些驱动在编译时由Makefile文件组织起来,所以我们新建一个hello文件夹,里面放入我们的hello world代码和编译这个hello world代码的Makefile,里面就只加上这一句话(更多makefile的细节还在学习中,暂时还不是很理解):
obj-y += helloworld.o
然后在外面的一个makefile中,添加hello文件夹的路径,使得编译器会去hello文件夹下寻找下一级的makefile,将驱动添加到编译列表中。
diff --git a/drivers/Makefile b/drivers/Makefile
index a110338c860c..b1d648dc48eb 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -187,3 +187,4 @@ obj-$(CONFIG_GNSS) += gnss/
obj-$(CONFIG_INTERCONNECT) += interconnect/
obj-$(CONFIG_COUNTER) += counter/
obj-$(CONFIG_MOST) += most/
+obj-y += hello/
也就是在文末追加一行指出hello路径。
然后执行命令构建内核,Android13新引入了编译工具bazel,在源码根目录执行:
tools/bazel build //common:kernel_x86_64
重新构建内核。
当编译成功完成后,切回AOSP的代码,AOSP的代码之前我们已经编译过并用模拟器打开,AOSP的代码不包含安卓内核的源码,我们使用的AOSP分支对应Android内核版本号5.15.41,在启动时两者内核版本号的不相同会报disagree xxx的错误。
当我们启动emulator时,使用的是AOSP中已经存好的一个编译过的内核,因此,我们要在启动emulator时进行一下内核的指定,指定为编译产物bzImage(x86架构的叫法):
emulator -shell -kernel /home/zhaojun/Android-kernel/bazel-bin/common/kernel_x86_64/bzImage
执行上述命令,我们的Android虚拟机就会再次启动,(启动前不要忘记source环境配置和lunch版本选择),然后我们查看shell中打印的日志,就可以看到我们的驱动被加载了: