微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > u-boot 启动过程 —— 基于S3C2410

u-boot 启动过程 —— 基于S3C2410

时间:11-10 来源:互联网 点击:
DE>    DE>DE>mov r1, #S3C2410_NAND_BASE DE>DE>    DE>DE>ldr r2, =0xf842 @ initial value enable tacls=3,rph0=6,rph1=0 DE>DE>    DE>DE>str r2, [r1, #oNFCONF] DE>DE>    DE>DE>ldr r2, [r1, #oNFCONF] DE>DE>    DE>DE>bic r2, r2, #0x800 @ enable chip DE>

在451行继续根据配置设定栈指针,为后面调用C函数执行拷贝作准备:

DE>    DE>DE>ldr r0, _TEXT_BASE /* upper 128 KiB: relocated uboot */ DE>DE>    DE>DE>sub r0, r0, #CFG_MALLOC_LEN /* malloc area */ DE>DE>    DE>DE>sub r0, r0, #CFG_GBL_DATA_SIZE /* bdinfo */ #ifdef CONFIG_USE_IRQ DE>DE>    DE>DE>sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ) #endif DE>DE>    DE>DE>sub sp, r0, #12 /* leave 3 words for abort-stack */ DE>

然后在460行,将SDRAM中的目标地址存入r0,0x0地址存入r1,u-boot长度存入r2,
跳入cpu/arm920t/s3c24x0/nand_read.c文件第154行执行nand_read_ll函数,该函数接受前面3个寄存器中的值作为参数,并将返回值放回r0:

DE>    DE>DE>ldr r0, _TEXT_BASE DE>DE>    DE>DE>mov r1, #0x0 DE>DE>    DE>DE>mov r2, #CFG_UBOOT_SIZE DE>DE>    DE>DE>bl nand_read_ll DE>

在nand_read_ll函数中实现了nandflash访问代码,并且支持自动跳过坏块的特性,函数循环执行nand页面读取并存入SDRAM,直到u-boot全部拷贝完,并返回0,该C代码留给读者自己阅读。nand_read_ll返回0后,会跳转到ok_nand_read,并482行对拷贝的头4K字节进行校验:

DE>    @ verify mov r0, #0 @ldr r1, =0x33f00000 ldr r1, _TEXT_BASE mov r2, #0x400 DE>DE>    DE>DE>@ 4 bytes * 1024 = 4K-bytes go_next: DE>DE>    DE>DE>ldr r3, [r0], #4 DE>DE>    DE>DE>ldr r4, [r1], #4 DE>DE>    DE>DE>teq r3, r4 DE>DE>    DE>DE>bne notmatch DE>DE>    DE>DE>subs r2, r2, #4 DE>DE>    DE>DE>beq done_nand_read DE>DE>    DE>DE>bne go_next DE>

校验通过后代码506行,在地址为_booted_from_nand的SDRAM位置保存1,以便告诉上层软件本次启动是从nand引导:

DE>done_nand_read: DE>DE>    DE>DE>ldr r0, _booted_from_nand DE>DE>    DE>DE>mov r1, #1 DE>DE>    DE>DE>strb r1, [r0] DE>

然后在518行,将中断向量表拷贝到0x0:

DE>    DE>DE>mov r0, #0 DE>DE>    DE>DE>ldr r1, _TEXT_BASE DE>DE>    DE>DE>mov r2, #0x40 irqvec_cpy_next: DE>DE>    DE>DE>ldr r3, [r1], #4 DE>DE>    DE>DE>str r3, [r0], #4 DE>DE>    DE>DE>subs r2, r2, #4 DE>DE>    DE>DE>bne irqvec_cpy_next DE>

在532行,设置栈指针:

DE>    DE>DE>ldr r0, _TEXT_BASEDE>DE>    DE>DE>/* upper 128 KiB: relocated uboot */ DE>DE>    DE>DE>sub r0, r0, #CFG_MALLOC_LENDE>DE>    DE>DE>/* malloc area */ DE>DE>    DE>DE>sub r0, r0, #CFG_GBL_DATA_SIZE /* bdinfo */ #ifdef CONFIG_USE_IRQ DE>DE>    DE>DE>sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ) #endif DE>DE>    DE>DE>sub sp, r0, #12DE>DE>    DE>DE>/* leave 3 words for abort-stack */ DE>

在541行,清除bss段并跳转到真正的C函数start_armboot,进入更高级的硬件初始化代码,汇编初始化部分也全部完成使命:

DE>    DE>DE>ldr r0, _bss_start /* find start of bss segment */ DE>DE>    DE>DE>ldr r1, _bss_end /* stop here */ DE>DE>    DE>DE>mov r2, #0x00000000 /* clear */ DE>DE> clbss_l:DE>DE>    DE>DE>str r2, [r0] /* clear loop... */ DE>DE>    DE>DE>add r0, r0, #4 DE>DE>    DE>DE>cmp r0, r1 DE>DE>    DE>DE>ble clbss_l DE>DE> DE>DE>    DE>DE>ldr pc, _start_armboot DE>

start_armboot函数位于lib_arm/board.c文件第277行,首先初始化globel_data类型的变量gd。该变量是一个结构,其成员大多是板子的一些基本设置,如序列号、ip地址、mac地址等(欲知结构的原型可参考include/asm-arm/globel_data.h和include/asm-arm/u-boot.h):

DE>         DE>DE>gd = (gd_t*)(_armboot_start - CFG_MALLOC_LEN - sizeof(gd_t));DE>DE>         DE>DE>/* compiler optimization barrier needed for GCC >= 3.4 */__asm__ __volatile__("": : :"memory");DE>DE>         DE>DE>memset ((void*)gd, 0, sizeof (gd_t));gd->bd = (bd_t*)((char*)gd - sizeof(bd_t));DE>DE>         DE>DE>memset (gd->bd, 0, sizeof (bd_t)); DE>

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top