二、android中bootimage的生成
0.linux VMLINUX 的生成
vmlinux(vmlinuz)是一个包含linux kernel的静态链接的可执行文件,文件型态可能是linux接受的可执行文件格式之一(ELF、COFF或a.out)。vmlinux是未压缩的内核,vmlinux 是ELF文件,即编译出来的最原始的文件。
下面以mtk6582分析为例子。
(1).先看out下的文件:/home/tonylau/tony-workspace/new-v387/my-ap/out/target/product/xxxx(项目名称),
dd该目录下包含所有的手机文件镜像,如bootimage,systemimage等等,还有需要用到的obj(临时文件)
(2).然后进入obj,进一步查看:/home/tonylau/tony-workspace/new-v387/my-ap/out/target/product/xxxx(项目名称)/obj
可以看出,该目录下包含生成(1)中各种image需要用到的临时文件,如app相关的,bootloader相关的,java相关的,kernel相关的(我们关心的是kernel相关的KERNEL_OBJ)
(3).在进入KERNEL_OBJ:/home/tonylau/tony-workspace/new-v387/my-ap/out/target/product//xxxx(项目名称)/obj/KERNEL_OBJ ====>>>>这是我们需要研究的编译vmlinux相关的地方。
====>>>>生成vmlinux:查看.vmlinux.cmd如下
【编译内核之后相应的文件会产生一个 .*.o.cmd的依赖文件, 据此文件可看出被编译的.o文件依赖的头文件,及被编译参数.
Linux Makefile通过在编译过程中生成的 .文件名.o.cmd(比如对于main.c文件,它对应的依赖文件名为.main.o.cmd)来定义相关的依赖关系。
】
( 依据arch/arm/kernel/vmlinux.lds 生成linux内核源码根目录下的vmlinux,这个vmlinux属于未压缩,带调试信息、符号表的最初的内核,大小约23MB;
根据链接脚本vmlinux.lds 链接生成了arch/arm/boot/compressed/vmlinux 文件。
/*在Build vmlinux小节的注释中,对vmlinux生成原理做了详尽的描述:
vmlinux: $(vmlinux-lds) $(vmlinux-init) $(vmlinux-main) vmlinux.o $(kallsyms.o) FORCE
vmlinux是由$(vmlinux-init) 和$(vmlinux-main)指定的目标文件最终链接生成的。通常它们是位于各个子目录下的built_int.o目标文件,一些特殊名字的.o文件由arch/$(ARCH)/Makefile生成。
目标文件.o链接为vmlinux的顺序是非常重要的,$(vmlinux-init)指定的目标文件优先级最高,接着是$(vmlinux-main),最后是kallsyms.o。于此同时System.map包含了内核所有的导出符号表。*/
)
cmd_vmlinux := arm-linux-androideabi-ld.bfd -EL -p --no-undefined -X --build-id -o vmlinux(目标文件) -T arch/arm/kernel/vmlinux.lds(依照文件) arch/arm/kernel/head.o arch/arm/kernel/init_task.o mediatek/custom/out/kernel/built-in.o xxx.o ...................(需要用到的各种o文件)
【PS】:vmlinux.lds:(初始化优先级)
__initcall_start = .;
*(.initcallearly.init) __initcall0_start = .;
*(.initcall0.init) *(.initcall0s.init) __initcall1_start = .;
*(.initcall1.init) *(.initcall1s.init) __initcall2_start = .;
*(.initcall2.init) *(.initcall2s.init) __initcall3_start = .;
*(.initcall3.init) *(.initcall3s.init) __initcall4_start = .;
*(.initcall4.init) *(.initcall4s.init) __initcall5_start = .;
*(.initcall5.init) *(.initcall5s.init) __initcallrootfs_start = .;
*(.initcallrootfs.init) *(.initcallrootfss.init) __initcall6_start = .;
*(.initcall6.init) *(.initcall6s.init) __initcall7_start = .;
*(.initcall7.init) *(.initcall7s.init) __initcall_end = .;
====>>>>生成mediatek/custom/out/kernel/built-in.o:查看.built-in.o.cmd如下,
cmd_mediatek/custom/out/kernel/built-in.o := arm-linux-androideabi-ld.bfd -EL -r -o mediatek/custom/out/kernel/built-in.o mediatek/custom/out/kernel/touchpanel/cyttsp4_mt_common.o mediatek/custom/out/kernel/touchpanel/cyttsp4_debug.o mediatek/custom/out/kernel/touchpanel/tpd_debug.o mediatek/custom/out/kernel/touchpanel/cyttsp4_i2c.o mediatek/custom/out/kernel/touchpanel/mtk_ttsp.o mediatek/custom/out/kernel/touchpanel/tpd_init.o mediatek/custom/out/kernel/touchpanel/cyttsp4_mtb.o mediatek/custom/out/kernel/touchpanel/cyttsp4_btn.o mediatek/custom/out/kernel/touchpanel/ft5206_driver.o(先编译) mediatek/custom/out/kernel/touchpanel/tpd_setting.o mediatek/custom/out/kernel/touchpanel/cyttsp4_core.o mediatek/custom/out/kernel/touchpanel/tpd_misc.o mediatek/custom/out/kernel/touchpanel/tpd_calibrate.o mediatek/custom/out/kernel/touchpanel/tpd_default.o mediatek/custom/out/kernel/touchpanel/focaltech_ctl.o mediatek/custom/out/kernel/touchpanel/cyttsp4_bus.o mediatek/custom/out/kernel/touchpanel/cyttsp4_loader.o mediatek/custom/out/kernel/touchpanel/tpd_button.o mediatek/custom/out/kernel/touchpanel/cyttsp4_device_access.o mediatek/custom/out/kernel/touchpanel/ft5x06_ex_fun.o mediatek/custom/out/kernel/touchpanel/mtk_tpd.o(后编译) mediatek/custom/out/kernel/cam_cal/a5142otp.o mediatek/custom/out/kernel/lens/FM50AF.o mediatek/custom/out/kernel/lens/dummy_lens.o mediatek/custom/out/kernel/magnetometer/cust_mag.o mediatek/custom/out/kernel/magnetometer/lsm303m.o mediatek/custom/out/kernel/magnetometer/mag.o mediatek/custom/out/kernel/flashlight/sub_strobe_2ndPart_2.o mediatek/custom/out/kernel/flashlight/strobe_part_id.o mediatek/custom/out/kernel/flashlight/leds_strobe.o mediatek/custom/out/kernel/flashlight/sub_strobe.o mediatek/custom/out/kernel/flashlight/main_strobe_2ndPart_2.o mediatek/custom/out/kernel/flashlight/kd_flashlightlist.o mediatek/custom/out/kernel/kpd/mtk_kpd_bkl.o mediatek/custom/out/kernel/vibrator/cust_vibrator.o mediatek/custom/out/kernel/lcm/hx8394a_dsi_vdo.o mediatek/custom/out/kernel/lcm/mt65xx_lcm_list.o mediatek/custom/out/kernel/alsps/stk3x1x.o mediatek/custom/out/kernel/alsps/cust_alsps.o mediatek/custom/out/kernel/dct/pmic_drv.o mediatek/custom/out/kernel/core/board.o mediatek/custom/out/kernel/camera/kd_camera_hw.o mediatek/custom/out/kernel/camera/dummyds.o mediatek/custom/out/kernel/imgsensor/sp2529yuv_Sensor.o mediatek/custom/out/kernel/imgsensor/gc2235_Sensor.o mediatek/custom/out/kernel/imgsensor/kd_sensorlist.o mediatek/custom/out/kernel/imgsensor/ov8858mipiraw_Sensor.o mediatek/custom/out/kernel/eeprom/dummy_eeprom.o mediatek/custom/out/kernel/sound/yusu_android_speaker.o mediatek/custom/out/kernel/headset/accdet_custom.o mediatek/custom/out/kernel/ssw/sim_switch.o mediatek/custom/out/kernel/leds/cust_leds.o mediatek/custom/out/kernel/accelerometer/lsm303d.o mediatek/custom/out/kernel/accelerometer/cust_acc.o mediatek/custom/out/kernel/accelerometer/accel.o
可以看出:其实结果就是把“:=”右边对应目录下的文件编译好,连接成build-in.o文件
====>>>>生成mediatek/custom/out/kernel/touchpanel/ft5206_driver.o:查看.ft5206_driver.o.cmd如下
cmd_mediatek/custom/out/kernel/touchpanel/ft5206_driver.o := arm-linux-androideabi-gcc -Wp,-MD,mediatek/custom/out/kernel/touchpanel/.ft5206_driver.o.d -nostdinc -isystem /home/tonylau/tony-workspace/new-v387/my-ap/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.7/bin/../lib/gcc/arm-linux-androideabi/4.7/include -I xxx(包含的头文件等等) -c -o mediatek/custom/out/kernel/touchpanel/ft5206_driver.o /home/tonylau/tony-workspace/new-v387/my-ap/kernel/mediatek/custom/out/kernel/touchpanel/ft5206_driver.c
1.linux 标准的zimage
该图来自 http://freeelectrons.com/docs/kernelinit
2.android 中的bootimage
在Android 产品中,内核格式是Linux标准的zImage,根文件系统采用ramdisk格式。这两者在Android下是直接合并在一起取名为boot.img,会放在一个独立分区当中。这个分区格式是Android自行制定的格式。
boot.img的格式比较简单,它主要分为三大块(有的可能有四块)
+—————–+
| boot header | 1 page
+—————–+
| kernel | n pages
+—————–+
| ramdisk | m pages
+—————–+
| second stage | o pages
+—————–+
n = (kernel_size + page_size – 1) / page_size
m = (ramdisk_size + page_size – 1) / page_size
o = (second_size + page_size – 1) / page_size
0. all entities are page_size aligned in flash
1. kernel and ramdisk are required (size != 0)
2. second is optional (second_size == 0 -> no second)