1.bootloader
在嵌入式操作系统中,BootLoader是在操作系统内核运行之前运行。可以初始化硬件设备、建立内存空间映射图,从而将系统的软硬件环境带到一个合适状态,以便为最终调用操作系统内核准备好正确的环境。
简单的说,bootloader作用就是初始化主要硬件(时钟,内存,硬盘),把操作系统从硬盘拷贝到内存,然后让CPU跳到内存中执行操作系统。
Bootloader是嵌入式系统的引导加载程序,它是系统上电后运行的第一段程序,其作用类似于PC机上的BIOS。
PC–>BIOS–>引导操作系统windows–>识别C,D盘–>运行应用程序
嵌入式系统—>BootLoader(最终目的是启动内核)—>linux内核—>挂接 根文件系统---->应用程序
因为我们的操作系统结构复杂,上电后程序无法直接被运行,这时候必须有一个帮手帮我把程序搬到运行内存中去,并上电自检,初始化各种设备,最终启动内核–>操作系统
2. uboot介绍
U-Boot是通用的Bootloader,是遵循GPL条款的开放源代码项目。
有下面特点(只列重点):
-
U-Boot的作用是系统引导,支持 linux,VxWorks, QNX, RTEMS, ARTOS, LynxOS, android等嵌入式操作系统
-
支持NFS挂载
-
有丰富的设备驱动源码,如串口,以太网,SDRAM等
-
上电自检
U-boot的源码结构
源码可从https://sourceforge.net/directory/os:windows/或https://www.denx.de/wiki/U-Boot/SourceCode获取
3. uboot引导启动内核过程
uboot的工作流程分为两个阶段,第一阶段由start.S引导,第二阶段由start_armboot引导
第一阶段start.S的工作为:
- 首先跳到reset
- 设置为管理模式
- 关看门狗
- 关中断
- 如果SDRAM(DDR)没有初始化,就cpu初始化,这里跳到cpu_init_crit
- 设置存储器
- 初始化栈(为了使用c库)Set up the stack
- _TEXT_BASE=0x33F80000 设置链接地址
- 初始化时钟
- 重定位(把flash的代码重定位到SDRAM的链接地址上去)relocate U-Boot to RAM
- 清bss,所谓bss,就是初始值为0或没有赋值的静态变量或全局变量,清除,免得浪费空间,,在u-boot.lds有bss 第1-11点为u-boot的硬件初始化,为第一阶段
- 从汇编跳到C函数start_armboot
第二阶段start_armboot的工作为:
(1)调用一系列的初始化函数。
(2)初始化存储设备(SDRAM(DDR
)或norflash)
(3)初始化简单硬件如串口,lcd等
(4)初始化相关网络设备,填写IP、MAC地址等。
(5)进去命令循环(即整个boot的工作循环),接受用户从串口输入的bootcmd命令,启动内核
上面说到,uboot从串口输入的bootcmd命令,启动内核
我们看到u-boot启动命令:bootcmd=nand read.jffs2 0x30007FC0 kernel; bootm 0x30007FC0(地址因机器而已)
这里包含两条信息:读内核和启动内核
步骤a: 从NAND FILSHE中的kernel分区(实际是0x00060000)读出内核
步骤b: 放到SDRAM内存地址0x30007FC0去,
启动内核的时候,首先对内核的头部要进行操作,
原因是在Flash中保存的内核是由两部分构成的,第一部分是头部64字节,
第二部分是真正的内核。所以实际真正的内核加载地址是0x30007FC0+64字节= 0x30008000
kernel分区: 是flash中内核区
其中在flash中定义了4大分区:
所以我们所谓的有分区,是在源码里写死了。
我们也可以在u-boot命令端上输入:mtd参看分区
其中0x00060000 就是内核(uImage)存放的位置(相对于为我的开发版)
我们在u-boot命令输入bootm时,会输出0x30008000这个就是把内核读到SDRAM的位置
从FLASH的0x00060000 读到——> SDRAM 的0x30008000
最终,系统进入了内核,u-boot把控制权交给了内核,以后没u-boot什么事了