基于cortex-A8的Bootloader设计
)mem_setup.S(board\samsung\smdkv210) 该源文件包含对内存进行初始化的汇编源码。 (4)board.c(arch\arm\lib\board.c) 该源文件是用C编写的,主要实现了U-Boot第二阶段启动过程。包括初始化环境变量,串口控制台,Flash和打印调试信息等,最后调用main_loop()函数。 (5)smdkv210.h(include\configs\Smdkv210.h) s5pv210平台的配置文件,该源文件定义了一些与CPU或者外设相关的参数,这些参数都是用宏来定义的。 2.3 U-Boot启动的一般流程 2.3.1 第一阶段初始化 U-Boot的启动过程分为两个阶段,第一个阶段主要由汇编代码实现,负责对CPU及底层硬件资源的初始化。第二阶段用C实现,负责使能Flash,网卡和引导操作系统等。其第一阶段流程如下图所示: 图2 U-Boot第一阶段启动流程 U-Boot上电后首先会设置cpu为管理模式,禁用L1缓存,关闭MMU和清除caches。之后会调用底层初始化函数lowlevel_init()。该函数实现如下: .globl lowlevel_init lowlevel_init: push {lr} #if defined(CONFIG_SPL_BUILD) /* 初始化时钟 */ bl system_clock_init /* 初始化内存 */ bl mem_ctrl_asm_init /* 初始化串口 */ bl uart_asm_init #endif pop {pc} 上述代码中system_clock_init(), mem_ctrl_asm_init(),uart_asm_init()这三个函数需要开发者结合具体硬件环境进行修改和实现。 初始化完成之后,U-Boot会调用一个拷贝函数将BL2拷贝到内存地址为0x3FF00000处,然后跳转到该位置执行BL2。在U-Boot中,BL1 和BL2是基于相同的一些源文件编译生成的。开发者在编写代码时需要使用预编译宏CONFIG_SPL_BUILD来实现BL1和BL2不同的功能。其拷贝函数实现如下: void copy_code_2_sdram_and_run(void) { unsigned long ch; void (*u_boot)(void); ch = *(volatile unsigned int *)(0xD0037488); /* 根据该地址的值判断传输通道 */ /* copy_bl2()函数不需要开发者去实现,s5pv210在出厂时已经固化在了0xD0037F98地址处 */ copy_sd_mmc_to_mem copy_bl2 = (copy_sd_mmc_to_mem) (*(unsigned int *) (0xD0037F98)); unsigned int ret; if (ch == 0xEB000000) { /* CONFIG_SYS_TEXT_BASE = 0x3FF00000 */ ret = copy_bl2(0, 49, 1024,(unsigned int *)CONFIG_SYS_TEXT_BASE, 0); } else if (ch == 0xEB200000) { ret = copy_bl2(2, 49, 1024,(unsigned int *)CONFIG_SYS_TEXT_BASE, 0); } else { return; } u_boot = (void *)CONFIG_SYS_TEXT_BASE; (*u_boot)(); /* 跳转到该地址执行 */ } 值得注意的是以上代码中,copy_bl2()函数不需要开发者去实现,s5pv210在出厂时已经将该函数固化在了0xD0037F98地址处。其函数原型如下: u32 (*copy_sd_mmc_to_mem)(u32 channel, u32 start_block, u16 block_size, u32 *trg, u32 init); /* 参数介绍: channel:通道数2或0,该值通过读取0xD0037488地址上的值判断。 start_block:从第几个扇区开始拷贝,一个扇区为512byte。 block_size:拷贝多少个扇区,这里拷贝512K trg:目的地址:0x3FF00000, 即离内存顶部1M的位置 init:是否需要初始化sd卡,写0即可。 */ 2.3.2 第二阶段初始化 U-Boot进入第二阶段后会首先声明一个gd_t结构体类型的指针指向内存地址(0x40000000 - GD_SIZE)处。0x40000000为内存结束地址,GD_SIZE为结构体gd_t的大小。这样相当于在内存最顶端分配了一段空间用于存放一个临时结构体gd_t。该结构体在global_data.h中被定义,U-Boot用它来存储所有的全局变量。之后U-Boot会调用 board_init_f()和board_init_r()两个函数进一步对底板进行初始化。 (1)board_init_f() 进入board_init_f()之后,U-Boot首先设置之前分配的临时结构体,然后开始划分内存空间,其内存分配示意图如下: 图3 U-Boot内存分配状态 从内存分配状态图中我们可以看到,gd指针指向的临时结构体存放在内存的最顶部。BL2代码存放在内存地址0x3ff00000处,即距离内存顶部1M空间的位置。接下来依次分配malloc空间,bd_t结构体空间和gd_t结构体空间,并且重新设置栈。最后将临时结构体拷贝到id指针所指向的位置。 board_init_f()实现过程大致如下: unsigned int board_init_f(ulong bootflag) { memset((void *)gd, 0, sizeof(gd_t)); ... 设置gd结构体; ... addr = CONFIG_SYS_TEXT_BASE; /* CONFIG_SYS_TEXT_BASE = 0x3ff00000000 */ addr_sp = addr - TOTAL_MALLOC_LEN; addr_sp -= sizeof (bd_t); bd = (bd_t *) addr_sp; gd->bd = bd; addr_sp -= sizeof (gd_t); id = (gd_t *) addr_sp; ... memcpy(id, (void *)gd, sizeof(gd_t)); base_sp = a
cortext-A8 Bootloader设计 s5pv210 相关文章:
- S5PV210(TQ210)学习笔记——内存配置(DDR2)(11-28)
- S5PV210(TQ210)学习笔记——LCD驱动编写(11-28)
- S5PV210(TQ210)学习笔记——8位HWECC与YAFFS2的OOB布局(11-28)
- S5PV210(TQ210)学习笔记——Nand配置(11-28)
- S5PV210(TQ210)学习笔记——触摸屏驱动编写(11-28)
- S5PV210(TQ210)学习笔记——内核移植与文件系统构建(11-28)