Chinaunix首页 | 论坛 | 博客
  • 博客访问: 389014
  • 博文数量: 120
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 741
  • 用 户 组: 普通用户
  • 注册时间: 2014-03-27 18:15
文章分类

全部博文(120)

文章存档

2016年(13)

2015年(41)

2014年(66)

我的朋友

分类: Android平台

2014-08-12 00:10:54

一.lichee下的编译
cong@dell:/work/ct/lichee$ ./build.sh -p sun7i_android
1.  ./build.sh -p sun7i_androi
  1. buildroot/scripts/mkcommon.sh $@
在lichee/buildroot/scripts/mkcommon.sh中
     根据module参数来执行不同的命令,默认是mklichee
  1. BR_SCRIPTS_DIR=buildroot/scripts
  2. chip=sun7i platform=android board= module=
  3. . ${BR_SCRIPTS_DIR}/mkcmd.sh
  4. mklichee
2.mklichee
在lichee/buildroot/scripts/mkcmd.sh中
  1. function mklichee()
  2. {
  3.     mksetting                      //一些打印
  4.     mk_info "build lichee ..."     //一些打印
  5.     
  6.     mkbr                         //2.1解压交叉工具链
  7.     mkkernel                     //2.2编译standby+内核+ko模块
  8.     mkuboot                      //2.3编译uboot  
  9.     mkrootfs                     //2.4解压交叉工具链  
  10.  
  11.     mk_info "build lichee OK."
  12. }
2.1 mkbr
在lichee/buildroot/scripts/mkcmd.sh中mkbr
mkbr的意思是: 解压交叉编译工具链
  1. function mkbr()
  2. {
  3.     build_script="scripts/build_${LICHEE_CHIP}_${LICHEE_PLATFORM}.sh"
  4.     (cd ${LICHEE_BR_DIR} && [ -x ${build_script} ] && ./${build_script})
  5. }
即: 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
  1. function mkkernel()
  2. {
  3.     build_script="scripts/build_${LICHEE_CHIP}_${LICHEE_PLATFORM}.sh"

  4.     prepare_toolchain                                 //检查编译工具链,如果不存在则调用上面的mkbr

  5.     // 在/work/ct/lichee/linux-3.3/.config.mark中写入字符串"android"作为标记
  6.     local config_mark="${LICHEE_KERN_DIR}/.config.mark"
  7.     if [ -f ${config_mark} ] ; then
  8.         echo "${LICHEE_PLATFORM}" > ${config_mark}
  9.     fi

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

  12.     mk_info "build kernel OK."
  13. }
(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
  1. function mkuboot()
  2. {
  3.     mk_info "build u-boot ..."

  4.     local build_script

  5.     if check_uboot_defconf ; then
  6.         build_script="build.sh"
  7.     else
  8.         build_script="build_${LICHEE_CHIP}_${LICHEE_PLATFORM}_${LICHEE_BOARD}.sh"
  9.     fi

  10.     prepare_toolchain        //检查编译工具链,如果不存在则调用上面的mkbr
  11.    
  12.     //即执行./ct/lichee/u-boot/build.sh
  13.     (cd ${LICHEE_UBOOT_DIR} && [ -x ${build_script} ] && ./${build_script})
  14.     [ $? -ne 0 ] && mk_error "build u-boot Failed" && return 1

  15.     mk_info "build u-boot OK."
  16. }
2.3.1 mkuboot的具体编译
    cd /work/ct/lichee/u-boot && [ -x build.sh ] && ./build.sh
  1. function build_uboot()
  2. {
  3.     case "$1" in      //$1是空的
  4.         clean)
  5.             make distclean CROSS_COMPILE=arm-linux-gnueabi-
  6.             ;;
  7.         *)
  8.             make distclean CROSS_COMPILE=arm-linux-gnueabi-
  9.             make -j8 ${LICHEE_CHIP} CROSS_COMPILE=arm-linux-gnueabi-
  10.             [ $? -ne 0 ] && exit 1
  11.             //真正编译的命令是:
  12.            make -j8 sun7i CROSS_COMPILE=arm-linux-gnueabi-
  13.             cp -f u-boot.bin ../out/${LICHEE_PLATFORM}/common/
  14.             ;;
  15.     esac
  16. }
  17. if [ -n "${LICHEE_CHIP}" ] ; then    //LICHEE_CHIP=sun7i
  18.     build_uboot $1
  19.     exit 0
  20. 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目录下
  1. cong@dell:/work/ct$ ls /work/ct/lichee/out/android/common
  2. 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中的解析可以有如下命令
  1. ./build.sh -p sun7i_android -m boot
  2. ./build.sh -p sun7i_android -m buildroot
  3. ./build.sh -p sun7i_android -m kernel
  4. ./build.sh -p sun7i_android -m uboot
  5. ./build.sh -p sun7i_android -m clean
  6. ./build.sh -p sun7i_android -m mrproer
  7. ./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脚本写得实在是太...
修改成如下形式,这样在没有修改时就不会每次都编译了
  1. standby:$(STANDBY_OBJ)
  2.     @$(CROSS_COMPILE)ld -T $(STANDBY_LD_FILE) -EL $(STANDBY_OBJ) -o $(STANDBY_OUPUTFILE).elf -Map $(STANDBY_OUPUTFILE).map
  3.     @$(CROSS_COMPILE)objdump -D $(STANDBY_OUPUTFILE).elf > $(STANDBY_OUPUTFILE).lst
  4.     @$(CROSS_COMPILE)objcopy -O binary $(STANDBY_OUPUTFILE).elf $(STANDBY_OUPUTFILE).bin
  5.     cp standby.bin standby.code
  6. %.o : %.c
  7.     $(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中添加:
  1. static void __aeabi_unwind_cpp_pr0(void)
  2. {
  3. };

  4. static void __aeabi_unwind_cpp_pr1(void)
  5. {
  6. };

二.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后面参数代表的是平台
  1. function lunch()
  2. {
  3.     //a. 只执行lunch则会打印lunch的菜单
  4.     //b. 执行lunch 16,会根据参数16从LUNCH_MENU_CHOICES找出16所代表的字符串 
  5.         //这儿的16代表sugar_cubietruck-eng

  6.     local product=$(echo -n $selection | sed -e "s/-.*$//")
  7.     check_product $product       //sugar_cubietruck
  8.    

  9.     local variant=$(echo -n $selection | sed -e "s/^[^\-]*-//")
  10.     check_variant $variant      //variant=eng

  11.     export TARGET_PRODUCT=$product
  12.     export TARGET_BUILD_VARIANT=$variant
  13.     export TARGET_BUILD_TYPE=release

  14.     set_stuff_for_environment     //设置环境变量
  15.     printconfig                  
  16. }
2.1 设置环境变量
  1. function set_stuff_for_environment()
  2. {
  3.     settitle             //设置变量PROMPT_COMMAND
  4.     set_java_home        //如果没有设置变量JAVA_HOME,则用默认设置
  5.     setpaths             //设置路径及环境变量
  6.     set_sequence_number  //设置BUILD_ENV_SEQUENCE_NUMBER=10

  7.     export ANDROID_BUILD_TOP=$(gettop)
  8. }
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
拷贝编译出来的内核及驱动文件
  1. function extract-bsp()
  2. {
  3.     LICHEE_DIR=$ANDROID_BUILD_TOP/../lichee
  4.     LINUXOUT_DIR=$LICHEE_DIR/out/android/common
  5.     LINUXOUT_MODULE_DIR=$LICHEE_DIR/out/android/common/lib/modules/*/*
  6.     CURDIR=$PWD
  7.     cd $DEVICE
  8.      // 删除kernel文件,并将/work/ct/lichee/out/android/common/bImage拷贝到
  9.     // 目录/work/ct/android42/device/softwinner/sugar-cubietruck下,改名为kernel
  10.     if [ -f kernel ]; then
  11.         rm kernel
  12.     fi
  13.     cp $LINUXOUT_DIR/bImage kernel

  14.     //删除ko目录
  15.     //将/work/ct/lichee/out/android/common/lib/modules/3.3/中的所有内容拷贝到
  16.       /work/ct/android42/device/softwinner/sugar-cubietruck/modules/modules
  17.     if [ -d modules ]; then
  18.         rm -rf modules
  19.     fi   
  20.     mkdir -p modules/modules
  21.     cp -rf $LINUXOUT_MODULE_DIR modules/modules  
  22.     chmod 0755 modules/modules/*

  23.     //生成文件: create modules.mk
  24. (cat << EOF) > ./modules/modules.mk
  25. # modules.mk generate by extract-files.sh , do not edit it !!!!
  26. PRODUCT_COPY_FILES += \\
  27.     \$(call find-copy-subdir-files,*,\$(LOCAL_PATH)/modules,system/vendor/modules)

  28. EOF

  29.     cd $CURDIR
  30. }


4. make -j8
4.1 make bootimage
在文件build/core/Makefile中
  1. INSTALLED_BOOTIMAGE_TARGET := $(PRODUCT_OUT)/boot.img
  2.  $(INSTALLED_BOOTIMAGE_TARGET): $(MKBOOTIMG) $(INTERNAL_BOOTIMAGE_FILES)
  3.     $(call pretty,"Target boot image: $@")
  4.     $(hide) $(MKBOOTIMG) $(INTERNAL_BOOTIMAGE_ARGS) $(BOARD_MKBOOTIMG_ARGS) --output $@
  5.     $(hide) $(call assert-max-image-size,$@,$(BOARD_BOOTIMAGE_PARTITION_SIZE),raw)
  6. 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的构成如下:
  1.  header大小为661字节   (padding 2048字节对齐)
  2. kenel               (padding 2048字节对齐)
  3. ramdisk.img         (padding 2048字节对齐)
4.2 make ramdisk
在文件build/core/Makefile中
  1. BUILT_RAMDISK_TARGET := $(PRODUCT_OUT)/ramdisk.img

  2. INSTALLED_RAMDISK_TARGET := $(BUILT_RAMDISK_TARGET)
  3. $(INSTALLED_RAMDISK_TARGET): $(MKBOOTFS) $(INTERNAL_RAMDISK_FILES) | $(MINIGZIP)
  4.     $(call pretty,"Target ram disk: $@")
  5.     $(hide) $(MKBOOTFS) $(TARGET_ROOT_OUT) | $(MINIGZIP) > $@
  6.     $(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
  1. function pack()
  2. {
  3.     T=$(gettop)
  4.     export ANDROID_IMAGE_OUT=$OUT
  5.     export PACKAGE=$T/../lichee/tools/pack

  6.     sh $DEVICE/package.sh $1
  7. }
最终会调用
cong@dell:/work/ct/android42$ vi ../lichee/tools/pack/pack
主流程会调用: do_prepare 与 do_pack_android
  1. function do_prepare()
  2. {    
  3.     //功能: 将./lichee/tools/pack/chips/sun7i/eFex/ 拷贝到 ./lichee/tools/pack/
  4.     cp -r chips/${PACK_CHIP}/eFex .   
  5.     cp -r chips/${PACK_CHIP}/eGon .
  6.     cp -r chips/${PACK_CHIP}/wboot .
  7.     //将./lichee/tools/pack/下的out目录清空
  8.     rm -rf out/
  9.     mkdir -p out/
  10. }

PACK_CHIP=sun7i,PACK_PLATFORM=android, PACK_BOARD=sugar-cubietruck

  1. function do_pack_android()
  2. {
  3.     cp -f chips/${PACK_CHIP}/configs/${PACK_PLATFORM}/default/* out/
  4.     cp -f chips/${PACK_CHIP}/configs/${PACK_PLATFORM}/${PACK_BOARD}/*.fex out/
  5.     cp -f chips/${PACK_CHIP}/configs/${PACK_PLATFORM}/${PACK_BOARD}/*.cfg out/ 2>> /dev/null
  6.         
  7.     //以下两句好像没有什么作用
  8.     do_debug
  9.     do_parse       //调用../lichee/tools/pack/pctools/linux/mod_update/script_parse这个python调本
  10.                    
  11.     cp -rf eFex/split_xxxx.fex wboot/bootfs wboot/bootfs.ini out/
  12.     
  13.     cp -f eGon/boot0_nand.bin out/boot0_nand.bin
  14.     cp -f eGon/boot1_nand.bin out/boot1_nand.fex
  15.     cp -f eGon/boot0_sdcard.bin out/boot0_sdcard.fex
  16.     cp -f eGon/boot1_sdcard.bin out/boot1_sdcard.fex
  17.     
  18.     cd out/
  19.     stan_cmd cp ${LICHEE_OUT}/u-boot.bin bootfs/linux/                   //更新u-boot.bin
  20.     
  21.     sed -i 's/\\bootfs/\/bootfs/g' bootfs.ini              //修改配置文件中的windows路径,将\替换为/
  22.     sed -i 's/\\\\/\//g' image.cfg                         //修改配置文件中的windows路径,将\替换为/
  23.     sed -i 's/imagename/;imagename/g' image.cfg            //修改配置文件,注掉image.cfg中的imagename
  24.     //重新生成image.cfg中的imagename
  25.     local IMG_NAME
  26.     if [ $PACK_DEBUG = "card0" ] ; then
  27.         IMG_NAME="${PACK_CHIP}_${PACK_PLATFORM}_${PACK_BOARD}_${PACK_DEBUG}.img"
  28.     else
  29.         IMG_NAME="${PACK_CHIP}_${PACK_PLATFORM}_${PACK_BOARD}.img"
  30.     fi   
  31.     echo "imagename = ${IMG_NAME}" >> image.cfg
  32.     echo "" >> image.cfg
  33.     
  34.     busybox unix2dos sys_config.fex
  35.     busybox unix2dos sys_partition.fex
  36.    //调用./lichee/boot/pack/pctools/linux/mod_update/下的命令
  37.     pack_cmd script sys_config.fex
  38.     pack_cmd script sys_partition.fex
  39.     
  40.     cp sys_config.bin bootfs/script.bin
  41.     //调用./lichee/boot/pack/pctools/linux/mod_update/下的命令
  42.     pack_cmd update_mbr sys_partition.bin 4 
  43.     pack_cmd update_boot0 boot0_nand.bin sys_config.bin NAND
  44.     pack_cmd update_boot0 boot0_sdcard.fex sys_config.bin SDMMC_CARD
  45.     pack_cmd update_boot1 boot1_nand.fex sys_config.bin NAND
  46.     pack_cmd update_boot1 boot1_sdcard.fex sys_config.bin SDMMC_CARD
  47.     
  48.     pack_cmd fsbuild bootfs.ini split_xxxx.fex
  49.     mv bootfs.fex bootloader.fex
  50.     
  51.     u_boot_env_gen env.cfg env.fex
  52.     
  53.     ln -s ${ANDROID_IMAGE_OUT}/boot.img boot.fex
  54.     ln -s ${ANDROID_IMAGE_OUT}/system.img system.fex
  55.     ln -s ${ANDROID_IMAGE_OUT}/recovery.img recovery.fex
  56.     
  57.     pack_cmd dragon image.cfg sys_partition.fex
  58.     
  59.     if [ -e ${IMG_NAME} ]; then
  60.         mv ${IMG_NAME} ../${IMG_NAME}
  61.         echo '----------image is at----------'
  62.         echo -e '\033[0;31;1m'
  63.         echo ${ROOT_DIR}/${IMG_NAME}
  64.         echo -e '\033[0m'
  65.     fi

  66.     cd ..
  67. }
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设备,可以直接进入烧写模式




阅读(1204) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~