Linux学习(三) 展讯Android 4.0编译 -- Makefile
2015-08-06 16:41
501 查看
在执行完envsetup操作后,只要输入make bootimage, makebootloader等命令就可以直接编译生成相关的文件,那么,makefile是如何定义才达到这样的目标呢?以Linux kernel生成的bootimage为例,我们一步一步的来学习Android是如何编译各模块的。
在命令行输入 make bootimage的命令,可以看到结果如下
rickzhang@android15:~/work/vlx40$ make
bootimage
============================================
PLATFORM_VERSION_CODENAME=REL
PLATFORM_VERSION=4.0.3
TARGET_PRODUCT=sp8810gabase
TARGET_BUILD_VARIANT=userdebug
TARGET_BUILD_TYPE=release
TARGET_BUILD_APPS=
TARGET_ARCH=arm
TARGET_ARCH_VARIANT=armv7-a-neon
HOST_ARCH=x86
HOST_OS=linux
HOST_BUILD_TYPE=release
BUILD_ID=IML74K
============================================
No private recovery resources for TARGET_DEVICE sp8810ga
make: Warning: File `build/target/board/Android.mk' has modification time 4.2e+02 s in the future
make -C kernel O=../out/target/product/sp8810ga/obj/KERNEL ARCH=arm CROSS_COMPILE=arm-eabi- modules_prepare
make[1]: Entering directory `/home/rickzhang/work/vlx40/kernel'
Using /home/rickzhang/work/vlx40/kernel as source for kernel
GEN /home/rickzhang/work/vlx40/out/target/product/sp8810ga/obj/KERNEL/Makefile
CHK include/linux/version.h
CHK include/generated/utsrelease.h
make[3]: `include/generated/mach-types.h' is up to date.
CALL /home/rickzhang/work/vlx40/kernel/scripts/checksyscalls.sh
..........
make[1]: Leaving directory `/home/rickzhang/work/vlx40/kernel'
target Prebuilt: (out/target/product/sp8810ga/kernel)
Target boot image: out/target/product/sp8810ga/boot.img
从Build结果可以看出,最后在out/target/product/sp8810ga/目录下生成了kernel, ramdisk.img, bootimage三个文件,其中,bootimage是kernel和ramdisk.img,再加上KERNEL_CMDLINE,FLASH_PAGE_SIZE 4个部分而生成的。那么,这些文件的依赖关系,是如何从Android 根目录下找到的呢?
首先给出基本的mk文件依赖关系:
./Makefile --> build/core/main.mk --> build/core/Makefile
|
--> build/target/board/Android.mk --> device/sprd/sp8810ga/AndroidBoard.mk --> kernel/AndroidKernel.mk --> kernel/Makefile
1. main.mk 分析
main.mk是Android编译体系中的核心文件,它通过搜索并include所有目录下的Androd.mk文件来完成所有模块的编译工作。
首先分析 make bootimage命令,如果在Android根目录下运行make命令,GNU make工具会查找当前目录的Makefile来执行,看看根目录下的Makefile内容:
rickzhang@android15:~/work/vlx40$ vi
Makefile
1 ### DO NOT EDIT THIS FILE ###
2 include build/core/main.mk
3 ### DO NOT EDIT THIS FILE ###
实际上Makefile是include了build/core/目录下的main.mk文件来执行,继续查看 main.mk:
747 .PHONY: bootimage
748 bootimage: $(INSTALLED_BOOTIMAGE_TARGET)
从这条语句可以得知,make bootimage的依赖Target就是 INSTALLED_BOOTIMAGE_TARGET,现在我们要找到这个变量,看看bootimage是如何编译生成的。
另外,从main.mk的体系来看,它include了大部分的makefile以编译各模块:
53 BUILD_SYSTEM := $(TOPDIR)build/core
681 include $(BUILD_SYSTEM)/Makefile
从以上681行可以看出,main.mk include 了 build/core/Makefile;
525 subdir_makefiles := \
526 $(shell build/tools/findleaves.py --prune=out --prune=.repo --prune=.git $(subdirs) Android.mk)
527
528 include $(subdir_makefiles)
从以上528行可以看到,main.mk include了 所有子模块下的Android.mk文件;
2. build/core/Makefile 分析
从build/core/Makefile中,可以找到关于INSTALLED_BOOTIMAGE_TARGET的定义。
rickzhang@android11:~/work/vlx40$ vi
build/core/Makefile
378 INSTALLED_BOOTIMAGE_TARGET := $(PRODUCT_OUT)/boot.img
390 $(INSTALLED_BOOTIMAGE_TARGET): $(MKBOOTIMG) $(INTERNAL_BOOTIMAGE_FILES)
391 $(call pretty,"Target boot image: $@")
392 $(hide) $(MKBOOTIMG) $(INTERNAL_BOOTIMAGE_ARGS) --output $@
393 $(hide) $(call assert-max-image-size,$@,$(BOARD_BOOTIMAGE_PARTITION_SIZE),raw)
从378行可以看出,INSTALLED_BOOTIMAGE_TARGET的定义被扩展为 $(PRODUCT_OUT)/boot.img,由于之前在envsetup.sh中已经选择了PRODUCT,因此$(PRODUCT_OUT)为 out/target/product/sp8810ga,make image命令就是要在该目录下生成 bootimage文件。从392行来看,需要使用$(MKBOOTIMG)工具,针对INTERNAL_BOOTIMAGE_ARGS来生成
bootimage。实际上,bootimage是由一系列的文件和参数组成的:
354 # -----------------------------------------------------------------
355 # the boot image, which is a collection of other images.
356 INTERNAL_BOOTIMAGE_ARGS := \
357 $(addprefix --second ,$(INSTALLED_2NDBOOTLOADER_TARGET)) \
358 --kernel $(INSTALLED_KERNEL_TARGET) \
359 --ramdisk $(INSTALLED_RAMDISK_TARGET)
360
361 INTERNAL_BOOTIMAGE_FILES := $(filter-out --%,$(INTERNAL_BOOTIMAGE_ARGS))
362
363 BOARD_KERNEL_CMDLINE := $(strip $(BOARD_KERNEL_CMDLINE))
364 ifdef BOARD_KERNEL_CMDLINE
365 INTERNAL_BOOTIMAGE_ARGS += --cmdline "$(BOARD_KERNEL_CMDLINE)"
366 endif
367
368 BOARD_KERNEL_BASE := $(strip $(BOARD_KERNEL_BASE))
369 ifdef BOARD_KERNEL_BASE
370 INTERNAL_BOOTIMAGE_ARGS += --base $(BOARD_KERNEL_BASE)
371 endif
372
373 BOARD_KERNEL_PAGESIZE := $(strip $(BOARD_KERNEL_PAGESIZE))
374 ifdef BOARD_KERNEL_PAGESIZE
375 INTERNAL_BOOTIMAGE_ARGS += --pagesize $(BOARD_KERNEL_PAGESIZE)
376 endif
从上述信息可以看到,bootimage(INTERNAL_BOOTIMAGE_ARGS)是由 --second $(INSTALLED_2NDBOOTLOADER_TARGET), --kernel $(INSTALLED_KERNEL_TARGET), --ramdisk $(INSTALLED_RAMDISK_TARGET), --cmdline "$(BOARD_KERNEL_CMDLINE)",
--base $(BOARD_KERNEL_BASE), --pagesize $(BOARD_KERNEL_PAGESIZE) 所组成的。
因此,我们目前搜索的目标变成了INSTALLED_KERNEL_TARGET,它就是Linux kernel编译后生成的文件。
3. build/target/board/Android.mk 分析
之前已经看到,main.mk文件会搜索并include所有子目录下的Android.mk文件,因此 build/target/board/Android.mk也已经被main.mk所引用。查看该文件,可以发现如下信息:
18 INSTALLED_KERNEL_TARGET := $(PRODUCT_OUT)/kernel
23 -include $(TARGET_DEVICE_DIR)/AndroidBoard.mk
因此,如果希望build INSTALLED_KERNEL_TARGET,就需要找到哪里编译 out/target/product/sp8810ga/kernel文件的,这时可以从 $(TARGET_DEVICE_DIR)/AndroidBoard.mk中来寻找;这里 -include的含义是在include AndroidBoard.mk文件时,遇到错误也不会中断;
4. device/sprd/sp8810ga/AndroidBoard.mk 分析
打开AndroidBoard.mk文件,查看其内容,寻找 INSTALLED_KERNEL_TARGET的依赖关系
14 include kernel/AndroidKernel.mk
15
16 file := $(INSTALLED_KERNEL_TARGET)
17 ALL_PREBUILT += $(file)
18 $(file) : $(TARGET_PREBUILT_KERNEL) | $(ACP)
19 $(transform-prebuilt-to-target)
从18行来看,为了build $(file),需要找到 TARGET_PREBUILT_KERNEL,而这个宏又可以从kernel/AndroidKernel.mk来寻找,这一次终于进入到kernel的目录中了;
注:分析其他产品的build规则,也是最终寻找这个TARGET_PREBUILT_KERNEL,例如 samsung平台的tuna:
rickzhang@android15:~/work/vlx40$ vi
device/samsung/tuna/device.mk
22 ifeq ($(TARGET_PREBUILT_KERNEL),)
23 LOCAL_KERNEL := device/samsung/tuna/kernel
24 else
25 LOCAL_KERNEL := $(TARGET_PREBUILT_KERNEL)
26 endif
TI平台的Panda:
rickzhang@android15:~/work/vlx40$ vi
device/ti/panda/device.mk
17 ifeq ($(TARGET_PREBUILT_KERNEL),)
18 LOCAL_KERNEL := device/ti/panda/kernel
19 else
20 LOCAL_KERNEL := $(TARGET_PREBUILT_KERNEL)
21 endif
可以看到,这些平台都是使用预先编译好的kernel文件,该文件已经放在device/xx/xx/目录下,如果需要自己编译kernel文件,则需要定义$TARGET_PREBUILT_KERNEL,本文不再分析其他平台的build实现过程。
5. kernel/AndroidKernel.mk 分析
rickzhang@android15:~/work/vlx40$ vi
kernel/AndroidKernel.mk
1
2 KERNEL_OUT := $(TARGET_OUT_INTERMEDIATES)/KERNEL
3 KERNEL_CONFIG := $(KERNEL_OUT)/.config
4 KERNEL_MODULES_OUT := $(TARGET_OUT)/lib/modules
5
6 ifeq ($(USES_UNCOMPRESSED_KERNEL),true)
7 TARGET_PREBUILT_KERNEL := $(KERNEL_OUT)/arch/arm/boot/Image
8 else
9 TARGET_PREBUILT_KERNEL := $(KERNEL_OUT)/arch/arm/boot/zImage
10 endif
11
12 $(KERNEL_OUT):
13 @echo "==== Start Kernel Compiling ... ===="
14
15 $(KERNEL_CONFIG): kernel/arch/arm/configs/$(KERNEL_DEFCONFIG)
16 mkdir -p $(KERNEL_OUT)
17 $(MAKE) -C kernel O=../$(KERNEL_OUT) ARCH=arm CROSS_COMPILE=arm-eabi- $(KERNEL_DEFCONFIG)
18
19 $(TARGET_PREBUILT_KERNEL) : $(KERNEL_OUT) $(KERNEL_CONFIG)
20 $(MAKE) -C kernel O=../$(KERNEL_OUT) ARCH=arm CROSS_COMPILE=arm-eabi- modules_prepare
21 $(MAKE) -C kernel O=../$(KERNEL_OUT) ARCH=arm CROSS_COMPILE=arm-eabi- headers_install
22 $(MAKE) -C kernel O=../$(KERNEL_OUT) ARCH=arm CROSS_COMPILE=arm-eabi- zImage -j4
23 $(MAKE) -C kernel O=../$(KERNEL_OUT) ARCH=arm CROSS_COMPILE=arm-eabi- modules
24 @-mkdir -p $(KERNEL_MODULES_OUT)
25 @-find $(KERNEL_OUT) -name *.ko | xargs -I{} cp {} $(KERNEL_MODULES_OUT)
从AndroidKernel.mk来看,如果需要build $TARGET_PREBUILT_TARGET,那么就需要调用到make函数进行真正的编译了,例如:
make -C kernel O=../ ..................... zImage -j4
可以看出来,这里实际上是寻找kernel目录下的Makefile文件,然后编译zImage,在生成zImage的同时,也生成了Image。从AndroidKernel.mk文件来看,使用:
18 $(file) : $(TARGET_PREBUILT_KERNEL) | $(ACP)
19 $(transform-prebuilt-to-target)
语句,将Image 通过 $(ACP)程序转变为kernel文件。Image可以从如下地址找到:
7 TARGET_PREBUILT_KERNEL := $(KERNEL_OUT)/arch/arm/boot/Image
我们可以通过 make -n bootimage > build_log.txt 文件,记录下来这个make的过程,-n表示只记录,并不真正执行make的编译动作。
echo "target Prebuilt: (out/target/product/sp8810ga/kernel)"
mkdir -p out/target/product/sp8810ga/
out/host/linux-x86/bin/acp -fp out/target/product/sp8810ga/obj/KERNEL/arch/arm/boot/Image out/target/product/sp8810ga/kernel
echo "Target boot image: out/target/product/sp8810ga/boot.img"
out/host/linux-x86/bin/mkbootimg --kernel out/target/product/sp8810ga/kernel --ramdisk
out/target/product/sp8810ga/ramdisk.img --cmdline "console=ttyS1,115200n8 mem=239M" --base 0x00000000 --output out/target/product/sp8810ga/boot.img
从上述信息可以看出来,通过make zImage -j4 的动作以后,在out/target/product/sp8810ga/obj/KERNEL/arch/arm/boot目录下生成了Image和zImage文件,通过out/host/linux-x86/bin/acp工具,将Image转变成为kernel,然后再使用mkbootimage工具,将kernel, ramdisk, cmdline,
base等信息一起打包生成了boot.img。
在命令行输入 make bootimage的命令,可以看到结果如下
rickzhang@android15:~/work/vlx40$ make
bootimage
============================================
PLATFORM_VERSION_CODENAME=REL
PLATFORM_VERSION=4.0.3
TARGET_PRODUCT=sp8810gabase
TARGET_BUILD_VARIANT=userdebug
TARGET_BUILD_TYPE=release
TARGET_BUILD_APPS=
TARGET_ARCH=arm
TARGET_ARCH_VARIANT=armv7-a-neon
HOST_ARCH=x86
HOST_OS=linux
HOST_BUILD_TYPE=release
BUILD_ID=IML74K
============================================
No private recovery resources for TARGET_DEVICE sp8810ga
make: Warning: File `build/target/board/Android.mk' has modification time 4.2e+02 s in the future
make -C kernel O=../out/target/product/sp8810ga/obj/KERNEL ARCH=arm CROSS_COMPILE=arm-eabi- modules_prepare
make[1]: Entering directory `/home/rickzhang/work/vlx40/kernel'
Using /home/rickzhang/work/vlx40/kernel as source for kernel
GEN /home/rickzhang/work/vlx40/out/target/product/sp8810ga/obj/KERNEL/Makefile
CHK include/linux/version.h
CHK include/generated/utsrelease.h
make[3]: `include/generated/mach-types.h' is up to date.
CALL /home/rickzhang/work/vlx40/kernel/scripts/checksyscalls.sh
..........
make[1]: Leaving directory `/home/rickzhang/work/vlx40/kernel'
target Prebuilt: (out/target/product/sp8810ga/kernel)
Target boot image: out/target/product/sp8810ga/boot.img
从Build结果可以看出,最后在out/target/product/sp8810ga/目录下生成了kernel, ramdisk.img, bootimage三个文件,其中,bootimage是kernel和ramdisk.img,再加上KERNEL_CMDLINE,FLASH_PAGE_SIZE 4个部分而生成的。那么,这些文件的依赖关系,是如何从Android 根目录下找到的呢?
首先给出基本的mk文件依赖关系:
./Makefile --> build/core/main.mk --> build/core/Makefile
|
--> build/target/board/Android.mk --> device/sprd/sp8810ga/AndroidBoard.mk --> kernel/AndroidKernel.mk --> kernel/Makefile
1. main.mk 分析
main.mk是Android编译体系中的核心文件,它通过搜索并include所有目录下的Androd.mk文件来完成所有模块的编译工作。
首先分析 make bootimage命令,如果在Android根目录下运行make命令,GNU make工具会查找当前目录的Makefile来执行,看看根目录下的Makefile内容:
rickzhang@android15:~/work/vlx40$ vi
Makefile
1 ### DO NOT EDIT THIS FILE ###
2 include build/core/main.mk
3 ### DO NOT EDIT THIS FILE ###
实际上Makefile是include了build/core/目录下的main.mk文件来执行,继续查看 main.mk:
747 .PHONY: bootimage
748 bootimage: $(INSTALLED_BOOTIMAGE_TARGET)
从这条语句可以得知,make bootimage的依赖Target就是 INSTALLED_BOOTIMAGE_TARGET,现在我们要找到这个变量,看看bootimage是如何编译生成的。
另外,从main.mk的体系来看,它include了大部分的makefile以编译各模块:
53 BUILD_SYSTEM := $(TOPDIR)build/core
681 include $(BUILD_SYSTEM)/Makefile
从以上681行可以看出,main.mk include 了 build/core/Makefile;
525 subdir_makefiles := \
526 $(shell build/tools/findleaves.py --prune=out --prune=.repo --prune=.git $(subdirs) Android.mk)
527
528 include $(subdir_makefiles)
从以上528行可以看到,main.mk include了 所有子模块下的Android.mk文件;
2. build/core/Makefile 分析
从build/core/Makefile中,可以找到关于INSTALLED_BOOTIMAGE_TARGET的定义。
rickzhang@android11:~/work/vlx40$ vi
build/core/Makefile
378 INSTALLED_BOOTIMAGE_TARGET := $(PRODUCT_OUT)/boot.img
390 $(INSTALLED_BOOTIMAGE_TARGET): $(MKBOOTIMG) $(INTERNAL_BOOTIMAGE_FILES)
391 $(call pretty,"Target boot image: $@")
392 $(hide) $(MKBOOTIMG) $(INTERNAL_BOOTIMAGE_ARGS) --output $@
393 $(hide) $(call assert-max-image-size,$@,$(BOARD_BOOTIMAGE_PARTITION_SIZE),raw)
从378行可以看出,INSTALLED_BOOTIMAGE_TARGET的定义被扩展为 $(PRODUCT_OUT)/boot.img,由于之前在envsetup.sh中已经选择了PRODUCT,因此$(PRODUCT_OUT)为 out/target/product/sp8810ga,make image命令就是要在该目录下生成 bootimage文件。从392行来看,需要使用$(MKBOOTIMG)工具,针对INTERNAL_BOOTIMAGE_ARGS来生成
bootimage。实际上,bootimage是由一系列的文件和参数组成的:
354 # -----------------------------------------------------------------
355 # the boot image, which is a collection of other images.
356 INTERNAL_BOOTIMAGE_ARGS := \
357 $(addprefix --second ,$(INSTALLED_2NDBOOTLOADER_TARGET)) \
358 --kernel $(INSTALLED_KERNEL_TARGET) \
359 --ramdisk $(INSTALLED_RAMDISK_TARGET)
360
361 INTERNAL_BOOTIMAGE_FILES := $(filter-out --%,$(INTERNAL_BOOTIMAGE_ARGS))
362
363 BOARD_KERNEL_CMDLINE := $(strip $(BOARD_KERNEL_CMDLINE))
364 ifdef BOARD_KERNEL_CMDLINE
365 INTERNAL_BOOTIMAGE_ARGS += --cmdline "$(BOARD_KERNEL_CMDLINE)"
366 endif
367
368 BOARD_KERNEL_BASE := $(strip $(BOARD_KERNEL_BASE))
369 ifdef BOARD_KERNEL_BASE
370 INTERNAL_BOOTIMAGE_ARGS += --base $(BOARD_KERNEL_BASE)
371 endif
372
373 BOARD_KERNEL_PAGESIZE := $(strip $(BOARD_KERNEL_PAGESIZE))
374 ifdef BOARD_KERNEL_PAGESIZE
375 INTERNAL_BOOTIMAGE_ARGS += --pagesize $(BOARD_KERNEL_PAGESIZE)
376 endif
从上述信息可以看到,bootimage(INTERNAL_BOOTIMAGE_ARGS)是由 --second $(INSTALLED_2NDBOOTLOADER_TARGET), --kernel $(INSTALLED_KERNEL_TARGET), --ramdisk $(INSTALLED_RAMDISK_TARGET), --cmdline "$(BOARD_KERNEL_CMDLINE)",
--base $(BOARD_KERNEL_BASE), --pagesize $(BOARD_KERNEL_PAGESIZE) 所组成的。
因此,我们目前搜索的目标变成了INSTALLED_KERNEL_TARGET,它就是Linux kernel编译后生成的文件。
3. build/target/board/Android.mk 分析
之前已经看到,main.mk文件会搜索并include所有子目录下的Android.mk文件,因此 build/target/board/Android.mk也已经被main.mk所引用。查看该文件,可以发现如下信息:
18 INSTALLED_KERNEL_TARGET := $(PRODUCT_OUT)/kernel
23 -include $(TARGET_DEVICE_DIR)/AndroidBoard.mk
因此,如果希望build INSTALLED_KERNEL_TARGET,就需要找到哪里编译 out/target/product/sp8810ga/kernel文件的,这时可以从 $(TARGET_DEVICE_DIR)/AndroidBoard.mk中来寻找;这里 -include的含义是在include AndroidBoard.mk文件时,遇到错误也不会中断;
4. device/sprd/sp8810ga/AndroidBoard.mk 分析
打开AndroidBoard.mk文件,查看其内容,寻找 INSTALLED_KERNEL_TARGET的依赖关系
14 include kernel/AndroidKernel.mk
15
16 file := $(INSTALLED_KERNEL_TARGET)
17 ALL_PREBUILT += $(file)
18 $(file) : $(TARGET_PREBUILT_KERNEL) | $(ACP)
19 $(transform-prebuilt-to-target)
从18行来看,为了build $(file),需要找到 TARGET_PREBUILT_KERNEL,而这个宏又可以从kernel/AndroidKernel.mk来寻找,这一次终于进入到kernel的目录中了;
注:分析其他产品的build规则,也是最终寻找这个TARGET_PREBUILT_KERNEL,例如 samsung平台的tuna:
rickzhang@android15:~/work/vlx40$ vi
device/samsung/tuna/device.mk
22 ifeq ($(TARGET_PREBUILT_KERNEL),)
23 LOCAL_KERNEL := device/samsung/tuna/kernel
24 else
25 LOCAL_KERNEL := $(TARGET_PREBUILT_KERNEL)
26 endif
TI平台的Panda:
rickzhang@android15:~/work/vlx40$ vi
device/ti/panda/device.mk
17 ifeq ($(TARGET_PREBUILT_KERNEL),)
18 LOCAL_KERNEL := device/ti/panda/kernel
19 else
20 LOCAL_KERNEL := $(TARGET_PREBUILT_KERNEL)
21 endif
可以看到,这些平台都是使用预先编译好的kernel文件,该文件已经放在device/xx/xx/目录下,如果需要自己编译kernel文件,则需要定义$TARGET_PREBUILT_KERNEL,本文不再分析其他平台的build实现过程。
5. kernel/AndroidKernel.mk 分析
rickzhang@android15:~/work/vlx40$ vi
kernel/AndroidKernel.mk
1
2 KERNEL_OUT := $(TARGET_OUT_INTERMEDIATES)/KERNEL
3 KERNEL_CONFIG := $(KERNEL_OUT)/.config
4 KERNEL_MODULES_OUT := $(TARGET_OUT)/lib/modules
5
6 ifeq ($(USES_UNCOMPRESSED_KERNEL),true)
7 TARGET_PREBUILT_KERNEL := $(KERNEL_OUT)/arch/arm/boot/Image
8 else
9 TARGET_PREBUILT_KERNEL := $(KERNEL_OUT)/arch/arm/boot/zImage
10 endif
11
12 $(KERNEL_OUT):
13 @echo "==== Start Kernel Compiling ... ===="
14
15 $(KERNEL_CONFIG): kernel/arch/arm/configs/$(KERNEL_DEFCONFIG)
16 mkdir -p $(KERNEL_OUT)
17 $(MAKE) -C kernel O=../$(KERNEL_OUT) ARCH=arm CROSS_COMPILE=arm-eabi- $(KERNEL_DEFCONFIG)
18
19 $(TARGET_PREBUILT_KERNEL) : $(KERNEL_OUT) $(KERNEL_CONFIG)
20 $(MAKE) -C kernel O=../$(KERNEL_OUT) ARCH=arm CROSS_COMPILE=arm-eabi- modules_prepare
21 $(MAKE) -C kernel O=../$(KERNEL_OUT) ARCH=arm CROSS_COMPILE=arm-eabi- headers_install
22 $(MAKE) -C kernel O=../$(KERNEL_OUT) ARCH=arm CROSS_COMPILE=arm-eabi- zImage -j4
23 $(MAKE) -C kernel O=../$(KERNEL_OUT) ARCH=arm CROSS_COMPILE=arm-eabi- modules
24 @-mkdir -p $(KERNEL_MODULES_OUT)
25 @-find $(KERNEL_OUT) -name *.ko | xargs -I{} cp {} $(KERNEL_MODULES_OUT)
从AndroidKernel.mk来看,如果需要build $TARGET_PREBUILT_TARGET,那么就需要调用到make函数进行真正的编译了,例如:
make -C kernel O=../ ..................... zImage -j4
可以看出来,这里实际上是寻找kernel目录下的Makefile文件,然后编译zImage,在生成zImage的同时,也生成了Image。从AndroidKernel.mk文件来看,使用:
18 $(file) : $(TARGET_PREBUILT_KERNEL) | $(ACP)
19 $(transform-prebuilt-to-target)
语句,将Image 通过 $(ACP)程序转变为kernel文件。Image可以从如下地址找到:
7 TARGET_PREBUILT_KERNEL := $(KERNEL_OUT)/arch/arm/boot/Image
我们可以通过 make -n bootimage > build_log.txt 文件,记录下来这个make的过程,-n表示只记录,并不真正执行make的编译动作。
echo "target Prebuilt: (out/target/product/sp8810ga/kernel)"
mkdir -p out/target/product/sp8810ga/
out/host/linux-x86/bin/acp -fp out/target/product/sp8810ga/obj/KERNEL/arch/arm/boot/Image out/target/product/sp8810ga/kernel
echo "Target boot image: out/target/product/sp8810ga/boot.img"
out/host/linux-x86/bin/mkbootimg --kernel out/target/product/sp8810ga/kernel --ramdisk
out/target/product/sp8810ga/ramdisk.img --cmdline "console=ttyS1,115200n8 mem=239M" --base 0x00000000 --output out/target/product/sp8810ga/boot.img
从上述信息可以看出来,通过make zImage -j4 的动作以后,在out/target/product/sp8810ga/obj/KERNEL/arch/arm/boot目录下生成了Image和zImage文件,通过out/host/linux-x86/bin/acp工具,将Image转变成为kernel,然后再使用mkbootimage工具,将kernel, ramdisk, cmdline,
base等信息一起打包生成了boot.img。
相关文章推荐
- linux内核日志 dmesg 出现的提示及含意
- 为Python配置caffe(基于linux)
- Linux 磁盘挂载共享
- 开发笔记-Linux-VI-MySQL
- Linux时间子系统之八:动态时钟框架(CONFIG_NO_HZ、tickless)
- Linux进程间通讯基础
- Linux时间子系统之七:定时器的应用--msleep(),hrtimer_nanosleep()
- 三条Linux命令查看硬件信息
- kickstart+vsftp+dhcp+tftp 无人值守安装centos6
- Linux时间子系统之六:高精度定时器(HRTIMER)的原理和实现
- Linux时间子系统之五:低分辨率定时器的原理和实现
- Linux时间子系统之四:定时器的引擎:clock_event_device
- Linux时间子系统之三:时间的维护者:timekeeper
- CentOS 6.5 安装 git
- linux 定制ISO
- linux rar
- Linux添加/删除用户和用户组
- linux 根空间消失
- 如何在Linux下查找可执行文件
- Linux多进程程序设计