![Android智能穿戴设备开发实战详解](https://wfqqreader-1252317822.image.myqcloud.com/cover/166/31729166/b_31729166.jpg)
3.5 编译Android Kernel
编译Android Kernel代码就是编译Android内核代码,在进行具体编译工作之前需要先了解在Android开源系统中包含的如下三部分代码。
● 仿真器公共代码:对应的工程名是kernel/common.get。
● MSM平台的内核代码:对应的工程名是kernel/msm.get。
● OMAP平台的内核代码:对应的工程名是kernel/omap.get。
在本节的内容中将详细讲解编译上述Android Kernel的基本知识。
3.5.1 获取Goldfish内核代码
Goldfish是一种虚拟的ARM处理器,通常在android的仿真环境中使用。在linux的内核中,Goldfish作为ARM体系结构的一种“机器”。在Android的发展过程中,Goldfish内核的版本也从Linux2.6.25升级到了Linux 3.4,此处理器的Linux内核和标准的Linux内核有以下三个方面的差别。
● Goldfish机器的移植。
● Goldfish一些虚拟设备的驱动程序。
● Android中特有的驱动程序和组件。
Goldfish处理器有两个版本,分别是ARMv5和ARMv7,在一般情况下只需使用ARMv5版本即可。在Android开源工程的代码仓库中,使用git工具得到Goldfish内核代码的命令如下所示。
![](https://epubservercos.yuewen.com/850D74/17180246404476806/epubprivate/OEBPS/Images/img00070001.jpg?sign=1739363970-SvrPtxdGbCOn9VBCAkOJ33WnCot6UtmT-0-a83e2f841622543c6943cb96ce1d3229)
在其Linux源代码的根目录中,配置和编译Goldfish内核的过程如下所示。
![](https://epubservercos.yuewen.com/850D74/17180246404476806/epubprivate/OEBPS/Images/img00070002.jpg?sign=1739363970-4iMslnpJvrD6JdvDL3WCAwG101hoJyA6-0-8f31d740057d5e4814566b1b5977b350)
其中,CROSS_COMPILE的path值用于指定交叉编译工具的路径。
编译结果如下所示。
![](https://epubservercos.yuewen.com/850D74/17180246404476806/epubprivate/OEBPS/Images/img00070003.jpg?sign=1739363970-NVUdXPB8ti6YgBBRcSqz9gRIHQSIAYZT-0-470cbc226b708777d0d654687dedf0a7)
● vmlinux:是Linux进行编译和连接之后生成的Elf格式的文件。
● Image:是未经过压缩的二进制文件。
● piggy:是一个解压缩程序。
● zImage:是解压缩程序和压缩内核的组合。
在Android源代码的根目录中,vmlinux和zImage分别对应Android代码prebuilt中的预编译的arm内核。使用zImage可以替换prebuilt中的“prebuilt/android-arm/”目录下的goldfish_defconfig,此文件的主要片断如下所示。
![](https://epubservercos.yuewen.com/850D74/17180246404476806/epubprivate/OEBPS/Images/img00071001.jpg?sign=1739363970-cxHIoAKdX0mFnVG9YJqfrVZlHzvCR4px-0-f9b9542ec30ae0204e8674cc295eb9f1)
因为GoldFish是arm处理器,所以CONFIG_ARM宏需要被使能,CONFIG_ARCH_GOLDFISH和CONFIG_MACH_GOLDFISH宏是GoldFish处理器这类机器使用的配置宏。
在gildfish_defconfig中,与Android系统相关的宏如下所示。
![](https://epubservercos.yuewen.com/850D74/17180246404476806/epubprivate/OEBPS/Images/img00071002.jpg?sign=1739363970-gbg1m6WptvughHA0k2BuUJrshLPYas6n-0-b5c1710692782202282af4503b5925ff)
在Goldfish处理器的各个配置选项中,体系结构和Goldfish的虚拟驱动程序基于标准Linux的内容的驱动程序框架,但是这些设备在不同的硬件平台的移植方式不同;Android专用的驱动程序是Android中特有的内容,非Linux标准,但和硬件平台无关。
和原Linux内核相比,Android内核增加了Android的相关Driver,对应的目录如下所示。
![](https://epubservercos.yuewen.com/850D74/17180246404476806/epubprivate/OEBPS/Images/img00072001.jpg?sign=1739363970-6G7u0hcZMtpzoMy98L3sxb3Jt6aNAL4u-0-f34bc1aa69391aed25b7691e370332e1)
主要分为以下几类Driver。
● Android IPC系统:Binder(binder.c)。
● Android日志系统:Logger(logger.c)。
● Android电源管理:Power(power.c)。
● Android闹钟管理:Alarm(alarm.c)。
● Android内存控制台:Ram_console(ram_console.c)。
● Android时钟控制的gpio:Timed_gpio(timed_gpio.c)。
对于本书讲解的驱动程序开发来说,我们比较关心的是GoldFish平台下相关的驱动文件,具体说明如下所示。
(1)字符输出设备
![](https://epubservercos.yuewen.com/850D74/17180246404476806/epubprivate/OEBPS/Images/img00072002.jpg?sign=1739363970-ExiGrvmZR65E3783Eq3BsFTMyAaZhbXK-0-16370411d1612f76fe9eb9edc6f8b940)
(2)图像显示设备(Frame Buffer)
![](https://epubservercos.yuewen.com/850D74/17180246404476806/epubprivate/OEBPS/Images/img00072003.jpg?sign=1739363970-EXprmyndRzl75O6ChFsMAmjc9HMfCSAe-0-46c84119e042f04f6cfa93af93551c4c)
(3)键盘输入设备文件
![](https://epubservercos.yuewen.com/850D74/17180246404476806/epubprivate/OEBPS/Images/img00072004.jpg?sign=1739363970-Z0da4FStu0ySgcrI1F919ZqWTOBdhJC1-0-c83e293f1fa5a4a7fced8d1c5621ea07)
(4)RTC设备(Real Time Clock)文件
![](https://epubservercos.yuewen.com/850D74/17180246404476806/epubprivate/OEBPS/Images/img00072005.jpg?sign=1739363970-NHHZGLoqTdnKaC3Qy1kKplh864zf4DGl-0-ccb2498271694af3b349d3f2d7f47b37)
(5)USB Device设备文件
![](https://epubservercos.yuewen.com/850D74/17180246404476806/epubprivate/OEBPS/Images/img00072006.jpg?sign=1739363970-0lI3B4kRITG6Mhx4QK4zL6pv5ZN3CYE9-0-d3acc4879e4a48407cf0cd01ebf22736)
(6)SD卡设备文件
![](https://epubservercos.yuewen.com/850D74/17180246404476806/epubprivate/OEBPS/Images/img00072007.jpg?sign=1739363970-XGQ6ijCZhNuQrmKEuGvFCXJxj0DWxN1i-0-0a3b7d7fd8956eeeaa4333bee2044539)
(7)FLASH设备文件
![](https://epubservercos.yuewen.com/850D74/17180246404476806/epubprivate/OEBPS/Images/img00072008.jpg?sign=1739363970-v4rJYd7BX2v1gw9vu9ObOtaz928LBjLO-0-08d1c7de8ab29a6e12b673b4f8f20074)
(8)LED设备文件
![](https://epubservercos.yuewen.com/850D74/17180246404476806/epubprivate/OEBPS/Images/img00072009.jpg?sign=1739363970-E4m8fxuxNzL0bEQBZiNh8iNw4DYLdHbo-0-1b950168a94765f4b18efdb6806973f6)
(9)电源设备
![](https://epubservercos.yuewen.com/850D74/17180246404476806/epubprivate/OEBPS/Images/img00072010.jpg?sign=1739363970-dRB7wpkPqabncfNNnCLq1aUbbE0xUmwi-0-aa4ab8f8c176d7fac6a67c0746abdc25)
(10)音频设备
![](https://epubservercos.yuewen.com/850D74/17180246404476806/epubprivate/OEBPS/Images/img00072011.jpg?sign=1739363970-nTV2Dvbi4yKU8gMAe4zpaNLLxkmTb0BE-0-d79f9a88ee0ad4d0915c1f0ce2ae1811)
(11)电源管理
![](https://epubservercos.yuewen.com/850D74/17180246404476806/epubprivate/OEBPS/Images/img00072012.jpg?sign=1739363970-pPbISw8BpViBLkDHgopbH48UTWbNdJnE-0-36228f5cb86a2e675706313746aa3ad1)
(12)时钟管理
![](https://epubservercos.yuewen.com/850D74/17180246404476806/epubprivate/OEBPS/Images/img00072013.jpg?sign=1739363970-xBiwXuLeTlYUA9wiWXoN2NPx5rP7Rza9-0-015bea520d4ef972e7b5260761691d19)
3.5.2 获取MSM内核代码
在当前市面中,谷歌的手机产品G1是基于MSM内核的,MSM是高通公司的应用处理器,在Android代码库中公开了对应的MSM的源代码。在Android开源工程的代码仓库中,使用git工具得到MSM内核代码的命令如下所示。
![](https://epubservercos.yuewen.com/850D74/17180246404476806/epubprivate/OEBPS/Images/img00073001.jpg?sign=1739363970-uH8hVU5PeJZEZIkkRy2QWY59kbnd7G3i-0-6573ecf81b914ca7530aa563094dbe31)
3.5.3 获取OMAP内核代码
OMAP是德州仪器公司的应用处理器,为Android使用的是OMAP3系列的处理器。在Android代码库中公开了对应的MSM的源代码,使用git工具得到MSM内核代码的命令如下所示。
![](https://epubservercos.yuewen.com/850D74/17180246404476806/epubprivate/OEBPS/Images/img00073002.jpg?sign=1739363970-khnXnsDN8In4b0Skj6C0xWMA2OVOSKaO-0-47e3730bccdd1dd9faa5b39d496df74e)
3.5.4 编译Android的Linux内核
了解了上述三类Android内核后,下面开始讲解编译Android内核的方法。在此假设以Ubuntu8.10为例,完整编译Android内核的流程如下所示。
(1)构建交叉编译环境
Android的默认硬件处理器是ARM,因此需要在机器上构建交叉编译环境。交叉编译器GNU Toolchain for ARM Processors下载地址如下所示。
![](https://epubservercos.yuewen.com/850D74/17180246404476806/epubprivate/OEBPS/Images/img00073003.jpg?sign=1739363970-00q00ZUmaSfVWK1m2Jx6ujwB08XP0rVU-0-7a30505cb8334c21ba584b0830f4ece3)
单击GNU/Linux对应的链接,再单击“Download Sourcery CodeBench Lite 5.12012.03-117”链接后直接下载,如图3-15所示。
![](https://epubservercos.yuewen.com/850D74/17180246404476806/epubprivate/OEBPS/Images/img00073004.jpg?sign=1739363970-VM3It2sxvkAYvQHvdRWYPt5XvfHtYT1J-0-b214431dc720d3c3a6cd5fce6d9007c1)
图3-15 下载交叉编译器
把arm-2008q3-73-arm-none-linux-gnueabi-i686-pc-linux-gnu.tar.bz2解压到一个目录之下,例如“~/programes/”,并加入PATH环境变量。
![](https://epubservercos.yuewen.com/850D74/17180246404476806/epubprivate/OEBPS/Images/img00073005.jpg?sign=1739363970-BvLcb1KrsohLrrQaTgxsdYYFjxrF29gU-0-75eab1a924f9e8e504a2e996368c9444)
然后添加:
![](https://epubservercos.yuewen.com/850D74/17180246404476806/epubprivate/OEBPS/Images/img00073006.jpg?sign=1739363970-G6M8VmpeDwN4sT4wfUqRhXAHCkFKStaC-0-843de1a7e01f80a86e324cf0a39f5293)
保存后并source~/.bashrc。
(2)获取内核源码,源码地址如下所示。
![](https://epubservercos.yuewen.com/850D74/17180246404476806/epubprivate/OEBPS/Images/img00074001.jpg?sign=1739363970-4HjtxQgNaknRCNsl8tUt6n41V24rFFbH-0-509d9875fd49297ed0027633b29adcde)
选择的内核版本要与选用的模拟器版本尽量一致。下载后并解压后得到kernel.git文件夹。
![](https://epubservercos.yuewen.com/850D74/17180246404476806/epubprivate/OEBPS/Images/img00074002.jpg?sign=1739363970-cZxLOeaB08NtdvMHqxZ5A1yhP0THXlOf-0-a4eabf184de748bb4b6247cecc3d44a1)
(3)获取内核编译配置信息文件
编译内核时需要使用configure,通常configure有很多选项,我们往往不知道需要哪些选项。在运行Android模拟器时,有一个文件“/proc/config.gz”,这是当前内核的配置信息文件,把config.gz获取并解压放到“kernel.git/”下,然后改名为.config。命令如下所示。
![](https://epubservercos.yuewen.com/850D74/17180246404476806/epubprivate/OEBPS/Images/img00074003.jpg?sign=1739363970-rXB1siJ9BEFGjdBKkHPwEomlJTCo63ji-0-f272e12c4ac99b180987998022d0d4e7)
(4)修改Makefile
修改195行的代码。
![](https://epubservercos.yuewen.com/850D74/17180246404476806/epubprivate/OEBPS/Images/img00074004.jpg?sign=1739363970-NqtqjUpvgdc0IwyPsfLj4OorDXvBagom-0-83a3890e46a167913bad272438e9a4d7)
将CROSS_COMPILE值改为arm-none-linux-gnueabi-,这是我们安装的交叉编译工具链的前缀,修改此处意在告诉make在编译时需要使用该工具链。然后注释掉562和563行的代码,命令如下所示。
![](https://epubservercos.yuewen.com/850D74/17180246404476806/epubprivate/OEBPS/Images/img00074005.jpg?sign=1739363970-bZxZlMufqnHVYRs7Fcwp2Ulm2ThkQVTo-0-8725f2b6754afd38ef8adbd4159fdc05)
必须将上述代码中的build id值注释掉,因为目前版本的Android内核不支持该选项。
(5)编译
使用make进行编译,并同时生成zImage。
![](https://epubservercos.yuewen.com/850D74/17180246404476806/epubprivate/OEBPS/Images/img00074006.jpg?sign=1739363970-iqn97W75tmvQRmhdjHBStnK7kgfdAcQp-0-b215c12e855a0b1d5910e8a7bbdc1f3e)
这样生成zImage大小为1.23MB,android-sdk-linux_x86-4.3_r1/tools/lib/images/kernel-qemu是1.24MB。
(6)使用模拟器加载内核测试,命令如下所示。
![](https://epubservercos.yuewen.com/850D74/17180246404476806/epubprivate/OEBPS/Images/img00074007.jpg?sign=1739363970-R5MttK4WdQHMqxPMlHMVvU7Jpz01vSoi-0-6796f2c44506cf7d14071975435a892c)
到此为止,模拟器加载成功。