http://blog.csdn.net/SkyZoom/archive/2007/09/18/1789657.aspx
文章是2年前移植u-boot时候分析的,u-boot方面文章比较多,但是mips方面的稍微少一点,因此贴上来就当资料搜集贴吧.
(Note: 图片上传后和原图有些出入,不知道什么原因,不过总体框图还是正确的)
1.1. 参考资料
詹荣开 <Bootloader技术内幕>
原作者未考证 <au1500(mips)及yamon启动过程>
2. 需求分析
Bootloader 在嵌入式系统中一般起硬件初始化和内核引导的作用,在产品中使用的Bootloader只要保证基本的功能和引导速度即可, 而作为开发使用的Bootloader,要求能提供灵活的配置方式和调试手段,一般选择已有的开源软件作为移植,下面主要分析Bootloader移植的 需求
2.1. 基本功能需求
基本功能包括:
1. 硬件初始化:
根据具体的硬件环境,初始化必要的寄存器和外设
2. 内核引导
从存储介质中读取内核映象, 并引导
3. 代码下载
提供一种或几种机制能从主机直接下载文件到SDRAM中
2.2. 扩展功能需求
扩展功能主要是为了提供调试手段的多样化和便利化做的一些工作,包括:
1. 环境变量的保存:
提供一种能将用户定制的一些参数和脚本保存的机制;
2. 文件写入存储介质:
提供将SDRAM中文件写入存储介质的功能;
3. USB调试手段:
提供使用USB作为控制终端和下载方式的调试开发功能;
4. 文件系统解析:
提供文件系统解析功能,使Bootloader能从存储介质的文件系统目录里读取文件。
3. 原理分析
3.1. Bootloader原理分析
(1) Boot Loader简介
Bootloader就是在操作系统内核运行之前运行的一段小程序。通过这段小程序,我们可以初始化硬件设备、建立内存空间的映射图,从而将系统的软硬件环境带到一个合适的状态,以便为最终调用操作系统内核准备好正确的环境。
(2) Boot Loader的操作模式(Operation Mode)
大多数 Boot Loader 都包含两种不同的操作模式:"启动加载"模式和"下载"模式,这种区别仅对于开发人员才有意义。但从最终用户的角度看,Boot Loader 的作用就是用来加载操作系统,而并不存在所谓的启动加载模式与下载工作模式的区别。
启 动加载(Boot loading)模式:这种模式也称为"自主"(Autonomous)模式。也即 Boot Loader 从目标机上的某个固态存储设备上将操作系统加载到 RAM 中运行,整个过程并没有用户的介入。这种模式是 Boot Loader 的正常工作模式,因此在嵌入式产品发布的时侯,Boot Loader 显然必须工作在这种模式下。
下载(Downloading)模式:在这种 模式下,目标机上的 Boot Loader 将通过串口连接或网络连接等通信手段从主机(Host)下载文件,比如:下载内核映像和根文件系统映像等。从主机下载的文件通常首先被 Boot Loader 保存到目标机的 RAM 中,然后再被 Boot Loader 写到目标机上的FLASH 类固态存储设备中。
(3) Bootloader的两段式启动
由 于 Boot Loader 的实现依赖于 CPU 的体系结构,因此大多数 Boot Loader 都分为 stage1 和 stage2 两大部分。依赖于 CPU 体系结构的代码,比如设备初始化代码等,通常都放在 stage1 中,而且通常都用汇编语言来实现,以达到短小精悍的目的。而 stage2 则通常用C语言来实现,这样可以实现给复杂的功能,而且代码会具有更好的可读性和可移植性。
Boot Loader 的 stage1 通常包括以下步骤(以执行的先后顺序):
?硬件设备初始化。
?为加载 Boot Loader 的 stage2 准备 RAM 空间。
?拷贝 Boot Loader 的 stage2 到 RAM 空间中。
?设置好堆栈。
?跳转到 stage2 的 C 入口点。
Boot Loader 的 stage2 通常包括以下步骤(以执行的先后顺序):
?初始化本阶段要使用到的硬件设备。
?检测系统内存映射(memory map)。
?将 kernel 映像和根文件系统映像从 flash 上读到 RAM 空间中。
?为内核设置启动参数。
?调用内核。
(4) Bootloader结构
Bootloader的组成模块结构如下图所示:
Shell控制台(通过串口输出和接收命令来控制)
上层功能(包括monitor功能,和最基本的启动linux kernel功能)
底层驱动
(主要两种:一种是读写存储介质<硬盘,flash驱动等>,一种是与主机通信<网卡和串口>)
架构相关代码(架构相关的初始化代码)
3.2. U-boot与Yamon比较
目前支持MIPS架构的Bootloader主要有U-Boot与Yamon两种,下面我们来分析比较一下
,如下表所示:
特点和功能 |
U-boot |
Yamon |
支持的 cpu 和 board |
1. 支持种类繁多,包括 arm 的各个系列 ,ppc,mips 2. mips 的支持较差,目前支持 au1100,au1500 系列, 4kec 的需要自己移植 ( 工作量主要在起始代码的初始化部分,包括 cahe 和中断的初始化 ) |
1. 基本上对 mips 系列的都支持 , 包括 SEADTM ,SEAD-2TM MaltaTM, AltasTM 2. 基本上属于 mips 系列专用,未听说过将 Yamon 应用去其他架构的实例(可行性低,相当于重写) |
Image 大小 |
通常 200k~300k 左右,可对一些功能进行裁减至 100k 下 |
一般最小 500k 主要包括初始代码 (start code)+ 大端 image+ 小端 image, 通过修改,可裁减掉一种 endian 的 image, 大概减少 200k 左右 最小化裁减:可能接近 100k |
代码结构 |
1. 采用了将平台无关和平台相关的代码分开处理的方法 |
1. 采用了将平台无关和平台相关的代码分开处理的方法 |
内核启动方式 |
串口, tftp ,本地 , DHCP |
串口, tftp ,本地 |
内核支持格式 |
Vmlinux, 或 gzip 压缩,或 bzip2 压缩,或 zImage |
只支持原始的 vmlinux, 网上有人也尝试修改过 yamon 来支持 zImage(amd 的 1500 开发板提供了支持 zImage 的补丁 ) |
调试功能 |
只有简单的 Go |
功能强大,支持 gdb ,还有异常处理等 |
可移植性 |
对于移植到新的板子或 cpu ,需要修改的目录结构较清晰,容易添加 |
因为 yamon 没有采用大量的 ifdef 来控制选项,是通过 yamon 启动后自动 detect 到 cpu 和 board 的类型的,所以修改稍微麻烦 |
可裁减性 |
结构清晰,易于裁减 |
结构也较清晰,但由于存在较多 yamon 自动检测的部分,裁减性稍差 |
可扩展性 |
易于扩展,对于扩展 shell 命令和增加 Driver 较为容易 |
对 shell command 和 Driver 的支持也较易添加 |
总结 |
U-boot 是一个较为通用的 Bootloader, 主要目的是启动内核,同时给开发者提供较为方便的移植性, U-Boot 的扩展功能什么丰富 ; Yamon(Yet Another Monitor) 是主要针对 MIPS 系列 cpu 的一个功能强大的 Rom monitor 程序 ,Yamon 的扩展功能较为单一 ;
|
|
结论 |
使用 U-Boot 作为开发用 Bootloader |
下面是Yamon的目录分析和启动流程图(主要根据参考资料里的总结)
Yamon目录结构
Yamon启动流程
3.3. U-Boot目录结构
根据上面的比较,我们简单分析一下U-Boot的代码目录结构,描述其代码主要功能,如下图所示:
4. 设计移植
4.1. 启动流程
下面我们详细分析U-Boot的启动流程,并指出针对具体的硬件,启动流程中需要修改的代码,如下图所示:
4.2. 移植分析
根据上述分析,我们代码移植也包括三方面:
(1) 片级移植:
片级移植主要是针对具体cpu的初始化代码的修改,针对我们的mips平台,主要包括: a) 通用寄存器的初始化
b) CP0的初始化(status, config, watch, count, compare, etc.)
c) Watchdog初始化
d) Cache初始化
e) TLB初始化
(2) 板级移植
a) 串口驱动
b) flash读写驱动(nor, nand)
c) HD读写驱动
d) 网卡驱动
(3) 功能层扩展
可根据需求添加新功能或裁减优化,包括调试功能,启动功能,下载功能
4.3. 修改代码
主要修改的代码说明如下:
(1) Makefile 添加开发板的编译支持;
(2) Include/configs/myboard.h 开发板的定义,启动参数等;
(3) cpu/mips/start.S 修改初始化代码和入口;
(4) board/myboard/flash.c 对应的Nor Flash驱动;
(5) board/myboard/myboard.c 对应的板级初始化代码;
(6) board/myboard/lowlevel_init.S 初始化硬件的汇编代码;
(7) board/myboard/serial.c 串口驱动;
(8) drivers/rtl8019.h drivers/rtl8019.c 修改RTL8019驱动的寄存器定义等。
5. 扩展功能
以下的功能是根据以后开发调试的不同需求,有可能需要添加的功能
5.1. Logo功能
LOGO功能在产品级使用中需要,在一般开发中可不使用,目前使用简单的写RGB数据来实现LOGO功能。
5.2. NOR Flash驱动
NOR Flash的读取是不需要驱动的,如果需要保存数据到NOR flash,或通过bootloader提供烧写功能,就必须实现NOR Flash驱动, 由于最终产品不会有NOR, 且目前开发板NOR已有烧写工具,因此未实现NOR Flash驱动。
5.3. Nand Flash驱动
在后期的开发板,将使用Nand Flash作为存储介质,如果需要使用U-boot作为开发用Bootloader,需要将Nand Flash驱动移植到U-Boot中。
5.4. ATA 驱动
在后期的开发板,如果使用硬盘作为存储介质,如果需要使用U-boot作为开发用Bootloader,需要将ATA驱动移植到U-Boot中。
5.5. 文件系统解析
目前U-Boot支持ext2, FAT等,如果需要支持其他文件系统,需要移植对应的代码。