[Android] i.MX6 Android源码中分离U-Boot和Linux-Kernel独立编译环境

以下内容针对Ubuntu 14.04.5操作系统上编译Android 4.3版本源码,其他版本Android源码编译环境的结构类似的话应该可以作为参考。

1. 分析主Makefile获取编译器

从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文件夹下作为独立编译环境的编译器来使用。

2. 创建独立编译环境

2.1 放置编译器及U-Boot、Kernel代码

建立新文件夹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

2.2 创建环境变量设置文件

在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-

2.3 创建独立编译环境Makefile

接着在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;

2.4 创建编译/清除U-Boot和Kernel的脚本

在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."

2.5 放置BoardConfig.mk文件及生成boot.img用的Ramdisk文件和tools二进制文件

2.5.1 放置BoardConfig.mk文件

正常根据公司名称和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文件,请注意放置时候保证脚本能够找到并读取此文件即可。


2.5.2 放置Ramdisk文件

编译生成boot.img文件时候需要先从LinuxKernel源码编译生成zImage文件,然后将zImage文件与生成好的ramdisk.img文件合并并加入Commandline参数来生成boot.img文件。
项目中ramdisk.img文件中的rootfs文件系统通常不会发生变化,所以将Android源码全编译生成的ramdisk.img文件copy过来,放置到bsp_build_env/ramdisk路径下供生成boot.img文件用。


2.5.3 放置tools二进制文件文件

将Android源码全编译后在out/host/linux-x86/bin 路径下会生成如下二进制文件,生成boot.img文件时候需要使用到:
minigzip
mkbootfs
mkbootimg

上面3个文件复制到bsp_build_env/tools路径下。
bootimage_make.sh脚本中会使用这几个工具生成boot.img


3. 测试独立编译环境生成结果

至此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
证明搭建的独立编译环境可以正常工作。

你可能感兴趣的:(Android)