全志V40/A40I的lichee 的编译 |
您所在的位置:网站首页 › chips是什么东西 › 全志V40/A40I的lichee 的编译 |
首先了解一下全志编译lichee的步骤 回顾编译方式:一般来说都是先配置一下芯片所包含的信息。 source build.sh config
摘要: 上面执行build.sh config 。那么主要深究的是这个过程,是怎么去编译。将我们需要的芯片产商平台,内核版本,系统类型,具体系列。编译进去的。 build.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 configconfig作为配置参数传进来也就是 $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函数
init_defconf 函数 那么看看init_defconf 函数在里面干了些什么东西。 那么必须要进入到这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
这个编译命令。那么下面就是开始介绍我们一旦编译 build.sh 这个文件。整体的源码是怎么操作走势如何。 译 source build.sh前面的操作都是一样的,但是由于没有带参数进来到mkcommon.sh文件。所以在大循环里面将会进入到这个循环里面了。 init_defconf在上面分析了,那么mklichee这个函数要进行分析。 函数:mklichee
那么接下来就是里面的三个函数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 里面的里面主要的两个函数,一个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 |