在这文章中简要分析了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的开始是
-
. = 0x42400000;
-
.boot_head ALIGN(4):
-
{
-
parameters/Boot1_head.o(.rodata)
-
}
-
-
.text ALIGN(4):
-
{
-
start/asm_start.o (.text)
-
*(EXCLUDE_FILE(standby/*.o arm_board/arm_start.o drivers/iic/sw_iic.o).text)
-
}
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中
-
a. svc模式
-
b. 禁mmu
-
c. 为svc system等模式设置栈,然后跳转到c函数eGon2_start
3. 在C函数中
在lichee/boot/boot1/core/start/eGon2_start.c中
-
void eGon2_start( void )
-
{
-
reposition_boot_standby();
-
//清bss
-
//初始化堆
-
//开启mmu
-
//初始化串口
-
-
//感觉不应该是在这个地方初始化
-
if(!script_relocation())
-
{
-
//但下面这句打印了,但这儿是空的
-
eGon2_printf("script installed early ok\n");
-
}
-
//初始化iic
-
//power的一些初始化
-
-
//初始化按键
-
eGon2_key_init();
-
//检测按键,但此时没有按键按下,直接返回
-
eGon2_boot_detect();
-
-
//即:NAND_Init
-
eGon2_block_device_init();
-
fs_ops.Write = eGon2_block_device_write;
-
fs_ops.Read = eGon2_block_device_read;
-
fs_ops.Init = reserved_init;
-
fs_ops.Exit = reserved_exit;
-
-
FS_regpartopts(&fs_ops);
-
FS_init(); //初始化文件系统
-
FSMount('c'); //挂载c盘
-
-
#ifndef SCRIPT_INSTALL_EARLY
-
//感觉这儿是正确的,但是下面的"script finish"又没有打印
-
//打开script.bin
-
hfile = FS_fopen("c:\\script.bin", "r"); //3.1 关于script.bin脚本
-
if(hfile)
-
{
-
__u32 length;
-
-
length = FS_filelen(hfile);
-
FS_fread((void *)SCRIPT_BASE, length, 1, hfile); //将配置文件读到SCRIPT_BASE处
-
FS_fclose(hfile);
-
eGon2_script_parser_init((char *)SCRIPT_BASE); //然后初始化 script接口
-
}
-
eGon2_printf("script finish\n");
-
#endif
-
//从script接口中读取nand的参数good_block_ratio
-
eGon2_block_ratio();
-
-
//然后运行elf, c:\boot.axf
-
char *str_pointer_array[1];
-
char str_array0[32] = "c:\\boot.axf";
-
str_pointer_array[0] = str_array0;
-
eGon2_run_app(1, str_pointer_array); //3.2 boot.axf的执行
-
-
-
for(;;)
-
{
-
//eGon2_printf("wait here\n");
-
for(i=0;i<10000;i++);
-
}
-
}
3.1 关于脚本script.bin
在脚本 lichee/tools/pack/pack(最后生成sun7i_android_sugar-cubietruck.img的脚本)中
-
function do_pack_android()
-
{
-
busybox unix2dos sys_config.fex ;;sys_config.fex是最原始可读的配置文件
-
pack_cmd script sys_config.fex ;;这儿应该是调用了fex2bin将sys_config.fex变成了sys_config.bin
-
cp sys_config.bin bootfs/script.bin ;;将sys_config.bin复制到bootfs/script.bin
-
;;bootfs在boot1中挂载成了C,
-
}
3.2 boot.axf的执行
eGon2_run_app(1, str_pointer_array);
-
typedef __s32 (* app_func)(__s32 argc, char *argv[]);
-
-
__s32 eGon2_run_app(__s32 argc, char **argv)
-
{
-
void *paddr;
-
H_FILE pfile;
-
__u32 entry;
-
app_func func;
-
__s32 ret;
-
__u32 length;
-
//以只读打开 c:\\boot.axf
-
pfile = FS_fopen(&argv[0][0], "r+");
-
//获取文件boot.axf的长度
-
length = FS_filelen(pfile);
-
//为boot.axf申请空间
-
paddr = eGon2_malloc(length);
-
//将boot.axf读取到刚申请的空间中
-
FS_fread(paddr, length, 1, pfile);
-
-
FS_fclose(pfile);
-
-
ret = elf_loader(paddr, &entry);
-
eGon2_free(paddr);
-
//获取boot.axf这个ELF文件的main地址
-
func = (app_func)entry;
-
-
flush_icache();
-
flush_dcache();
-
//从main处开始执行boot.axf
-
func(argc, argv);
-
-
return 0;
-
}
下面就执行boot.axf了
阅读(745) | 评论(0) | 转发(0) |