全志V40/A40I的lichee 的编译

您所在的位置:网站首页 chips是什么东西 全志V40/A40I的lichee 的编译

全志V40/A40I的lichee 的编译

2024-01-23 22:24| 来源: 网络整理| 查看: 265

首先了解一下全志编译lichee的步骤

回顾编译方式:

一般来说都是先配置一下芯片所包含的信息。

source build.sh config

在这里插入图片描述 编译;

source build.sh

摘要: 在这里插入图片描述

正文

上面执行build.sh config 。那么主要深究的是这个过程,是怎么去编译。将我们需要的芯片产商平台,内核版本,系统类型,具体系列。编译进去的。

build.sh代码: 在这里插入图片描述 这是一个比较简单的脚本代码。 跳到buildroot/scripts/目录下执行mkcommon.sh 附带一个参数 $@ 。 看图说话; 在这里插入图片描述 ①首先build.sh 脚本执行下来直接到mkcommon.sh脚本,有两个分支②。 ②shflags配置和执行mksetup.sh脚本。 ③mksetup脚本包含了两个函数 select-board 和 init_defconf 。 ④调用到架构内核的配置。 注:select_board和init_defconf函数mkcmd.sh 脚本里面(里面包含大量函数)。 那么先分析mkcommon.sh,在分析shflags和mksetup.sh,主要分析select-board 和 init_defconf 函数, 最后分析到架构上面去。

分析mkcommon.sh

在整一个脚本里面分为五大块执行,分开看可以更加清晰看到整栋源码楼

startsource shflagsdefine option, format:parse the command-lineinit default config start #!/bin/bash BR_SCRIPTS_DIR=`dirname $0` *$0 就是自身目录名字 * source shflags . ${BR_SCRIPTS_DIR}/shflags/shflags *执行shflags* [ -f .buildconfig ] && . .buildconfig *如果buildconfig 存在即编译 * . ${BR_SCRIPTS_DIR}/mkcmd.sh *执行mkcmd.sh 里面包含大量的命令* [ -f .buildconfig ] && . .buildconfig if [ "x$1" = "xconfig" ] ; then *判断传来参数是否config* . ${BR_SCRIPTS_DIR}/mksetup.sh exit $? elif [ "x$1" = "xpack" ] ; then *判断传来参数是否 pack* init_defconf mkpack exit $? elif [ "x$1" = "xpack_debug" ] ; then *判断传来参数是否pack_debug* init_defconf mkpack -d card0 exit $? elif [ "x$1" = "xpack_dump" ] ; then *判断传来参数是否pack_dump* init_defconf mkpack -m dump exit $? elif [ "x$1" = "xpack_secure" ] ; then *判断传来参数是否pack_secure* init_defconf mkpack -s secure exit $? elif [ "x$1" = "xpack_prev_refurbish" ] ; then *判断传来参数是否pack_prev_refurbish* init_defconf mkpack -s secure -f prev_refurbish exit $? elif [ "x$1" = "xpack_prvt" ] ; then *判断传来参数是否pack_prev_refurbish* init_defconf mkpack -f prvt exit $? elif [ "x$1" = "xpack_nor" ] ;then *判断传来参数是否xpack_nor* init_defconf if [ "x$2" = "xdebug" ] ; then *判断传来第二个参数是否debug* mkpack -f spinor -d card0 else mkpack -f spinor fi exit $? elif [ "x$1" = "xclean" ] ;then *判断传来参数是否xclean* init_defconf mkclean exit $? elif [ "x$1" = "xdistclean" ] ;then *判断传来参数是否xdistclean* init_defconf mkdistclean exit $? elif [ $# -eq 0 ] ; then init_defconf *执行 init_defconf 函数* mklichee *执行 mklichee函数* exit $?

fi

define option, format: DEFINE_string 'platform' '' 'platform to build, e.g. sun9iw1p1' 'p' DEFINE_string 'kernel' 'linux-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' FLAGS_HELP="Top level build script for lichee Examples: 1. Set the config option $ ./build.sh config 2. Build lichee using preset config value $ ./build.sh 3. Pack a linux, dragonboard image $ ./build.sh pack 4. Build lichee using command argument $ ./build.sh -p " parse the command-line FLAGS "$@" || exit $? eval set -- "${FLAGS_ARGV}" chip=${FLAGS_platform%%_*} platform=${FLAGS_platform##*_} kernel=${FLAGS_kernel} board=${FLAGS_board} module=${FLAGS_module} if [ "${platform}" = "${chip}" ] ; then platform="linux" fi if [ -z "${module}" ] ; then module="all" fi if ! init_chips ${chip} || \ ! init_platforms ${platform} ; then mk_error "invalid platform '${FLAGS_platform}'" exit 1 fi if ! init_kern_ver ${kernel} ; then mk_error "invalid kernel '${FLAGS_kernel}'" exit 1 fi if [ ${FLAGS_board} ] && \ ! init_boards ${chip} ${board} ; then mk_error "invalid board '${FLAGS_board}'" exit 1 fi init default config init_defconf if [ ${module} = "all" ]; then mklichee elif [ ${module} = "boot" ] ; then mkboot elif [ ${module} = "buildroot" ] ; then mkbr elif [ ${module} = "kernel" ] ; then mkkernel elif [ ${module} = "clean" ] ; then mkclean elif [ ${module} = "distclean" ] ; then mkdistclean else mk_error "invalid module '${module}'" exit 1 fi exit $?

到这里mkcommon.sh文件的所有命令都执行完成;

蕴涵大量函数的脚本:mkcmd.sh

这个脚本里面身包含了功能性函数,换句话说就是将里面的所有函数命令都包含出来。

这个函数类似我们查看其他库的 -help 命令一样。 使用这个函数介绍mkcmd.sh 这个脚本里面 大体包含什么东西。 function mkhelp() { printf " mkscript - lichee build script : 1.0.0 : james : mkboot build boot mkbr build buildroot mkkernel build kernel mkrootfs build rootfs for linux, dragonboard mklichee build total lichee mkclean clean current board output mkdistclean clean entires output mkpack pack firmware for lichee mkhelp show this message" } 回到mkcommon.sh文件的主体: #!/bin/bash BR_SCRIPTS_DIR=`dirname $0` *$0 就是自身目录名字 * * . ${BR_SCRIPTS_DIR}/shflags/shflags *执行shflags* [ -f .buildconfig ] && . .buildconfig *如果buildconfig 存在即编译 * . ${BR_SCRIPTS_DIR}/mkcmd.sh *执行mkcmd.sh 里面包含大量的命令* [ -f .buildconfig ] && . .buildconfig

既然这个mkcmd.sh的脚本就是配置函数的那么不详细看,用到在去到那里面找。回到mkcommon.sh脚本里面,停留在一大堆循环的最开始的位置。

if [ "x$1" = "xconfig" ] ; then

当一开始我们执行下面命令的时候。

source build.sh config

config作为配置参数传进来也就是 $1.。判断成立然后执行下面这个脚本。

. ${BR_SCRIPTS_DIR}/mksetup.sh

## 分析mksetup.sh脚本里面包含了什么东西

. buildroot/scripts/mkcmd.sh *加载mkcmd.sh 里面的命令函数* function mksetup() { rm -f .buildconfig printf "\n" printf "Welcome to mkscript setup progress\n" select_board *select_board函数 选择系列配置* init_defconf *init_defconf函数初始化定义配置* }

分析这两个函数,都在mkcmd.sh文件里面。

select_board函数

在这里插入图片描述 通过层层查找下去会发现这里面是一个这样的结构。 在这里插入图片描述 经过层层分析之后最后得到一个这样的结构。 select_board—>select_kern_ver->select_plaform->select_chip 这个结构使我们非常熟悉的一个图解。每个函数在里面都实习了自己的选项和功能。也就是下图 在这里插入图片描述 我们所熟悉这个选项结构就是在上面编译出来。

init_defconf 函数 那么看看init_defconf 函数在里面干了些什么东西。 在这里插入图片描述 在里面出来表明路径和配置之外,特别注重的就是这句命令,他就是这个函数里面的太阳。

defconf=`awk '$1=="'$pattern'" {print $2,$3}' buildroot/scripts/mkrule` 注:在 buildroot/scripts/mkrule文件下,按照“$pattern” 字符串来查找这个文件的一 个行字符。 并且将同行第二段和第三段字符打印出来。 在这里需要自行补课awk命令。

那么必须要进入到这mkrule文件里面分析。 在这里插入图片描述 里面却是一堆这样的东西。那么这些玩意是什么呢? 我们将其中的一行(第一行)抽离出来看。将他们分成3段来看。这就是上面提到的$1,$2 ,$3。他们各自代表里面的一段,其实里面就是可以看成 $1=sun8iw1p1_android 在这里插入图片描述

defconf=`awk '$1=="'$pattern'" {print $2,$3}' buildroot/scripts/mkrule`

意思就是通过 $1 找到对应的行,然后将后面两段的指令都给执行了。在这里详细讲解一下所谓$1 ,$2 ,$3里面究竟是什么东西。

一、sun8iw1p1_android ($1) 其实是我们芯片和平台来的。但是一定的格式命名要求符合,chip_platform。并且chip和platform是必须与芯片平台保持一致。在对照上面图片。其实$1 就是你自己选择芯片和平台。他直接拿过来使用了。所以才有行代码。对应起来每一项都是自己选择么. 。我们之前选择的每一次决定都影响着之后的编译路径。

pattern="${LICHEE_CHIP}_${LICHEE_PLATFORM}_${LICHEE_BOARD}" 相等于: LICHEE_CHIP = chip LICHEE_PLATFORM = android LICHEE_BOARD = board

在这里插入图片描述

二、 sun8i_defconfig ($2) 也就是所谓中间段。这个是配置我们的buildroot配置的。 具体的位置 。里面包含了产商写的配置文件。

/lichee/buildroot/configs

在这里插入图片描述 三、sun8iw1p1smp_android_defconfig ($3) 在最后的一段里面。这个是配置内核文件。 文件具体位置。里面文件很多有各个产商的内核配置代码。意思就是说当我们编译$1这个平台的芯片和对应的平台。 使用到对应配置内核文件。

/lichee/linux-3.10/arch/arm/configs

在这里插入图片描述 所以到这里就比较清晰了。其实init_deconf函数,就是将自己选择平台和芯片型号。都会给你找到对应的配置文件和内核文件。他们全部都编译进去。最后有关于init_deconf函数的代码不再分析了仅仅是调整输出目录。配置环境等等。 init_defconf函数分析完了那么整一个mksetup.sh函数了。那么现在还是再次回到mkcommon.sh文件主体里面。会发现到了函数已经到、 define option, format: parse the command-line init default config 这些配置和判断操作了。 代码十分简单看一下就可以了解大概状况。 所以不再详细source build.sh config 这个命令了。但是我们一旦配置完之后是不是还会执行

source build.sh

这个编译命令。那么下面就是开始介绍我们一旦编译 build.sh 这个文件。整体的源码是怎么操作走势如何。

译 source build.sh

前面的操作都是一样的,但是由于没有带参数进来到mkcommon.sh文件。所以在大循环里面将会进入到这个循环里面了。 init_defconf在上面分析了,那么mklichee这个函数要进行分析。 在这里插入图片描述

函数:mklichee

在这里插入图片描述 其中里面的mk_info函数就是一个打印函数,那么就要去到check_eev函数里面遨游。 发现里面也是空空的东西,仅仅是判断这些文件是否存在,做一个出错判断。 在这里插入图片描述 mklichee函数那么只剩下 mkbr && mkkernel && mkrootfs 这句可以分析的了。里面应该还是三个函数并且都要求同是成立,不然就返回1。

mkbr && mkkernel && mkrootfs [ $? -ne 0 ] && return 1

那么接下来就是里面的三个函数mkbr ,mkkernel ,mkrootfs。看得是十分熟悉名字应该就是我们的buildroot,内核,根文件系统。

################################################################### 在mkcmd.sh文件里面有着这些定义好的路径,要细心对应观察 里面是都会用到的路径。 在下面就不在详细讲解了

#define importance variable LICHEE_TOP_DIR=`pwd` LICHEE_BR_DIR=${LICHEE_TOP_DIR}/buildroot LICHEE_KERN_DIR=${LICHEE_TOP_DIR}/${LICHEE_KERN_VER} LICHEE_TOOLS_DIR=${LICHEE_TOP_DIR}/tools LICHEE_OUT_DIR=${LICHEE_TOP_DIR}/out

################################################################### 函数:mkbr 去到LICHEE_BR_DIR 目录下,然后判断scripts/build.sh是否存在。存在即执行 scripts/build.sh脚本。

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

mkkernel函数

function mkkernel() { mk_info "build kernel ..." local build_script="scripts/build.sh" prepare_toolchain /* prepare_toolchain 函数*/ # mark kernel .config belong to which platform local config_mark="${LICHEE_KERN_DIR}/.config.mark" ‘去到LCHEE_KERN_DIR路径’ 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." }

分段来讲解这个作用于内核的函数: 如果/external-toolchain文件存在的话,进去里面编译 mkbr函数。后面就是配置一下各个文件环境。 ①: prepare_toolchain 函数

function prepare_toolchain(){ mk_info "prepare toolchain of ${LICHEE_CHIP}..." tooldir=${LICHEE_BR_OUT}/external-toolchain if [ ! -d ${tooldir} ] ; then mk_info "The toolchain doesn't exsit. So compile the buildroot ..." mkbr fi if ! echo $PATH | grep -q "${tooldir}" ; then export PATH=${tooldir}/bin:$PATH fi }

小提一下mkbr函数; 就是执行scripts/build.sh这个脚本。

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

② : if [ -f ${config_mark} ] 判断这个文件是否存在,存在将会执行循环里面的函数③。不存在将会执行下面这个命令。将平台写进到 ${config_mark}文件里面。 这种类型sysfs操作和proc文件操作。

echo "${LICHEE_PLATFORM}" > ${config_mark}

③ (cd ${LICHEE_KERN_DIR} && [ -x KaTeX parse error: Expected 'EOF', got '&' at position 18: …uild_script} ] &̲& ./{build_script} “clean”) 在这里也就说明一下,③和④都是相对来说的。③的功能相对就是一个清空复位的操作。可以明显看到向./${build_script} 里面配置一个 " clean "进去。

④(cd ${LICHEE_KERN_DIR} && [ -x KaTeX parse error: Expected 'EOF', got '&' at position 18: …uild_script} ] &̲& ./{build_script}) 这里说下目录去到那里了不然跟丢了不知道跑到那个目录下了这主要是判断这个文件

LICHEE_KERN_DIR = lichee/linux-3.10。

scripts/build.sh 是否存在,并且执行。build.sh里面配置ARM架构,连接模块,连接库文件等等一些内核操作。

函数: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} if [ -f "${LICHEE_BR_OUT}/images/rootfs.squashfs" ]; then cp ${LICHEE_BR_OUT}/images/rootfs.squashfs ${LICHEE_PLAT_OUT} fi if [ "x$PACK_TINY_ANDROID" = "xtrue" ];then packtinyandroid fi 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." }

关于这函数的作用,一进来就判断平台是不是Linux,很明显我们的平台是android,内核是Linux-3.10。所以就没有进入循环里面。 主要实现这两行代码:

去到这个文件目录下: cd ${LICHEE_BR_DIR}/target/dragonboard 创建 一个modules目录: · ${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)

到这里就将真个编译流程都走完一遍了,但是会发现一些到内核配置和根文件系统等等的build.sh 脚本都没有详细讲解, 包含了产家的配置等需要自己去看看或者稍微浏览一下这个是产家提供的一些对应芯片内容。

还有一个章节就是讲解:source build.sh clean 在这里插入图片描述 那么回到 mkcommon.sh 脚本里面。在第二大层的循环分支里面包含了:

elif [ "x$1" = "xclean" ] ;then init_defconf mkclean exit $?

里面的里面主要的两个函数,一个init_defconf在前面已经讲过了。只要分析 mkclean这个函数:

function mkclean() { clkernel mk_info "clean product output in ${LICHEE_PLAT_OUT} ..." cd ${LICHEE_PLAT_OUT} ls | grep -v "buildroot" | xargs rm -rf * 查找到有关的内容删除掉* cd - > /dev/null }

这个函数相对简单点,一进来直接跑到 clkernel 函数里面的进行操作。看这个名字就知道应该是释放有关内核的资源。 clkernel函数相关:

function clkernel() { mk_info "clean kernel ..." local build_script="scripts/build.sh" prepare_toolchain (cd ${LICHEE_KERN_DIR} && [ -x ${build_script} ] && ./${build_script} "clean") mk_info "clean kernel OK." }

首先进入这个函数里面的话,那么直接执行这个函数了 prepare_toolchain。然后去到 对应的配置内核的目录下。判断这个文件(${build_script})是否存在并且,传clean进去 ,放之前配置内核的东西都往下面传递全部释放之前使用到的动态资源。 现在主要分析prepare_toolchain函数:其实里面就是一个工具链。

function prepare_toolchain() { mk_info "prepare toolchain of ${LICHEE_CHIP}..." tooldir=${LICHEE_BR_OUT}/external-toolchain if [ ! -d ${tooldir} ] ; then mk_info "The toolchain doesn't exsit. So compile the buildroot ..." mkbr fi if ! echo $PATH | grep -q "${tooldir}" ; then export PATH=${tooldir}/bin:$PATH fi }

当工具链不存在的话编译buildroot,构建buildroot。

在这里就分析有关于lichee目录下的build.sh脚本以及他们常用传参,也就完结了。里面其实还有很多可以使用的参数作为测试版本,调试版本等等。需要细心观察了。

关注微信公众号:(技术Code城)



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3