#lichee 目录下
./build.sh -psun7i_android -k 3.4
#build.sh 解析
#!/bin/bash
set -e
#"Exitimmediately if a simple command exits with a non-zero status."
#也就是说,在"set -e"之后出现的代码,一旦出现了返回值非零,整个脚本就会立即退出
buildroot/scripts/mkcommon.sh$@ #$@ 为参数 -p sun7i_android -k 3.4
#mkcommon.sh
#!/bin/bash
#
#scripts/mkcommon.sh
# (c) Copyright2013
# AllwinnerTechnology Co., Ltd. <www.allwinnertech.com>
# James Deng<csjamesdeng@allwinnertech.com>
#
# This program isfree software; you can redistribute it and/or modify
# it under theterms of the GNU General Public License as published by
# the FreeSoftware Foundation; either version 2 of the License, or
# (at your option)any later version.
BR_SCRIPTS_DIR=`dirname$0` #提取出运行目录 ./buildroot/scripts/
if ["$1" = "pack" ] ; then #如果是运行打包动作
${BR_SCRIPTS_DIR}/build_pack.sh #运行打包脚本
exit 0
fi
# source shflags
.${BR_SCRIPTS_DIR}/shflags/shflags #加载命令行工具
.${BR_SCRIPTS_DIR}/mkcmd.sh #加载shell编译脚本
# define option,format:
# 'long option' 'default value' 'help message''short option'
#命令行工具shflags使用
#三个参数含义分别为命令行参数名,参数默认值,以及参数的帮助信息
DEFINE_string'platform' 'sun7i' 'platform to build, e.g. sun7i' 'p'
DEFINE_string'kernel' '3.4' 'kernel to build, e.g. 3.3' 'k'
DEFINE_string'board' '' 'board to build, e.g. evb' 'b'
DEFINE_string'module' '' 'module to build, e.g. buildroot, kernel, uboot, clean' 'm'
DEFINE_boolean'independent' false 'output build to independent directory' 'i'
# parse thecommand-line
# 解析传进来的参数
FLAGS"$@" || exit $?
#语法:eval cmdLine
#eval会对后面的cmdLine进行两遍扫描,如果第一遍扫描后,cmdLine是个普通命令,则执行此命令;
#如果cmdLine中含有变量的间接引用,则保证间接引用的语义。
eval set --"${FLAGS_ARGV}"
#参数是: -p sun7i_android -k 3.4
chip=${FLAGS_platform%%_*} #提取出chip sun7i
platform=${FLAGS_platform##*_}#提取出平台 android
kernel=${FLAGS_kernel} #提取出内核 3.4
board=${FLAGS_board} #提取出板子 这里空
module=${FLAGS_module} #提取出模块 这里空
if ["${platform}" = "${chip}" ] ; then #如果未指定平台,默认为linux
platform="linux"
fi
if [ -z"${module}" ] ; then #如果未指定模块,默认编译所有
module="all"
fi
if ! init_chips${chip} || \ #初始化芯片参数: sun7i
#查询该目录下{LICHEE_TOOLS_DIR}/pack/chips/是否有 以该芯片命名的目录
#并导出该变量 exportLICHEE_CHIP=${chip}
! init_platforms ${chip} ${platform} ; then
#检查是否支持该平台
#并导出 exportLICHEE_PLATFORM=${platform}
mk_error "invalid platform'${FLAGS_platform}'"
exit 1
fi
if [ ${FLAGS_board}] && \ #如果指定了板子,检查是否支持该板子
! init_boards ${chip} ${platform} ${board} ;then
mk_error "invalid board'${FLAGS_board}'"
exit 1
fi
if ["${kernel}" = "3.3" ] ; then #如果指定了内核3.3 ,判断该目录是否存在
# 3.4 就不检查了?
LICHEE_KERN_DIR=${LICHEE_TOP_DIR}/linux-3.3
if [ ! -d ${LICHEE_KERN_DIR} ] ; then
mk_error "invalid kernel'${kernel}'"
exit 1
fi
fi
# init outputdirectory
init_outdir #初始化输出目录,检查配置是否存在
#这里默认配置:sun7ismp_android_defconfig,配置组成在check_kern_defconf 函数中
#请自己查看
#设置了导出目录:
# exportLICHEE_PLAT_OUT="${LICHEE_OUT_DIR}/${LICHEE_PLATFORM}/common"
#导出plat 目录 .../lichee/out/android/common
#export LICHEE_BR_OUT="${LICHEE_PLAT_OUT}/buildroot"
#导出 br 目录 ../lichee/out/android/common/buildroot
if [ ${module} ="all" ]; then
mklichee
elif [ ${module} ="boot" ] ; then
mkboot
elif [ ${module} ="buildroot" ] ; then
mkbr
elif [ ${module} ="kernel" ] ; then
mkkernel
elif [ ${module} ="uboot" ] ; then
mkuboot
elif [ ${module} ="clean" ] ; then
mkclean
elif [ ${module} ="mrproer" ] ; then
mkmrproer
elif [ ${module} ="distclean" ] ; then
mkdistclean
else
mk_error "invalid module '${module}'"
exit 1
fi
exit $?
#编译all
functionmklichee()
{
mksetting #打印编译信息
mk_info "build lichee ..." #显示编译,带颜色显示
#编译交叉编译工具 ----这里就不分析了
#编译内核
#编译uboot
#编译文件系统
mkbr && mkkernel && mkuboot&& mkrootfs
[ $? -ne 0 ] && return 1
mk_info "build lichee OK."
}
编译内核所做的事情:
#,根据平台配置,编译内核 ,把编译好的内核,模块 以及.config 拷到了output 目录下
#把output 目录下的所有内容,LICHEE_PLAT_OUT
#也就是 …/lichee/out/android/common
编译uboot 所做的事情
# 根据平台选择编译脚本 —–其实这一步没起作用,最终用的build.sh
# 先make distclean ,再根据芯片 sun7i进行编译,生成u-boot.bin
#所有这里可以选择把distclean 去掉,节约编译时间
# 把u-boot.bin拷贝到了 lichee/out/android/common 目录下
编译rootfs所做的事情:
#根据linux 或者dragonboard 做相应的操作
# 而这 do nothing ,skip
//———————————-other————————————
functionmkrootfs()
{
mk_info "build rootfs ..."
if [ ${LICHEE_PLATFORM} = "linux"] ; then
make O=${LICHEE_BR_OUT} -C${LICHEE_BR_DIR} target-generic-getty-busybox
[ $? -ne 0 ] && mk_error"build rootfs Failed" && return 1
make O=${LICHEE_BR_OUT} -C${LICHEE_BR_DIR} target-finalize
[ $? -ne 0 ] && mk_error"build rootfs Failed" && return 1
make O=${LICHEE_BR_OUT} -C${LICHEE_BR_DIR} LICHEE_GEN_ROOTFS=y rootfs-ext4
[ $? -ne 0 ] && mk_error"build rootfs Failed" && return 1
cp ${LICHEE_BR_OUT}/images/rootfs.ext4${LICHEE_PLAT_OUT}
elif [ ${LICHEE_PLATFORM} ="dragonboard" ] ; then
echo "Regenerating dragonboardRootfs..."
(cd${LICHEE_BR_DIR}/target/dragonboard; \
if [ ! -d "./rootfs" ];then \
echo "extract dragonboardrootfs.tar.gz"; \
tar zxf rootfs.tar.gz; \
fi \
)
mkdir -p${LICHEE_BR_DIR}/target/dragonboard/rootfs/lib/modules
rm -rf ${LICHEE_BR_DIR}/target/dragonboard/rootfs/lib/modules/*
cp -rf${LICHEE_KERN_DIR}/output/lib/modules/*${LICHEE_BR_DIR}/target/dragonboard/rootfs/lib/modules/
(cd${LICHEE_BR_DIR}/target/dragonboard; ./build.sh)
cp${LICHEE_BR_DIR}/target/dragonboard/rootfs.ext4 ${LICHEE_PLAT_OUT}
else
mk_info "skip make rootfs for${LICHEE_PLATFORM}"
fi
mk_info "build rootfs OK."
}
# return true ifused default config
functioncheck_uboot_defconf()
{
local defconf
local ret=1
defconf="${LICHEE_CHIP}_${LICHEE_PLATFORM}_${LICHEE_BOARD}"
#编译 sun7i_android
#这里少了一个.sh,脚本有问题:sun7i_android.sh
if [ ! -f${LICHEE_UBOOT_DIR}/include/configs/${defconf} ] ; then
ret=0
defconf="${LICHEE_CHIP}" #这里少了一个.sh 应该为:sun7i.sh
fi
export LICHEE_UBOOT_DEFCONF=${defconf}
return ${ret}
}
function mkuboot()
{
mk_info "build u-boot ..."
local build_script
if check_uboot_defconf ; then #查看配置是是否存在,指定编译脚本
build_script="build.sh" #运行此编译脚本
else
build_script="build_${LICHEE_CHIP}_${LICHEE_PLATFORM}_${LICHEE_BOARD}.sh"
fi
prepare_toolchain
//运行编译脚本
(cd ${LICHEE_UBOOT_DIR} && [ -x${build_script} ] && ./${build_script})
[ $? -ne 0 ] && mk_error"build u-boot Failed" && return 1
mk_info "build u-boot OK."
}
#关键的编译函数:
functionbuild_uboot()
{
case "$1" in
clean)
make distcleanCROSS_COMPILE=arm-linux-gnueabi-
;;
*)
make distcleanCROSS_COMPILE=arm-linux-gnueabi- #清楚所有配置
make -j${jobs} ${LICHEE_CHIP}CROSS_COMPILE=arm-linux-gnueabi-
#根据芯片 编译 这里是sun7i
[ $? -ne 0 ] && exit 1
#拷贝u-boot.bin 到输出目录
cp -f u-boot.bin ../out/${LICHEE_PLATFORM}/common/
;;
esac
}
functionmksetting() #打印要编译的信息
{
printf "\n"
printf "mkscript currentsetting:\n"
printf " Chip: ${LICHEE_CHIP}\n"
printf " Platform: ${LICHEE_PLATFORM}\n"
printf " Board: ${LICHEE_BOARD}\n"
printf " Output Dir: ${LICHEE_PLAT_OUT}\n"
printf "\n"
}
编译内核函数
functionmkkernel()
{
mk_info "build kernel ..."
local build_script
if check_kern_defconf ; then #检查设置,编译配置文件
if [ ${LICHEE_PLATFORM} ="linux" ] ; then
build_script="scripts/build_${LICHEE_CHIP}.sh"
else
build_script="scripts/build_${LICHEE_CHIP}_${LICHEE_PLATFORM}.sh"
#指定编译脚本 scripts/build_sun7i_android.sh
fi
else
build_script="scripts/build_${LICHEE_CHIP}_${LICHEE_PLATFORM}_${LICHEE_BOARD}.sh"
fi
prepare_toolchain #准备交叉编译工具,就是导出环境变量
#lichee/out/android/common/buildroot/external-toolchain
# mark kernel .config belong to whichplatform
localconfig_mark="${LICHEE_KERN_DIR}/.config.mark" #标记编译平台 android
if [ -f ${config_mark} ] ; then
if ! grep -q"${LICHEE_PLATFORM}" ${config_mark} ; then
mk_info "clean last time buildfor different platform"
(cd ${LICHEE_KERN_DIR} && [-x ${build_script} ] && ./${build_script} "clean")
echo "${LICHEE_PLATFORM}"> ${config_mark}
fi
else
echo "${LICHEE_PLATFORM}"> ${config_mark}
fi
#进入内核目录 ,检查编译脚本是否可执行,执行该脚本
#./scripts/build_sun7i_android.sh
(cd ${LICHEE_KERN_DIR} && [ -x${build_script} ] && ./${build_script})
[ $? -ne 0 ] && mk_error"build kernel Failed" && return 1
mk_info "build kernel OK."
}
脚本#build_sun7i_android.sh 如下
#!/bin/bash
#
#scripts/build_sun7i_android.h
#
# (c) Copyright2013
# AllwinnerTechnology Co., Ltd. <www.allwinnertech.com>
# James Deng<csjamesdeng@allwinnertech.com>
#
# This program isfree software; you can redistribute it and/or modify
# it under theterms of the GNU General Public License as published by
# the FreeSoftware Foundation; either version 2 of the License, or
# (at your option)any later version.
set -e
cpu_cores=`cat/proc/cpuinfo | grep "processor" | wc -l`
if [ ${cpu_cores}-le 8 ] ; then
jobs=${cpu_cores}
else
jobs=`expr ${cpu_cores} / 2`
fi
# Setup commonvariables
export ARCH=arm
exportCROSS_COMPILE=arm-linux-gnueabi-
exportAS=${CROSS_COMPILE}as
exportLD=${CROSS_COMPILE}ld
exportCC=${CROSS_COMPILE}gcc
exportAR=${CROSS_COMPILE}ar
exportNM=${CROSS_COMPILE}nm
exportSTRIP=${CROSS_COMPILE}strip
exportOBJCOPY=${CROSS_COMPILE}objcopy
exportOBJDUMP=${CROSS_COMPILE}objdump
KERNEL_VERSION="3.4"
LICHEE_KDIR=`pwd`
LICHEE_MOD_DIR=${LICHEE_KDIR}/output/lib/modules/${KERNEL_VERSION}
export LICHEE_KDIR
build_standby()
{
echo "build standby"
# If .config is newer thaninclude/config/auto.conf, someone tinkered
# with it and forgot to run make oldconfig.
# if auto.conf.cmd is missing then we areprobably in a cleaned tree so
# we execute the config step to be sure tocatch updated Kconfig files
if [ .config -nt include/config/auto.conf-o \
! -f include/config/auto.conf.cmd ] ;then
echo "Generating autoconf.h forstandby"
make -f Makefile ARCH=armCROSS_COMPILE=${CROSS_COMPILE} \
silentoldconfig
fi
make ARCH=${ARCH}CROSS_COMPILE=${CROSS_COMPILE} KDIR=${LICHEE_KDIR} \
-C ${LICHEE_KDIR}/arch/arm/mach-sun7i/pm/standbyall
}
NAND_ROOT=${LICHEE_KDIR}/modules/nand
build_nand_lib()
{
echo "build nand library${NAND_ROOT}/lib"
if [ -d ${NAND_ROOT}/lib ]; then
echo "build nand library now"
make -C modules/nand/lib clean 2>/dev/null
make -C modules/nand/lib lib install
else
echo "build nand with existinglibrary"
fi
}
HDMI_ROOT=${LICHEE_KDIR}/drivers/video/sun7i/hdmi/aw
build_hdmi_lib()
{
echo "build hdcp library${HDMI_ROOT}/hdcp"
if [ -d ${HDMI_ROOT}/hdcp ]; then
echo "build hdcp library now"
# make -C ${HDMI_ROOT}/hdcp clean 2>/dev/null
make -C ${HDMI_ROOT}/hdcp install
else
echo "build hdcp with existinglibrary"
fi
}
build_kernel()
{
echo "Building kernel"
if [ ! -f .config ] ; then #如果配置文件不存在,则拷贝编译脚本
printf "\n\033[0;31;1mUsingdefault config ...\033[0m\n\n"
cparch/arm/configs/${LICHEE_KERN_DEFCONF} .config
fi
build_standby
#编译内核
make ARCH=armCROSS_COMPILE=${CROSS_COMPILE} -j${jobs} uImage modules
#二进制拷贝
${OBJCOPY} -R .note.gnu.build-id -S -Obinary vmlinux bImage
#删除原来的输出目录
rm -rf output
#创建模块输出目录
mkdir -p ${LICHEE_MOD_DIR}
#拷贝内核文件
cp bImage output/
#把配置文件也拷贝到了输出目录
cp .config output/
#把所有 模块拷贝到了 output/lib/modules/3.4/
for file in $(find drivers sound cryptoblock fs security net -name "*.ko"); do
cp $file ${LICHEE_MOD_DIR}
done
cp -f Module.symvers ${LICHEE_MOD_DIR}
#cpdrivers/net/wireless/bcm4330/firmware/bcm4330.bin ${LICHEE_MOD_DIR}
#cpdrivers/net/wireless/bcm4330/firmware/bcm4330.hcd ${LICHEE_MOD_DIR}
#cpdrivers/net/wireless/bcm4330/firmware/nvram.txt${LICHEE_MOD_DIR}/bcm4330_nvram.txt
}
build_modules()
{
echo "Building modules"
if [ ! -f include/generated/utsrelease.h ];then
printf "Please build kernelfirst\n"
exit 1
fi
make -C modules/exampleLICHEE_MOD_DIR=${LICHEE_MOD_DIR} LICHEE_KDIR=${LICHEE_KDIR} \
install
build_nand_lib
make -C modules/nandLICHEE_MOD_DIR=${LICHEE_MOD_DIR} LICHEE_KDIR=${LICHEE_KDIR} \
install
build_hdmi_lib
make -C drivers/video/sun7i/hdmi/awLICHEE_MOD_DIR=${LICHEE_MOD_DIR} LICHEE_KDIR=${LICHEE_KDIR} \
install
(
export LANG=en_US.UTF-8
unset LANGUAGE
make -C modules/maliLICHEE_MOD_DIR=${LICHEE_MOD_DIR} LICHEE_KDIR=${LICHEE_KDIR} \
install
)
##build ar6302 sdio wifi module
#make -C modules/wifi/ar6302/AR6K_SDK_ISC.build_3.1_RC.329/hostCROSS_COMPILE=${CROSS_COMPILE} \
# ARCH=arm KERNEL_DIR=${LICHEE_KDIR} INSTALL_DIR=${LICHEE_MOD_DIR} \
# all install
##build ar6003 sdio wifi module
#make -Cmodules/wifi/ar6003/AR6kSDK.build_3.1_RC.514/hostCROSS_COMPILE=${CROSS_COMPILE} \
# ARCH=arm KERNEL_DIR=${LICHEE_KDIR} INSTALL_DIR=${LICHEE_MOD_DIR} \
# all
##build usi-bmc4329 sdio wifi module
#make -C modules/wifi/usi-bcm4329/v4.218.248.15/open-src/src/dhd/linux\
# CROSS_COMPILE=${CROSS_COMPILE} ARCH=arm LINUXVER=${KERNEL_VERSION} \
# LICHEE_MOD_DIR=${LICHEE_MOD_DIR} LINUXDIR=${LICHEE_KDIR} \
# INSTALL_DIR=${LICHEE_MOD_DIR} dhd-cdc-sdmmc-gpl
##build bcm40181 sdio wifi module5.90.125.69.2
#make -Cmodules/wifi/bcm40181/5.90.125.69.2/open-src/src/dhd/linux \
# CROSS_COMPILE=${CROSS_COMPILE} ARCH=arm LINUXVER=${KERNEL_VERSION} \
# LICHEE_MOD_DIR=${LICHEE_MOD_DIR} LINUXDIR=${LICHEE_KDIR} \
# INSTALL_DIR=${LICHEE_MOD_DIR} OEM_ANDROID=1 dhd-cdc-sdmmc-gpl
##build bcm40183 sdio wifi module
#make -Cmodules/wifi/bcm40183/5.90.125.95.3/open-src/src/dhd/linux \
# CROSS_COMPILE=${CROSS_COMPILE} ARCH=arm LINUXVER=${KERNEL_VERSION} \
# LICHEE_MOD_DIR=${LICHEE_MOD_DIR} LINUXDIR=${LICHEE_KDIR} \
# INSTALL_DIR=${LICHEE_MOD_DIR} OEM_ANDROID=1 dhd-cdc-sdmmc-gpl
}
gen_output()
{
echo "Copy output to target ..."
rm -rf ${LICHEE_PLAT_OUT}/lib
cp -rf ${LICHEE_KDIR}/output/*${LICHEE_PLAT_OUT}
}
clean_kernel()
{
echo "Cleaning kernel"
make distclean
rm -rf output/*
}
clean_modules()
{
echo "Cleaning modules"
make -C modules/exampleLICHEE_MOD_DIR=${LICHEE_MOD_DIR} LICHEE_KDIR=${LICHEE_KDIR} clean
(
export LANG=en_US.UTF-8
unset LANGUAGE
make -C modules/maliLICHEE_MOD_DIR=${LICHEE_MOD_DIR} LICHEE_KDIR=${LICHEE_KDIR} clean
)
##build ar6302 sdio wifi module
#make -Cmodules/wifi/ar6302/AR6K_SDK_ISC.build_3.1_RC.329/hostCROSS_COMPILE=${CROSS_COMPILE} \
# ARCH=arm KERNEL_DIR=${LICHEE_KDIR} INSTALL_DIR=${LICHEE_MOD_DIR} \
# clean
##build ar6003 sdio wifi module
#make -Cmodules/wifi/ar6003/AR6kSDK.build_3.1_RC.514/hostCROSS_COMPILE=${CROSS_COMPILE} \
# ARCH=arm KERNEL_DIR=${LICHEE_KDIR} INSTALL_DIR=${LICHEE_MOD_DIR} \
# clean
##build usi-bmc4329 sdio wifi module
#make -C modules/wifi/usi-bcm4329/v4.218.248.15/open-src/src/dhd/linux\
# CROSS_COMPILE=${CROSS_COMPILE} ARCH=arm LINUXVER=${KERNEL_VERSION} \
# LICHEE_MOD_DIR=${LICHEE_MOD_DIR} LINUXDIR=${LICHEE_KDIR} \
# INSTALL_DIR=${LICHEE_MOD_DIR} clean
##build bcm40181 sdio wifi module5.90.125.69.2
#make -Cmodules/wifi/bcm40181/5.90.125.69.2/open-src/src/dhd/linux \
# CROSS_COMPILE=${CROSS_COMPILE} ARCH=arm LINUXVER=${KERNEL_VERSION} \
# LICHEE_MOD_DIR=${LICHEE_MOD_DIR} LINUXDIR=${LICHEE_KDIR} \
# INSTALL_DIR=${LICHEE_MOD_DIR} clean
##build bcm40183 sdio wifi module
#make -Cmodules/wifi/bcm40183/5.90.125.95.3/open-src/src/dhd/linux \
# CROSS_COMPILE=${CROSS_COMPILE} ARCH=arm LINUXVER=${KERNEL_VERSION} \
# LICHEE_MOD_DIR=${LICHEE_MOD_DIR} LINUXDIR=${LICHEE_KDIR} \
# INSTALL_DIR=${LICHEE_MOD_DIR} OEM_ANDROID=1 clean
}
case"$1" in
kernel)
build_kernel
;;
modules)
build_modules
;;
clean)
clean_modules
clean_kernel
;;
*)
build_kernel #编译内核 ,把编译好的内核,模块 拷到了output 目录下
build_modules #变所有模块
gen_output #把output 目录下的所有内核,LICHEE_PLAT_OUT
#也就是 .../lichee/out/android/common
;;
esac
functioninit_chips()
{
local chip=$1 #传进来的参数:sun7i
local cnt=0
local ret=1
for chipdir in${LICHEE_TOOLS_DIR}/pack/chips/* ; do
chips[$cnt]=`basename $chipdir`
if [ ${chips[$cnt]} = ${chip} ] ;then #检测是否有该芯片的目录
ret=0
export LICHEE_CHIP=${chip}
fi
((cnt+=1))
done
return ${ret}
}
functioninit_platforms()
{
local chip=$1 #传进来的芯片 sun7i
local platform=$2 #传进来的平台 android
local cnt=0
local ret=1
for platdir in${LICHEE_TOOLS_DIR}/pack/chips/${chip}/configs/* ; do
platforms[$cnt]=`basename $platdir`
if [ ${platforms[$cnt]} = ${platform} ]; then #检查是否支持该平台打包
ret=0
export LICHEE_PLATFORM=${platform}
fi
((cnt+=1))
done
return ${ret}
}
# output toout/<chip>/<platform>/common directory only when
# both buildrootand kernel use default config file.
functioninit_outdir()
{
if check_br_defconf &&check_kern_defconf ; then
#check_kern_defconf 检查配置是否存在
exportLICHEE_PLAT_OUT="${LICHEE_OUT_DIR}/${LICHEE_PLATFORM}/common"
#导出plat 目录 .../lichee/out/android/common
exportLICHEE_BR_OUT="${LICHEE_PLAT_OUT}/buildroot"
#导出 br 目录 ../lichee/out/android/common/buildroot
else
exportLICHEE_PLAT_OUT="${LICHEE_OUT_DIR}/${LICHEE_PLATFORM}/${LICHEE_BOARD}"
exportLICHEE_BR_OUT="${LICHEE_PLAT_OUT}/buildroot"
fi
mkdir -p ${LICHEE_BR_OUT} #创建目录
}
android编译命令分析
一.lichee下的编译
cong@dell:/work/ct/lichee$./build.sh -p sun7i_android
1. ./build.sh -p sun7i_androi
buildroot/scripts/mkcommon.sh $@
在lichee/buildroot/scripts/mkcommon.sh中
根据module参数来执行不同的命令,默认是mklichee
BR_SCRIPTS_DIR=buildroot/scripts
chip=sun7i platform=android board= module=
. ${BR_SCRIPTS_DIR}/mkcmd.sh
mklichee
2.mklichee
在lichee/buildroot/scripts/mkcmd.sh中
function mklichee()
{
mksetting //一些打印
mk_info "build lichee..." //一些打印
mkbr //2.1解压交叉工具链
mkkernel //2.2编译standby+内核+ko模块
mkuboot //2.3编译uboot
mkrootfs //2.4解压交叉工具链
mk_info "build lichee OK."
}
2.1 mkbr
在lichee/buildroot/scripts/mkcmd.sh中mkbr
mkbr的意思是: 解压交叉编译工具链
function mkbr()
{
build_script="scripts/build_${LICHEE_CHIP}_${LICHEE_PLATFORM}.sh"
(cd ${LICHEE_BR_DIR} && [ -x${build_script} ] && ./${build_script})
}
即: cd /work/ct/lichee/buildroot && [-x scripts/build_sun7i_android.sh ] && ./scripts/build_sun7i_android.sh
会调用/work/ct/lichee/buildroot/scripts/build_sun7i_android.sh来检查
/work/ct/lichee/out/android/common/buildroot/external-toolchain这个目录下是否存在.install的文件,不存在则解压
2.2 mkkernel
在lichee/buildroot/scripts/mkcmd.sh中mkkernel
function mkkernel()
{
build_script="scripts/build_${LICHEE_CHIP}_${LICHEE_PLATFORM}.sh"
prepare_toolchain //检查编译工具链,如果不存在则调用上面的mkbr
// 在/work/ct/lichee/linux-3.3/.config.mark中写入字符串"android"作为标记
localconfig_mark="${LICHEE_KERN_DIR}/.config.mark"
if [ -f ${config_mark} ] ; then
echo "${LICHEE_PLATFORM}"> ${config_mark}
fi
(cd ${LICHEE_KERN_DIR} && [ -x${build_script} ] && ./${build_script})
[ $? -ne 0 ] && mk_error"build kernel Failed" && return 1
mk_info "build kernel OK."
}
(cd/work/ct/lichee/linux-3.3 && [ -x scripts/build_sun7i_android.sh ]&& ./scripts/build_sun7i_android.sh)
2.2.1 mkkernel的具体编译
在/work/ct/lichee/linux-3.3/scripts/build_sun7i_android.sh中
因为没有参数,所以要执行三步: build_kernel, build_modules 和 gen_output
build_kernel
a. 将 arch/arm/configs/sun7ismp_android_defconfig拷贝到 ./.config
b. build_standby 在/work/ct/lichee/linux-3.3/arch/arm/mach-sun7i/pm/standby中
c. 编译内核 uImage 和 modules,
将vmlinux objcopy -O binary就成了bImage,这样 [buz]Image都有了
再将 [buz]Image--> lichee/linux-3.3/output
将所有的ko -->./lichee/linux-3.3/output/lib/modules/3.3/下
build_modules 编译放在 ./lichee/linux-3.3/modules中的驱动
gen_output 把上述所有的内容拷贝到: /work/ct/lichee/out/android/common
所以/work/ct/lichee/linux-3.3/output/ 与 /work/ct/lichee/out/android/common/中的内容基本一样(少了buildroot)
2.3 mkuboot
在lichee/buildroot/scripts/mkcmd.sh中mkuboot
function mkuboot()
{
mk_info "build u-boot ..."
local build_script
if check_uboot_defconf ; then
build_script="build.sh"
else
build_script="build_${LICHEE_CHIP}_${LICHEE_PLATFORM}_${LICHEE_BOARD}.sh"
fi
prepare_toolchain //检查编译工具链,如果不存在则调用上面的mkbr
//即执行./ct/lichee/u-boot/build.sh
(cd ${LICHEE_UBOOT_DIR} && [ -x${build_script} ] && ./${build_script})
[ $? -ne 0 ] && mk_error"build u-boot Failed" && return 1
mk_info "build u-boot OK."
}
2.3.1 mkuboot的具体编译
cd /work/ct/lichee/u-boot && [ -xbuild.sh ] && ./build.sh
function build_uboot()
{
case "$1" in //$1是空的
clean)
make distclean CROSS_COMPILE=arm-linux-gnueabi-
;;
*)
make distcleanCROSS_COMPILE=arm-linux-gnueabi-
make -j8 ${LICHEE_CHIP}CROSS_COMPILE=arm-linux-gnueabi-
[ $? -ne 0 ] && exit 1
//真正编译的命令是:
make -j8 sun7iCROSS_COMPILE=arm-linux-gnueabi-
cp -f u-boot.bin../out/${LICHEE_PLATFORM}/common/
;;
esac
}
if [ -n "${LICHEE_CHIP}" ] ;then //LICHEE_CHIP=sun7i
build_uboot $1
exit 0
fi
make -j8 sun7iCROSS_COMPILE=arm-linux-gnueabi-
然后将编译出来的u-boot.bin复制到/work/ct/lichee/out/android/common中
2.4 mkrootfs
在lichee/buildroot/scripts/mkcmd.sh中mkrootfs
平台是android时,只是打印而己
2.5总结一下
mkbr mkkernel mkuboot 都是放到 lichee/out/android/common目录下
cong@dell:/work/ct$ ls/work/ct/lichee/out/android/common
bImage buildroot lib u-boot.bin uImagezImage
mkbr -->/work/ct/lichee/out/android/common/{buildroot,lib}
mkkernel -->/work/ct/lichee/out/android/common/{bImage,uImage,zImage}
mkuboot -->/work/ct/lichee/out/android/common/u-boot.bin
3.附录
3.1 编译命令
根据buildroot/scripts/mkcommon.sh中的解析可以有如下命令
./build.sh -p sun7i_android -m boot
./build.sh -p sun7i_android -m buildroot
./build.sh -p sun7i_android -m kernel
./build.sh -p sun7i_android -m uboot
./build.sh -p sun7i_android -m clean
./build.sh -p sun7i_android -m mrproer
./build.sh -p sun7i_android -m distclean
可单独编译 boot, kernel等.
3.2 standby中的Makefile
在/work/ct/lichee/linux-3.3/arch/arm/mach-sun7i/pm/standby中这个Makefile脚本写得实在是太...
修改成如下形式,这样在没有修改时就不会每次都编译了
standby:$(STANDBY_OBJ)
@$(CROSS_COMPILE)ld -T$(STANDBY_LD_FILE) -EL $(STANDBY_OBJ) -o $(STANDBY_OUPUTFILE).elf -Map$(STANDBY_OUPUTFILE).map
@$(CROSS_COMPILE)objdump -D $(STANDBY_OUPUTFILE).elf> $(STANDBY_OUPUTFILE).lst
@$(CROSS_COMPILE)objcopy -O binary$(STANDBY_OUPUTFILE).elf $(STANDBY_OUPUTFILE).bin
cp standby.bin standby.code
%.o : %.c
$(CC) $(INCLUDE) $(CFLAGS) -c $<
此处还有一个编译错误,需要将linux-3.3/arch/arm/mach-sun7i/pm/mem_divlibc.c中的__div0注掉
./../mem_serial.o:(.ARM.exidx+0x0):undefined reference to `__aeabi_unwind_cpp_pr0'
./../mem_int.o:(.ARM.exidx+0x0):undefined reference to `__aeabi_unwind_cpp_pr1'
网上都说在编译时加上-nostdlib选项,但是不管用
lichee/linux-3.3/arch/arm/mach-sun7i/pm/pm_debug.c中添加:
static void __aeabi_unwind_cpp_pr0(void)
{
};
static void __aeabi_unwind_cpp_pr1(void)
{
};
二.android下的编译
1. source./build/envsetup.sh
添加命令
including device/softwinner/sugar-cubietruck/vendorsetup.sh
including sdk/bash_completion/adb.bash
2. lunch
lunch是定义在 ./build/envsetup.sh中的一个命令
lunch后面参数代表的是平台
function lunch()
{
//a. 只执行lunch则会打印lunch的菜单
//b. 执行lunch 16,会根据参数16从LUNCH_MENU_CHOICES找出16所代表的字符串
//这儿的16代表sugar_cubietruck-eng
local product=$(echo -n $selection |sed -e "s/-.*$//")
check_product $product //sugar_cubietruck
local variant=$(echo -n $selection |sed -e "s/^[^\-]*-//")
check_variant $variant //variant=eng
export TARGET_PRODUCT=$product
export TARGET_BUILD_VARIANT=$variant
export TARGET_BUILD_TYPE=release
set_stuff_for_environment //设置环境变量
printconfig
}
2.1 设置环境变量
function set_stuff_for_environment()
{
settitle //设置变量PROMPT_COMMAND
set_java_home //如果没有设置变量JAVA_HOME,则用默认设置
setpaths //设置路径及环境变量
set_sequence_number //设置BUILD_ENV_SEQUENCE_NUMBER=10
export ANDROID_BUILD_TOP=$(gettop)
}
ANDROID_BUILD_PATHS=
/work/ct/android42/out/host/linux-x86/bin:
/work/ct/android42/development/scripts:
/work/ct/android42/development/emulator/qtools:
/work/ct/android42/prebuilts/gcc/linux-x86/arm/arm-eabi-4.6/bin:
/work/ct/android42/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.6/bin:
/work/ct/android42/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.6/bin:
/work/ct/android42/prebuilts/gcc/linux-x86/mips/mipsel-linux-android-4.6/bin:
ANDROID_PRE_BUILD_PATHS=/opt/android/jdk1.6.0_45/bin:
ANDROID_PRODUCT_OUT=/work/ct/android42/out/target/product/sugar-cubietruck
ANDROID_HOST_OUT=/work/ct/android42/out/host/linux-x86
ANDROID_BUILD_TOP=/work/ct/android42
3.extract-bsp
./device/softwinner/common/vendorsetup.sh
拷贝编译出来的内核及驱动文件
function extract-bsp()
{
LICHEE_DIR=$ANDROID_BUILD_TOP/../lichee
LINUXOUT_DIR=$LICHEE_DIR/out/android/common
LINUXOUT_MODULE_DIR=$LICHEE_DIR/out/android/common/lib/modules/*/*
CURDIR=$PWD
cd $DEVICE
// 删除kernel文件,并将/work/ct/lichee/out/android/common/bImage拷贝到
// 目录/work/ct/android42/device/softwinner/sugar-cubietruck下,改名为kernel
if [ -f kernel ]; then
rm kernel
fi
cp $LINUXOUT_DIR/bImage kernel
//删除ko目录
//将/work/ct/lichee/out/android/common/lib/modules/3.3/中的所有内容拷贝到
/work/ct/android42/device/softwinner/sugar-cubietruck/modules/modules
if [ -d modules ]; then
rm -rf modules
fi
mkdir -p modules/modules
cp -rf $LINUXOUT_MODULE_DIRmodules/modules
chmod 0755 modules/modules/*
//生成文件: create modules.mk
(cat << EOF) >./modules/modules.mk
# modules.mk generate by extract-files.sh ,do not edit it !!!!
PRODUCT_COPY_FILES += \\
\$(callfind-copy-subdir-files,*,\$(LOCAL_PATH)/modules,system/vendor/modules)
EOF
cd $CURDIR
}
4. make -j8
4.1 make bootimage
在文件build/core/Makefile中
INSTALLED_BOOTIMAGE_TARGET :=$(PRODUCT_OUT)/boot.img
$(INSTALLED_BOOTIMAGE_TARGET):$(MKBOOTIMG) $(INTERNAL_BOOTIMAGE_FILES)
$(call pretty,"Target boot image:$@")
$(hide) $(MKBOOTIMG)$(INTERNAL_BOOTIMAGE_ARGS) $(BOARD_MKBOOTIMG_ARGS) --output $@
$(hide) $(callassert-max-image-size,$@,$(BOARD_BOOTIMAGE_PARTITION_SIZE),raw)
endif # TARGET_BOOTIMAGE_USE_EXT2
即: out/host/linux-x86/bin/mkbootimg --kernelout/target/product/sugar-cubietruck/kernel --ramdiskout/target/product/sugar-cubietruck/ramdisk.img --base 0x40000000 --output out/target/product/sugar-cubietruck/boot.img
其中 mkbootimg是在system/core/mkbootimg/mkbootimg.c中生成的
boot.img的构成如下:
header大小为661字节 (padding 2048字节对齐)
kenel (padding 2048字节对齐)
ramdisk.img (padding 2048字节对齐)
4.2 make ramdisk
在文件build/core/Makefile中
BUILT_RAMDISK_TARGET :=$(PRODUCT_OUT)/ramdisk.img
INSTALLED_RAMDISK_TARGET :=$(BUILT_RAMDISK_TARGET)
$(INSTALLED_RAMDISK_TARGET): $(MKBOOTFS)$(INTERNAL_RAMDISK_FILES) | $(MINIGZIP)
$(call pretty,"Target ram disk:$@")
$(hide) $(MKBOOTFS) $(TARGET_ROOT_OUT)| $(MINIGZIP) > $@
$(warning "cong: $(hide)$(MKBOOTFS) $(TARGET_ROOT_OUT) | $(MINIGZIP) > $@")
即: out/host/linux-x86/bin/mkbootfsout/target/product/sugar-cubietruck/root | out/host/linux-x86/bin/minigzip >out/target/product/sugar-cubietruck/ramdisk.img
其中mkbootfs是在./system/core/cpio/mkbootfs.c中生成的
5.pack
android42/device/softwinner/common/vendorsetup.sh
function pack()
{
T=$(gettop)
export ANDROID_IMAGE_OUT=$OUT
export PACKAGE=$T/../lichee/tools/pack
sh $DEVICE/package.sh $1
}
最终会调用
cong@dell:/work/ct/android42$vi ../lichee/tools/pack/pack
主流程会调用: do_prepare 与 do_pack_android
function do_prepare()
{
//功能: 将./lichee/tools/pack/chips/sun7i/eFex/ 拷贝到 ./lichee/tools/pack/
cp -r chips/${PACK_CHIP}/eFex .
cp -r chips/${PACK_CHIP}/eGon .
cp -r chips/${PACK_CHIP}/wboot .
//将./lichee/tools/pack/下的out目录清空
rm -rf out/
mkdir -p out/
}
PACK_CHIP=sun7i,PACK_PLATFORM=android,PACK_BOARD=sugar-cubietruck
function do_pack_android()
{
cp -fchips/${PACK_CHIP}/configs/${PACK_PLATFORM}/default/* out/
cp -fchips/${PACK_CHIP}/configs/${PACK_PLATFORM}/${PACK_BOARD}/*.fex out/
cp -fchips/${PACK_CHIP}/configs/${PACK_PLATFORM}/${PACK_BOARD}/*.cfg out/ 2>>/dev/null
//以下两句好像没有什么作用
do_debug
do_parse //调用../lichee/tools/pack/pctools/linux/mod_update/script_parse这个python调本
cp -rf eFex/split_xxxx.fex wboot/bootfswboot/bootfs.ini out/
cp -f eGon/boot0_nand.binout/boot0_nand.bin
cp -f eGon/boot1_nand.binout/boot1_nand.fex
cp -f eGon/boot0_sdcard.binout/boot0_sdcard.fex
cp -f eGon/boot1_sdcard.binout/boot1_sdcard.fex
cd out/
stan_cmd cp ${LICHEE_OUT}/u-boot.binbootfs/linux/ //更新u-boot.bin
sed -i 's/\\bootfs/\/bootfs/g'bootfs.ini //修改配置文件中的windows路径,将\替换为/
sed -i 's/\\\\/\//g' image.cfg //修改配置文件中的windows路径,将\替换为/
sed -i 's/imagename/;imagename/g'image.cfg //修改配置文件,注掉image.cfg中的imagename
//重新生成image.cfg中的imagename
local IMG_NAME
if [ $PACK_DEBUG = "card0" ]; then
IMG_NAME="${PACK_CHIP}_${PACK_PLATFORM}_${PACK_BOARD}_${PACK_DEBUG}.img"
else
IMG_NAME="${PACK_CHIP}_${PACK_PLATFORM}_${PACK_BOARD}.img"
fi
echo "imagename =${IMG_NAME}" >> image.cfg
echo "" >> image.cfg
busybox unix2dos sys_config.fex
busybox unix2dos sys_partition.fex
//调用./lichee/boot/pack/pctools/linux/mod_update/下的命令
pack_cmd script sys_config.fex
pack_cmd script sys_partition.fex
cp sys_config.bin bootfs/script.bin
//调用./lichee/boot/pack/pctools/linux/mod_update/下的命令
pack_cmd update_mbr sys_partition.bin 4
pack_cmd update_boot0 boot0_nand.binsys_config.bin NAND
pack_cmd update_boot0 boot0_sdcard.fexsys_config.bin SDMMC_CARD
pack_cmd update_boot1 boot1_nand.fexsys_config.bin NAND
pack_cmd update_boot1 boot1_sdcard.fexsys_config.bin SDMMC_CARD
pack_cmd fsbuild bootfs.ini split_xxxx.fex
mv bootfs.fex bootloader.fex
u_boot_env_gen env.cfg env.fex
ln -s ${ANDROID_IMAGE_OUT}/boot.imgboot.fex
ln -s ${ANDROID_IMAGE_OUT}/system.imgsystem.fex
ln -s ${ANDROID_IMAGE_OUT}/recovery.imgrecovery.fex
pack_cmd dragon image.cfgsys_partition.fex
if [ -e ${IMG_NAME} ]; then
mv ${IMG_NAME} ../${IMG_NAME}
echo '----------image isat----------'
echo -e '\033[0;31;1m'
echo ${ROOT_DIR}/${IMG_NAME}
echo -e '\033[0m'
fi
cd ..
}