Cubietruck---5. boot1源码流程简略分析

来源:互联网 发布:淘宝怎么用图片搜索 编辑:程序博客网 时间:2024/04/28 05:54
在这文章中简要分析了boot0的过程,在boot0的最后将boot1从nand的第2个block读到了内存的0x42400000
Cubietruck---4. boot0源码流程简略分析 
http://blog.chinaunix.net/uid-26009923-id-4211982.html
一. boot1源码简要分析
下面分析一下boot1, 其代码都在目录lichee/boot/boot1/core/中
1. 链接脚本
从链接脚本文件lichee/boot/boot1/core/config.lds中看出,boot1的开始是
  1. . = 0x42400000;
  2.     .boot_head ALIGN(4):
  3.     { 
  4.         parameters/Boot1_head.o(.rodata)
  5.     } 

  6.     .text ALIGN(4):
  7.     { 
  8.         start/asm_start.(.text)
  9.         *(EXCLUDE_FILE(standby/*.o arm_board/arm_start.o drivers/iic/sw_iic.o).text)
  10.     }
boot1的开头是一个只读的结构体 boot1_file_head_t, 里面记录了boot1的长度等信息
注意:关于BT1_head中的boot_head.length与boot_head.check_sum两个值
在脚本 lichee/boot/boot1/core/make_nand中(可能是编译boot1的makefile的改名)有如下
      -$(WORKTOOLS)/gen_check_code $(TMPTARGET)
说明这个boot1_file_head_t结构体中的值boot1_file_head_t.boot_head.length与check_sum不是在编译时就有的,
而是能过工具gen_check_code生成的.
2. 首先运行汇编asm_start.s
在lichee/boot/boot1/core/start/asm_start.S中
  1.  a. svc模式
  2. b. 禁mmu
  3. c. 为svc system等模式设置栈,然后跳转到c函数eGon2_start
3. 在C函数中
在lichee/boot/boot1/core/start/eGon2_start.c中
  1. void eGon2_start( void )
  2. {
  3.     reposition_boot_standby();
  4.    //清bss
  5.    //初始化堆    
  6.    //开启mmu
  7.    //初始化串口

  8.    //感觉不应该是在这个地方初始化
  9.     if(!script_relocation())
  10.     { 
  11.         //但下面这句打印了,但这儿是空的
  12.         eGon2_printf("script installed early ok\n");
  13.     } 
  14.     //初始化iic 
  15.     //power的一些初始化
  16.     
  17.     //初始化按键
  18.     eGon2_key_init();
  19.     //检测按键,但此时没有按键按下,直接返回
  20.     eGon2_boot_detect();
  21.        
  22.     //即:NAND_Init
  23.     eGon2_block_device_init(); 
  24.     fs_ops.Write = eGon2_block_device_write;
  25.     fs_ops.Read = eGon2_block_device_read;
  26.     fs_ops.Init = reserved_init;
  27.     fs_ops.Exit = reserved_exit;

  28.     FS_regpartopts(&fs_ops);
  29.     FS_init();                 //初始化文件系统
  30.     FSMount('c');              //挂载c盘

  31. #ifndef SCRIPT_INSTALL_EARLY
  32.     //感觉这儿是正确的,但是下面的"script finish"又没有打印
  33.     //打开script.bin
  34.     hfile = FS_fopen("c:\\script.bin", "r");      //3.1 关于script.bin脚本
  35.     if(hfile)
  36.     {
  37.         __u32 length;

  38.         length = FS_filelen(hfile);
  39.         FS_fread((void *)SCRIPT_BASE, length, 1, hfile); //将配置文件读到SCRIPT_BASE处
  40.         FS_fclose(hfile);
  41.         eGon2_script_parser_init((char *)SCRIPT_BASE);   //然后初始化 script接口 
  42.     }
  43.     eGon2_printf("script finish\n");
  44. #endif

  45.     //从script接口中读取nand的参数good_block_ratio
  46.     eGon2_block_ratio();

  47.     //然后运行elf, c:\boot.axf
  48.     char *str_pointer_array[1];
  49.     char str_array0[32] = "c:\\boot.axf";
  50.     str_pointer_array[0] = str_array0;
  51.     eGon2_run_app(1, str_pointer_array);           //3.2 boot.axf的执行


  52.     for(;;)
  53.     {
  54.         //eGon2_printf("wait here\n");
  55.         for(i=0;i<10000;i++);
  56.     }
  57. }
3.1 关于脚本script.bin
在脚本 lichee/tools/pack/pack(最后生成sun7i_android_sugar-cubietruck.img的脚本)中
  1. function do_pack_android()
  2. {
  3.     busybox unix2dos sys_config.fex        ;;sys_config.fex是最原始可读的配置文件
  4.     pack_cmd script sys_config.fex         ;;这儿应该是调用了fex2bin将sys_config.fex变成了sys_config.bin
  5.     cp sys_config.bin bootfs/script.bin    ;;将sys_config.bin复制到bootfs/script.bin
  6.                                            ;;bootfs在boot1中挂载成了C, 
  7. }
3.2 boot.axf的执行
eGon2_run_app(1, str_pointer_array); 
  1. typedef __s32 (* app_func)(__s32 argc, char *argv[]);

  2. __s32 eGon2_run_app(__s32 argc, char **argv)
  3. {
  4.     void *paddr;
  5.     H_FILE pfile;
  6.     __u32 entry;
  7.     app_func func;
  8.     __s32 ret;
  9.     __u32 length;
  10.     //以只读打开 c:\\boot.axf
  11.     pfile = FS_fopen(&argv[0][0], "r+");
  12.     //获取文件boot.axf的长度
  13.     length = FS_filelen(pfile);
  14.     //为boot.axf申请空间
  15.     paddr = eGon2_malloc(length);
  16.     //将boot.axf读取到刚申请的空间中
  17.     FS_fread(paddr, length, 1, pfile);

  18.     FS_fclose(pfile);

  19.     ret = elf_loader(paddr, &entry);
  20.     eGon2_free(paddr);
  21.     //获取boot.axf这个ELF文件的main地址
  22.     func = (app_func)entry;

  23.     flush_icache();
  24.     flush_dcache();
  25.     //从main处开始执行boot.axf
  26.     func(argc, argv);

  27.     return 0;
  28. }
下面就执行boot.axf了
0 0