2009年3月16日星期一

Bootloader 和 Uboot

前几天拿到一块ARM的板子,看了一下手册,有些地方觉得比较晕乎,其中bootloader 和uboot就是其中之一,现在把自己google,baidu到的资料重新blog一下,以期和大家共同学习。
Bootloader:
在专用的嵌入式板子运行GNU/Linux系统已经变得越来越流行。一个嵌入式Linux系统从软件的角度看通常可以分为四个层次:
1、 引导加载程序。包括固化在固件(firmware)中的boot代码(可选),和BootLoader两大部分。
2、 Linux内核。特定于嵌入式板子的定制内核以及内核的启动参数。
3、 文件系统。包括根文件系统和建立于Flash内存设备之上文件系统。通常用ramdisk来作为rootfs。
4、 用户应用程序。特定于用户的应用程序。有时在用户应用程序和内核层之间可能还会包括一个嵌入式图形用户界面。常用的嵌入式GUI有:MicroWindows和MiniGUI懂。
引导加载程序是系统加电后运行的第一段软件代码。PC机中的引导加载程序由BIOS(其本质就是一段固件程序)和位于硬盘MBR中的OS BootLoader(比如,LILO和GRUB等)一起组成。BIOS在完成硬件检测和资源分配后,将硬盘MBR中的BootLoader读到系统的 RAM中,然后将控制权交给OS BootLoader。BootLoader的主要运行任务就是将内核映象从硬盘上读到 RAM 中,然后跳转到内核的入口点去运行,也即开始启动操作系统。
而在嵌入式系统中,通常并没有像BIOS那样的固件程序(注,有的嵌入式CPU也会内嵌一段短小的启动程序),因此整个系统的加载启动任务就完全由 BootLoader来完成。比如在一个基于ARM7TDMI core的嵌入式系统中,系统在上电或复位时通常都从地址0x00000000处开始执行,而在这个地址处安排的通常就是系统的BootLoader程 序。
简单地说,BootLoader就是在操作系统内核运行之前运行的一段小程序。通过这段小程序,我们可以初始化硬件设备、建立内存空间的映射图,从而将系统的软硬件环境带到一个合适的状态,以便为最终调用操作系统内核准备好正确的环境。
 通常,BootLoader是严重地依赖于硬件而实现的,特别是在嵌入式世界。因此,在嵌入式世界里建立一个通用的BootLoader几乎是不可能 的。尽管如此,我们仍然可以对BootLoader归纳出一些通用的概念来,以指导用户特定的BootLoader设计与实现。
常见bootloader介绍
1.U-BOOT介绍
uboot是一个庞大的公开源码的软件。他支持一些系列的arm体系,包含常见的外设的驱动,是一个功能强大的板极支持包。其代码可以从http://sourceforge.net/projects/u-boot下载
U-BOOT是由PPCBOOT发展起来的,是PowerPC、ARM9、Xscale、 X86等系统通用的Boot方案,从官方版本 0.3.2开始全面支持SC系列单板机。u-boot是一个open source的bootloader,目前版本是0.4.0。u-boot是在ppcboot以及armboot的基础上发展而来,虽然宣称是0.4.0 版本,却相当的成熟和稳定,已经在许多嵌入式系统开发过程中被采用。由于其开发源代码,其支持的开发板众多。唯一遗憾的是并不支持我们现在学习所用 samsung 44B0X的开发板。
为什么我们需要u-boot?显然可以将ucLinux直接烧入flash,从而不需要额外的 引导装载程序(bootloader)。但是从软件升级的角度以及程序修补的来说,软件的自动更新非常重要。事实上,引导装载程序 (bootloader)的用途不仅如此,但仅从软件的自动更新的需要就说明我们的开发是必要的。
同时,u-boot移植的过程也是一个对嵌入式系统包括软硬件以及操作系统加深理解的一个过程。
2. vivi介绍
下载地址http://www.mizi.com/developer
  vivi是韩国mizi 公司开发的bootloader, 适用于ARM9处理器。 Vivi有两种工作模式:启动加载模式和下载模式。启动加载模式可以在一段时间后(这个时间可更改)自行启动linux内核,这时vivi的默认模式。在 下载模式下,vivi为用户提供一个命令行接口,通过接口可以使用vivi提供的一些命令,如下:
  命令
  功能
  Load
  把二进制文件载入Flash或RAM
  Part
  操作MTD分区信息。显示、增加、删除、复位、保存MTD分区
  Param
  设置参数
  Boot
  启动系统
  Flash
  管理Flash,如删除Flash的数据
  vivi代码分析
  vivi的代码包括arch,init,lib,drivers和include等几个目录,共200多条文件。
  Vivi主要包括下面几个目录:
  arch:此目录包括了所有vivi支持的目标板的子目录,例如s3c2410目录。
  drivers:其中包括了引导内核需要的设备的驱动程序(MTD和串口)。MTD目录下分map、nand和nor三个目录。
  init:这个目录只有main.c和version.c两个文件。和普通的C程序一样,vivi将从main函数开始执行。
  lib:一些平台公共的接口代码,比如time.c里的udelay()和mdelay()。
  include:头文件的公共目录,其中的s3c2410.h定义了这块处理器的一些寄存器。Platform/smdk2410.h定义了与开发板相关的资源配置参数,我们往往只需要修改这个文件就可以配置目标板的参数,如波特率、引导参数、物理内存映射等。

这是我板子ATEB9200的启动过程分析:
启动过程分析
整个开发板上电启动过程分三阶段,分别是:芯片 boot 选择,uboot 引导阶段和最终
的 linux 引导阶段。
芯片启动模式选择
系统启动,首先根据 SW801 的跳线设置,当连接 1-2 的时候 0x10000000(分配的
是 Nor Flash)地址重映射到 0x00000000 地址,而 Nor Flash 中烧写的是 Uboot 程序,
因此 uboot 会启动,具体启动过程见下节。当连接 2-3 时,首先启动芯片 ROM 的
bootloader 程序, bootloader 程序首先依次检查 SPI 接口的 Dataflash,TWI 的 E2PROM
和连接 EBI 的 8 位并行存储器是否存在有效的中断向量表,如果找到有效的中断向量表,
就会将对应的向量表拷贝到 SRAM 中,然后跳到中断向量表执行。最后如果找不到合法的
中断向量表,则运行一个 Uploader 程序,此时会初始化 DBG 口,在超级终端不停打印
CCCC,用户可以使用 xmodem 协议通过超级终端下载 Uboot 程序到 SRAM 中。
(注:其实就是提供了两种模式,第一种是直接启动自己的板子上的已经做好的uboot,这个Uboot已经可以使用,我们为了不重复的烧写flash,把uboot烧写到flash上并且保护起来,复位不清楚;第二种就是手动加载uboot.其实第一种模式是经过第一次以后才能作的。)
Uboot 引导过程
当跳线 SW801 连接至 1-2 时,芯片从外部存储器启动。
uboot 在 Flash 中的地址分配如下图,包括:boot 代码,环境变量和 Uboot 代码三
部分组成,具体地址分配的地址空间如下,见图 4-1。
boot.bin 是 uboot 系统最先执行的程序,它负责初始化系统的基本的软硬件环境,为
uboot 的运行做准备。
初始化完后,解压 uboot 并且运行 uboot。首先 uboot 从 SPI 接口的 DataFlash 中
将 linux 拷贝到 SDRAM 的 0x21000000,将文件系统拷贝到 SDRAM 的 0x21100000
地址,然后跳转到 0x21000000 地址,uboot 首先检查 linux 的文件头,进行 CRC 校验,
如果正确,跳到 linux 内核执行。

没有评论: