大家发现错误要告诉我,大家一起学习;
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)中断初始化 <这步可有可无,如果所写的bootloader 的第一阶段代码用到中断,就必须初始化> (5)初始化时钟(clock);DDR 在使用之前必须配置好时钟 (6)初始化DDR (7)初始化NAND (8)调用nand-read函数,将全部代码放到内存中 —————————————< 至此第一阶段的代码>————————————— (9)跳转 (10)初始化串口(UART),打印shell
注:在写bootloader 时,第一阶段和第二阶段代码的链接地址是不同的,解决办法有两种, a.将第一阶段和第二阶段代码分开编译,但这种方法比较麻烦 b.保证第一阶段代码位置无关即可
|