浅谈arm开发板SD卡和NAND的启动过程
开发板:smdk6410
大家发现错误要告诉我,大家一起学习;
SD卡启动:
SD卡内存空间分布图:
————
| 1K | 预留1K,内部空白
————
| 8K | 用于存放bootloader第一阶段的代码
————
| 16K | 保存环境变量
————
| 256K | bootloader全部代码,包括前8K代码
————
| ... |
———-
一上电就会地址映射,启动原理:
(1)pc 被置为0,0 地址被映射到IROM的起始位置;
(2)此时将开始执行,pc 会跳转到SD 卡启动的代码处;
(3)将SD卡的前8K代码放到IRAM(SRAM的一种,6410中物理地址0x0c000000~0x0c002000-1,共8K)中;
(4)pc指向IRAM的起始地址0x0c000000,开始执行bootloader;
启动步骤:
(1)初始化sp, sp = 0x0c002000
(2)映射外设端口,即告诉程序数据该走哪个端口,地址该走哪个端口;6410外设和内存统一编址,分界线是0x70000000,低地址为内存,高地址为外设
(3)关掉看门狗(WDT),否则系统会定时重启
(4)初始化DDRC(内存控制器)
(5)调用movi-read函数,将SD 内256K 空间存的代码读到内存中0x57e00000(u-boot的链接地址,在编译u-boot 的时候可改)
——————————————< 至此第一阶段的代码 >—————————————
(6)跳转到movi-read 函数的下一个函数,比如说a 函数(这里执行的a 函数就是内存中的a 函数了)
(7)UART(串口)初始化
NAND启动:
NAND 内存空间分布图:
———--
| ... |
———-- 0x40000,256K
| |
———— 0x2000
| 8K |
———— 0
启动原理:
(1)通过stepping stone controller(IRAM控制器),去读NAND 中前8K的代码;
--->这种方法已经基本不用了,如今通过NAND 控制器去读 NAND 中前8K 的代码
(2)将NAND 的前8K 代码放到IRAM 中
(3)pc 被置为0,此时的0 地址被映射到IRAM的起始地址,开始执行代码
启动步骤(大致思路和SD 卡相同):
(1)初始化栈,sp = 0x2000
(2)映射外设端口,即告诉程序数据该走哪个端口,地址该走哪个端口;6410外设和内存统一编址,分界线是0x70000000,低地址为内存,高地址为外设
(3)关闭看门狗(WDT),默认WDT 会定时重启系统
(4)中断初始化
(5)初始化时钟(clock);DDR 在使用之前必须配置好时钟
(6)初始化DDR
(7)初始化NAND
(8)调用nand-read函数,将全部代码放到内存中
—————————————< 至此第一阶段的代码>—————————————
(9)跳转
(10)初始化串口(UART),打印shell
注:在写bootloader 时,第一阶段和第二阶段代码的链接地址是不同的,解决办法有两种,
a.将第一阶段和第二阶段代码分开编译,但这种方法比较麻烦
b.保证第一阶段代码位置无关即可