U-Boot 启动过程及简单代码分析
这里以 AR7241 的 U-Boot 为例
MIPS 架构简介
MIPS 地址空间:
这里说的是地址空间,不是内存空间。内存只是映射在一部分地址空间上而已。
内存分为4段 (Kuseg、Kseg0、Kseg1、Kseg2),其中 Kseg0 (0x80000000 ~ 0x9fffffff) 为缓存段,直接映射在物理地址段上。
Kseg1 (0xa0000000 ~ 0xbfffffff) 为非缓存段,直接映射在物理地址段上。
Kuseg 和 Kseg2 需要经过地址转换才能访问。
在 CPU 复位时,缓存未被初始化,只有 Kseg1 能够被直接访问。
AR71XX 物理段:
内存、Flash、IO寄存器等都被映射在物理段上
范围为 0~0x1fffffff,访问时需要通过宏 KSEG0ADDR(_addr) 来通过 Kseg0 访问或 KSEG1ADDR(_addr) 来通过 Kseg1 访问。
物理地址一般不能直接访问,都需要通过 Kseg0 或 Kseg1 来访问。
主要的映射范围:
DDR:0~0x0fffffff (这一段直接映射物理内存,一般通过带缓存的 Kseg0 来访问,以便加快速度)
I/O空间:0x10000000 ~ 0x1dffffff (这一段直接控制硬件,必须通过 Kseg1 来访问)
SPI Flash 空间:0x1f000000 ~ 0x1fffffff (这一段映射闪存的前 16MB 数据)
AR71XX 启动过程
CPU 上电时,物理段中,SPI Flash 的前4MB 被循环映射在 0x1f000000 上,因此会被重复 4 次。
执行地址为 KSEG1ADDR(0x1fc00000),即 0xbfc00000。
*注意:U-Boot 在编译时,实际设置的基址,即启动地址为 KSEG0ADDR(0x1f000000),即 0x9f000000。下面会讲到为什么要这么设置。
U-Boot 中的起始代码在 cpu/mips/start.S 中:
ap147_setup初始化加载ART分区参数:
地址计算(8M)
u8 *art = (u8 *) KSEG1ADDR(0x1f7f0000);
ap147_mtdlayout_8M=mtdparts=spi0.0:256k(u-boot)ro,64k(u-boot-env)ro,6336k(rootfs),1408k(kernel),64k(mib0),64k(art),7744k@0x50000(firmware)
root@AP147:~# cat /proc/mtd
dev: size erasesize name
mtd0: 00040000 00010000 "u-boot"
mtd1: 00010000 00010000 "u-boot-env"
mtd2: 00630000 00010000 "rootfs"
mtd3: 00060000 00010000 "rootfs_data"
mtd4: 00160000 00010000 "kernel"
mtd5: 00010000 00010000 "mib0"
mtd6: 00010000 00010000 "art"
mtd7: 00790000 00010000 "firmware"
通过以上数据可以计算得到8M FLASH ART 偏移地址,以及16M FLASH ART偏移地址,特别是当8M的固件,硬件是16M FLASH,需要计算好ART的偏移,
否则有可能出现:artgui工具读取的ART数据,与设备启动过程中加载的ART参数不一致,从而导致校准参数无法保存或者校准失败。