以下内容针对Ubuntu 14.04.5操作系统上编译Android 4.3版本源码,其他版本Android源码编译环境的结构类似的话应该可以作为参考。
从build/core/Makefile文件中查看.PHONY: kernelimage和.PHONY: bootloader后看到以下内容
BOOTLOADER_CROSS_TOOLCHAIN := `pwd`/prebuilts/gcc/linux-x86/arm/arm-eabi-4.6/bin/arm-eabi-
KERNEL_CROSS_TOOLCHAIN := `pwd`/prebuilts/gcc/linux-x86/arm/arm-eabi-4.6/bin/arm-eabi-
由此可以确定编译U-Boot和Kernel的交叉编译工具链都指向如下路径:
prebuilts/gcc/linux-x86/arm/arm-eabi-4.6/
所以将此路径下的所有文件Copy到新建的compiler文件夹下作为独立编译环境的编译器来使用。
建立新文件夹bsp_build_env作为根目录,bsp_build_env/compiler/arm-eabi-4.6路径下ls结果如下:
SOURCES
arm-eabi
bin
include
lib
libexec
share
原来Android源码下的kernel_imx 和 bootable/bootloader/uboot-imx 路径是两个的独立的git工程,不需要变化,仍然按照从服务器上直接获取的方式git clone到bsp_build_env目录下
现在bsp_build_env目录下有三个文件夹了
compiler
kernel_imx
uboot-imx
在bsp_build_env下创建envsetup文件,内容如下:
export PATH=`pwd`/compiler/arm-eabi-4.6/bin:$PATH
export ARCH=arm
export CC=arm-eabi-gcc
export CXX=arm-eabi-g++
export CPP="arm-eabi-gcc -E"
export AS=arm-eabi-as
export LD=arm-eabi-ld
export GDB=arm-eabi-gdb
export STRIP=arm-eabi-strip
export RANLIB=arm-eabi-ranlib
export OBJCOPY=arm-eabi-objcopy
export OBJDUMP=arm-eabi-objdump
export AR=arm-eabi-ar
export NM=arm-eabi-nm
export TARGET_PREFIX=arm-eabi-
export CROSS_COMPILE=arm-eabi-
接着在bsp_build_env下创建Makefile文件,内容如下:
bootimage:
@sh script/bootimage_make.sh;
image-mfg:
@sh script/image_mfg_make.sh;
uboot:
@sh script/bootloader_make.sh;
uboot-mfg:
@sh script/bootloader_mfg_make.sh;
clean-kernel:
@sh script/clean_kernel.sh;
clean-uboot:
@sh script/clean_uboot.sh;
在bsp_build_env下创建script目录,其中编写以下shell脚本文件
bootloader_make.sh
(编译生成u-boot.bin)
bootloader_mfg_make.sh
(编译生成u-boot-mfg.bin, 用于Mfgtool)
bootimage_make.sh
(编译生成boot.img)
image_mfg_make.sh
(编译生成uImage-mfg, 用于Mfgtool)
clean_kernel.sh
(清除编译Kernel生成的中间文件和boot.img、uImage-mfg文件)
clean_uboot.sh
(清除编译U-Boot生成的中间文件和u-boot.bin、u-boot-mfg.bin)
注意:以下脚本中的config配置文件名称的前缀中有些xxxx内容需要根据使用的芯片类型和自定义的board名称等来填写实际的内容。
(1) bootloader_make.sh
#!/bin/sh
source `pwd`/envsetup
ubootdir=uboot-imx
start=`date +%s`
ls -al >/dev/null 2>&1
make -C $ubootdir distclean && \
make -C $ubootdir xxxx_android_config && \
make -C $ubootdir -j4 2>&1 | tee build_uboot.log && \
install -D uboot-imx/u-boot.bin output/u-boot.bin;
if [ -e "output/u-boot.bin" ];then
echo " u-boot.bin is ready";
else
echo " u-boot.bin make failed~~~";
fi;
end=`date +%s`
dif=$[ end - start ]
echo " U-Boot Build Script End($dif Seconds)."
(2) bootloader_mfg_make.sh
#!/bin/sh
source `pwd`/envsetup
ubootdir=uboot-imx
start=`date +%s`
ls -al >/dev/null 2>&1
make -C $ubootdir distclean && \
make -C $ubootdir xxxx_mfg_config && \
make -C $ubootdir -j4 2>&1 | tee build_uboot.log && \
install -D uboot-imx/u-boot.bin output/u-boot-mfg.bin;
if [ -e "output/u-boot-mfg.bin" ];then
echo " u-boot-mfg.bin is ready";
else
echo " u-boot-mfg.bin make failed~~~";
fi;
end=`date +%s`
dif=$[ end - start ]
echo " U-Boot for MFG Build Script End($dif Seconds)."
(3) bootimage_make.sh
#!/bin/sh
source `pwd`/envsetup;
kerneldir=kernel_imx
kernelcmdline=`grep "BOARD_KERNEL_CMDLINE := console=ttymxc0,115200" device/xxxx/xxxx/BoardConfig.mk | cut -d "=" -f 2- |sed 's/^[ \t]*//g'`
start=`date +%s`
ls -al >/dev/null 2>&1
make -C $kerneldir xxxx_android_defconfig \
&& make -C $kerneldir -j4 uImage 2>&1 | tee build_kernel.log \
&& install -D kernel_imx/arch/arm/boot/zImage output/kernel;
tools/mkbootimg --kernel output/kernel --ramdisk ramdisk/ramdisk.img --cmdline "$kernelcmdline" --base 0x10800000 --output output/boot.img;
if [ -e "output/boot.img" ];then
echo " boot.img is ready";
else
echo " boot.img make failed~~~";
fi;
rm -rf output/kernel;
echo " KernelCommandline: $kernelcmdline";
end=`date +%s`
dif=$[ end - start ]
echo " Kernel Build Script End($dif Seconds)."
(4) image_mfg_make.sh
#!/bin/bash
source `pwd`/envsetup;
kerneldir=kernel_imx
start=`date +%s`
ls -al >/dev/null 2>&1
make -C $kerneldir imx6_updater_defconfig \
&& make -C $kerneldir V=1 -j4 uImage 2>&1 | tee build_kernel.log \
&& install -D kernel_imx/arch/arm/boot/uImage output/uImage-mfg;
if [ -e "output/uImage-mfg" ];then
echo " uImage-mfg is ready";
else
echo " uImage-mfg make failed~~~";
fi;
end=`date +%s`
dif=$[ end - start ]
echo " uImage-mfg for MFG Build Script End($dif Seconds)."
(5) clean_kernel.sh
#!/bin/sh
source `pwd`/envsetup
kerneldirname=kernel_imx
make -C $kerneldirname clean && \
rm -rf output/kernel output/boot.img output/uImage-mfg
echo " Kernel output removed."
echo " Kernel Clean Script End."
(6) clean_uboot.sh
#!/bin/sh
source `pwd`/envsetup
ubootdir=uboot-imx
make -C $ubootdir distclean && \
rm -rf output/u-boot*.bin
echo " U-Boot output removed."
echo " U-Boot Clean Script End."
正常根据公司名称和Board名称会在Android源码的device文件夹下面放置和配置自己产品对应的公司名称和Board名称文件夹,下面会有一个配置文件设置编译生成boot.img时候传递给Kernel的Commandline参数
通常内容类似下面:
device/xxxx/xxxx/BoardConfig.mk
BOARD_KERNEL_CMDLINE := console=ttymxc0,115200 init=/init video=mxcfb0:dev=ldb,bpp=32 video=mxcfb1:off video=mxcfb2:off fbmem=10M vmalloc=400M androidboot.console=ttymxc0
上面的bootimage_make.sh脚本就是从device/xxxx/xxxx/BoardConfig.mk文件中查找”BOARD_KERNEL_CMDLINE := console=ttymxc0,115200”开头的这行内容并将其中的Commandline参数记录下来用于编译生成boot.img文件,请注意放置时候保证脚本能够找到并读取此文件即可。
编译生成boot.img文件时候需要先从LinuxKernel源码编译生成zImage文件,然后将zImage文件与生成好的ramdisk.img文件合并并加入Commandline参数来生成boot.img文件。
项目中ramdisk.img文件中的rootfs文件系统通常不会发生变化,所以将Android源码全编译生成的ramdisk.img文件copy过来,放置到bsp_build_env/ramdisk路径下供生成boot.img文件用。
将Android源码全编译后在out/host/linux-x86/bin 路径下会生成如下二进制文件,生成boot.img文件时候需要使用到:
minigzip
mkbootfs
mkbootimg
上面3个文件复制到bsp_build_env/tools路径下。
bootimage_make.sh脚本中会使用这几个工具生成boot.img
至此U-Boot和Kernel的处理编译环境已经搭建完毕,运行一下命令测试是否成功的生成对应文件或者能够清除编译生成结果。
(1) 生成output/u-boot.bin
make u-boot
(2) 生成output/u-boot-mfg.bin
make u-boot-mfg
(3) 生成output/boot.img
make bootimage
(4) 生成output/uImage-mfg
make image-mfg
(5) 清除Kernel编译生成临时文件及boot.img、uImage-mfg
make clean-kernel
(6) 清除U-Boot编译生成临时文件及u-boot.bin、u-boot-mfg.bin
make clean-uboot
测试确认可以正常生成和清除output下的
u-boot.bin
u-boot-mfg.bin
boot.img
uImage-mfg
证明搭建的独立编译环境可以正常工作。