加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > Linux > 正文

全志A33编译脚本分析

发布时间:2020-12-13 23:46:35 所属栏目:Linux 来源:网络整理
导读:0x00 环境说明: 分析所使用的SDK为锐尔威视的开发板的资料中的Linux-SDK 0x01 脚本分析: 顶层目录下的build.sh: buildroot/scripts/mkcommon.sh [email?protected] 本质上是调用的? buildroot/scripts/mkcommon.sh 并直接把所有的参数传过去 mkcommon.sh

0x00 环境说明:

分析所使用的SDK为锐尔威视的开发板的资料中的Linux-SDK

0x01 脚本分析:

顶层目录下的build.sh:

buildroot/scripts/mkcommon.sh [email?protected]

本质上是调用的? buildroot/scripts/mkcommon.sh 并直接把所有的参数传过去

mkcommon.sh前几行:

BR_SCRIPTS_DIR=`dirname $0`

# source shflags
. ${BR_SCRIPTS_DIR}/shflags/shflags

. ${BR_SCRIPTS_DIR}/mkcmd.sh

设置目录,导入相关命令

然后是:

[ -f .buildconfig ] && . .buildconfig

.buildconfig 文件存在时source该文件

往后是:

if [ "x$1" = "xconfig" ] ; then
???? . ${BR_SCRIPTS_DIR}/mksetup.sh
???? exit $?
elif [ "x$1" = "xpack" ] ; then
???? init_defconf
???? mkpack
???? exit $?
elif [ "x$1" = "xpack_debug" ] ; then
???? init_defconf
???? mkpack -d card0
???? exit $?
elif [ "x$1" = "xpack_dump" ] ; then
???? init_defconf
???? mkpack -m dump
???? exit $?
elif [ "x$1" = "xpack_prvt" ] ; then
???? init_defconf
???? mkpack -f prvt
???? exit $?
elif [ $# -eq 0 ] ; then
???? init_defconf
???? mklichee
???? exit $?
fi

根据传入的参数进行相关的操作,从上到下判断的参数依次是:

1、config

2、pack

3、pack_debug

4、pack_dump

5、pack_prvt

6、参数为空

step1:“./build.sh? config”

按照编译时的操作顺序,首先执行时传入的参数为 config,调用的是 该目录下的 mksetup.sh:

. buildroot/scripts/mkcmd.sh

function mksetup()
{
???? rm -f .buildconfig
???? printf "n"
???? printf "Welcome to mkscript setup progressn"

??? select_board

??? init_defconf
}

mksetup

可以知道具体流程如下:

1、导入 buildroot/scripts/mkcmd.sh 中符号(函数)

2、删除配置文件 .buildconfig(顶层目录)

3、打印提示信息

4、执行 mkcmd.sh 中的 select_board

5、执行 mkcmd.sh 中的 init_defconf

在 select_board 中需要用户设置 chip、platform、kernel、board 等配置

在 init_defconf 则主要设置一些编译时所需要的路径信息

最终会在顶层目录的 .buildconfig 文件中生成如下信息(不同的选择会有所差异):

export LICHEE_CHIP=sun8iw5p1
export LICHEE_PLATFORM=dragonboard
export LICHEE_KERN_VER=linux-3.4
export LICHEE_BOARD=vstar

step2:“cp? a33_vstar_defconfig? .config”

在 Linux 内核的顶层目录下生成编译配置文件 .config

后续可以通过命令修改配置:

make? menuconfig

当然也可以直接进行编辑

step3:“./build.sh ”

编译时直接调用 build.sh,不传入任何参数,在 mkcommon.sh 中执行的是第六条分支:

elif [ $# -eq 0 ] ; then
???? init_defconf
???? mklichee
???? exit $?
fi

其中 init_defconf 确保环境的初始化

编译时主要执行的命令是 mklichee

在 mkcmd.sh 文件中查看 mklichee 的实现:

function mklichee()
{

??? mk_info "----------------------------------------"
???? mk_info "build lichee ..."
???? mk_info "chip: $LICHEE_CHIP"
???? mk_info "platform: $LICHEE_PLATFORM"
???? mk_info "kernel: $LICHEE_KERN_VER"
???? mk_info "board: $LICHEE_BOARD"
???? mk_info "output: out/${LICHEE_CHIP}/${LICHEE_PLATFORM}/${LICHEE_BOARD}"
???? mk_info "----------------------------------------"
????
???? check_env

??? mkbr && mkkernel && mkrootfs
???? [ $? -ne 0 ] && return 1
????
???? mk_info "----------------------------------------"
???? mk_info "build lichee OK."
???? mk_info "----------------------------------------"
}

其中 mk_info 设置打印字符串的格式:

function mk_info()
{
???? echo -e "33[47;30mINFO: $*33[0m"
}

mklichee 大致流程为:

1、打印相关配置信息

2、调用 check_env 检查环境

3、依次调用 mkbr、mkkernel、mkrootfs

4、检查执行结果

mkbr:

function mkbr()
{
???? mk_info "build buildroot ..."

??? local build_script="scripts/build.sh"
???? (cd ${LICHEE_BR_DIR} && [ -x ${build_script} ] && ./${build_script})
???? [ $? -ne 0 ] && mk_error "build buildroot Failed" && return 1

??? mk_info "build buildroot OK."
}

该命令实现:进入顶层目录下的 buildroot 文件夹,并执行该文件夹下的 scripts/build.sh

buildroot/scripts/build.sh 先进行编译环境的配置,然后执行:

case "$1" in
???? clean)
???????? rm -rf ${LICHEE_BR_OUT}
???????? ;;
???? *)
???????? if [ "x${LICHEE_PLATFORM}" = "xlinux" ] ; then
???????????? build_buildroot
???????????? export PATH=${LICHEE_BR_OUT}/external-toolchain/bin:$PATH
???????????? build_external
???????? else
???????????? build_toolchain
???????? fi
???????? ;;
esac

调用时未传入任何参数,直接跳过第一种参数为 “clean” 时的情况,后续为:

1、当 platform 配置为 linux 时,调用build_buildroot、导出路径、调用build_external

2、当 platform 配置其他情况(android/dragonboard)时,直接调用 build_toolchain

其中 build_buildroot 与 build_external :

build_buildroot()
{
???? if [ ! -f ${LICHEE_BR_OUT}/.config ] ; then
???????? printf "nUsing default config ...nn"
???????? make O=${LICHEE_BR_OUT} -C ${LICHEE_BR_DIR} ${LICHEE_BR_DEFCONF}
???? fi

??? make O=${LICHEE_BR_OUT} -C ${LICHEE_BR_DIR} LICHEE_GEN_ROOTFS=n
???????? BR2_JLEVEL=${LICHEE_JLEVEL}
}

build_external()
{
???? for dir in ${EXTERNAL_DIR}/* ; do
???????? if [ -f ${dir}/Makefile ]; then
???????????? BUILD_COMMAND="make -C ${dir} ${BUILD_OPTIONS} all"
???????????? eval $BUILD_COMMAND
???????????? BUILD_COMMAND="make -C ${dir} ${BUILD_OPTIONS} install"
???????????? eval $BUILD_COMMAND
???????? fi
???? done
}

build_buildroot 编译生成 交叉工具链(arm-linux-gnueabi),其中:

LICHEE_PLAT_OUT="${LICHEE_OUT_DIR}/${LICHEE_CHIP}/${LICHEE_PLATFORM}/${out_dir}"

LICHEE_BR_OUT="${LICHEE_PLAT_OUT}/buildroot"

build_external 编译扩展的软件工具包,其中:

EXTERNAL_DIR=${LICHEE_BR_DIR}/external-packages

build_toolchain:

build_toolchain()
{
???? local tooldir="${LICHEE_BR_OUT}/external-toolchain"
???? mkdir -p ${tooldir}
???? if [ -f ${tooldir}/.installed ] ; then
???????? printf "external toolchain has been installedn"
???? else
???????? printf "installing external toolchainn"
???????? printf "please wait for a few minutes ...n"
???????? tar --strip-components=1
???????????? -jxf ${LICHEE_BR_DIR}/dl/gcc-linaro.tar.bz2
???????????? -C ${tooldir}
???????? [ $? -eq 0 ] && touch ${tooldir}/.installed
???? fi

??? export PATH=${tooldir}/bin:${PATH}
}

作用是直接安装交叉工具链(gcc-linaro),路径为:${LICHEE_BR_DIR}/dl/gcc-linaro.tar.bz2

mkbr到这里就分析完了,下面看mkkernel:

function mkkernel()
{
???? mk_info "build kernel ..."

??? local build_script="scripts/build.sh"

??? prepare_toolchain

??? # mark kernel .config belong to which platform
???? local config_mark="${LICHEE_KERN_DIR}/.config.mark"
???? if [ -f ${config_mark} ] ; then
???????? if ! grep -q "${LICHEE_PLATFORM}" ${config_mark} ; then
???????????? mk_info "clean last time build for 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

??? (cd ${LICHEE_KERN_DIR} && [ -x ${build_script} ] && ./${build_script})
???? [ $? -ne 0 ] && mk_error "build kernel Failed" && return 1

??? mk_info "build kernel OK."
}

流程为处理配置文件之后调用 linux3.4/scripts/build.sh 编译Linux内核:

case "$1" in
kernel)
???? build_kernel
???? ;;
modules)
???? build_modules
???? ;;
clean)
???? clean_kernel
???? clean_modules
???? ;;
*)
???? build_kernel
???? build_modules
???? build_ramfs
???? gen_output
???? ;;
esac

下面分析 mkrootfs:

function mkrootfs()
{
???? 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 dragonboard Rootfs..."
???????? (
???????????? cd ${LICHEE_BR_DIR}/target/dragonboard;
???????????? if [ ! -d "./rootfs" ]; then
???????????? echo "extract dragonboard rootfs.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."
}

作用是生成根文件系统,按照配置的平台的不同分为以下情况:

1、linux:从头开始编译根文件系统

2、dragonboard:直接解压打包好的根文件系统(rootfs.tar.gz),然后加入相关的驱动模块

3、android:直接跳过,android的根文件系统不在这里生成

如果需要进行根文件系统的定制修改,需要分析 mkrootfs 的一些细节

?

0x02 简单汇总:

最后贴上笔者分析过程中的简单笔记,分析的时候可以凑合着看

build.sh-> buildroot/scripts/mkcommon.sh [email?protected]

. ./mkcmd.sh(导入相关编译命令)
[ -f .buildconfig ] && . .buildconfig

$1==config:
???? mksetup.sh
???????? rm -f .buildconfig(build.sh目录下)
???????? select_board
???????? init_defconf(配置输出路径)
???????????? LICHEE_PLAT_OUT:/root/a33_linux/dragonboard/out/sun8iw5p1/linux/common
???????????? LICHEE_BR_OUT:/root/a33_linux/dragonboard/out/sun8iw5p1/linux/common/buildroot

$1==pack:
???? init_defconf
???? mkpack
???????? check_env
???????? (cd ${LICHEE_TOOLS_DIR}/pack &&
???????????? ./pack -c ${LICHEE_CHIP} -p ${LICHEE_PLATFORM} -b ${LICHEE_BOARD} [email?protected]) ./pack -c sun8iw5p1 -p linux -b vstar???????????? $1为空:???? init_defconf???? mklichee???????? mk_info(打印一些配置信息)???????? check_env(检查配置,即检查之前有没有运行"./build.sh config"命令)???????? mkbr && mkkernel && mkrootfs???????????? mkbr:(编译buildroot)???????????????? 执行scripts/build.sh???????????? mkkernel:(编译内核)???????????????? prepare_toolchain(检查工具链)???????????????? 使用${LICHEE_KERN_DIR}/.config.mark文件中的平台设置???????????????? 执行scripts/build.sh???????????? mkrootfs:(编译rootfs)???????????????? linux:???????????????????? make O=${LICHEE_BR_OUT} -C ${LICHEE_BR_DIR} target-generic-getty-busybox???????????????????? make O=${LICHEE_BR_OUT} -C ${LICHEE_BR_DIR} target-finalize???????????????????? make O=${LICHEE_BR_OUT} -C ${LICHEE_BR_DIR} LICHEE_GEN_ROOTFS=y rootfs-ext4???????????????????? cp ${LICHEE_BR_OUT}/images/rootfs.ext4 ${LICHEE_PLAT_OUT}??????????????? ???????????????? dragonboard:???????????????????? cd ${LICHEE_BR_DIR}/target/dragonboard???????????????????? tar zxf rootfs.tar.gz???????????????????? 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}??????????????? ???????????????? Android:(Android不在这里编译根文件系统) #make O=/root/a33_linux/dragonboard/out/sun8iw5p1/linux/common/buildroot???????????????? scripts/build.sh: $1==clean:??? ???? rm -rf ${LICHEE_BR_OUT} 默认:???? ${LICHEE_PLATFORM}==linux:???????? build_buildroot???????? export PATH=${LICHEE_BR_OUT}/external-toolchain/bin:$PATH???????? build_external???? 默认:???????? build_toolchain

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读