一、前言    

     刚开始用全志的编译脚本还不太习惯,虽然很方便,但是编译出问题的时候却不知道从哪里入手解决.

二、初步接触全志编译脚本工具

第一个接触的脚本是build.sh

litin@linuxService:~/Android/allwinner/cqa64_android_v5.1/lichee$ cat build.sh 
#!/bin/bash
set -e
buildroot/scripts/mkcommon.sh $@
从脚本内容可知,它只是间接调用其他脚本“buildroot/scripts/mkcommon.sh”

litin@linuxService:~/Android/allwinner/cqa64_android_v5.1/lichee$ cat buildroot/scripts/mkcommon.sh
#!/bin/bash

BR_SCRIPTS_DIR=`dirname $0`

# source shflags
. ${BR_SCRIPTS_DIR}/shflags/shflags
[ -f .buildconfig ] && . .buildconfig     
. ${BR_SCRIPTS_DIR}/mkcmd.sh             ####把一些常用的命令导出,方便直接调用

[ -f .buildconfig ] && . .buildconfig

if [ "x$1" = "xconfig" ] ; then          ####输入build.sh config 则执行mksetup.sh脚本
    . ${BR_SCRIPTS_DIR}/mksetup.sh
    exit $?
elif [ "x$1" = "xpack" ] ; then          ###输入build.sh pack, 则执行命令init_defconf和mkpack -d card0
    if [  "x$2" = "x-d" ] ; then
        init_defconf
        mkpack -d card0
        exit $?
    else
        init_defconf
        mkpack
        exit $?
    fi
elif [ "x$1" = "xpack_debug" ] ; then     
    init_defconf
    mkpack -d card0
    exit $?
elif [ "x$1" = "xpack_dump" ] ; then       ###输入build.sh 则执行命令初始化配置 和 mkpack -m dump
    init_defconf
    mkpack -m dump
    exit $?
elif [ "x$1" = "xpack_secure" ] ; then     ###输入build.sh pack_secure,加密式的打包
    init_defconf
    mkpack -s secure -d $2
    exit $?
elif [ "x$1" = "xpack_prev_refurbish" ] ; then
        init_defconf
        mkpack -s secure -f prev_refurbish
        exit $?
elif [ "x$1" = "xpack_prvt" ] ; then
    init_defconf
    mkpack -f prvt
    exit $?
elif [ "x$1" = "xpack_nor" ] ;then
    init_defconf
    if [ "x$2" = "xdebug" ] ; then
        mkpack -f spinor -d card0
    else
        mkpack -f spinor
    fi
    exit $?
elif [ "x$1" = "xpack_erase" ] ; then
    init_defconf
    mkpack -f erase
    exit $?
elif [ $# -eq 0 ] ; then           ###build.sh 后面不带参数则执行初始化配置和编译linux内核
    init_defconf
    mklichee
    exit $?
fi

# define option, format:
#   'long option' 'default value' 'help message' 'short option'
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 <platform>
"

# 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 $?

2.全志的瑞士军刀“mkcmd.sh”

    “mkcmd.sh”这个工具位于“lichee/buildroot/scripts/mkcmd.sh”,如果想知道这命令里面包含什么功能可以输入“mkhelp”

litin@linuxService:~/Android/allwinner/cqa64_android_v5.1/lichee$ mkhelp 

                mkscript - lichee build script

<version>: 1.0.0
<author >: james

<command>:
    mkboot      build boot           ###暂时没啥用,只是单纯显示信息
    mkbr        build buildroot      ###生成编译链,初始化编译环境
    mkkernel    build kernel         ###编译内核
    mkrootfs    build rootfs for linux, dragonboard  ###编译生成rootfs文件系统(安卓系统不在这里生成文件系统)
    mklichee    build total lichee   ###(输入build.sh命令则)编译以上三个东西mkbr && mkkernel && mkrootfs
    
    mkclean     clean current board output  ###清除板载的输出文件
    mkdistclean clean entires output        ###清除所有编译文件
    mkpack      pack firmware for lichee    ###打包全志固件(执行pack命令)
    mkhelp      show this message           ###打印帮助信息(也就是本信息)

3.全志dtb文件的分析

dtb文件是使用pack命令来生成或者拷贝的。

===========================lichee/tools/pack/pack===============================
function do_ini_to_dts()
{
        #these args used to conver sys_config to dts
        if [ -z "`echo ${PACK_CHIP} | grep "sun5[0-9]i"`" ]; then
                local DTC_DES_ARCH=arm
                local KERN_VER=linux-3.4
                return
        else
                local DTC_DES_ARCH=arm64
                local KERN_VER=linux-3.10
        fi
        local DTC_COMPILER=${LICHEE_OUT}/../../../../$KERN_VER/scripts/dtc/dtc
{
        #these args used to conver sys_config to dts
        if [ -z "`echo ${PACK_CHIP} | grep "sun5[0-9]i"`" ]; then
                local DTC_DES_ARCH=arm
                local KERN_VER=linux-3.4
                return
        else
                local DTC_DES_ARCH=arm64
                local KERN_VER=linux-3.10
        fi
        local DTC_COMPILER=${LICHEE_OUT}/../../../../$KERN_VER/scripts/dtc/dtc
        local DTC_DEP_FILE=${LICHEE_OUT}/../../../../$KERN_VER/arch/$DTC_DES_ARCH/boot/dts/.${PACK_CHIP}-${PACK_BOARD}.dtb.d.dtc.tmp
        local DTC_SRC_PATH=${LICHEE_OUT}/../../../../$KERN_VER/arch/$DTC_DES_ARCH/boot/dts/
        local DTC_SRC_FILE=${LICHEE_OUT}/../../../../$KERN_VER/arch/$DTC_DES_ARCH/boot/dts/.${PACK_CHIP}-${PACK_BOARD}.dtb.dts
        local DTC_INI_FILE_BASE=${LICHEE_OUT}/../../../../tools/pack/out/sys_config.fex
        local DTC_INI_FILE=${LICHEE_OUT}/../../../../tools/pack/out/sys_config_fix.fex
        cp $DTC_INI_FILE_BASE $DTC_INI_FILE
        sed -i "s/\(\[dram\)_para\(\]\)/\1\2/g" $DTC_INI_FILE
        sed -i "s/\(\[nand[0-9]\)_para\(\]\)/\1\2/g" $DTC_INI_FILE

        if [ ! -f $DTC_COMPILER ]; then
                printf "Script_to_dts: Can not find dtc compiler.\n"
                return
        fi
        if [ ! -f $DTC_DEP_FILE ]; then
                printf "Script_to_dts: Can not find [%s-%s.dts]. Will use common dts file instead.\n" ${PACK_CHIP} ${PACK_BOARD}
                DTC_DEP_FILE=${LICHEE_OUT}/../../../../$KERN_VER/arch/$DTC_DES_ARCH/boot/dts/.${PACK_CHIP}-soc.dtb.d.dtc.tmp
                DTC_SRC_FILE=${LICHEE_OUT}/../../../../$KERN_VER/arch/$DTC_DES_ARCH/boot/dts/.${PACK_CHIP}-soc.dtb.dts
        fi
        $DTC_COMPILER -O dtb -o ${LICHEE_OUT}/sunxi.dtb \
                -b 0                    \
                -i $DTC_SRC_PATH        \
                -F $DTC_INI_FILE        \
                -d $DTC_DEP_FILE $DTC_SRC_FILE
        printf "Conver script to dts ok.\n"
        return
}


(1)sunxi.dtb的初步生成

这个dtb是直接拷贝

运行打包命令:build.sh pack 提示错误信息

Script_to_dts: Can not find [sun50iw1p1-t1.dts]. Will use common dts file instead.

可知当“sun50iw1p1-t1.dts”文件不存在的时候会取一个默认的dts文件:

DTC_SRC_FILE=${LICHEE_OUT}/../../../../$KERN_VER/arch/$DTC_DES_ARCH/boot/dts/.${PACK_CHIP}-soc.dtb.dts
也就是选取linux源码下的文件“linux-3.10/arch/arm64/boot/dts/.sun50iw1p1-soc.dtb.dts”。

(2)dtb的参数覆盖

全志的dtb设备树文件是由多个文件合并生成的

        $DTC_COMPILER -O dtb -o ${LICHEE_OUT}/sunxi.dtb \
                -b 0                    \
                -i $DTC_SRC_PATH        \
                -F $DTC_INI_FILE        \
                -d $DTC_DEP_FILE $DTC_SRC_FILE
展开上面的命令可知

/linux-3.10/scripts/dtc/dtc -O dtb 
-o /lichee/out/sun50iw1p1/android/common/sunxi.dtb	
-b  0			  
-i /linux-3.10/arch/arm64/boot/dts/	  
-F /lichee/tools/pack/out/sys_config_fix.fex	 #sys_config.fex 和sys_config.fex其实已经合而为一了
-d /linux-3.10/arch/arm64/boot/dts/.sun50iw1p1-soc.dtb.d.dtc.tmp 
/linux-3.10/arch/arm64/boot/dts/.sun50iw1p1-soc.dtb.dts 

dtb文件的生成是分优先级的:sys_config.fex>sys_config_fix.fex>..sun50iw1p1-soc.dtb.dts/.sun50iw1p1-soc.dtb.d.dtc.tmp
默认情况下,sys_config.fex优先级最高,一般只需要修改它就行了。

(3)科普一下dtc命令

这个命令的源码在“linux-3.10/scripts/dtc/dtc.c”如果想知道有什么功能,可以输入查询命令

litin@linuxService:~/Android/allwinner/cqa64_android_v5.1/lichee$ ./linux-3.10/scripts/dtc/dtc -h
Usage:
	dtc [options] <input file>

Options:
	-h
		This help text
	-q
		Quiet: -q suppress warnings, -qq errors, -qqq all
	-I <input format>
		Input formats are:
			dts - device tree source text
			dtb - device tree blob
			fs - /proc/device-tree style directory
	-o <output file>
	-O <output format>
		Output formats are:
			dts - device tree source text
			dtb - device tree blob
			asm - assembler source
	-V <output version>
		Blob version to produce, defaults to 17 (relevant for dtb
		and asm output only)
	-d <output dependency file>
	-R <number>
		Make space for <number> reserve map entries (relevant for 
		dtb and asm output only)
	-S <bytes>
		Make the blob at least <bytes> long (extra space)
	-p <bytes>
		Add padding to the blob of <bytes> long (extra space)
	-b <number>
		Set the physical boot cpu
	-f
		Force - try to produce output even if the input tree has errors
	-i
		Add a path to search for include files
	-s
		Sort nodes and properties before outputting (only useful for
		comparing trees)
	-v
		Print DTC version and exit
	-H <phandle format>
		phandle formats are:
			legacy - "linux,phandle" properties only
			epapr - "phandle" properties only
			both - Both "linux,phandle" and "phandle" properties
	-W [no-]<checkname>
	-E [no-]<checkname>
			enable or disable warnings and errors
生成的dtb文件也可以通过dtb命令逆向

./dtc -I dtb -O dts ../../arch/arm/boot/dts/imx6q-sabresd-ldo.dtb  > ~/f.dts



Logo

更多推荐