第1章
BootLoader 的概念与功能
1.1 嵌入式 Linux 软件结构与分布
一般情况下嵌入式 Linux 系统中的软件主要分为以下几部分:
1) 引导加载程序:其中包括内部 ROM 中的固化启动代码和 BootLoader 两部分。
内部固化 ROM 是厂家在芯片生产时候固化的,作用基本上是引导 BootLoader。
有的芯片比较复杂,比如 Omap3 在 flash 中没有代码的时候有许多启动方式:
USB、UART 或以太网等等。而 S3C24x0 则很简单,只有 Norboot 和
Nandboot。
2) Linux kernel 和 drivers。
3) 文件系统。包括根文件系统和建立于 Flash 内存设备之上的文件系统(EXT4、
UBI、CRAMFS 等等)。它是提供管理系统的各种配置文件以及系统执行用户应
用程序的良好运行环境及载体。
4) 应用程序。用户自定义的应用程序,存放于文件系统之中。
在 Flash 存储器中,他们的分布一般如下:
BootLoader
BootLoader
参数区
Linux
Kernel
根文件系统
其他文件系统......
(被挂载到根文件系统或者作为
但是以上只是大部分情况下的分布,也有一些可能根文件系统是 initramfs,被一起压缩
到了内核映像里,或者没有 Bootloader 参数区,等等。
1.2 在嵌入式 Linux 中 BootLoader 的必要性
Linux 内核的启动除了内核映像必须在主存的适当位置,CPU 还必须具备一定的条件:
1. CPU 寄存器的设置:
2. CPU 模式:
3. Cache 和 MMU 的设置:
R0=0;
R1=Machine ID(即 Machine Type Number,定义在
linux/arch/arm/tools/mach-types);
R2=内核启动参数在 RAM 中起始基地址;
必须禁止中断(IRQs 和 FIQs);
CPU 必须 SVC 模式;
MMU 必须关闭;
指令 Cache 可以打开也可以关闭;
数据 Cache 必须关闭;
但是在 CPU 刚上电启动的时候,一般连内存控制器都没有初始化过,根本无法在主存中
运行程序,更不可能处在 Linux 内核启动环境中。为了初始化 CPU 及其他外设,使得 Linux
内核可以在系统主存中运行,并让系统符合 Linux 内核启动的必备条件,必须要有一个先于
内核运行的程序,他就是所谓的引导加载程序(Boot Loader)。
而 BootLoader 并不是 Linux 才需要,而是几乎所有运行操作系统的设备都需要。我们的
PC 的 BOIS 就是 Boot Loader 的一部分(只是前期引导,后面一般还有外存中的各种 Boot
Loader),对于 Linux PC 来说,Boot Loader = BIOS + GRUB/LILO。
1.3 Boot Loader 的功能和选择
综上所述:BootLoader 是在操作系统内核启动之前运行的一段小程序。通过这段程序,
我们可以初始化硬件设备,从而将系统的软硬件环境带到一个合适的状态,以便为最终调用
操作系统内核准备好正确的环境,最后从别处(Flash、以太网、UART)载入内核映像到主
存并跳到入口地址。
由于 BootLoader 需要直接操作硬件,所以它严重依赖于硬件,而且依据所引导的操作
系统的不同,也有不同的选择。对于嵌入式世界中更是如此。就 S3C24x0 而言,如果是引导
Linux,一般选用韩国的 mizi 公司设计的 vivi 或者 DENX 软件工程中心的 Das U-boot,如果
是引导 Win CE,就选用 Eboot。如果是开发 StrongARM 构架下的 LART,就可选用由 Jan-
Derk Bakker 和 Erik Mouw 发布的 Blob(Boot Loader Object)。如果是要引导 eCos 系统,可
以选用同是 Redhat 公司开发的 Redboot。
所以在嵌入式世界中建立一个通用的 BootLoader 几乎是不可能的,而可能的是让一个
Boot Loader 代码支持多种不同的构架和操作系统,并让她有很好的可移植性。U-boot 就是
支持多平台多操作系统的一个杰出代表。这也是 U-boot 的优势所在,因为如果在开发
S3C2440 时熟悉了 U-boot,再转到别的平台的时候,就可以很快地完成这个平台下 U-boot
的移植。而且 U-boot 的代码结构越来越合理,对于新功能的添加也十分容易。
*推荐阅读:嵌入式系统 Boot Loader 技术内幕
第2章
U-boot 简介
2.1 Uboot 的起源
U-Boot 是 Das U-Boot 的简称,其含义是 Universal Boot Loader,是遵循 GPL 条款的开
放源码项目。最早德国 DENX 软件工程中心的 Wolfgang Denk 基于 8xxROM 和 FADSROM
的源码创建了 PPCBoot 工程项目,此后不断添加处理器的支持。而后,Sysgo Gmbh 把
PPCBoot 移植到 ARM 平台上,创建了 ARMBoot 工程项目。最终,以 PPCBoot 工程和
ARMBoot 工程为基础,创建了 U-Boot 工程,2002 年 12 月 17 日第一个版本 U-Boot-0.2.0
发布,同时 PPCBoot 和 ARMBoot 停止维护。
而今,U-Boot 作为一个主流、通用的 BootLoader,成功地被移植到包括 PowerPC、
ARM、X86 、MIPS、NIOS、XScale 等主流体系结构上的百种开发板,成为功能最多、灵活
性最强,并且开发最积极的开源 BootLoader。目前。U-Boot 仍然由 DENX 的 Wolfgang
Denk 维护。
2.2 Uboot 的开发情况和资源
最早 U-boot 的版本号是由 X.Y.Z 来表示的,从 0.2.0 一直发展到 1.3.4。之后便开始使用
年份加月份的表示方法,从 2008.11 到现在的 2010.3 平均每 3 个多月出一个新版本。每次代
码的结构和定义都会有一些修正和改进,其代码越来越规整,功能越来越强,但是移植的难
度反而越来越小,需要修改的地方越来越少。
U-boot不仅有主线版本,在 U-boot的Git代码仓库中还有 各个CPU构架的分支版本,这
些分支会在一定的时候将修改汇入主线。
下面总结一下关于 U-boot 源代码的网络资源:
官方链接
德国 DENX 软件工程中心主页
U-boot 官方主页 wiki/U-Boot/WebHome
(注意其中的 邮件列表链接)
U-boot 官方源码 FTP 下载 ftp://ftp.denx.de/pub/u-boot/
U-boot 官方 Git 代码仓库
针对 S3C2440 的修改
Openmoko 手机的 U-boot 源码 Git
boot.git;a=shortlog;h=refs/heads/stable
buserror 的 U-boot 源码 Git
(针对 mini2440)
Tekkaman Ninja 的 U-boot 源码 Git
(针对 mini2440)
openmoko/mini2440.git
第3章
开发环境搭建
3.1 交叉编译工具链的安装
编译U-boot给mini2440 的时候,必须使用交叉编译工具链。你可以使用 友善之臂提供的
交叉编译工具(gcc版本 4.3.2),也可以使用crosstool-0.43 或crosstool-ng自己编译一个。
至于如何用工具自己编译交叉编译工具链,请看 Tekkaman Ninja 的博客的相关文章:
用crosstool0.43 建立 ARM-Linux 交叉编译环境
用crosstool-ng建立Linux交叉编译环境(以S3C2440(armv4t)为例)
在编译好交叉编译工具链后,要在环境变量的 PATH 中添加编译工具的路径(也就是
arm-*-linux-*-gcc 所在的路径),这样在编译时系统才找得到编译器的命令。在 Ubuntu 下的
修改方法如下:
vi ~/.profile,
在最后加上:PATH="<交叉编译工具的路径>:$PATH"。
3.2 网路服务的设置
在使用 U-boot 的时候常常会用到宿主机的 TFTP 和 NFS 这两种网络服务,所以最好在
开发前设置好。下面以 Ubuntu 下使用 apt-get 安装为例,简单介绍一下安装配置过程:
3.2.1 安装配置 TFTP 服务
安装配置 TFTP 服务的大致步骤如下:
(1)安装 tftp-hpa、tftpd-hpa 和 openbsd-inetd 程序;
(2)修改配置文件/etc/inetd.conf;
(3)根据配置文件的路径,建立 tftp 目录,并修改目录权限;
(4)重启 tftp 服务;
(5)本地传输测试。
以下是一个安装和配置主要步骤的脚本,大家参考:
#!/bin/sh
TFTPDIR=<你想要的tftp目录路径>
echo install tftp server ...
sudo apt-get install tftp-hpa tftpd-hpa
#
#
#tftp
if [ "$?" = "0" ]
then
echo "install tftp-hpa and tftpd-hpa OK!!"
else
echo "install tftp-hpa and tftpd-hpa error !!!"
exit 1
fi
sudo apt-get install openbsd-inetd
if [ "$?" = "0" ]
then
echo "install openbsd-inetd OK!!"
else
echo "install openbsd-inetd error !!!"
exit 1
fi
echo modify /etc/inetd.conf
dgram udp wait root /usr/sbin/in.tftpd /usr/sbin/in.tftpd -c -s <你想要的tftp目录路径>
sudo vi /etc/inetd.conf
#建立tftp目录,并修改目录权限:
mkdir -p $TFTPDIR
if [ "$?" = "0" ]
then
echo "make tftp dir $TFTPDIR OK!!"
else
echo "make tftp dir $TFTPDIR error !!!"
#
exit 1
fi
sudo chmod 777 $TFTPDIR
#重启tftp server
sudo /etc/init.d/openbsd-inetd restart
3.2.2 安装配置 NFS 服务
安装配置 NFS 服务的大致步骤如下:
(1)安装 NFS 内核服务;
(2)重新配置 portmap 服务,修改/etc/hosts.deny 和/etc/hosts.allow 配置文件,重启
portmap 服务;
(3)修改 NFS 服务的配置文件/etc/exports,添加服务目录和配置,重新导入配置;
(4)重启 NFS 服务,并检查可挂载的目录;
(5)在本地挂载测试。
以下是一个安装和配置主要步骤的脚本,大家参考:
#!/bin/sh
echo install tftp server ...
sudo apt-get install nfs-kernel-server
if [ "$?" = "0" ]
then
echo "install nfs-kernel-server OK!!"
else
echo "install nfs-kernel-server error !!!"
exit 1
#
fi
sudo dpkg-reconfigure portmap
#对Should portmap be bound to the loopback address? 选N.
sudo vi /etc/hosts.deny
#portmap:ALL
#lockd:ALL
#mountd:ALL
#rquotad:ALL
#statd:ALL
sudo vi /etc/hosts.allow
#portmap: 192.168.1.
#lockd: 192.168.1.
#rquotad: 192.168.1.
#mountd: 192.168.1.
#statd: 192.168.1.
sudo service portmap restart
sudo vi /etc/exports
#/home/tekkaman/development/share
192.168.1.0/24(rw,nohide,insecure,no_wdelay,no_root_squash,no_subtree_check,sync)
#特别要注意上面的IP的形式,以前是形如 192.168.1.*,现在是IP/掩码为数的形式。用旧的格式可能会
出问题
#具体的说明,建议看man手册 : man exports
sudo exportfs -r
sudo /etc/init.d/nfs-kernel-server restart
showmount -e 127.0.0.1
3.3 串口终端程序的安装配置
在使用 U-boot 的时候,必然会用到串口与开发板进行通信,所以串口终端程序必不可
少。下面简单介绍一下 Linux 下常用的串口终端:minicom 和 C-kermit 的安装配置(以
Ubuntu 下使用 apt-get 安装为例)。
3.3.1 C-kermit 的安装配置(推荐安装)
在 Linux 下是通过串口传输文件到开发板,就属 C-kermit 比较好用。
(1)安装 ckermit 程序;
(2)编写 ckermit 的配置文件~/.kermrc。
下面是一个很简单的安装和配置脚本,供大家参考:
#!/bin/sh
#
echo install C-kermit ...
sudo apt-get install ckermit
if [ "$?" = "0" ]
then
echo "install ckermit OK!!"
else
echo "install ckermit error !!!"
exit 1
fi
#如果是USB转串口,就是类似/dev/ttyUSB0 的设备,如果是原生的硬件串口,就是类似/dev/ttyS0 的设备节
点。
#根据你使用的串口,设备节点编号可能有变,你可以ls /dev/tty*看看你用的到底有什么设备节点。
cat >~/.kermrc <
set line /dev/ttyUSB0
set speed 115200
set carrier-watch off
set handshake none
set flow-control none
robust
set file type bin
set file name u-boot.bin
set rec pack 1000
set send pack 1000
set window 5
c
EOF
3.3.2 minicom 的安装配置
minicom 是在 Linux 系统下比较常用的串口终端工具,简单的安装配置步骤如下:
(1)安装 minicom 程序;
(2)使用 minicom -s 命令生成配置文件~/.minirc.dfl。
#!/bin/sh
echo install Minicom ...
sudo apt-get install minicom
if [ "$?" = "0" ]
then
echo "install minicom OK!!"
else
echo "install minicom error !!!"
#
exit 1
fi
minicom -s
运行命令 minicom -s 后,屏幕出现如下界面:
+----[配置]----+
| 文件名和路径
| 文件传输协议
|
|
| 串口设置
|
| 调制解调器和拨号 |
| 屏幕和键盘
|
| 设置保存为dfl |
| 设置保存为.. |
| 退出
|
| 退出Minicom |
+------------+
1.使用方向键选择“串口设置”,出现具体的配置:
+-----------------------------------------------------------------------+
| A - 串口设备: /dev/ttyUSB0
|
| B - 锁文件的位置: /var/lock
|
| C - 调入程序:
|
| D - 调出程序
:
|
| E - Bps/Par/Bits
: 115200 8N1
|
| F - 硬件数据流控制: 否
|
| G - 软件数据流控制
:否
|
| 希望修改哪个设置?
|
+-----------------------------------------------------------------------+
使用相应的字母键配置,比如修改设备节点则输入 A,光标转移到“串口设备”选项后,可
以对其值进行修改,完成后回车确定。如果选择了 E 则出现:
+---------------[普通参数]---------------+
|
|
| 当前: 115200 8N1
|
| 速度
参数
数据
|
| A:
L: None S: 5
|
| B:
M: Even T: 6
|
| C: 9600
N: Odd
U: 7
|
| D: 38400
O: Mark V: 8 |
| E: 115200
P: Space
|
|
|
| 停止位
|
| W: 1
Q: 8-N-1
|
| X: 2
R: 7-E-1
|
|
|
|
|
| 退出Mini| 选择, 或按 退出? |
+------------------------------------+
选择 E 和 Q,设置好后回车,回到“配置”菜单后再进入 “调制解调器和拨号”,清除以下几
项的数据:
A - 初始化字符串 ......
B - 重置字符串 .......
K - 停机字符串 ......
清除完后,回车退到“配置”菜单后再进入 “设置保存为 dfl”,就会保存配置到
~/.minirc.dfl。然后选择“退出”退出配置状态,就可以通过串口连接开发板了。
还有一个图形化的串口终端:gtkterm,图形配置,简单易用,但无法传输文件。
第4章
熟悉 U-boot 的使用与烧写
要开发和移植 U-boot,首先要对 U-boot 有一定的了解,起码要会使用。所以这里首先熟
悉一下 U-boot 的使用以及如何将 U-boot 烧入 mini2440。
当然在这之前首先必须保证你的开发板上已经有了U-boot。如果没有,就请先烧入一个
已经编译好的U-boot。已经针对mini2440 编译好的U-boot-2009.11 的bin文件在Tekkaman
Ninja 的 博客中有,可以直接烧入,链接:u-boot.bin_tekkaman_2009.11.tar.bz2
把它烧到mini2440 的NAND或者NOR Flash的起始地址即可,烧入的方法请参考 友善之
臂官方 网提供的《MINI2440 用户手册》。
4.1 烧写 Uboot 到 mini2440 开发板
4.2 常用 Uboot 命令详解
U-boot 发展到现在,其命令行模式已经非常接近 Linux 下的 shell 了,在 Tekkaman
Ninja 编译的 U-boot-2009.11 中的命令行模式下支持“Tab”键的命令补全和命令的历史记录功
能。而且如果命令的前几个字符和别的命令不重复,那就只需要打出这几个字符即可,比如
查看 U-boot 的版本号命令是“ version”,但是在所有其它命令中没有任何一个的命令是由“v”
开头的,所以只需要输入“v”即可。
[u-boot@MINI2440]# version
U-Boot 2009.11 ( 4 月 04 2010 - 12:09:25)
[u-boot@MINI2440]# v
U-Boot 2009.11 ( 4 月 04 2010 - 12:09:25)
[u-boot@MINI2440]# base
Base Address: 0x00000000
[u-boot@MINI2440]# ba
Base Address: 0x00000000
下面简单介绍常用的命令。
4.2.1 获取帮助
命令:help 或 ?
功能:查看当前 U-boot 支持的所有命令。
[u-boot@MINI2440]# help
?
- alias for 'help'
askenv - get environment variables from stdin
base - print or set address offset
bdinfo - print Board Info structure
bmp - manipulate BMP image data
boot - boot default, i.e., run 'bootcmd'
bootd - boot default, i.e., run 'bootcmd'
bootelf - Boot from an ELF image in memory
bootm - boot application image from memory
bootp - boot image via network using BOOTP/TFTP protocol
bootvx - Boot vxWorks from an ELF image
cmp - memory compare
coninfo - print console devices and information
cp
- memory copy
crc32 - checksum calculation
date - get/set/reset date & time
dcache - enable or disable data cache
dhcp - boot image via network using DHCP/TFTP protocol
echo - echo args to console
editenv - edit environment variable
eeprom - EEPROM sub-system
erase - erase FLASH memory
exit - exit script
fatinfo - print information about filesystem
fatload - load binary file from a dos filesystem
fatls - list files in a directory (default /)
flinfo - print FLASH memory information
fsinfo - print information about filesystems
fsload - load binary file from a filesystem image
go
- start application at address 'addr'
help - print online help
i2c - I2C sub-system
icache - enable or disable instruction cache
iminfo - print header information for application image
imls - list all images found in flash
imxtract- extract a part of a multi-image
itest - return true/false on integer compare
loadb - load binary file over serial line (kermit mode)
loads - load S-Record file over serial line
loadx - load binary file over serial line (xmodem mode)
loady - load binary file over serial line (ymodem mode)
loop - infinite loop on address range
ls
- list files in a directory (default /)
md
- memory display
mm
- memory modify (auto-incrementing address)
mmc - MMC sub-system
mtest - simple RAM read/write test
mw
- memory write (fill)
nand - NAND sub-system
nboot - boot from NAND device
nfs - boot image via network using NFS protocol
nm
- memory modify (constant address)
ping - send ICMP ECHO_REQUEST to network host
printenv- print environment variables
protect - enable or disable FLASH write protection
rarpboot- boot image via network using RARP/TFTP protocol
reginfo - print register information
reset - Perform RESET of the CPU
run - run commands in an environment variable
saveenv - save environment variables to persistent storage
setenv - set environment variables
showvar - print local hushshell variables
sleep - delay execution for some time
source - run script from memory
test - minimal test like /bin/sh
tftpboot- boot image via network using TFTP protocol
unzip - unzip a memory region
usb - USB sub-system
usbboot - boot from USB device
version - print monitor version
如果想获取某条命令的详细帮助,可使用:
help <想要查的指令>
或者 ? <想要查的指令> ,
甚至 h <想要查的指令缩写>。
以 bmp 指令为例:
[u-boot@MINI2440]# help bmp
bmp - manipulate BMP image data
Usage:
bmp info
- display image info
bmp display [x y] - display image at x,y
[u-boot@MINI2440]# ? bmp
bmp - manipulate BMP image data
Usage:
bmp info
- display image info
bmp display [x y] - display image at x,y
[u-boot@MINI2440]# h bm
bmp - manipulate BMP image data
Usage:
bmp info
- display image info
bmp display [x y] - display image at x,y
4.2.2 环境变量与相关指令
和 shell 类似,U-Boot 也有环境变量(environment variables,简称 ENV)
,U-boot 默认
的一些环境变量如下:
环境变量
解释说明
bootdelay 执行自动启动(bootcmd 中的命令)的等候秒
数
baudrate 串口控制台的波特率
netmask 以太网的网络掩码
ethaddr 以太网的 MAC 地址
bootfile 默认下载文件名
bootargs 传递给 Linux 内核的启动参数
bootcmd 自动启动时执行命令
serverip 文件服务器端的 IP 地址
ipaddr 本地 IP 地址
stdin 标准输入设备,一般是串口
stdout 标准输出,一般是串口,也可是 LCD(VGA)
stderr 标准出错,一般是串口,也可是 LCD(VGA)
查看当前 U-boot 的 ENV 值可使用 printenv 命令:
[u-boot@MINI2440]# printenv
bootargs=noinitrd root=/dev/nfs rw nfsroot=192.168.0.1:/home/tekkaman/working/nfs/rootfs
ip=192.168.0.2:192.168.0.1::255.255.255.0 console=ttySAC0,115200 init=/linuxrc mem=64M
bootcmd=nfs 0x30008000 192.168.0.1:/home/tekkaman/working/nfs/zImage.img;bootm
bootdelay=1
baudrate=115200
ethaddr=08:08:11:18:12:27
ipaddr=192.168.0.2
serverip=192.168.0.1
gatewayip=192.168.0.1
netmask=255.255.255.0
tekkaman=bmp d 70000
stdin=serial
stdout=serial
stderr=serial
ethact=dm9000
Environment size: 470/131068 bytes
你会发现有些上面提到的 ENV 没有显示,还有一个名为“tekkaman”的 ENV。原因是如果
没有设置这个环境变量就它不会被打印出,也可以自己定义 ENV,并在命令中使用${ENV}来
调用它。同时还可以删除这个 ENV。设置 ENV 的命令是 setenv,格式为:
setenv name value
第 1 个参数 name 是环境变量的名称。
第 2 个参数 value 是要设置的值,如果没有第 2 个参数,表示删除这个环境变量。
范例:先将”tekkaman”参数删除,再设置,最后在一个命令串中调用。
[u-boot@MINI2440]# printenv tekkaman
tekkaman=bmp d 70000
[u-boot@MINI2440]# setenv tekkaman
[u-boot@MINI2440]# printenv tekkaman
## Error: "tekkaman" not defined
[u-boot@MINI2440]# setenv tekkaman echo "I am Tekkaman Ninja!"
[u-boot@MINI2440]# printenv tekkaman
tekkaman=echo I am Tekkaman Ninja!
[u-boot@MINI2440]# echo I Love Linux ;${tekkaman}
I Love Linux
I am Tekkaman Ninja!
当设置或改动了 ENV,它只保存在了内存中。如果需要它保存在存放 ENV 的固态存储器
中,请使用:saveenv。
[u-boot@MINI2440]# saveenv
Saving Environment to NAND...
Erasing Nand...
Erasing at 0x6000000000002 -- 0% complete.
Writing to Nand... done
[u-boot@MINI2440]#
如果在启动时,U-boot 打印出:“Warning - bad CRC, using default environment”,说明
U-boot 没有在存放 ENV 的固态存储器中找到有效的 ENV,只好使用编译时定义的默认
ENV。如果 U-boot 存放 ENV 的固态存储器的驱动是没问题的,那只要运行 saveenv 就可
以把当前系统的所有 ENV 写入固态存储器,下次启动就不会有这个警告了。
ENV 可以放在多种固体存储器中,对于 mini2440 来说 Nor Flash、Nand Flash 或
EEPROM 都可以,这依赖 include/configs 下的配置文件是如何定义的。例如:
Nor Flash:
#define CONFIG_ENV_IS_IN_FLASH 1 /* Total Size of Environment Sector */
#define CONFIG_ENV_OFFSET 0X40000
#define CONFIG_ENV_SIZE
0x20000
Nand Flash:
#define CONFIG_ENV_IS_IN_NAND 1 /* Total Size of Environment Sector */
#define CONFIG_ENV_OFFSET 0X40000
#define CONFIG_ENV_SIZE
0x20000
EEPROM:
#define CONFIG_ENV_IS_IN_EEPROM 1 /* use EEPROM for environment vars */
#define CONFIG_ENV_OFFSET
0x000 /* environment starts at offset 0 */
#define CONFIG_ENV_SIZE
0x400 /* 1KB */
CONFIG_ENV_OFFSET :是在整个存储器中的偏移地址;
CONFIG_ENV_SIZE :是指用来保存 ENV 的分区大小。
注意 CONFIG_ENV_OFFSET 和 CONFIG_ENV_SIZE 的设置,请不要覆盖了其他分区
4.2.3 串口传输命令
命令:
loadb - load binary file over serial line (kermit mode)
loadx - load binary file over serial line (xmodem mode)
loady - load binary file over serial line (ymodem mode)
功能:以不同的协议从串口获取 Host 传输过来的文件.。
格式:
Load? [ off ] [ baud ]
第 1 个参数 off 是下载到 SDRAM 的地址。如果不填,就使用默认配置:
CONFIG_SYS_LOAD_ADDR
第 2 个参数是波特率,一般不填,用默认的 115200.
在 windows 下的超级终端可以用这些协议发送文件,但是在 ubuntu 下基本只能用 kermit
协议。以下是使用 C-kermit 来发送一个文件到 mini2440。
[u-boot@MINI2440]# loadb
## Ready for binary (kermit) download to 0x30008000 at 115200 bps...
上面已经启动了 U-boot 的 kermit 传输协议,这时按下 Ctrl + \ , 再按 c, 切换到 C-kermit
的命令行模式,输入命令:send <文件路径>,回车。
[u-boot@MINI2440]# loadb
## Ready for binary (kermit) download to 0x30008000 at 115200 bps...
(Back at MAGI-Linux)
----------------------------------------------------
C-Kermit 8.0.211, 10 Apr 2004, for Linux
Copyright (C) 1985, 2004,
Trustees of Columbia University in the City of New York.
Type ? or HELP for help.
(/home/tekkaman/桌面/) C-Kermit>send /home/tekkaman/development/share/zImage.img
C-kermit 就开始传送,并且显示一个传送界面,并动态显示传送进度。
C-Kermit 8.0.211, 10 Apr 2004, MAGI-Linux
Current Directory: /home/tekkaman/
~L ~]
Communication Device: /dev/ttyUSB0
Communication Speed: 115200
Parity: none
RTT/Timeout: 01 / 02
SENDING: /home/tekkaman/development/share/zImage.img => zImage.img
File Type: BINARY
File Size: 2277540
Percent Done: 19 /////////-
...10...20...30...40...50...60...70...80...90..100
Estimated Time Left: 00:03:35
Transfer Rate, CPS: 8536
Window Slots: 1 of 1
Packet Type: D
Packet Count: 557
Packet Length: 1000
Error Count: 0
Last Error:
Last Message:
X to cancel file, Z to cancel group, to resend last packet,
E to send Error packet, ^C to quit immediately, ^L to refresh screen.
传送完毕后,输入 c ,回到 U-boot 的串口界面。
[u-boot@MINI2440]# loadb
## Ready for binary (kermit) download to 0x30008000 at 115200 bps...
(Back at MAGI-Linux)
----------------------------------------------------
C-Kermit 8.0.211, 10 Apr 2004, for Linux
Copyright (C) 1985, 2004,
Trustees of Columbia University in the City of New York.
Type ? or HELP for help.
(/home/tekkaman/桌面/) C-Kermit>send /home/tekkaman/development/share/zImage.img
(/home/tekkaman/桌面/) C-Kermit>c
Connecting to /dev/ttyUSB0, speed 115200
Escape character: Ctrl-\ (ASCII 28, FS): enabled
Type the escape character followed by C to get back,
or followed by ? to see other options.
----------------------------------------------------
## Total Size
= 0x0022c0a4 = 2277540 Bytes
## Start Addr
= 0x30008000
[u-boot@MINI2440]#
4.2.4 网络命令
只要 U-boot 的网卡驱动没问题,就可以通过网络来传输文件到开发板,这比串口快多
了。你可以直接用交叉网线连接开发板和电脑,也可以用普通直连网线通过路由器连到电
脑,不过记得配置好网络,关闭防火墙。
先测试网络是否畅通,在开发板使用 ping 命令,看看同电脑的网络连接是否畅通:
[u-boot@MINI2440]# ping 192.168.1.100
dm9000 i/o: 0x20000300, id: 0x90000a46
DM9000: running in 16 bit mode
MAC: 08:08:11:18:12:27
operating at 100M full duplex mode
Using dm9000 device
host 192.168.1.100 is alive
如果出现:
[u-boot@MINI2440]# ping 192.168.1.100
dm9000 i/o: 0x20000300, id: 0x90000a46
DM9000: running in 16 bit mode
MAC: 08:08:11:18:12:27
operating at 100M full duplex mode
Using dm9000 device
ping failed; host 192.168.1.100 is not alive
这种无法 ping 通的问题,原因可能是:
1、U-boot 网卡驱动有问题;
2、U-boot 网络协议延时配置有问题;
3、网络参数配置问题,比如 IP 配置等,Host 和 Target 都有可能有问题。Host 最好关闭
IPv6。
如果还找不到原因,可用 Wireshark 抓包看看。
如果网络畅通,就可以使用下面的命令从 tftp 服务目录或者 nfs 服务目录下载文件到
SDRAM 了。
命令:
dhcp
:使用 DHCP/TFTP 协议获取文件
rarpboot :使用 RARP/TFTP 协议获取文件
nfs
:使用 NFS 协议获取文件
tftpboot :使用 TFTP 协议获取文件
bootp
:使用 BOOTP/TFTP 协议获取文件
以上命令的格式都为:指令 [目的 SDRAM 地址] [[主机 IP:]文件名]
注意:
要使用 dhcp、rarpboot 或 bootp 要路由器或 Host 支持的这些协议和服务。
如果没有输入[目的 SDRAM 地址],系统就是用编译时定义的 CONFIG_SYS_LOAD_ADDR
在使用如果 tftpboot 和 nfs 命令没有定义[主机 IP:],则使用 ENV 中的 serverip
其它命令必需定义[主机 IP:],否则使用提供动态 IP 服务的主机 IP。
以下是使用范例,请注意红色字体:
[u-boot@MINI2440]# nfs 0x30008000 192.168.1.100:/home/tekkaman/development/share/u-boot.bin
dm9000 i/o: 0x20000300, id: 0x90000a46
DM9000: running in 16 bit mode
MAC: 08:08:11:18:12:27
operating at 100M full duplex mode
Using dm9000 device
File transfer via NFS from server 192.168.1.100; our IP address is 192.168.1.101
Filename '/home/tekkaman/development/share/u-boot.bin'.
Load address: 0x30008000
Loading: ###################################################
done
Bytes transferred = 256220 (3e8dc hex)
[u-boot@MINI2440]# tftp u-boot.bin
dm9000 i/o: 0x20000300, id: 0x90000a46
DM9000: running in 16 bit mode
MAC: 08:08:11:18:12:27
operating at 100M full duplex mode
Using dm9000 device
TFTP from server 192.168.1.100; our IP address is 192.168.1.101
Filename 'u-boot.bin'.
Load address: 0x30008000
Loading: T ##################
done
Bytes transferred = 256220 (3e8dc hex)
[u-boot@MINI2440]# dhcp 192.168.1.100:u-boot.bin
dm9000 i/o: 0x20000300, id: 0x90000a46
DM9000: running in 16 bit mode
MAC: 08:08:11:18:12:27
operating at 100M full duplex mode
BOOTP broadcast 1
BOOTP broadcast 2
DHCP client bound to address 192.168.1.101
Using dm9000 device
TFTP from server 192.168.1.100; our IP address is 192.168.1.101
Filename 'u-boot.bin'.
Load address: 0x30008000
Loading: ##################
done
Bytes transferred = 256220 (3e8dc hex)
[u-boot@MINI2440]# bootp 192.168.1.100:u-boot.bin
dm9000 i/o: 0x20000300, id: 0x90000a46
DM9000: running in 16 bit mode
MAC: 08:08:11:18:12:27
operating at 100M full duplex mode
BOOTP broadcast 1
BOOTP broadcast 2
DHCP client bound to address 192.168.1.101
Using dm9000 device
TFTP from server 192.168.1.100; our IP address is 192.168.1.101
Filename 'u-boot.bin'.
Load address: 0x30008000
Loading: ##################
done
Bytes transferred = 256220 (3e8dc hex)
[u-boot@MINI2440]# rarpboot 192.168.1.100:u-boot.bin
4.2.5 Nand Flash 操作指令
常用的 Nand Flash 指令如下:
指令
nand info
nand device [dev]
nand read addr off size
nand write addr off size
nand write[.yaffs[1]]
addr off size
nand erase [clean] [off size]
nand bad
nand dump[.oob] off
nand scrub
nand markbad off
功能
显示可使用的 Nand Flash
显示或设定当前使用的 Nand Flash
Nand Flash 读取命令,从 Nand 的 off 偏移地
址处读取 size 字节的数据到 SDRAM 的 addr
地址。
Nand Flash 烧写命令,将 SDRAM 的 addr 地
址处的 size 字节的数据烧写到 Nand 的 off 偏
移地址。
烧写 yaffs 映像专用的命令,.yaffs1 for
512+16 NAND
Nand Flash 檫除命令,擦除 Nand Flash 的 off
偏移地址处的 size 字节的数据
显示 Nand Flash 的坏块
显示 Nand Flash 中的数据(16 进制)
彻底擦除整块 Nand Flash 中的数据,包括
OOB。可以擦除软件坏块标志。
标示 Nand 的 off 偏移地址处的块为坏块
使用范例:
[u-boot@MINI2440]# nand info
Device 0: NAND 128MiB 3,3V 8-bit, sector size 128 KiB
[u-boot@MINI2440]# nand device 0
Device 0: NAND 128MiB 3,3V 8-bit... is now current device
[u-boot@MINI2440]# nand read 0x30008000 0x60000 200000
NAND read: device 0 offset 0x60000, size 0x200000
2097152 bytes read: OK
[u-boot@MINI2440]# nand bad
Device 0 bad blocks:
030a0000
030c0000
030e0000
07ee0000
[u-boot@MINI2440]# nand markbad 0x500000
block 0x00500000 successfully marked as bad
[u-boot@MINI2440]# nand bad
Device 0 bad blocks:
00500000
030a0000
030c0000
030e0000
07ee0000
[u-boot@MINI2440]# nand scrub
NAND scrub: device 0 whole chip
Warning: scrub option will erase all factory set bad blocks!
There is no reliable way to recover them.
Use this command only for testing purposes if you
are sure of what you are doing!
Really scrub this NAND flash?
Erasing at 0x2f4000008000000 -- 0% complete.
NAND 128MiB 3,3V 8-bit: MTD Erase failure: -5
NAND 128MiB 3,3V 8-bit: MTD Erase failure: -5
NAND 128MiB 3,3V 8-bit: MTD Erase failure: -5
Erasing at 0x7ea000008000000 -- 0% complete.
NAND 128MiB 3,3V 8-bit: MTD Erase failure: -5
Erasing at 0x7fe000008000000 -- 0% complete.
OK
[u-boot@MINI2440]# nand bad
Device 0 bad blocks:
030a0000
030c0000
030e0000
07ee0000
[u-boot@MINI2440]# nand dump 0x8000
Page 00008000 dump:
ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
(略)
OOB:
ff ff ff ff ff ff ff ff
ff ff ff ff ff ff ff ff
ff ff ff ff ff ff ff ff
ff ff ff ff ff ff ff ff
ff ff ff ff ff ff ff ff
ff ff ff ff ff ff ff ff
ff ff ff ff ff ff ff ff
ff ff ff ff ff ff ff ff
[u-boot@MINI2440]# tftp u-boot.bin
dm9000 i/o: 0x20000300, id: 0x90000a46
DM9000: running in 16 bit mode
MAC: 08:08:11:18:12:27
operating at 100M full duplex mode
Using dm9000 device
TFTP from server 192.168.1.100; our IP address is 192.168.1.101
Filename 'u-boot.bin'.
Load address: 0x30008000
Loading: T ##################
done
Bytes transferred = 256220 (3e8dc hex)
[u-boot@MINI2440]# nand write 0x30008000 0 40000
NAND write: device 0 offset 0x0, size 0x40000
Writing at 0x2000000020000 -- 100% is complete. 262144 bytes written: OK
[u-boot@MINI2440]# nand dump 0x8000
Page 00008000 dump:
00 00 53 e1 01 00 00 2a 15 40 e0 e3 19 00 00 ea
(略)
60 30 97 e5 03 00 54 e1 f6 ff ff ba 00 40 a0 e3
OOB:
ff ff ff ff ff ff ff ff
ff ff ff ff ff ff ff ff
ff ff ff ff ff ff ff ff
ff ff ff ff ff ff ff ff
ff ff ff ff ff ff ff ff
65 a9 6b f3 ff 33 fc 30
f3 33 cf 33 0f f0 ff 00
cc 0f 59 55 57 96 a5 5b
nboot 指令也是一条 Nand Flash 读取指令,它是将 Nand Flash 的 offset 偏移地址的内
核映像读取到 SDRAM 的 loadAddr 位置。它会自动读取到内核映像(使用 mkimage 处理过
的)的结束,所以不用给出读取大小。
格式:nboot loadAddr dev offset
使用范例:
[u-boot@MINI2440]# tftp 192.168.1.100:zImage.img
dm9000 i/o: 0x20000300, id: 0x90000a46
DM9000: running in 16 bit mode
MAC: 08:08:11:18:12:27
operating at 100M full duplex mode
Using dm9000 device
TFTP from server 192.168.1.100; our IP address is 192.168.1.101
Filename 'zImage.img'.
Load address: 0x30008000
Loading: T #################################################################
#################################################################
##########################
done
Bytes transferred = 2277540 (22c0a4 hex)
[u-boot@MINI2440]# nand erase 0x100000 300000
NAND erase: device 0 offset 0x100000, size 0x300000
Erasing at 0x3e000001800000 -- 0% complete.
OK
[u-boot@MINI2440]# nand write 0x30008000 0x100000 300000
NAND write: device 0 offset 0x100000, size 0x300000
Writing at 0x3e000000020000 -- 100% is complete. 3145728 bytes written: OK
[u-boot@MINI2440]# nand device 0
Device 0: NAND 128MiB 3,3V 8-bit... is now current device
[u-boot@MINI2440]# nboot 30008000 0 0x100000
Loading from NAND 128MiB 3,3V 8-bit, offset 0x100000
Image Name: tekkaman
Created:
2010-03-29 12:59:51 UTC
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 2277476 Bytes = 2.2 MB
Load Address: 30008000
Entry Point: 30008040
[u-boot@MINI2440]# bootm 30008000
## Booting kernel from Legacy Image at 30008000 ...
Image Name: tekkaman
Created:
2010-03-29 12:59:51 UTC
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 2277476 Bytes = 2.2 MB
Load Address: 30008000
Entry Point: 30008040
Verifying Checksum ... OK
XIP Kernel Image ... OK
OK
Starting kernel ...
Uncompressing Linux... done, booting the kernel.
Linux version 2.6.33.1 (tekkaman@MAGI-Linux) (gcc version 4.3.2 (crosstool-NG-1.6.1-tekkaman) ) #5 Mon
Mar 29 20:58:50 CST 2010
CPU: ARM920T [41129200] revision 0 (ARMv4T), cr=c0007177
CPU: VIVT data cache, VIVT instruction cache
Machine: MINI2440
(略)
4.2.6 内存/寄存器操作指令
nm
修改内存值 (指定地址)
格式: nm [.b, .w, .l] address
mm
修改内存值(地址自动加一)
格式: mm [.b, .w, .l] address
md
显示内存值
格式: md [.b, .w, .l] address [# of objects]
mw
用指定的数据填充内存
格式: mw [.b, .w, .l] address value [count]
cp
内存的拷贝(包括内存与 Nor Flash 间的数据拷贝)
格式:cp [.b, .w, .l] source target count
上面是查看和修改内存值的指令,可以查看和修改 SDRAM 和寄存器值。
[.b, .w, .l]代表了查看和修改形式:bit、word、long
使用范例:
[u-boot@MINI2440]# md.b 0x30008000 20
30008000: cc 33 fe 33 cc b3 4c 33 ac 33 de 33 5c 13 cc 33 .3.3..L3.3.3\..3
30008010: cc 32 cc 31 dc 33 cf 33 cc 33 4e 33 8f 13 cc 33 .2.1.3.3.3N3...3
[u-boot@MINI2440]# md.w 0x30008000 20
30008000: 33cc 33fe b3cc 334c 33ac 33de 135c 33cc .3.3..L3.3.3\..3
30008010: 32cc 31cc 33dc 33cf 33cc 334e 138f 33cc .2.1.3.3.3N3...3
30008020: 338c 33cd 33cc 7bcc 3bcc 33cc 135e 734c .3.3.3.{.;.3^.Ls
30008030: 7bdc 37cc 31dc 33c4 038c 33e8 77cc 13cc .{.7.1.3...3.w..
[u-boot@MINI2440]# md.l 0x30008000 20
30008000: 33fe33cc 334cb3cc 33de33ac 33cc135c .3.3..L3.3.3\..3
30008010: 31cc32cc 33cf33dc 334e33cc 33cc138f .2.1.3.3.3N3...3
30008020: 33cd338c 7bcc33cc 33cc3bcc 734c135e .3.3.3.{.;.3^.Ls
30008030: 37cc7bdc 33c431dc 33e8038c 13cc77cc .{.7.1.3...3.w..
30008040: 234c77ce 33dc339c 33ec3ece f3cc36ec .wL#.3.3.>.3.6..
30008050: 37dc33cc 73cc3f5c 17dd314c 33cc62e8 .3.7\?.sL1...b.3
30008060: b6cc33dc 33c233cc 33cc32cc 33cc3f68 .3...3.3.2.3h?.3
30008070: 73cc31cc b3cc33cc 33cc37c9 33df13cc .1.s.3...7.3...3
[u-boot@MINI2440]# nm 0x30008000
30008000: 33fe33cc ? 12345678
30008000: 12345678 ? 34567890
30008000: 34567890 ? q
[u-boot@MINI2440]# nm.b 0x30008000
30008000: 90 ? 11
30008000: 11 ? 12
30008000: 12 ? q
[u-boot@MINI2440]# mm 0x30008000
30008000: 34567812 ? 54321123
30008004: 334cb3cc ? 12345678
30008008: 33de33ac ? 21234543
3000800c: 33cc135c ? q
[u-boot@MINI2440]# md.b 0x30008000 20
30008000: 23 11 32 54 78 56 34 12 43 45 23 21 5c 13 cc 33
30008010: cc 32 cc 31 dc 33 cf 33 cc 33 4e 33 8f 13 cc 33
#.2TxV4.CE#!\..3
.2.1.3.3.3N3...3
[u-boot@MINI2440]# mw.b 0x30008000 aa 10
[u-boot@MINI2440]# mw.b 0x30008010 55 10
[u-boot@MINI2440]# md.b 0x30008000 20
30008000: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa ................
30008010: 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 UUUUUUUUUUUUUUUU
[u-boot@MINI2440]# cp.b 0x30008000 0x30008010 10
[u-boot@MINI2440]# md.b 0x30008000 20
30008000: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa ................
30008010: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa ................
你可以试着修改 LED 相连的 GPIO 寄存器的数据寄存器值,可以控制 LED 的点亮!
先熄灭后点亮 LED1 的范例:(这个实验要结合芯片数据手册和 mini2440 的原理图来理
解)
[u-boot@MINI2440]# md 0x56000014 1
56000014: 00000600 ....
[u-boot@MINI2440]# nm.w 0x56000014
56000014: 0600 ? 620 (熄灭)
56000014: 0620 ? 600 (点亮)
4.2.7 Nor Flash 指令
Nor Flash 的命令经常用于烧写数据到 Nor Flash 。
flinfo 打印 Flash 存储器的信息,并列出所有 Sector。
flinfo N 单独打 Flash 存储器 N Block 的信息。(在有多块 Nor Flash 时使用)
[u-boot@MINI2440]# flinfo
Bank # 1: SST: 1x SST39VF1601 (2MB)
Size: 2 MB in 32 Sectors
Sector Start Addresses:
00000000 (RO) 00010000 (RO) 00020000 (RO) 00030000 (RO) 00040000
00050000
00060000 (RO) 00070000 (RO) 00080000
00090000
000A0000
000B0000
000C0000
000D0000
000E0000
000F0000
00100000
00110000
00120000
00130000
00140000
00150000
00160000
00170000
00180000
00190000
001A0000
001B0000
001C0000
001D0000
001E0000
001F0000
[u-boot@MINI2440]# flinfo 1
Bank # 1: SST: 1x SST39VF1601 (2MB)
Size: 2 MB in 32 Sectors
Sector Start Addresses:
00000000 (RO) 00010000 (RO) 00020000 (RO) 00030000 (RO) 00040000
00050000
00060000 (RO) 00070000 (RO) 00080000
00090000
000A0000
000B0000
000C0000
000F0000
00100000
00110000
00140000
00150000
00160000
00190000
001A0000
001B0000
001E0000
001F0000
[u-boot@MINI2440]# flinfo 2
Only FLASH Banks # 1 ... # 1 supported
000D0000
00120000
00170000
001C0000
000E0000
00130000
00180000
001D0000
后面带有(RO)的说明这个 Sector 已经写保护了。
因为 Nor Flash 的读取接口和 SDRAM 是一样的,所以 Nor Flash 的读取也是使用 md 命
令。范例如下:
[u-boot@MINI2440]# md.b 0x0 20
00000000: 12 00 00 ea 14 f0 9f e5 14 f0 9f e5 14 f0 9f e5
00000010: 14 f0 9f e5 14 f0 9f e5 14 f0 9f e5 14 f0 9f e5
................
................
[u-boot@MINI2440]# md 0x0 20
00000000: ea000012 e59ff014 e59ff014 e59ff014
00000010: e59ff014 e59ff014 e59ff014 e59ff014
................
................
00000020: 33f80260 33f802c0 33f80320 33f80380 `..3...3 ..3...3
00000030: 33f803e0 33f80440 33f804a0 deadbeef ...3@..3...3....
00000040: 33f80000 33f80000 33fbe8dc 3400374c ...3...3...3L7.4
00000050: e10f0000 e3c0001f e38000d3 e129f000 ..............).
00000060: e3a00453 e3a01000 e5801000 e3e01000
00000070: e59f0488 e5801000 e59f1484 e59f0484
S...............
................
但由于 Nor Flash 的烧写时序和 SDRAM 的写入不同,烧写 Nor Flash 不能使用 mm 等
命令,只能使用 cp 命令从内存拷贝到 Nor Flash,而且之前必须解除保护并擦除!命令如
下:
protect :对 Flash 写保护的操作,可以使能和解除写保护。
格式:
protect on/off start end
protect on/off start +end
protect on/off N:SF[-SL]
protect on/off bank N
protect on/off all
第 1 个参数 on 代表使能写保护;off 代表解除写保护。
第 2 、3 参数是指定 Flash 写保护操作范围
start end 是照起始地址和结束地址定义范围,start 是擦除块的起始地址;end 是擦除末
尾块的结束地址。
例如:擦除 Sector 2 和 Sector 3 区域命令为 erase 20000 3ffff 。
start +end 是照起始地址和操作字节数定义范围,这种方式最常用。start 是擦除块的起始
地址;end 是擦除的字节数。
例如:擦除 Sector 2 和 Sector 3 区域命令为 erase 20000 +20000
N:SF[-SL]是按照组和扇区,N 表示 Flash 的 Block 号,SF 表示擦除起始 Sector 号,SL
表示擦除结束 Sector 号。
例如:擦除 Block1 的 Sector 2 和 Sector 3 区域命令为 erase 1:2-3。
bank N 是擦除整个 Block,擦除 Block 号为 N 的整个 Flash。
all 是擦除全部 Flash。
注意:Nor Flash 擦除的最小单位是 Sector,也就是 0x10000 字节,如果你定义的大小
不满 1 Sector 或超过 Sector 的边界,那么被定义到的 Sector 会被全部擦除。
erase :擦除 Flash 的命令
格式:
erase start end
erase start +end
erase N:SF[-SL]
erase bank N
erase all
参数是指定 Flash 擦除操作范围,跟写保护的方式相同。
范例将 mini2440 的 Nor Flash 的 Sector 16 写保护,再解除保护,擦除数据,最后将起
始的 20 字节拷贝到 Sector 16。
[u-boot@MINI2440]# flinfo 1
Bank # 1: SST: 1x SST39VF1601 (2MB)
Size: 2 MB in 32 Sectors
Sector Start Addresses:
00000000 (RO) 00010000 (RO) 00020000 (RO) 00030000 (RO) 00040000
00050000
00060000 (RO) 00070000 (RO) 00080000
00090000
000A0000
000B0000
000C0000
000D0000
000E0000
000F0000
00100000
00110000
00120000
00130000
00140000
00150000
00160000
00170000
00180000
00190000
001A0000
001B0000
001C0000
001D0000
001E0000
001F0000
[u-boot@MINI2440]# protect on 1:16-16
Protect Flash Sectors 16-16 in Bank # 1
[u-boot@MINI2440]# flinfo 1
Bank # 1: SST: 1x SST39VF1601 (2MB)
Size: 2 MB in 32 Sectors
Sector Start Addresses:
00000000 (RO) 00010000 (RO) 00020000 (RO) 00030000 (RO) 00040000
00050000
00060000 (RO) 00070000 (RO) 00080000
00090000
000A0000
000B0000
000C0000
000D0000
000E0000
000F0000
00100000 (RO) 00110000
00120000
00130000
00140000
00150000
00160000
00170000
00180000
00190000
001A0000
001B0000
001C0000
001D0000
001E0000
001F0000
[u-boot@MINI2440]# protect off 0x100000 0x10ffff
Un-Protect Flash Sectors 16-16 in Bank # 1
[u-boot@MINI2440]# flinfo 1
Bank # 1: SST: 1x SST39VF1601 (2MB)
Size: 2 MB in 32 Sectors
Sector Start Addresses:
00000000 (RO) 00010000 (RO) 00020000 (RO) 00030000 (RO) 00040000
00050000
00060000 (RO) 00070000 (RO) 00080000
00090000
000A0000
000B0000
000C0000
000D0000
000E0000
000F0000
00100000
00110000
00120000
00130000
00140000
00150000
00160000
00170000
00180000
00190000
001A0000
001B0000
001C0000
001D0000
001E0000
001F0000
[u-boot@MINI2440]# erase 0x100000 +20
Erasing sector 16 ... ok.
Erased 1 sectors
[u-boot@MINI2440]# cp.b 0x0 0x100000 0x20
Copy to Flash... done
[u-boot@MINI2440]# md.b 100000 20
00100000: 12 00 00 ea 14 f0 9f e5 14 f0 9f e5 14 f0 9f e5 ................
00100010: 14 f0 9f e5 14 f0 9f e5 14 f0 9f e5 14 f0 9f e5 ................
4.2.8 USB 操作指令
指令
usb reset
usb stop [f]
usb tree
usb info [dev]
usb storage
usb dev [dev]
usb part [dev]
功能
初始化 USB 控制器
关闭 USB 控制器
已连接的 USB 设备树
显示 USB 设备[dev]的信息
显示已连接的 USB 存储设备
显示和设置当前 USB 存储设备
显示 USB 存储设备[dev]的分区信息
usb read addr blk# cnt
读取 USB 存储设备数据
我将一个 4G 的 kingstonU 盘(可引导盘)插入 mini2440,然后读取他的头 512 字节
(MBR):
[u-boot@MINI2440]#
usb reset
(Re)start USB...
USB: scanning bus for devices... 2 USB Device(s) found
scanning bus for storage devices... 1 Storage Device(s) found
[u-boot@MINI2440]# usb tree
Device Tree:
1 Hub (12 Mb/s, 0mA)
| OHCI Root Hub
|
+-2 Mass Storage (12 Mb/s, 100mA)
Kingston DT 101 II 0019E02CB6EB5B8B1B120051
[u-boot@MINI2440]# usb info
1: Hub, USB Revision 1.10
- OHCI Root Hub
- Class: Hub
- PacketSize: 8 Configurations: 1
- Vendor: 0x0000 Product 0x0000 Version 0.0
Configuration: 1
- Interfaces: 1 Self Powered 0mA
Interface: 0
- Alternate Setting 0, Endpoints: 1
- Class Hub
- Endpoint 1 In Interrupt MaxPacket 2 Interval 255ms
2: Mass Storage, USB Revision 2.0
- Kingston DT 101 II 0019E02CB6EB5B8B1B120051
- Class: (from Interface) Mass Storage
- PacketSize: 64 Configurations: 1
- Vendor: 0x0951 Product 0x1613 Version 1.0
Configuration: 1
- Interfaces: 1 Bus Powered 100mA
Interface: 0
- Alternate Setting 0, Endpoints: 2
- Class Mass Storage, Transp. SCSI, Bulk only
- Endpoint 1 In Bulk MaxPacket 64
- Endpoint 2 Out Bulk MaxPacket 64
[u-boot@MINI2440]# usb storage
Device 0: Vendor: Kingston Rev: PMAP Prod: DT 101 II
Type: Removable Hard Disk
Capacity: 3875.0 MB = 3.7 GB (7936000 x 512)
[u-boot@MINI2440]# usb dev 0
USB device 0:
Device 0: Vendor: Kingston Rev: PMAP Prod: DT 101 II
Type: Removable Hard Disk
Capacity: 3875.0 MB = 3.7 GB (7936000 x 512)
... is now current device
[u-boot@MINI2440]# usb part 0
print_part of 0
Partition Map for USB device 0 -- Partition Type: DOS
Partition
4
Start Sector
63
Num Sectors
7935937
Type
c
[u-boot@MINI2440]# usb read 0x30008000 0 200
USB read: device 0 block # 0, count 512 ... .........................
512 blocks read: OK
[u-boot@MINI2440]# md.b 0x30008000 200
30008000: fa 31 c0 8e d8 8e c0 8e d0 bc 00 7c fb fc 89 e6 .1.........|....
30008010: bf 00 06 b9 00 01 f3 a5 ea dc 06 00 00 10 00 01 ................
30008020: 00 00 7c 00 00 00 00 00 00 00 00 00 00 80 3f 00
..|...........?.
30008030: ff 00 ed 01 1e 0e 1f 3a 16 10 00 74 06 1f ea 36 .......:...t...6
30008040: e7 00 f0 3d fb 54 75 05 8c d8 fb eb 1d 80 fc 08 ...=.Tu.........
30008050: 75 1b e8 81 00 8a 36 13 00 fe ce 8b 0e 15 00 86
u.....6.........
30008060: cd c0 e1 06 0a 0e 11 00 31 c0 f8 eb 65 80 fc 02 ........1...e...
30008070: 72 cb 80 fc 04 77 c6 60 80 cc 40 50 be 00 00 c7 r....w.`..@P....
30008080: 04 10 00 30 e4 89 44 02 89 5c 04 8c 44 06 66 31
...0..D..\..D.f1
30008090: c0 66 89 44 0c 88 f0 f6 26 11 00 88 cf 88 eb c0 .f.D....&.......
300080a0: ef 06 81 e1 3f 00 01 c8 48 89 c7 a1 13 00 f7 26 ....?...H......&
300080b0: 11 00 f7 e3 01 f8 81 d2 00 00 89 44 08 89 54 0a ...........D..T.
300080c0: 58 30 c0 8a 16 10 00 e8 0c 00 88 26 03 00 61 a1
300080d0: 02 00 1f ca 02 00 9c ff 1e 22 00 c3 80 fa 8f 7f
X0.........&..a.
........."......
300080e0: 04 88 16 2d 06 be 87 07 e8 8d 00 be be 07 31 c0
...-..........1.
300080f0: b9 04 00 f6 04 80 74 03 40 89 f5 81 c6 10 00 e2 ......t.@.......
30008100: f2 48 74 02 cd 18 bf 05 00 be 1d 06 c7 44 02 01 .Ht..........D..
30008110: 00 66 8b 46 08 66 89 44 08 b8 00 42 8a 16 2d 06 .f.F.f.D...B..-.
30008120: cd 13 73 0d 4f 74 49 30 e4 8a 16 2d 06 cd 13 eb ..s.OtI0...-....
30008130: d8 a1 fe 7d 3d 55 aa 75 37 fa 66 a1 4c 00 66 a3 ...}=U.u7.f.L.f.
30008140: 3f 06 be 13 04 8b 04 48 89 04 c1 e0 06 8e c0 31 ?......H.......1
30008150: ff be 1d 06 b9 60 00 fc f3 a5 c7 06 4c 00 17 00
.....`......L...
30008160: a3 4e 00 fb 8a 16 2d 06 89 ee fa ea 00 7c 00 00 .N....-......|..
30008170: be aa 07 e8 02 00 eb fe ac 20 c0 74 09 b4 0e bb ......... .t....
30008180: 07 00 cd 10 eb f2 c3 53 74 61 72 74 20 62 6f 6f .......Start boo
30008190: 74 69 6e 67 20 66 72 6f 6d 20 55 53 42 20 64 65 ting from USB de
300081a0: 76 69 63 65 2e 2e 2e 0d 0a 00 42 6f 6f 74 20 66 vice......Boot f
300081b0: 61 69 6c 65 64 00 00 00 ea eb d4 ca 00 00 00 00 ailed...........
300081c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
300081d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
300081e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 80 01 ................
300081f0: 01 00 0c fe 7f ec 3f 00 00 00 c1 17 79 00 55 aa
......?.....y.U.
在所有的命令使用前,必须先插入 USB 设备,然后使用:usb reset,以初始化 USB 控
制器,获取设备信息。
4.2.9 SD 卡(MMC)指令
[u-boot@MINI2440]# ? mmc
mmc - MMC sub-system
Usage:
mmc init [dev] - init MMC sub system
mmc device [dev] - show or set current device
SD 卡的使用命令比较简单,只有初始化和设备信息的显示,读写是通过文件系统命令实
现的。
使用和 USB 类似,在所有的命令使用前,必须先插入 SD 卡,然后使用:mmc init,以
初始化 MMC 控制器,获取设备信息。
我在 mini2440 中插入 1GB SD 卡:
[u-boot@MINI2440]# mmc init
mmc: Probing for SDHC ...
mmc: SD 2.0 or later card found
trying to detect SD Card...
Manufacturer: 0x00, OEM "Product name:
Serial number:
"
7864775
Manufacturing date: 11/2006
CRC:
0x4f, b0 = 1
READ_BL_LEN=6, C_SIZE_MULT=7, C_SIZE=4095
size = 0
SD Card detected RCA: 0x2 type: SD
mmc1 is available
[u-boot@MINI2440]# mmc device
mmc1 is current device
", revision 0.0
FAT 文件系统指令
4.2.10
fatinfo:显示文件系统的相关信息
格式:fatinfo
Interface:代表接口,如 usb、mmc;
dev:代表设备编号,如 0、1......;
part:代表存储设备中的分区,如 1、2......。
fatload:从 FAT32 文件系统中读取二进制文件到 SDRAM。
格式:fatload [bytes]
Interface、dev 和 part 同上;
addr:代表写入 SDRAM 的地址;
filename:代表存储设备中的文件名;
bytes:代表从存储设备中读取的文件大小,可不填;如果填的数据比文件小,就只读取
bytes 字节,如果填的数据比文件大,也只读取文件的大小。
fatls:列出 FAT32 文件系统中目录里的文件。
格式:fatls [directory]
Interface、dev 和 part 同上;
directoryr:代表所要查看的目录,可不填,默认为/。
这些指令基本上要和 U 盘或者 SD 卡同时使用,主要用于读取这些移动存储器上的
FAT32 分区。
使用范例:
[u-boot@MINI2440]# usb part 0
print_part of 0
Partition Map for USB device 0 -- Partition Type: DOS
Partition
Start Sector
4
63
Num Sectors
7935937
Type
c
[u-boot@MINI2440]# fatinfo usb 0:4
Interface: USB
Device 0: Vendor: Kingston Rev: PMAP Prod: DT 101 II
Type: Removable Hard Disk
Capacity: 3875.0 MB = 3.7 GB (7936000 x 512)
Partition 4: Filesystem: FAT32 "7600_16385_"
[u-boot@MINI2440]# fatls usb 0:4
boot/
efi/
sources/
support/
upgrade/
43 autorun.inf
383562 bootmgr
111880 setup.exe
256220 u-boot.bin
4 file(s), 5 dir(s)
[u-boot@MINI2440]# fatls usb 0:4 /boot/
./
../
fonts/
zh-cn/
262144 bcd
3170304 boot.sdi
1024 bootfix.bin
97280 bootsect.exe
4096 etfsboot.com
485440 memtest.exe
6 file(s), 4 dir(s)
[u-boot@MINI2440]# fatload usb 0:4 0x30008000 u-boot.bin
reading u-boot.bin
........................
256220 bytes read
[u-boot@MINI2440]# fatload usb 0:4 0x30008000 u-boot.bin 200
reading u-boot.bin
512 tes read
4.2.11 系统引导指令
boot 和 bootd 都是运行 ENV”bootcmd”中指定的指令。
bootm 指令是专门用于启动在 SDRAM 中的用 U-boot 的 mkimage 工具处理过的内核映
像。
格式:bootm [addr [arg ...]]
addr 是内核映像所在的 SDRAM 中的地址
当启动的是 Linux 内核时,'arg' 可以使 initrd 的地址。
范例:
[u-boot@MINI2440]# setenv bootcmd tftp\;bootm
[u-boot@MINI2440]# saveenv
Saving Environment to NAND...
Erasing Nand...
Erasing at 0x6000000000002 -- 0% complete.
Writing to Nand... done
[u-boot@MINI2440]# boot
dm9000 i/o: 0x20000300, id: 0x90000a46
DM9000: running in 16 bit mode
MAC: 08:08:11:18:12:27
operating at 100M full duplex mode
Using dm9000 device
TFTP from server 192.168.1.100; our IP address is 192.168.1.101
Filename 'zImage.img'.
Load address: 0x30008000
Loading: T #################################################################
#################################################################
##########################
done
Bytes transferred = 2277540 (22c0a4 hex)
## Booting kernel from Legacy Image at 30008000 ...
Image Name: tekkaman
Created:
2010-03-29 12:59:51 UTC
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 2277476 Bytes = 2.2 MB
Load Address: 30008000
Entry Point: 30008040
Verifying Checksum ... OK
XIP Kernel Image ... OK
OK
Starting kernel ...
Uncompressing Linux... done, booting the kernel.
Linux version 2.6.33.1 (tekkaman@MAGI-Linux) (gcc version 4.3.2 (crosstool-NG-1.6.1-tekkaman) ) #5 Mon
Mar 29 20:58:50 CST 2010
CPU: ARM920T [41129200] revision 0 (ARMv4T), cr=c0007177
CPU: VIVT data cache, VIVT instruction cache
Machine: MINI2440
(略)
U-Boot 2009.11 ( 4 月 04 2010 - 12:09:25)
modified by tekkamanninja (tekkamanninja@163.com)
Love Linux forever!!
I2C: ready
DRAM: 64 MB
Flash: 2 MB
NAND: 128 MiB
Video: 240x320x16 20kHz 62Hz
In: serial
Out: serial
Err: serial
Net: dm9000
U-Boot 2009.11 ( 4 月 04 2010 - 12:09:25)
modified by tekkamanninja
(tekkamanninja@163.com)
Love Linux forever!!
Hit any key to stop autoboot: 0
[u-boot@MINI2440]# bootd
dm9000 i/o: 0x20000300, id: 0x90000a46
DM9000: running in 16 bit mode
MAC: 08:08:11:18:12:27
operating at 100M full duplex mode
Using dm9000 device
TFTP from server 192.168.1.100; our IP address is 192.168.1.101
Filename 'zImage.img'.
Load address: 0x30008000
Loading: T #################################################################
#################################################################
##########################
done
Bytes transferred = 2277540 (22c0a4 hex)
## Booting kernel from Legacy Image at 30008000 ...
Image Name: tekkaman
Created:
2010-03-29 12:59:51 UTC
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 2277476 Bytes = 2.2 MB
Load Address: 30008000
Entry Point: 30008040
Verifying Checksum ... OK
XIP Kernel Image ... OK
OK
Starting kernel ...
(略)
4.2.13 其他指令
run
-运一个 ENV 定义的命令脚本。
使用范例:
[u-boot@MINI2440]# setenv a_run_test echo $bootfile \; version
[u-boot@MINI2440]# run a_run_test
zImage.img
U-Boot 2009.11 ( 4月 04 2010 - 12:09:25)
reset - 重启 CPU
其他指令,可以用“help”查到用法。
4.3 下载与烧写
使用 U-boot 将映像文件烧写到板上的 Flash,一般步骤是:
(1)通过网络、串口、U 盘、SD 卡等方式将文件传输到 SDRAM;
(2)使用 Nand Flash 或 Nor Flash 相关的读写命令将 SDRAM 中的数据烧入 Flash。
下面是烧写范例:
如果使用 SD 卡和 U 盘形式更新 U-boot,那么首先 SD 卡和 U 盘中必须有 FAT32 文件
系统,并在里面存放了 u-boot.bin 文件。
4.3.1 通过 SD 卡烧入 Nand Flash:
[u-boot@MINI2440]# mmc init
mmc: Probing for SDHC ...
mmc: SD 2.0 or later card found
trying to detect SD Card...
Manufacturer:
0x00, OEM "Product name:
" ", revision 0.0
Serial number:
7864775
Manufacturing date: 11/2006
CRC:
0x4f, b0 = 1
READ_BL_LEN=6, C_SIZE_MULT=7, C_SIZE=4095
size = 0
SD Card detected RCA: 0x2 type: SD
mmc1 is available
[u-boot@MINI2440]# fatload mmc 1 0x30008000 u-boot.bin
reading u-boot.bin
256220 bytes read
[u-boot@MINI2440]# nand erase 0 0x40000
NAND erase: device 0 offset 0x0, size 0x40000
Erasing at 0x2000000000004 -- 0% complete.
OK
[u-boot@MINI2440]# nand write 0x30008000 0 0x40000
NAND write: device 0 offset 0x0, size 0x40000
Writing at 0x2000000020000 -- 100% is complete. 262144 bytes written: OK
4.3.2 通过 U 盘烧入 Nor Flash:
[u-boot@MINI2440]# usb start
(Re)start USB...
USB: scanning bus for devices... 2 USB Device(s) found
scanning bus for storage devices... 1 Storage Device(s) found
[u-boot@MINI2440]# usb storage
Device 0: Vendor: Kingston Rev: PMAP Prod: DT 101 II
Type: Removable Hard Disk
Capacity: 3875.0 MB = 3.7 GB (7936000 x 512)
[u-boot@MINI2440]# usb part 0
print_part of 0
Partition Map for USB device 0 -- Partition Type: DOS
Partition Start Sector Num Sectors Type
4
63 7935937
c
[u-boot@MINI2440]# fatload usb 0:4 0x30008000 u-boot.bin
reading u-boot.bin
........................
256220 bytes read
[u-boot@MINI2440]# protect off all
Un-Protect Flash Bank # 1
[u-boot@MINI2440]# erase 0x0 0x3ffff
Erasing sector 0 ... ok.
Erasing sector 1 ... ok.
Erasing sector 2 ... ok.
Erasing sector 3 ... ok.
Erased 4 sectors
[u-boot@MINI2440]# cp.b 0x30008000 0x0 0x3ffff
Copy to Flash... done
4.3.3 通过 TFTP 服务烧入 Nand Flash:
[u-boot@MINI2440]# tftpboot 30008000 192.168.1.100:u-boot.bin
dm9000 i/o: 0x20000300, id: 0x90000a46
DM9000: running in 16 bit mode
MAC: 08:08:11:18:12:27
operating at 100M full duplex mode
Using dm9000 device
TFTP from server 192.168.1.100; our IP address is 192.168.1.101
Filename 'u-boot.bin'.
Load address: 0x30008000
Loading: T ##################
done
Bytes transferred = 256220 (3e8dc hex)
[u-boot@MINI2440]# nand erase 0 0x40000
NAND erase: device 0 offset 0x0, size 0x40000
Erasing at 0x2000000000004 -- 0% complete.
OK
[u-boot@MINI2440]# nand write 0x30008000 0 0x40000
NAND write: device 0 offset 0x0, size 0x40000
Writing at 0x2000000020000 -- 100% is complete. 262144 bytes written: OK
4.3.4 通过 NFS 服务烧入 Nand Flash:
[u-boot@MINI2440]# nfs 30008000 192.168.1.100:/home/tekkaman/development/share/u-boot.bin
dm9000 i/o: 0x20000300, id: 0x90000a46
DM9000: running in 16 bit mode
MAC: 08:08:11:18:12:27
operating at 100M full duplex mode
Using dm9000 device
File transfer via NFS from server 192.168.1.100; our IP address is 192.168.1.101
Filename '/home/tekkaman/development/share/u-boot.bin'.
Load address: 0x30008000
Loading: ###################################################
done
Bytes transferred = 256220 (3e8dc hex)
[u-boot@MINI2440]# nand erase 0 0x40000
NAND erase: device 0 offset 0x0, size 0x40000
Erasing at 0x2000000000004 -- 0% complete.
OK
[u-boot@MINI2440]# nand write 0x30008000 0 0x40000
NAND write: device 0 offset 0x0, size 0x40000
Writing at 0x2000000020000 -- 100% is complete. 262144 bytes written: OK
4.4 内核引导
内核的引导步骤如下:
(1)用 U-boot 的 mkimage 工具处理内核映像 zImage。
(2)通过网络、串口、U 盘、SD 卡等方式将处理过的内核映像传输到 SDRAM 的一定
位置(一般使用 0x30008000)
(3)然后使用”bootm"等内核引导命令来启动内核。
为什么要用 U-boot 的 mkimage 工具处理内核映像 zImage?
因为在用 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 指定制作映象的源文件
以下是制作内核映像的命令示例:
mkimage -n 'tekkaman' -A arm -O linux -T kernel -C none -a 0x30008000 -e
0x30008040 -d zImage zImage.img
以下是使用范例:
4.4.1 通过 SD 卡引导内核:
首先 SD 卡中必须有 FAT32 文件系统,并在里面存放了处理过的内核映像文件。
[u-boot@MINI2440]# mmc init
mmc: Probing for SDHC ...
mmc: SD 2.0 or later card found
trying to detect SD Card...
Manufacturer:
0x00, OEM "Product name:
" ", revision 0.0
Serial number:
7864775
Manufacturing date: 11/2006
CRC:
0x4f, b0 = 1
READ_BL_LEN=6, C_SIZE_MULT=7, C_SIZE=4095
size = 0
SD Card detected RCA: 0x2 type: SD
mmc1 is available
[u-boot@MINI2440]# fatload mmc 1 30008000 zImage.img
reading zImage.img
2277540 bytes read
[u-boot@MINI2440]# bootm 30008000
## Booting kernel from Legacy Image at 30008000 ...
Image Name: tekkaman
Created:
2010-03-29 12:59:51 UTC
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 2277476 Bytes = 2.2 MB
Load Address: 30008000
Entry Point: 30008040
Verifying Checksum ... OK
XIP Kernel Image ... OK
OK
Starting kernel ...
Uncompressing Linux... done, booting the kernel.
Linux version 2.6.33.1 (tekkaman@MAGI-Linux) (gcc version 4.3.2 (crosstool-NG-1.6.1-tekkaman) ) #5 Mon
Mar 29 20:58:50 CST 2010
CPU: ARM920T [41129200] revision 0 (ARMv4T), cr=c0007177
CPU: VIVT data cache, VIVT instruction cache
Machine: MINI2440
(略)
4.4.2 通过 TFTP 服务引导内核
[u-boot@MINI2440]# tftpboot 0x30008000 192.168.1.100:zImage.img
dm9000 i/o: 0x20000300, id: 0x90000a46
DM9000: running in 16 bit mode
MAC: 08:08:11:18:12:27
operating at 100M full duplex mode
Using dm9000 device
TFTP from server 192.168.1.100; our IP address is 192.168.1.101
Filename 'zImage.img'.
Load address: 0x30008000
Loading: T #################################################################
#################################################################
##########################
done
Bytes transferred = 2277540 (22c0a4 hex)
[u-boot@MINI2440]# bootm 30008000
## Booting kernel from Legacy Image at 30008000 ...
Image Name: tekkaman
Created:
2010-03-29 12:59:51 UTC
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 2277476 Bytes = 2.2 MB
Load Address: 30008000
Entry Point: 30008040
Verifying Checksum ... OK
XIP Kernel Image ... OK
OK
Starting kernel ...
Uncompressing Linux... done, booting the kernel.
Linux version 2.6.33.1 (tekkaman@MAGI-Linux) (gcc version 4.3.2 (crosstool-NG-1.6.1-tekkaman) ) #5 Mon
Mar 29 20:58:50 CST 2010
CPU: ARM920T [41129200] revision 0 (ARMv4T), cr=c0007177
CPU: VIVT data cache, VIVT instruction cache
Machine: MINI2440
(略)
4.4.3 通过 NFS 服务引导内核:
[u-boot@MINI2440]# nfs 30008000 192.168.1.100:/home/tekkaman/development/share/zImage.img
dm9000 i/o: 0x20000300, id: 0x90000a46
DM9000: running in 16 bit mode
MAC: 08:08:11:18:12:27
operating at 100M full duplex mode
Using dm9000 device
File transfer via NFS from server 192.168.1.100; our IP address is 192.168.1.101
Filename '/home/tekkaman/development/share/zImage.img'.
Load address: 0x30008000
Loading: #################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#######################################################
done
Bytes transferred = 2277540 (22c0a4 hex)
[u-boot@MINI2440]# bootm 30008000
## Booting kernel from Legacy Image at 30008000 ...
Image Name: tekkaman
Created:
2010-03-29 12:59:51 UTC
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 2277476 Bytes = 2.2 MB
Load Address: 30008000
Entry Point: 30008040
Verifying Checksum ... OK
XIP Kernel Image ... OK
OK
Starting kernel ...
Uncompressing Linux... done, booting the kernel.
Linux version 2.6.33.1 (tekkaman@MAGI-Linux) (gcc version 4.3.2 (crosstool-NG-1.6.1-tekkaman) ) #5 Mon
Mar 29 20:58:50 CST 2010
CPU: ARM920T [41129200] revision 0 (ARMv4T), cr=c0007177
CPU: VIVT data cache, VIVT instruction cache
Machine: MINI2440
(略)
4.4.4 通过 Nand Flash 引导内核:
首先要将处理过的内核映像文件烧入 Nand Flash 的一定位置(由内核分区表决定)。以
后每次启动时用 Nand Flash 的读取命令先将这个内核映像文件读到内存的一定位置(由制作
内核映像时的-a 参数决定),再使用 bootm 命令引导内核。
内核映像文件的烧入:
[u-boot@MINI2440]# nfs 30008000 192.168.1.100:/home/tekkaman/development/share/zImage.img
dm9000 i/o: 0x20000300, id: 0x90000a46
DM9000: running in 16 bit mode
MAC: 08:08:11:18:12:27
operating at 100M full duplex mode
Using dm9000 device
File transfer via NFS from server 192.168.1.100; our IP address is 192.168.1.101
Filename '/home/tekkaman/development/share/zImage.img'.
Load address: 0x30008000
Loading: #################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#######################################################
done
Bytes transferred = 2277540 (22c0a4 hex)
[u-boot@MINI2440]# nand erase 0x80000 0x300000
NAND erase: device 0 offset 0x80000, size 0x300000
Erasing at 0x36000001800000 -- 0% complete.
OK
[u-boot@MINI2440]# nand write 30008000 0x80000 300000
NAND write: device 0 offset 0x80000, size 0x300000
Writing at 0x36000000020000 -- 100% is complete. 3145728 bytes written: OK
内核引导:
[u-boot@MINI2440]# nand read 30008000 0x80000 300000
NAND read: device 0 offset 0x80000, size 0x300000
3145728 bytes read: OK
[u-boot@MINI2440]# bootm 30008000
## Booting kernel from Legacy Image at 30008000 ...
Image Name: tekkaman
Created:
2010-03-29 12:59:51 UTC
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 2277476 Bytes = 2.2 MB
Load Address: 30008000
Entry Point: 30008040
Verifying Checksum ... OK
XIP Kernel Image ... OK
OK
Starting kernel ...
Uncompressing Linux... done, booting the kernel.
Linux version 2.6.33.1 (tekkaman@MAGI-Linux) (gcc version 4.3.2 (crosstool-NG-1.6.1-tekkaman) ) #5 Mon
Mar 29 20:58:50 CST 2010
CPU: ARM920T [41129200] revision 0 (ARMv4T), cr=c0007177
CPU: VIVT data cache, VIVT instruction cache
Machine: MINI2440
(略)
第5章
U-boot 源码简要分析
本次移植使用的是 U-boot-2009.11。
先来看看源码目录结构,再按照代码的执行顺序简单地分析源码。
5.1 U-boot 源码整体框架
源码解压以后,我们可以看到以下的文件和文件夹:
cpu
board
common
drivers
disk
fs
net
include
doc
lib_arm
lib_avr32
lib_blackfin
lib_generic
lib_i386
lib_m68k
lib_microblaze
api
examples
与处理器相关的文件。每个子目录中都包括 cpu.c 和
interrupt.c、start.S、u-boot.lds。
cpu.c 初始化 CPU、设置指令 Cache 和数据 Cache 等
interrupt.c 设置系统的各种中断和异常
start.S 是 U-boot 启动时执行的第一个文件,它主要做最早其
的系统初始化,代码重定向和设置系统堆栈,为进入 U-boot
第二阶段的 C 程序奠定基础
u-boot.lds 链接脚本文件,对于代码的最后组装非常重要
已经支持的所有开发板相关文件,其中包含 SDRAM 初始化代
码、Flash 底层驱动、板级初始化文件。
其中的 config.mk 文件定义了 TEXT_BASE,也就是代码在
内存的其实地址,非常重要。
与处理器体系结构无关的通用代码,U-boot 的命令解析代码
/common/command.c、所有命令的上层代码 cmd_*.c、U-
boot 环境变量处理代码 env_*.c、等都位于该目录下
包含几乎所有外围芯片的驱动,网卡、USB、串口、LCD、
Nand Flash 等等
支持的 CPU 无关的重要子系统:
磁盘驱动的分区处理代码
文件系统:FAT、JFFS2、EXT2 等
网络协议:NFS、TFTP、RARP、DHCP 等等
头文件,包括各 CPU 的寄存器定义,文件系统、网络等等
configs 子目录下的文件是与目标板相关的配置头文件
U-Boot 的说明文档,在修改配置文件的时候可能用得上
处理器体系相关的初始化文件
lib_mips lib_nios 比较重要的是其中的 board.c 文件,几乎是 U-boot 的所有架
lib_nios2
构第二阶段代码入口函数和相关初始化函数存放的地方。
lib_ppc
lib_sh
lib_sparc
外部扩展应用程序的 API 和范例
一些特殊构架需要的启动代码和上电自检程序代码
nand_spl
onenand_ipl
post
libfdt
支持平坦设备树(flattened device trees)的库文件
编译 S-Record 或 U-Boot 映像等相关工具,制作 bootm 引导
的内核映像文件工具 mkimage 源码就在此
控制整个编译过程的主 Makefile 文件和规则文件
tools
Makefile
MAKEALL
config.mk
rules.mk
mkconfig
CHANGELOG
CHANGELOG-before-U-Boot-1.1.5
COPYING
CREDITS
MAINTAINERS
README
一些介绍性的文档、版权说明
标为红色的是移植时比较重要的文件或文件夹。
5.2 Uboot 代码的大致执行流程(以 S3C24x0 为例)
从链接脚本文件 u-boot.lds 中可以找到代码的起始:
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
OUTPUT_ARCH(arm)
ENTRY(_start)
SECTIONS
{
. = 0x00000000;
. = ALIGN(4);
.text :
{
cpu/arm920t/start.o
*(.text)
}
(.text)
......
从中知道程序的入口点是_start,定位于 cpu/arm920t /start.S(即 u-boot 启动的第一阶
段)。
下面我们来仔细分析一下 start.S。(请对照数据手册阅读源码)
#include
#include
/*
*************************************************************************
*
* Jump vector table as in table 3.1 in [1]
*
*************************************************************************
*/
.globl _start
_start:
b
ldr
ldr
ldr
ldr
start_code
pc, _undefined_instruction
pc, _software_interrupt
pc, _prefetch_abort
pc, _data_abort
//位于\include 目录下是一个包含其他头文件的
头文件
//位于\include\linux 目录下
u-boot 的主入口,跳入了后面的 start_code
ldr
ldr
ldr
pc, _not_used
pc, _irq
pc, _fiq
_undefined_instruction:
.word undefined_instruction
_software_interrupt: .word software_interrupt
_prefetch_abort:
.word prefetch_abort
_data_abort:
.word data_abort
_not_used:
.word not_used
_irq:
.word irq
_fiq:
.word fiq
.balignl 16,0xdeadbeef
/*
*************************************************************************
*
* Startup Code (called from the ARM reset exception vector)
*
* do important init only if we don't start from memory!
* relocate armboot to ram
* setup stack
* jump to second stage
*
*************************************************************************
*/
_TEXT_BASE:
.word
TEXT_BASE
这些是跳转向量表,和芯片的体系结构有关
ldr 语句的意思是将第二个操作数(如:
_undefined_instruction)指向的地址数据传给
PC
.word 为定义一个 4 字节的空间
undefined_instruction 为地址, 即后面标号所
对的偏移地址数据
16 字节对齐,并以 0xdeadbeef 填充,它是个
Magic number 。
这些和上面的一样,定义一个 4 字节的空间存
放地址
.globl _armboot_start
_armboot_start:
.word _start
/*
* These are defined in the board-specific linker script.
*/
.globl _bss_start
_bss_start:
.word __bss_start
.globl _bss_end
_bss_end:
.word _end
#ifdef CONFIG_USE_IRQ
/* IRQ stack memory (calculated at run-time) */
.globl IRQ_STACK_START
IRQ_STACK_START:
.word
0x0badc0de
/* IRQ stack memory (calculated at run-time) */
.globl FIQ_STACK_START
FIQ_STACK_START:
.word 0x0badc0de
#endif
/*
* the actual start code
*/
start_code:
/*
* set the cpu to SVC32 mode
*/
mrs
r0, cpsr
bic
r0, r0, #0x1f
orr
r0, r0, #0xd3
msr
cpsr, r0
bl
bl
coloured_LED_init
red_LED_on
代码从这里开始执行!!
让系统进入 SVC(管理员模式)
这些都是为 AT91RM9200 写的
#if
defined(CONFIG_AT91RM9200DK) || defined(CONFIG_AT91RM9200EK)
/*
* relocate exception table
*/
ldr
r0, =_start
ldr
r1, =0x0
mov
r2, #16
copyex:
subs
ldr
str
bne
r2, r2, #1
r3, [r0], #4
r3, [r1], #4
copyex
#endif
#if defined(CONFIG_S3C2400) || defined(CONFIG_S3C2410)
/* turn off the watchdog */
# if defined(CONFIG_S3C2400)
# define pWTCON 0x15300000
# define INTMSK 0x14400008
/* Interupt-Controller base addresses */
# define CLKDIVN 0x14800014
/* clock divisor register */
#else
# define pWTCON 0x53000000
# define INTMSK 0x4A000008
/* Interupt-Controller base addresses */
# define INTSUBMSK
0x4A00001C
# define CLKDIVN 0x4C000014
/* clock divisor register */
# endif
ldr
mov
str
系统时钟的寄存器地址定义
r0, =pWTCON
r1, #0x0
r1, [r0]
关闭看门狗
/*
* mask all IRQs by setting all bits in the INTMR - default
*/
mov
r1, #0xffffffff
ldr
r0, =INTMSK
str
r1, [r0]
# if defined(CONFIG_S3C2410)
ldr
r1, =0x3ff
ldr
r0, =INTSUBMSK
str
r1, [r0]
# endif
#endif
关闭所有中断
/* FCLK:HCLK:PCLK = 1:2:4 */
/* default FCLK is 120 MHz ! */
ldr
r0, =CLKDIVN
mov
r1, #3
str
r1, [r0]
/* CONFIG_S3C2400 || CONFIG_S3C2410 */
设置时钟的分频比
/*
* we do sys-critical inits only at reboot,
* not when booting from ram!
*/
#ifndef CONFIG_SKIP_LOWLEVEL_INIT
bl
cpu_init_crit
#endif
跳入 cpu_init_crit ,这是一个系统初始化函
数,他还会调用 board/*/lowlevel_init.S 中的
lowlevel_init 函数。
主要是对系统总线的初始化,初始化了连接存
储器的位宽、速度、刷新率等重要参数。经过
#ifndef CONFIG_SKIP_RELOCATE_UBOOT
relocate:
/* relocate U-Boot to RAM
*/
这个函数的正确初始化,Nor Flash、SDRAM
adr
r0, _start
/* r0 <- current position of code */
才可以被系统使用。下面的代码重定向就依赖
ldr
r1, _TEXT_BASE
/* test if we run from flash or RAM */
cmp
r0, r1
/* don't reloc during debug
*/ 它。
代码重定向,它首先检测自己是否已经在内存
beq
stack_setup
中:
ldr
r2, _armboot_start
如果是直接跳到下面的堆栈初始化代码
ldr
r3, _bss_start
stack_setup。
sub
r2, r3, r2
/* r2 <- size of armboot
*/
如果不是就将自己从 Nor Flash 中拷贝到内存
add
r2, r0, r2
/* r2 <- source end address
*/
中
copy_loop:
ldmia
*/
stmia
r0!, {r3-r10} /* copy from source address [r0]
r1!, {r3-r10} /* copy to target address [r1]
*/
#endif
*/ 自拷贝循环
cmp
r0, r2
/* until source end addreee [r2]
ble
copy_loop
/* CONFIG_SKIP_RELOCATE_UBOOT */
请注意看英文注释
/* Set up the stack
*/
stack_setup:
ldr
r0, _TEXT_BASE /* upper 128 KiB: relocated uboot */
sub
r0, r0, #CONFIG_SYS_MALLOC_LEN /* malloc area
*/
sub
r0, r0, #CONFIG_SYS_GBL_DATA_SIZE /* bdinfo
*/
堆栈初始化代码(为第二阶段的 C 语言做准
#ifdef CONFIG_USE_IRQ
sub
r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ) 备)
#endif
sub
sp, r0, #12
/* leave 3 words for abort-stack */
clear_bss: r0, _bss_start
ldr r1, _bss_end
ldr r2, #0x00000000
mov
clbss_l:str r2, [r0] r0, r0, #4
add r0, r1
cmp clbss_l
ble
ldr
_start_armboot:
/* clear loop...
/* find start of bss segment
/* stop here
*/
/* clear
*/
*/
pc, _start_armboot
.word start_armboot
/*
*************************************************************************
*
* CPU_init_critical registers
*
* setup important registers
* setup memory timing
*
*************************************************************************
*/
#ifndef CONFIG_SKIP_LOWLEVEL_INIT
cpu_init_crit:
/*
* flush v4 I/D caches
*/
mov
r0, #0
mcr
p15, 0, r0, c7, c7, 0 /* flush v3/v4 cache */
mcr
p15, 0, r0, c8, c7, 0 /* flush v4 TLB */
/*
* disable MMU stuff and caches
*/
mrc
p15, 0, r0, c1, c0, 0
bic
r0, r0, #0x00002300 @ clear bits 13, 9:8 (--V- --RS)
bic
r0, r0, #0x00000087 @ clear bits 7, 2:0 (B--- -CAM)
orr
r0, r0, #0x00000002 @ set bit 2 (A) Align
orr
r0, r0, #0x00001000 @ set bit 12 (I) I-Cache
mcr
p15, 0, r0, c1, c0, 0
*/
对 BSS 段清零(为第二阶段的 C 语言做准
备)
BSS 段(bss segment)通常是用来存放程序
中未初始化的全局变量的一块内存区域。BSS
是英文 Block Started by Symbol 的简称。BSS
段属于静态内存分配。在编译时,编译器已经
为他们分配好了空间,只不过他们的值为 0,
为了节省空间,在 bin 或 ELF 文件中不占空
间。
编译器会计算出_bss_start 和_bss_end 的值,
不是定义的
跳入第二阶段的 C 语言代码入口
_start_armboot (已经被重定向到内存)
前面所说的 cpu_init_crit 系统初始化函数
操作 CP15 协处理器,
/*
* before relocating, we have to setup RAM timing
* because memory timing is board-dependend, you will
* find a lowlevel_init.S in your board directory.
*/
mov
ip, lr
bl
lowlevel_init
mov
lr, ip
mov
pc, lr
#endif /* CONFIG_SKIP_LOWLEVEL_INIT */
......
调用 board/*/lowlevel_init.S 中的 lowlevel_init
函数,对系统总线的初始化,初始化了连接存
储器的位宽、速度、刷新率等重要参数。经过
这个函数的正确初始化,Nor Flash、SDRAM
才可以被系统使用。
后面的代码略,主要是中断相关代码,但是 U-
boot 基本不使用中断所以暂且略过。
现在我们再来看看 lib_arm/board.c 中的第二阶段入口函数 start_armboot :
void start_armboot (void)
{
init_fnc_t **init_fnc_ptr;
char *s;
#if defined(CONFIG_VFD) || defined(CONFIG_LCD)
unsigned long addr;
#endif
/* Pointer is writable since we allocated a register for it */
gd = (gd_t*)(_armboot_start - CONFIG_SYS_MALLOC_LEN -
sizeof(gd_t));
/* compiler optimization barrier needed for GCC >= 3.4 */
__asm__ __volatile__("": : :"memory");
memset ((void*)gd, 0, sizeof (gd_t));
gd->bd = (bd_t*)((char*)gd - sizeof(bd_t));
memset (gd->bd, 0, sizeof (bd_t));
gd->flags |= GD_FLG_RELOC;
monitor_flash_len = _bss_start - _armboot_start;
for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
if ((*init_fnc_ptr)() != 0) {
hang ();
}
}
/* armboot_start is defined in the board-specific linker script */
mem_malloc_init (_armboot_start - CONFIG_SYS_MALLOC_LEN,
CONFIG_SYS_MALLOC_LEN);
#ifndef CONFIG_SYS_NO_FLASH
/* configure available FLASH banks */
display_flash_config (flash_init ());
#endif /* CONFIG_SYS_NO_FLASH */
#ifdef CONFIG_VFD
#
ifndef PAGE_SIZE
#
define PAGE_SIZE 4096
#
endif
/*
* reserve memory for VFD display (always full pages)
*/
/* bss_end is defined in the board-specific linker script */
addr = (_bss_end + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1);
vfd_setmem (addr);
gd->fb_base = addr;
#endif /* CONFIG_VFD */
#ifdef CONFIG_LCD
/* board init may have inited fb_base */
if (!gd->fb_base) {
gd_t 和 bd_t 这两个数据结
构比较重要,建议大家看
看。
分配一个存储全局数据的区域,地
址给指针 gd
全局数据的区清零
给 gd->bd(指针)赋值(在 gd 的
前面)并清零
gd->flags 赋值,表示已经重定向
(在内存中)
monitor_flash_len 为 u-boot 代码长
度。
初始化循环:
init_sequence 是一个初始化函数
集的函数指针数组(后面讲解)
如果有任何一个函数失败就进入死
循环。
这个始化函数集比较重要,
建议大家认真跟踪一下。
初始化堆空间,清零。
初始化 Nor Flash 相关参数,并显
示其大小。
初始化 VFD 存储区(LCD 显示相
关)
#
#
#
ifndef PAGE_SIZE
define PAGE_SIZE 4096
endif
/*
* reserve memory for LCD display (always full pages)
*/
/* bss_end is defined in the board-specific linker script */
addr = (_bss_end + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1);
lcd_setmem (addr);
gd->fb_base = addr;
初始化 LCD 显存
}
#endif /* CONFIG_LCD */
#if defined(CONFIG_CMD_NAND)
puts ("NAND: ");
nand_init();
/* go init the NAND */
#endif
#if defined(CONFIG_CMD_ONENAND)
onenand_init();
#endif
#ifdef CONFIG_HAS_DATAFLASH
AT91F_DataflashInit();
dataflash_print_info();
#endif
/* initialize environment */
env_relocate ();
#ifdef CONFIG_VFD
/* must do this after the framebuffer is allocated */
drv_vfd_init();
#endif /* CONFIG_VFD */
#ifdef CONFIG_SERIAL_MULTI
serial_initialize();
#endif
/* get the devices list going. */
jumptable_init ();
#if defined(CONFIG_API)
/* Initialize API */
api_init ();
#endif
console_init_r ();
初始化 OneNand
初始化 DataFlash
初始化环境变量,如果认为没有找
到存储其中的,就用默认值并打
印:“*** Warning - bad CRC,
using default environment”。这
是我们常看到的。
初始化 VFD(LCD 显示相关)
初始化串口。
从环境变量里获取 IP 地址
/* IP Address */
gd->bd->bi_ip_addr = getenv_IPaddr ("ipaddr");
stdio_init ();
初始化 Nand Flash 控制器,并显
示其容量大小。
初始化标准输入输出设备。比如:
串口、LCD、键盘等等
初始化全局数据表中的跳转表 gd-
>jt。
跳转表是一个函数指针数组,定义
了 u-boot 中基本的常用的函数库,
gd->jt 是这个函数指针数组的首指
针。
初始化 API,用于为 U-boot 编写的
“应用程序”
/* fully init console as a device */
#if defined(CONFIG_ARCH_MISC_INIT)
/* miscellaneous arch dependent initialisations */
arch_misc_init ();
#endif
#if defined(CONFIG_MISC_INIT_R)
/* miscellaneous platform dependent initialisations */
misc_init_r ();
初始化 console,平台无关,不一定
是串口哦,如果把标准输出设为
vga,字符会显示在 LCD 上。
平台相关的其他初始化,有的平台
有
#endif
/* enable exceptions */
enable_interrupts ();
/* Perform network card initialisation if necessary */
#ifdef CONFIG_DRIVER_TI_EMAC
/* XXX: this needs to be moved to board init */
extern void davinci_eth_set_mac_addr (const u_int8_t *addr);
if (getenv ("ethaddr")) {
uchar enetaddr[6];
eth_getenv_enetaddr("ethaddr", enetaddr);
davinci_eth_set_mac_addr(enetaddr);
}
#endif
#if defined(CONFIG_DRIVER_SMC91111) || defined
(CONFIG_DRIVER_LAN91C96)
/* XXX: this needs to be moved to board init */
if (getenv ("ethaddr")) {
uchar enetaddr[6];
eth_getenv_enetaddr("ethaddr", enetaddr);
smc_set_mac_addr(enetaddr);
}
#endif /* CONFIG_DRIVER_SMC91111 || CONFIG_DRIVER_LAN91C96 */
/* Initialize from environment */
if ((s = getenv ("loadaddr")) != NULL) {
load_addr = simple_strtoul (s, NULL, 16);
}
#if defined(CONFIG_CMD_NET)
if ((s = getenv ("bootfile")) != NULL) {
copy_filename (BootFile, s, sizeof (BootFile));
}
#endif
中断使能(一般不使用,很多平台
此函数是空的)
TI 芯片中的内置 MAC 初始化(平
台相关)
一种网卡芯片初始化(平台相关)
获取 bootfile 参数
一些板级初始化(有的板子有)
#ifdef BOARD_LATE_INIT
board_late_init ();
#endif
#ifdef CONFIG_GENERIC_MMC
puts ("MMC: ");
mmc_initialize (gd->bd);
#endif
#ifdef CONFIG_BITBANGMII
bb_miiphy_init();
#endif
#if defined(CONFIG_CMD_NET)
#if defined(CONFIG_NET_MULTI)
puts ("Net: ");
#endif
eth_initialize(gd->bd);
#if defined(CONFIG_RESET_PHY_R)
debug ("Reset Ethernet PHY\n");
reset_phy();
#endif
#endif
/* main_loop() can return to retry autoboot, if so just run it again. */
for (;;) {
SD 卡/MMC 控制器初始化
MII 相关初始化
网卡初始化
进入主循环,其中会读取 bootdelay
和 bootcmd
在 bootdelay 时间内按下键进入命
令行,否则执行 bootcmd 的命令。
main_loop ();
}
/* NOTREACHED - no way out of command loop except booting */
}
标有红色的是比较重要的地方。大致的 U-boot 启动流程就简单介绍到这。