/cpu/mpc83xx/u-boot.lds文件时连接器脚本文件,其中
.text : {
cpu/mpc83xx/start.o (.text) ……………………. }
……………… ENTRY(_start)
规定了代码段从/cpu/mpc83xx/start.s开始。而ENTRY(_start)这一句告诉编译器uboot.bin的镜像入口点为start.s中的_start标号。 UBOOT内存映射:
Range Start Range End Definition Size 0x0000_0000 0x07ff_ffff DDR 128M 0xa000_0000 0xafff_ffff PCI Express 1 Mem 256M 0xb000_0000 0xb0ff_ffff PCI Express 1 Config 16M 0xb100_0000 0xb17f_ffff PCI Express 1 IO 8M 0xe000_0000 0xe00f_ffff IMMR 1M 0xfe00_0000 0xffff_ffff NOR Flash (CS0) 32M The 32M NOR flash starts at address 0xfe000000:
Range Start Range End Definition 0xfe00_0000 0xfe05_ffff U-Boot 0xfe0a_0000
0xfe2f_ffff Kernel 0xfe30_0000 0xfe7f_ffff
Ramdisk file system 0xfe80_0000
0xfe81_0000
DTB
6
下面通过uboot源码实现看看这些实现过程;
2 U-Boot 启动流程
2.1 总体启动流程 1.
/cpu/mpc83xx/u-boot.lds文件时连接器脚本文件,其中
.text : {
cpu/mpc83xx/start.o (.text) ………….. } ………
ENTRY(_start)
规定了代码段从/cpu/mpc83xx/start.s开始。而ENTRY(_start)这一句告诉编译器uboot.bin的镜像入口点为start.s中的_start标号。
2. CPU入口函数_start(FLASH中运行): 主要功能:
(1) 设置IMMRBAR
(2) 初始化E300处理器内核 (3) 初始化并使能MMU (4) 使能数据cache
(5) 调用CPU初始化函数cpu_init_f (6) 调用主板初始化函数board_init_f
3. CPU初始化函数cpu_init_f(FLASH中运行): 主要功能:
7
/cpu/mpc83xx/start.S
/cpu/mpc83xx/cpu_init.c
(1) 初始化CPU相关寄存器 (2) 建立系统内存映射
4. 主板初始化函数一board_init_f(FLASH中运行):
主要功能:
(1) 初始化Time Base (2) 初始化串口 (3) 初始化console (4) 检查CPU型号 (5) 初始化DDR内存
(6) 将U-Boot重定位到内存中
5. 主板初始化函数二board_init_r(内存中运行):
主要功能:
(1) 使能指令cache (2) 初始化FLASH驱动 (3) 初始化中断 (4) 初始化以太网
(5) 进入main主循环处理用户命令
(6) 从FLASH中加载Linux内核、文件系统以及DTB
/lib_ppc/board.c
/lib_ppc/board.c
8
2.2 init_e300_core 函数
初始化e300核心,禁止中断响应,只允许machine check中断和system reset中断,禁止指令和数据地址转换,即关闭MMU,进行实地址转换,设置为supervisor级别,禁止看门狗,无效指令和数据cache,等,为系统创建一个干净可靠的初始环境。 2.3 窗口重映射
从前面MPC8308上电流程可以看出,上电之后,第一条代码是从0xFFF0_0100的地方开始执行的,但是flash并不一定会分配在0xFF00_0000到0xFFFF_FFFF的地方(以32M的为例)。在本系统中,Flash的地址就被分配到了0xFE00_0000到0xFFFF_FFFF的地方。所以这其中需要做一个跳转,这正是这段代码中map_flash_by_law1,remap_flash_by_law0等函数要做的,具体的流程可以由下面的五张图来说明:
9
1 开始时,BR0,OR0为全零,4G全是重复的Flash,CPU通过LBLAW0访问Flash空间 FF80_0000到 FFFF_FFFF。
2 map_flash_by_law1函数使用LBLAW1映射FE00_0000到FEFF_FFFF这段空间。
3 跳转到FE00_0000这段空间执行代码,由于4G空间重复,只要偏移地址计算正确就会顺序执行。
10