《深入解析Android 虚拟机》——第1章,第1.4节编译Android Kernel

简介:

本节书摘来自异步社区《深入解析Android 虚拟机》一书中的第1章,第1.4节编译Android Kernel,作者 钟世礼,更多章节内容可以访问云栖社区“异步社区”公众号查看

1.4 编译Android Kernel
编译Android Kernel代码就是编译Android内核代码,在进行具体编译工作之前,需要先了解在Android开源系统中包含的以下3部分代码。

仿真器公共代码:对应的工程名是kernel/common.get。
MSM平台的内核代码:对应的工程名是kernel/msm.get。
OMAP平台的内核代码:对应的工程名是kernel/omap.get。
在本节的内容中,将详细讲解编译上述Android Kernel的基本知识。

1.4.1 获取Goldfish内核代码
Goldfish是一种虚拟的ARM处理器,通常在Android的仿真环境中使用。在Linux的内核中,Goldfish作为ARM体系结构的一种“机器”。在Android的发展过程中,Goldfish内核的版本也从Linux 2.6.25升级到了Linux 3.4,此处理器的Linux内核和标准的Linux内核有以下3个方面的差别。

Goldfish机器的移植。
Goldfish一些虚拟设备的驱动程序。
Android中特有的驱动程序和组件。
Goldfish处理器有两个版本,分别是ARMv5和ARMv7,在一般情况下,只需使用ARMv5版本即可。在Android开源工程的代码仓库中,使用git工具得到Goldfish内核代码的命令如下所示:

$ git clone git://android.git.kernel.org/kernel/common.git
在其Linux源代码的根目录中,配置和编译Goldfish内核的过程如下所示:

$make ARCH=arm goldfish_defconfig .config
$make ARCH=arm CROSS_COMPILE={path}/arm-none-linux-gnueabi-

其中,CROSS_COMPILE的path值用于指定交叉编译工具的路径。

编译结果如下所示:

LD vmlinux
SYSMAP system.map
SYSMAP .tmp_system.map
OBJCOPY arch/arm/boot/Image
Kernel: arch/arm/boot/Image is ready
AS arch/arm/boot/compressed/head.o
GZIP arch/arm/boot/compressed/piggy.gz
AS arch/arm/boot/compressed/piggy.o
CC arch/arm/boot/compressed/misc.o
LD arch/arm/boot/compressed/vmlinux
   OBJCONPY arch/arm/boot/zImage
   Kernel: arch/arm/boot/zImage is ready

vmlinux:是Linux进行编译和连接之后生成的Elf格式的文件。
Image:是未经过压缩的二进制文件。
piggy:是一个解压缩程序。
zImage:是解压缩程序和压缩内核的组合。
在Android源代码的根目录中,vmlinux和zImage分别对应Android代码prebuilt中的预编译的ARM内核。使用zImage可以替换 prebuilt中的“prebuilt/android-arm/”目录下的goldfish_defconfig,此文件的主要片断如下所示:

CONFIG_ARM=y
#
# System Type
#
CONFIG_ARCH_GOLDFISH=y
#
# Goldfish options
#
CONFIG_MACH_GOLDFISH=y
# CONFIG_MACH_GOLDFISH_ARMV7 is not set

因为GoldFish是ARM处理器,所以CONFIG_ARM宏需要被使能,CONFIG_ARCH_GOLDFISH和CONFIG_MACH_GOLDFISH宏是GoldFish处理器这类机器使用的配置宏。

在gildfish_defconfig中,与Android系统相关的宏如下所示:

#
# android
#
CONFIG_ANDROID=y
CONFIG_ANDROID_BUNDER_IPC=y #binder ipc驱动程序
CONFIG_ANDROID_LOGGER=y #log记录器驱动程序
# CONFIG_ANDROID_RAM_CONSOLE is not set
CONFIG_ANDROID_TIMED_OUTPUT=y #定时输出驱动程序框架
CONFIG_ANDROID_LOW_MEMORY_KILLER=y
CONFIG_ANDROID_PMEM=y #物理内存驱动程序
CONFIG_ASHMEM=y #匿名共享内存驱动程序
CONFIG_RTC_INTF_ALARM=y
CONFIG_HAS_WAKELOCK=y 电源管理相关的部分wakelock和earlysuspend
CONFIG_HAS_EARLYSUSPEND=y
CONFIG_WAKELOCK=y
CONFIG_WAKELOCK_STAT=y
CONFIG_USER_WAKELOCK=y
CONFIG_EARLYSUSPEND=y
goldfish_defconfig 配置文件中,另外有一个宏是处理器虚拟设备的“驱动程序”,其内容如下所示:
CONFIG_MTD_GOLDFISH_NAND=y
CONFIG_KEYBOARD_GOLDFISH_EVENTS=y
CONFIG_GOLDFISH_TTY=y
CONFIG_BATTERY_GOLDFISH=y
CONFIG_FB_GOLDFISH=y
CONFIG_MMC_GOLDFISH=y
CONFIG_RTC_DRV_GOLDFISH=y

在Goldfish处理器的各个配置选项中,体系结构和Goldfish的虚拟驱动程序基于标准Linux内容的驱动程序框架,但是这些设备在不同硬件平台的移植方式不同;Android专用的驱动程序是Android中特有的内容,非Linux标准,但是和硬件平台无关。

和原Linux内核相比,Android内核增加了Android的相关驱动(Driver),对应的目录如下所示:

kernel/drivers/android
Android的相关驱动主要分为以下几类驱动。

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)字符输出设备:

kernel/drivers/char/goldfish_tty.c
(2)图象显示设备(Frame Buffer):

kernel/drivers/video/goldfishfb.c
(3)键盘输入设备文件:

kernel/drivers/input/keyboard/goldfish_events.c
(4)RTC设备(Real Time Clock)文件:

kernel/drivers/rtc/rtc-goldfish.c
(5)USB Device设备文件:

kernel/drivers/usb/gadget/android_adb.c
(6)SD卡设备文件:

kernel/drivers/mmc/host/goldfish.c
(7)FLASH设备文件:

kernel/drivers/mtd/devices/goldfish_nand.c
kernel/drivers/mtd/devices/goldfish_nand_reg.h
(8)LED设备文件:

kernel/drivers/leds/ledtrig-sleep.c
(9)电源设备:

kernel/drivers/power/goldfish_battery.c
(10)音频设备:

kernel/arch/arm/mach-goldfish/audio.c
(11)电源管理:

kernel/arch/arm/mach-goldfish/pm.c
(12)时钟管理:

kernel/arch/arm/mach-goldfish/timer.c

1.4.2 获取MSM内核代码
在目前市面上,谷歌的手机产品G1是基于MSM内核的,MSM是高通公司的应用处理器,在Android代码库中公开了对应的MSM的源代码。在Android开源工程的代码仓库中,使用Git工具得到MSM内核代码的命令如下所示:

$ git clone git://android.git.kernel.org/kernel/msm.git

1.4.3 获取OMAP内核代码
OMAP是德州仪器公司的应用处理器,为Android使用的是OMAP3系列的处理器。在Android代码库中公开了对应的OMAP的源代码,使用Git工具得到OMAP内核代码的命令如下所示:

$ git clone git://android.git.kernel.org/kernel/omap.git

1.4.4 编译Android的Linux内核
了解了上述3类Android内核后,下面开始讲解编译Android内核的方法。在此以Ubuntu 8.10为例,完整编译Android内核的流程如下。

(1)构建交叉编译环境。

Android的默认硬件处理器是ARM,因此需要在自己的机器上构建交叉编译环境。交叉编译器GNU Toolchain for ARM Processors下载地址如下所示:

单击GNU/Linux对应的链接,再单击“Download Sourcery CodeBench Lite 5.1 2012.03-117”链接后直接下载,如图1-20所示。



把arm-2008q3-71-arm-none-linux-gnueabi-i686-pc-linux- gnu.tar.bz2解压到一目录下,例如“~/programes/”,并加入PATH环境变量:

vim ~/.bashrc

然后添加:

ARM_TOOLCHIAN=~/programes/arm-2008q3/bin/
export PATH=${PATH}:${ARM_TOOLCHIAN};
保存后并source ~/.bashrc。

(2)获取内核源码,源码地址如下所示:

http://code.google.com/p/android/downloads/list

选择的内核版本要与选用的模拟器版本尽量一致。下载并解压后得到kernel.git文件夹。

tar -xvf ~/download/linux-3.2.5-android-4.3_r1.tar.gz

(3)获取内核编译配置信息文件。

编译内核时需要使用configure,通常configure有很多选项,我们往往不知道需要那些选项。在运行Android模拟器时,有一个文件“/proc/config.gz”,这是当前内核的配置信息文件,把config.gz获取并解压到“kernel.git/”下,然后改名为.config。命令如下所示:

cd kernel.git/
emulator &
adb pull /proc/config.gz
gunzip config.gz
mv config .config
(4)修改Makefile。

修改195行的代码:

CROSS_COMPILE    = arm-none-linux-gnueabi-

将CROSS_COMPILE值改为arm-none-linux-gnueabi-,这是安装的交叉编译工具链的前缀,修改此处意在告诉make在编译的时候要使用该工具链。然后注释掉562和563行的如下代码:

#LDFLAGS_BUILD_ID = $(patsubst -Wl$(comma)%,%,/
#                  $(call ld-option, -Wl$(comma)--build-id,))

必须将上述代码中的build id 值注释掉,因为目前版本的Android内核不支持该选项。

(5)编译。

使用make进行编译,并同时生成zImage:

  LD      arch/arm/boot/compressed/vmlinux
  OBJCOPY arch/arm/boot/zImage
  Kernel: arch/arm/boot/zImage is ready
这样生成zImage大小为1.23 MB,android- sdk-linux_x86-4.3_r1/tools/lib/images/kernel-qemu是1.24 MB。

(6)使用模拟器加载内核测试,命令如下所示:

cd android/out/cupcake/out/target/product/generic
emulator -image system.img -data userdata.img -ramdisk ramdisk.img -kernel ~/project/android/kernel.git/ arch/arm/boot/zImage &

到此为止,模拟器就加载成功了。

相关文章
|
10月前
|
数据采集 监控 API
告别手动埋点!Android 无侵入式数据采集方案深度解析
传统的Android应用监控方案需要开发者在代码中手动添加埋点,不仅侵入性强、工作量大,还难以维护。本文深入探讨了基于字节码插桩技术的无侵入式数据采集方案,通过Gradle插件 + AGP API + ASM的技术组合,实现对应用性能、用户行为、网络请求等全方位监控,真正做到零侵入、易集成、高稳定。
989 96
|
Java 开发工具 Android开发
Android与iOS开发环境搭建全解析####
本文深入探讨了Android与iOS两大移动操作系统的开发环境搭建流程,旨在为初学者及有一定基础的开发者提供详尽指南。我们将从开发工具的选择、环境配置到第一个简单应用的创建,一步步引导读者步入移动应用开发的殿堂。无论你是Android Studio的新手还是Xcode的探索者,本文都将为你扫清开发道路上的障碍,助你快速上手并享受跨平台移动开发的乐趣。 ####
|
安全 Java Android开发
为什么大厂要求安卓开发者掌握Kotlin和Jetpack?深度解析现代Android开发生态优雅草卓伊凡
为什么大厂要求安卓开发者掌握Kotlin和Jetpack?深度解析现代Android开发生态优雅草卓伊凡
514 0
为什么大厂要求安卓开发者掌握Kotlin和Jetpack?深度解析现代Android开发生态优雅草卓伊凡
|
XML JavaScript Android开发
【Android】网络技术知识总结之WebView,HttpURLConnection,OKHttp,XML的pull解析方式
本文总结了Android中几种常用的网络技术,包括WebView、HttpURLConnection、OKHttp和XML的Pull解析方式。每种技术都有其独特的特点和适用场景。理解并熟练运用这些技术,可以帮助开发者构建高效、可靠的网络应用程序。通过示例代码和详细解释,本文为开发者提供了实用的参考和指导。
631 15
|
监控 Shell Linux
Android调试终极指南:ADB安装+多设备连接+ANR日志抓取全流程解析,覆盖环境变量配置/多设备调试/ANR日志分析全流程,附Win/Mac/Linux三平台解决方案
ADB(Android Debug Bridge)是安卓开发中的重要工具,用于连接电脑与安卓设备,实现文件传输、应用管理、日志抓取等功能。本文介绍了 ADB 的基本概念、安装配置及常用命令。包括:1) 基本命令如 `adb version` 和 `adb devices`;2) 权限操作如 `adb root` 和 `adb shell`;3) APK 操作如安装、卸载应用;4) 文件传输如 `adb push` 和 `adb pull`;5) 日志记录如 `adb logcat`;6) 系统信息获取如屏幕截图和录屏。通过这些功能,用户可高效调试和管理安卓设备。
10719 2
|
存储 Linux API
深入探索Android系统架构:从内核到应用层的全面解析
本文旨在为读者提供一份详尽的Android系统架构分析,从底层的Linux内核到顶层的应用程序框架。我们将探讨Android系统的模块化设计、各层之间的交互机制以及它们如何共同协作以支持丰富多样的应用生态。通过本篇文章,开发者和爱好者可以更深入理解Android平台的工作原理,从而优化开发流程和提升应用性能。
|
Java 调度 Android开发
安卓与iOS开发中的线程管理差异解析
在移动应用开发的广阔天地中,安卓和iOS两大平台各自拥有独特的魅力。如同东西方文化的差异,它们在处理多线程任务时也展现出不同的哲学。本文将带你穿梭于这两个平台之间,比较它们在线程管理上的核心理念、实现方式及性能考量,助你成为跨平台的编程高手。
|
存储 监控 算法
Java虚拟机(JVM)垃圾回收机制深度解析与优化策略####
本文旨在深入探讨Java虚拟机(JVM)的垃圾回收机制,揭示其工作原理、常见算法及参数调优方法。通过剖析垃圾回收的生命周期、内存区域划分以及GC日志分析,为开发者提供一套实用的JVM垃圾回收优化指南,助力提升Java应用的性能与稳定性。 ####
|
开发框架 Dart Android开发
安卓与iOS的跨平台开发:Flutter框架深度解析
在移动应用开发的海洋中,Flutter作为一艘灵活的帆船,正引领着开发者们驶向跨平台开发的新纪元。本文将揭开Flutter神秘的面纱,从其架构到核心特性,再到实际应用案例,我们将一同探索这个由谷歌打造的开源UI工具包如何让安卓与iOS应用开发变得更加高效而统一。你将看到,借助Flutter,打造精美、高性能的应用不再是难题,而是变成了一场创造性的旅程。
|
11月前
|
Oracle 关系型数据库 虚拟化
在VMware的Win10虚拟机中安装使用ENSP
本文介绍了在Windows 10虚拟机上安装ENSP及相关软件的全过程,包括VirtualBox、WinPcap、Wireshark、VLC和ENSP的安装步骤,并提供图文演示,帮助用户顺利完成配置与测试。
2685 134

推荐镜像

更多