您的位置:首页 > 移动开发 > Android开发

Cubietruck---3. android编译命令分析

2016-06-13 17:29 513 查看
一.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"作为标记

    local config_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 && [ -x build.sh ] && ./build.sh

function build_uboot()

{

    case "$1" in      //$1是空的

        clean)

            make distclean CROSS_COMPILE=arm-linux-gnueabi-

            ;;

        *)

            make distclean CROSS_COMPILE=arm-linux-gnueabi-

            make -j8 ${LICHEE_CHIP} CROSS_COMPILE=arm-linux-gnueabi-

            [ $? -ne 0 ] && exit 1

            //真正编译的命令是:

           make -j8 sun7i CROSS_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 sun7i CROSS_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 uImage zImage

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_DIR modules/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 += \\

    \$(call find-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) $(call assert-max-image-size,$@,$(BOARD_BOOTIMAGE_PARTITION_SIZE),raw)

endif # TARGET_BOOTIMAGE_USE_EXT2

即: out/host/linux-x86/bin/mkbootimg  --kernel out/target/product/sugar-cubietruck/kernel --ramdisk out/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/mkbootfs out/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 -f chips/${PACK_CHIP}/configs/${PACK_PLATFORM}/default/* out/

    cp -f chips/${PACK_CHIP}/configs/${PACK_PLATFORM}/${PACK_BOARD}/*.fex
out/

    cp -f chips/${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/bootfs
wboot/bootfs.ini out/

    

    cp -f eGon/boot0_nand.bin out/boot0_nand.bin

    cp -f eGon/boot1_nand.bin out/boot1_nand.fex

    cp -f eGon/boot0_sdcard.bin out/boot0_sdcard.fex

    cp -f eGon/boot1_sdcard.bin out/boot1_sdcard.fex

    

    cd out/

    stan_cmd cp ${LICHEE_OUT}/u-boot.bin
bootfs/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.bin sys_config.bin NAND

    pack_cmd update_boot0 boot0_sdcard.fex sys_config.bin SDMMC_CARD

    pack_cmd update_boot1 boot1_nand.fex sys_config.bin NAND

    pack_cmd update_boot1 boot1_sdcard.fex sys_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.img
boot.fex

    ln -s ${ANDROID_IMAGE_OUT}/system.img
system.fex

    ln -s ${ANDROID_IMAGE_OUT}/recovery.img
recovery.fex

    

    pack_cmd dragon image.cfg sys_partition.fex

    

    if [ -e ${IMG_NAME} ]; then

        mv ${IMG_NAME} ../${IMG_NAME}

        echo '----------image is at----------'

        echo -e '\033[0;31;1m'

        echo ${ROOT_DIR}/${IMG_NAME}

        echo -e '\033[0m'

    fi

    cd ..

}

pack过程对u-boot.bin的处理
a. 把lichee/tools/pack/chips/su7i/bin/u-boot-sun7i.bin拷到lichee/tools/pack/out目录下,并改名为u-boot.fex
b.然后用update_uboot把u-boot-sun7i.bin修改一下
update_uboot u-boot.fex  sys_config.bin,应该是加了一堆标志
因为没有updata-uboot的代码不知道它真正干了什么
c.最后就把修改后的u-boot打包到最终生成的sun7i-android-suger-cubietruck.img中了
但是自己编出来的u-boot.bin中间执行update-uboot时,根本就不会修改它,这样生成的sun7i-android-suger-cubietruck.img不正确也无法用PhoenixSuit烧写了。

问题:
这样我就不知道自己编出来的u-boot是如何烧到板子上去了?
我记得以前linux3.3内核的android版本,可以直接用fastboot烧的,但这个v2.0_A20_android_source.tar.gz,根本进不去fastboot(bootdelay=0)
如何去烧自己编出来的u-boot?有知道的告知一下?
解决: 进fastboot的方法
按住pc端键盘字母键“s”,上电启动A20设备,可以不重新设置等待时间进入uboot命令行。如果还是进不了fastboot,将lichee\tools\pack\chips\sun7i\configs\android\default\env.cfg中的bootdelay=0改成bootdelay=3,重新打包固件即可

进入烧写模式 
1.安装好PhoenixSuit后,双击桌面PhoenixSuit快键方式,选择“一键刷机”,选择好需要的固件。
2,串口一直输出数字2,即按住pc端键盘数字键“2”,上电启动A20设备,可以直接进入烧写模式
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android