Bootloader移植(下)
U-BOOT 启动流程
u-boot启动三个2
两个阶段:汇编阶段(特殊功能寄存器C语言不能直接访问,C运行之前需要准备堆栈),C阶段
两次搬移:u-boot自搬移,内核搬移,(提高速度)
两次初始化:基本硬件初始化,大部分硬件初始化,(C语言写的程序,比较好维护)
第一条指令位置(参考u-boot.map) arch/arm/cpu/armv7/start.S 里的 _start: b reset
设置为SVC模式 msr cpsr,r0
关闭MMU Cache cpu_init_cp15
基本硬件设备初始化 board/samsung/fs4412/lowlevel_init.S 的 lowlevel_init
关中断 看门狗(时钟 串口,flash,内存等的初始化时间可能比较长,这样的话,看门狗会使开发板不停的重启,所以在初始化硬件之前,先关闭MMU Cache,关中断 看门狗)
,初始化时钟 串口,flash,内存
自搬移到内存 relocate_code
(把u-boot剩下的部分搬到内存中,然后运行)
设置栈, IRQ stack frame
(C代码运行之前,必须先设置栈)
准备进入C部分 bl _main ( 参u-boot.map )
大部分硬件初始化 arch\arm\lib\board.c\board_init_f 里的init_sequence
搬移内核到内存运行 common/main.c main_loop -> getenv ("bootcmd")
bootdelay >= 0 && s && !abortboot (bootdelay))
下的 run_command (bootcmd)
uboot是在开发板上的EMMC里面,开发板上电后,BootLoader运行,设置为SVC模式,关闭MMU
Cache,基本硬件初始化,自搬移到内存(uboot剩余程序进内存),设置栈,准备进入C语言部分,大部分硬件初始化,搬移内核到内存(通过网络—tftp服务,将uImage和设备树文件加载到内存),挂载根文件系统(通过网络—nfs服务,将rootfs加载到内存)
启动步骤(重点)
-
上电启动bootloader
硬件基本初始化
自搬移到内存
搬移内核到内存
传递内核启动参数(parmer_struct 或taglist) -
加载内核
a. 自解压内核 decompess //arch/arm/boot/compressed/head.S
b. 运行内核汇编部分 head.S 入口stext //arch/arm/kernel/head.S
检测合法性(CPU 类型,机器类型)
c. 运行内核C部分 start_kernel //init/main.c
CPU,机器参数的安装 setup_arch
中断,定时,终端,内存等最基本的初始化
创建核心进程 kernel_init运行,启动多任务调度,原父进程空转cpu_ide -
挂载rootfs (mount_root)
-
运行应用程序 //第一个应用程序是init (由u-boot的bootargs里的init=/linuxrc来指定)
a. 运行启动脚本 (run_init_process("/etc/init.d/rcS")) //由init来解析脚本执行
b. 其它应用程序 //一般添加在脚本的最后(如在rcS末尾加 ./app)
U-BOOT 启动源码分析
- 上电系统从哪里开始,启动代码放在什么位置 ?
上电后,有的系统可通过硬件管脚的电平来选择从Nandflash还是从Norflash启动。这里是指定从Nandflash启动的
启动代码U-boot 是不能放在RAM中的,因掉电就消失了。
- boot第一件是为何是设置为SVC模式?
为安全性,CPU本身提出了多种模式来实现安全性,和效率兼顾。
SVC模式就是CPU对资源的一种保护。在普通用户模式是不能访问到的。只有切换到SVC模式才能访问。
- 为什么并关闭中断,MMU,看门狗等?
初始时为安全性,把系统单纯化, 排除掉别的干扰,仅仍u-boot实现单纯的搬移代码,
的功能。 所以关掉中断,避免中断打断带来的保存返回的问题。 关掉MMU,因为u-boot软件是硬件实地址访问。
根本没有用到内存地址映射。 看门狗如果没关,硬件上默认到时会复位的。 所以要关掉
- 为何设备初始引导不能用C代码,要用汇编代码?
特殊指令,如操作协处理器, MMC CASH ,切换SVC模式, 等C不能做到。
- U-BOOT为何要搬移到RAM中运行?
在RAM中速度更快,但因掉电就没了,所以要保存在Nandflash或Norflash中。
如果搬移,直接在Norflash上运行也是可以的。 Nandflash因是按块操作的,不太合适直接运行。
- U-boot如何传递参数到内核。 移植时要注意哪些?
方式一 采用param_struct: (我们现在使用的是这种方式) 见common/cmd_boot.c go命令的优化
方式二 采用taglist:
U-BOOT 移植方法
-
善用对比软件Beyond
-
选择官方源码版本下载, 配置编译
a. 指定交叉编译工具链
b. 指定cpu 和board(参考最类似配置如origen)
c. 编译 -
实现串口信息输出
a. 跟踪运行路径(led点灯法)
b. 串口输出(检查uart初始化相关部分代码见lowlevel_init.s) -
网卡移植(实现能用tftp nfs 方便开发调试)
a. 寄存器地址
b. 参数设置 -
FLASH移植(实现能下载软件到FLASH,产品能离线运行)