首先看看全志Android源文件的代码目录
A33_Vstar_Android_20170227.tar.bz2
A33_Vstar_Lichee_20170227.tar.bz2两个压缩包文件
进入ubuntu分别解压这两个文件夹
$ tar -vxf A33_Vstar_Android_20170227.tar.bz2
$ tar -vxf A33_Vstar_Lichee_20170227.tar.bz2
lichee 目录包含 buildroot 工具、uboot 源码和 Linux 内核源码
进入Lichee查看一下编译命令
$ cd lichee/
$ ls
brandy buildroot build.sh clean.sh linux-3.4 out README tools
$ vi build.sh
lichee目录下的build.sh
#!/bin/bash
set -e //表示在set -e后面的所有代码中只要出现返回值非零,整个脚本会退出
buildroot/scripts/mkcommon.sh $@ // $@:表示显示当前所有脚本参数的内容
接下来我们看看下这个脚本 /lichee/buildroot/scripts/common.sh
#!/bin/bash
set -e
//定义的变量
PLATFORM=""
MODULE=""
CUR_DIR=$PWD
OUT_DIR=$CUR_DIR/out
KERN_VER=3.3
KERN_DIR=$CUR_DIR/linux-${KERN_VER}
KERN_OUT_DIR=$KERN_DIR/output
BR_DIR=$CUR_DIR/buildroot
BR_OUT_DIR=$BR_DIR/output
U_BOOT_DIR=$CUR_DIR/u-boot
KERN_VER_RELEASE=3.3.0
update_kdir()
{
KERN_VER=$1
KERN_DIR=${CUR_DIR}/linux-${KERN_VER}
KERN_OUT_DIR=$KERN_DIR/output
}
/*帮助文件,就是在lichee文件下面执行./build.sh -h的时候会出现的提示内容
-h显示帮助信息
-p选择你所需要开发的平台
-k内核
-m所在的模块(比如kernel,uboot之类的)后面的脚本内容会用到这个参数
再下面就是几个例子*/
show_help()
{
printf "
NAME
build - The top level build script for Lichee Linux BSP
SYNOPSIS
build [-h] | [-p platform] [-k kern_version] [-m module] | pack
OPTIONS
-h Display help message
-p [platform] platform, e.g. sun6i, sun6i_dragonboard, sun6i_fiber
sun6i: full linux bsp
sun6i_dragonboard: board test packages
sun6i_fiber: android kernel
-k [kern_ver] 3.3(default) [OPTIONAL]
-m [module] Use this option when you dont want to build all. [OPTIONAL]
e.g. kernel, buildroot, uboot, all(default)...
pack To start pack program
Examples:
./build.sh -p sun6i
./build.sh -p sun6i_dragonboard
./build.sh -p sun6i_fiber
./build.sh -p sun6i_fiber_a31s
./build.sh pack
"
}
//怎么知道这个OPTION是什么意思呢,你可以在lichee下面执行./build.sh -h可以看到一个OPTION的参数
//也可以找到common.sh里面有一个show_help()的方法
//以./build.sh -p sun6i_fiber这个为例子
//所以可以知道 PLATFORM == sun6i_fiber
下面的脚本内容都是些函数
现在来看看最后的部分
这里的$1就是上面实例中./build.sh 所带的参数
//if $1== pack
if [ "$1" = "pack" ]; then
echo "generate rootfs now, it will takes several minutes and log in out/"
if [ ! -d "${OUT_DIR}" ]; then
mkdir -pv ${OUT_DIR}
fi
regen_rootfs > out/gen_rootfs_log.txt 2>&1
gen_output_sun6i >> out/gen_rootfs_log.txt 2>&1
echo "generate rootfs has finished!"
${BR_DIR}/scripts/build_pack.sh
exit 0
//if $1 == pack_deagonboard
elif [ "$1" = "pack_dragonboard" ]; then
regen_dragonboard_rootfs
gen_output_sun6i_dragonboard
${BR_DIR}/scripts/build_pack.sh
exit 0
//if $1 == pcack_prvt
elif [ "$1" = "pack_prvt" ]; then
${BR_DIR}/scripts/build_prvt.sh
exit 0
fi
//知道 PLATFORM == sun6i_fiber
while getopts hp:m:k: OPTION
do
case $OPTION in
h) show_help
exit 0
;;
p) PLATFORM=$OPTARG
;;
m) MODULE=$OPTARG
;;
k) KERN_VER=$OPTARG
update_kdir $KERN_VER
;;
*) show_help
exit 1
;;
esac
done
// 执行上面之后这个PLATFORM就不为空了
//在这里也说下这个shell的判断语言的参数是什么意思
-e filename 如果 filename存在,则为真
-d filename 如果 filename为目录,则为真
-f filename 如果 filename为常规文件,则为真
-L filename 如果 filename为符号链接,则为真
-r filename 如果 filename可读,则为真
-w filename 如果 filename可写,则为真
-x filename 如果 filename可执行,则为真
-s filename 如果文件长度不为0,则为真
-h filename 如果文件是软链接,则为真
filename1 -nt filename2 如果 filename1比 filename2新,则为真。
filename1 -ot filename2 如果 filename1比 filename2旧,则为真。
-eq 等于
-ne 不等于
-gt 大于
-ge 大于等于
-lt 小于
-le 小于等于
至于!号那就是取非
if [ -z "$PLATFORM" ]; then
show_help
exit 1
fi
if [ -z "$PLATFORM" ]; then
show_help
exit 1
fi
clean_output
// if $MODULE == buildroot 进入相关目录执行脚本,后面都是一样
if [ "$MODULE" = buildroot ]; then
cd ${BR_DIR} && ./build.sh -p ${PLATFORM}
// if $MODULE == kernel
elif [ "$MODULE" = kernel ]; then
export PATH=${BR_OUT_DIR}/external-toolchain/bin:$PATH
cd ${KERN_DIR} && ./build.sh -p ${PLATFORM}
// if $MODULE == uboot
elif [ "$MODULE" = "uboot" ]; then
case ${PLATFORM} in
a12_nuclear*)
echo "build uboot for sun5i_a12"
cd ${U_BOOT_DIR} && ./build.sh -p sun5i_a12
;;
a12*)
echo "build uboot for sun5i_a12"
cd ${U_BOOT_DIR} && ./build.sh -p sun5i_a12
;;
a13_nuclear*)
echo "build uboot for sun5i_a12"
cd ${U_BOOT_DIR} && ./build.sh -p sun5i_a13
;;
a13*)
echo "build uboot for sun5i_a13"
cd ${U_BOOT_DIR} && ./build.sh -p sun5i_a13
;;
*)
echo "build uboot for ${PLATFORM}"
cd ${U_BOOT_DIR} && ./build.sh -p ${PLATFORM}
;;
esac
//如果MODULE不等于以上这些,就执行这里
//进入buildroot目录,这个BR_DIR在common.sh最开始的地方有定义,执行脚本
cd ${BR_DIR} && ./build.sh -p ${PLATFORM}
//设置环境变量
export PATH=${BR_OUT_DIR}/external-toolchain/bin:$PATH
//执行该脚本编译内核(根据你选择相关平台来执行相关脚本 如果编译build_sun6i.sh )
cd ${KERN_DIR} && ./build.sh -p ${PLATFORM}
buildroot目录下build.sh脚本
#!/bin/bash
set -e
//定义变量
PLATFORM=""
MODULE=""
//帮助文件,在lichee文件下面执行.build.sh -h 的时候会出现的提示内容
-h显示帮助信息
-p选择所需要的开发平台
-k内核
-m在所在的模块(比如kernel,uboot之类的)后面的脚本内容会用到这个参数
再下面是几个例子
show_help()
{
printf "\nbuild.sh - Top level build scritps\n"
echo "Valid Options:"
echo " -h Show help message"
echo " -p <platform> platform:sun6i sun6i_fiber sun6i_fiber_a31s or sun6i_dragonboard"
printf " -m <module> module\n\n"
}
//获得PLATFORM和MODULE的值
while getopts hp:m: OPTION
do
case $OPTION in
h) show_help
;;
p) PLATFORM=$OPTARG
;;
m) MODULE=$OPTARG
;;
*) show_help
;;
esac
done
//如果platform等于空,则显示帮助并退出
if [ -z "$PLATFORM" ]; then
show_help
exit 1
fi
//如果moudle等于空,则MODULE==all
if [ -z "$MODULE" ]; then
MODULE="all"
fi
//判断目录下面的文件是否为可执行文件,执行相关脚本(这个脚本的功能就是解压工具链以及设置环境变量) 然后再回去看 ./scripts/common.sh
if [ -x ./scripts/build_${PLATFORM}.sh ]; then
./scripts/build_${PLATFORM}.sh $MODULE
else
//如果没有可执行文件就显示错误信息,并显示帮助退出
printf "\nERROR: Invalid Platform\nonly sun6i sun6i_fiber sun6i_fiber_a31s or sun6i_dragonboard support\n"
show_help
exit 1
fi
进入lichee/linux-3.3/scripts/build_sun6i.sh
1.设置编译工具链环境变量
2.
LICHEE_ROOT=`(cd ${LICHEE_KDIR}/..; pwd)`
export PATH=${LICHEE_ROOT}/buildroot/output/external-toolchain/bin:${LICHEE_ROOT}/tools/pack/pctools/linux/android:$PATH
//这个$1就是lichee/linux-3.4/build.sh所执行的./scripts/build_${PLATFORM}.sh $MODULE
//MODULE值== all,所以执行all分支下面的函数
case "$1" in
kernel)
build_kernel
;;
modules)
build_modules
;;
clean)
clean_kernel
clean_modules
;;
all)
build_kernel
#build_modules
build_ramfs
;;
*)
show_help
;;
esac
这样内核就编译完了,kernel编译完成之后就是编译uboot
编译uboot在lichee/buildroot/scripts/common.sh的最下方可以看到
//编译UBOOT
elif [ "$MODULE" = "uboot" ]; then
case ${PLATFORM} in
a12_nuclear*)
echo "build uboot for sun5i_a12"
cd ${U_BOOT_DIR} && ./build.sh -p sun5i_a12
;;
a12*)
echo "build uboot for sun5i_a12"
cd ${U_BOOT_DIR} && ./build.sh -p sun5i_a12
;;
a13_nuclear*)
echo "build uboot for sun5i_a12"
cd ${U_BOOT_DIR} && ./build.sh -p sun5i_a13
;;
a13*)
echo "build uboot for sun5i_a13"
cd ${U_BOOT_DIR} && ./build.sh -p sun5i_a13
;;
*)
echo "build uboot for ${PLATFORM}"
cd ${U_BOOT_DIR} && ./build.sh -p ${PLATFORM}
;;
esac
else
cd ${BR_DIR} && ./build.sh -p ${PLATFORM}
export PATH=${BR_OUT_DIR}/external-toolchain/bin:$PATH
cd ${KERN_DIR} && ./build.sh -p ${PLATFORM}
#regen_rootfs
gen_output_${PLATFORM}
//最后编译完成会显示如下信息
echo -e "\033[0;31;1m###############################\033[0m"
echo -e "\033[0;31;1m# compile success #\033[0m"
echo -e "\033[0;31;1m###############################\033[0m"
fi