一、BootLoader简介
1.1、嵌入式Linux软件结构与分布
在一般情况下嵌入式Linux系统中的软件主要分为以下几部分:
1) 引导加载程序:其中包括内部ROM中的固化启动代码和Boot Loader两部分。内部固化ROM是厂家在芯片生产时候固化的,作用基本上是引导Boot Loader。有的芯片比较复杂,比如Omap3,他在flash中没有代码的时候有许多启动方式:USB、UART或以太网等等。而S3C24x0则很简单,只有Norboot和Nandboot。
2) Linux kernel 和drivers。
3) 文件系统。包括根文件系统和建立于Flash内存设备之上的文件系统(EXT4、UBI、CRAMFS等等)。它是提供管理系统的各种配置文件以及系统执行用户应用程序的良好运行环境的载体。
4) 应用程序。用户自定义的应用程序,存放于文件系统之中。
在Flash 存储器中,他们的一般分布如下:
1. CPU 寄存器的设置: | R0=0; R1=Machine ID(即Machine Type Number,定义在linux/arch/arm/tools/mach-types); R2=内核启动参数在 RAM 中起始基地址; |
2. CPU 模式: | 必须禁止中断(IRQs和FIQs); CPU 必须 SVC 模式; |
3. Cache 和 MMU 的设置: | MMU 必须关闭; 指令 Cache 可以打开也可以关闭; 数据 Cache 必须关闭; |
常用的Nand Flash指令如下:
指令 |
功能 |
nand info |
显示可使用的Nand Flash |
nand device [dev] |
显示或设定当前使用的Nand Flash |
nand read addr off size |
Nand Flash读取命令,从Nand的off偏移地址处读取size字节的数据到SDRAM的addr地址。 |
nand write addr off size |
Nand Flash烧写命令,将SDRAM的addr地址处的size字节的数据烧写到Nand的off偏移地址。 |
nand write[.yaffs[1]] addr off size |
烧写yaffs映像专用的命令,.yaffs1 for 512+16 NAND |
nand erase [clean] [off size] |
Nand Flash檫除命令,擦除Nand Flash的off偏移地址处的size字节的数据 |
nand bad |
显示Nand Flash的坏块 |
nand dump[.oob] off |
显示Nand Flash中的数据(16进制) |
nand scrub |
彻底擦除整块Nand Flash中的数据,包括OOB。可以擦除软件坏块标志。 |
nand markbad off |
标示Nand的off偏移地址处的块为坏块 |
erase :擦除Flash的命令
格式:
erase start end
erase start +end
erase N:SF[-SL]
erase bank N
erase all
参数是指定Flash 擦除操作范围,跟写保护的方式相同。
4、USB 操作指令
指令 |
功能 |
usb reset |
初始化USB控制器 |
usb stop [f] |
关闭USB控制器 |
usb tree |
已连接的USB设备树 |
usb info [dev] |
显示USB设备[dev]的信息 |
usb storage |
显示已连接的USB存储设备 |
usb dev [dev] |
显示和设置当前USB存储设备 |
usb part [dev] |
显示USB存储设备[dev]的分区信息 |
usb read addr blk# cnt |
读取USB存储设备数据 |
SD卡的使用命令比较简单,只有初始化和设备信息的显示,读写是通过文件系统命令实现的。
mmc init [dev] - 初始化MMC子系统
mmc device [dev] - 查看和设置当前设备
使用和USB类似,在所有的命令使用前,必须先插入SD卡,然后使用:mmc init,以初始化MMC 控制器,获取设备信息。
6、 系统引导指令 boot 和bootd 都是运行ENV”bootcmd”中指定的指令。
bootm 指令是专门用于启动在SDRAM中的用U-boot的mkimage工具处理过的内核映像。
格式:bootm [addr [arg ...]]
addr 是内核映像所在的SDRAM中的地址
当启动的是Linux内核时,'arg' 可以使 initrd 的地址。
eeprom - I2C 接口的EEPROM 读写指令
格式:
eeprom read addr off cnt
eeprom write addr off cnt
第一个参数addr 是要写入或读出的数据在SDRAM中的存放地址;
第二个参数off 是在EEPROM中的偏移;
第三个参数cnt 是读写的数据字节数。
date - 设置和读取RTC
格式:
date [MMDDhhmm[[CC]YY][.ss]]
MM:月份
DD:日期
hh:小时
mm 分钟
CC:年份的前两个数字
YY:年份的后两个数字
ss:秒数
9、脚本运行指令run var [...]
var :ENV中的脚本名reset -重启CPU
11、环境变量 环境变量 |
解释说明 |
bootdelay |
执行自动启动(bootcmd中的命令)的等候秒数 |
baudrate |
串口控制台的波特率 |
netmask |
以太网的网络掩码 |
ethaddr |
以太网的MAC地址 |
bootfile |
默认的下载文件名 |
bootargs |
传递给Linux内核的启动参数 |
bootcmd |
自动启动时执行命令 |
serverip |
TFTP服务器端的IP地址 |
ipaddr |
本地的IP地址 |
stdin |
标准输入设备,一般是串口 |
stdout |
标准输出,一般是串口,也可以是LCD(VGA) |
stderr |
标准出错,一般是串口,也可以是LCD(VGA) |
要看到你的板上的ENV值可使用printenv命令。
你会发现有些有的ENV上面没有,原因是如果你没有设置这个环境变量就不会打印出,你也可以自己定义ENV,并在命令中使用${ENV}来调用它。同时你也可以删除这个ENV。设置ENV的命令是setenv,格式为:
setenv name value
第1个参数是环境变量的名称。
ENV可以放在许多固体存储器中,对于mini2440来说Nor Flash、Nand Flash或EEPROM都可以,就看你如何配置了(include/configs下的配置文件)。例如:
Nor Flash:
#defineCONFIG_ENV_IS_IN_FLASH 1
#defineCONFIG_ENV_OFFSET 0X40000
#defineCONFIG_ENV_SIZE 0x20000 /* Total Size of Environment Sector */
Nand Flash:
#defineCONFIG_ENV_IS_IN_NAND 1
#defineCONFIG_ENV_OFFSET 0X40000
#defineCONFIG_ENV_SIZE 0x20000 /* Total Size of Environment Sector */
EEPROM:
#defineCONFIG_ENV_IS_IN_EEPROM 1/* use EEPROM for environment vars */
#defineCONFIG_ENV_OFFSET 0x000/* environment starts at offset 0 */
#defineCONFIG_ENV_SIZE 0x400/* 1KB */
CONFIG_ENV_OFFSET是在整个存储器中的偏移地址;
CONFIG_ENV_SIZE是指其使用的大小。
注意:CONFIG_ENV_OFFSET和 CONFIG_ENV_SIZE的设置,不要覆盖了其他分区。
[u-boot@apple_guet]#mmc init
[u-boot@apple_guet]#fatload mmc 1 0x30008000 u-boot.bin
[u-boot@apple_guet]#nand erase 0 0x40000
[u-boot@apple_guet]#nand write 0x30008000 0 0x40000
4.2、通过U盘烧入Nor Flash
[u-boot@apple_guet]#usb start
[u-boot@apple_guet]#usb part0
[u-boot@apple_guet]#fatload usb 0:4 0x30008000 u-boot.bin
[u-boot@apple_guet]#protect off all
[u-boot@apple_guet]#erase 0x0 0x3ffff
[u-boot@MINI2440]#cp.b 0x30008000 0x0 0x3ffff
4.3、通过TFTP服务烧入Nand Flash
[u-boot@apple_guet]#tftpboot 30008000 192.168.1.100:u-boot.bin
[u-boot@MINI2440]#nand erase 0 0x40000
[u-boot@apple_guet]#nand write 0x30008000 0 0x40000
4.4、通过NFS 服务烧入Nand Flash
[u-boot@apple_guet]#nfs 30008000 192.168.1.100:/home/tekkaman/development/share/u-boot.bin
[u-boot@apple_guet]#nand erase 0 0x40000
[u-boot@apple_guet]#nand write 0x30008000 0 0x40000
五、内核引导
内核的引导步骤如下:
因为在用bootm命令引导内核的时候,bootm需要读取一个64字节的文件头,来获取这个内核映象所针对的CPU体系结构、OS、加载到内存中的位置、在内存中入口点的位置以及映象名等等信息。这样bootm才能为OS设置好启动环境,并跳入内核映象的入口点。而mkimage就是添加这个文件头的专用工具。具体的实现请看U-boot中bootm的源码和mkimage的源码。
mkimage工具的使用:
参数说明:
-A指定CPU的体系结构,可用值有:alpha、arm、x86、ia64、mips、mips64、ppc、s390、sh、sparc、sparc64、m68k等
-O指定操作系统类型,可用值有:openbsd、netbsd、freebsd、4_4bsd、linux、svr4、esix、solaris、irix、sco、dell、ncr、lynxos、vxworks、psos、qnx、u-boot、rtems、artos
-T指定映象类型,可用值有:standalone、kernel、ramdisk、multi、firmware、script、filesystem
-C指定映象压缩方式,可用值有:
none不压缩(一般使用这个,因为zImage是已经被bzip2压缩过的自解压内核)
gzip用gzip的压缩方式
bzip2用bzip2的压缩方式
-a指定映象在内存中的加载地址,映象下载到内存中时,要按照用mkimage制作映象时,这个参数所指定的地址值来下载
-e指定映象运行的入口点地址,这个地址就是-a参数指定的值加上0x40(因为前面有个mkimage添加的0x40个字节的头)
-n指定映象名
-d指定制作映象的源文件
5.2、使用范例:
[u-boot@apple_guet]#mmc init
[u-boot@apple_guet]# fatload mmc 1 30008000 zImage.img
[u-boot@apple_guet]#bootm 30008000
2、通过TFTP服务引导内核
[u-boot@apple_guet]# tftpboot 0x30008000 192.168.1.122:zImage.img
[u-boot@apple_guet]# bootm 30008000
3、通过NFS服务引导内核
[u-boot@apple_guet]# nfs 30008000 192.168.1.100:/home/tekkaman/development/share/zImage.img
[u-boot@apple_guet]# bootm 30008000
4、通过Nand Flash引导内核:
[u-boot@apple_guet]# nfs 30008000 192.168.1.100:/home/tekkaman/development/share/zImage.img
Bytes transferred = 2277540 (22c0a4 hex)
[u-boot@apple_guet]# nand erase 0x80000 0x300000
[u-boot@apple_guet]# nand write 30008000 0x80000 300000
内核引导:
[u-boot@apple_guet]# nand read 30008000 0x80000 300000
[u-boot@apple_guet]# bootm 30008000