http://blog.mcuol.com/User/travellinux/Article/43353_1.htm
在嵌入式软件开发过程中,经常需要烧写内核文件Kernel和根文件系统映像RootFS到Flash存储器中,然后重启BootLoader从Flash rom加载运行Kernel及RootFS,以验证/调试我们的软件程序。通常这种方法并不适合嵌入式软件开发阶段,因为其不仅有损Flash的使用寿命,而且也非常耗时。
为避免这些弊端和不足,本文详细叙述了BootLoader(以U-Boot为例)从网络加载启动Linux kernel和NFS根文件系统的方法技巧,极大地方便了嵌入式软件开发调试过程。
说明:从网络启动嵌入式目标板(即目标板的网络引导功能),需要为开发主机设置BOOTP/DHCP、TFTP和NFS等网络服务。其中,BOOTP/DHCP协议是用来为网络主机提供基本引导信息的标准方法,包括其他(如TFTP和NFS)的地址。TFTP是用来下载远程文件的最简单网络协议。对嵌入式linux系统来说,目标板可通过TFTP协议从TFTP服务器获得内核映像。NFS则是客户端和服务器之间用来共享整个目录树的标准和最简单的协议。对嵌入式linux系统来说,目标板可通过NFS协议来加载NFS服务器为它导出的根文件系统。并用这三个协议可以提供非常有效的主机/目标板开发设置。
一、
BootLoader环境变量及内核参数设置
这里,开发板BootLoader采用的是U-boot,其环境变量设置如下:
Uboot
> printenv
bootdelay=3
baudrate=115200
ethaddr=52:54:4c:ea:fc:6d
ipaddr=192.168.0.76
①
serverip=192.168.0.79
②
netmask=255.255.255.0
rootpath=/home/dvr/rfsys
③
stdin=serial
stdout=serial
stderr=serial
bootcmd=tftp 0xc0c00000 uImage;bootm 0xc0c00000
④
bootargs=console=ttyS0,115200 mem=40M root=/dev/nfs \
nfsroot=192.168.0.79:/home/dvr/rfsys,nolock \
ip=192.168.0.76:192.168.0.79:192.168.0.1:\
255.255.255.0:Hi3515_DVR:eth0:off
⑤
注解:
① 设置目标板IP地址
② 设置服务器IP地址
③ 设置根文件系统在服务器上的路径,注意该路径一定要设定为服务器上的nfs目录。
④ bootcmd是u-boot启动后执行的命令,命令之间用分号分隔。
tftp 0xc0c00000 uImage 表示通过tftp 将内核映像下载到RAM中地址为0xc0c00000;
bootm 0xc0c00000 启动linux操作系统
⑤ bootargs定义u-boot传送给linux内核的命令行参数,该命令行指定以网络文件系统作为根文件系统。
其中
root=/dev/nfs,并非真的设备,而是一个告诉内核经由网络取得根文件系统的旗标;
参数
nfsroot这个参数告诉内核以那一台机器,那个目录以及那个网络文件系统选项作为根文件系统使用。参数的格式如下:
如果指令列上没有给定nfsroot参数,则将使用‘/tftpboot/%s’预设值。其选项定义如下:
-- 指定网络文件系统服务端的互联网地址(IP address)。如果没有给定此栏位,则使用由nfsaddrs变量(见下面)所决定的值。此参数的用途之一是允许使用不同机器作为反向地址解析协议(RARP) 及网络文件系统服务端。通常你可以不管它(设为空白)。
-- 服务端上要作为根挂入的目录名称。如果字串中有个‘%s’符记(token),此符记将代换为客户端互联网地址之ASCII表示法。
-- 标准的网络文件系统选项。所有选项都以逗号分开。如果没有给定此选项栏位则使用下列的预设值:
(略)
参数
nfsaddrs或者
ip设定网络通讯所需的各种网络接口地址。如果没有给定这个参数,则内核核会试著使用反向地址解析协议以及/或是启动协议(BOOTP)以找出这些参数。其格式如下:
ip=${ipaddr}:${serverip}:\
${gatewayip}:${netmask}:\
${hostname:${netdev}:off
参数解析:
-- 客户端的互联网地址。如果没设,此地址将由反向地址解析协议(RARP)或启动协议来决定。使用何种协议端视配置核心时打开的选项以及 参数而定。如果设定此参数,就不会使用反向地址解析协议或启动协议。
-- 网络文件系统服务端之互联网地址。如果使用反向地址解析协议来决定客户端地址并且设定此参数,则只接受从指定之服务端传来的回应。要使用不同的机器作为反向地址解析与网络文件系统服务端的话,在此指定你的反向地址解析协议服务端(保持空白)并在 nfsroot 参数(见上述)中指定你的网络文件系统服务端。如果此项目空白则使用回答反向地址解析协议或启动协议之服务端的地址。
-- 网关(gateway)之互联网地址,若服务端位於不同的子网络上时。如果此项目空白则不使用任何网关并假设服务端在本地的(local)网络上,除非由启动协议接收到值。
-- 本地网络界面的网络掩码。如果为空白,则网络掩码由客户端的互联网地址导出,除非由启动协议接收到值。
-- 客户端的名称。如果空白,则使用客户端互联网地址之 ASCII-标记法,或由启动协议接收的值。
-- 要使用的网络设备名称。如果为空白,所有设备都会用来发出反向地址解析请求,启动协议请求由最先找到的设备发出。网络文件系统使用接收到反向地址解析协议或启动协议回应的设备。如果你只有一个设备那你可以不管它。
-- 用以作为自动配置的方法。如果是 `rarp或是 `bootp则使用所指示的协议。如果此值为`both或空白,若配置核心时有打开这两种协议则都使用。 `none表示不使用自动配置。这种情况下你必须指定前述栏位中所有必要的值。
此参数可以作为 nfsaddrs 的参数单独使用(前面没有任何 `:` 字符),这种情况下会使用自动配置。然而,此种情况不能使用 `none作为值。
二、
内核配置要求
添加内核对NFS的支持:
--Networking Options
(*)TCP/IP networking
(*)IP: kernel level autoconfiguration
(*)IP: DHCP support
(*)IP: Bootp support
(*)IP: Rarp support
--File systems
Network File Systems
(*)NFS file system support
(*)Root file system on NFS
三、
TFTP服务器的配置
以root用户登录,运行setup命令
#setup
选择Systme services,选择tftp。
打开tftp配置文件/etc/xinetd.d/tftp
将server_args设定为内核映像文件所在目录,默认为/tftpboot
设定如下:
service tftp
{
disable = no
socket_type = dgram
protocol = udp
wait = yes
user = root
server = /usr/sbin/in.tftpd
server_args = -s /tftpboot
per_source = 11
cps = 100 2
flags = IPv4
}
重新启动PC linux操作系统或者运行service xinetd restart命令启动tftp服务器。
运行netstat -a | grep tftp 可以查看tftp服务器是否配置成功。
四、
NFS服务器的配置
以root身份登陆Linux服务器,编辑/etc目录下的共享目录配置文件exports,指定共享目录及权限等。
执行如下命令编辑文件/etc/exports:
# vi /etc/exports
在该文件里添加如下内容:
/home/dvr/rfsys 192.168.0.*(rw,sync,no_root_squash)
编辑完过后保存退出,然后运行命令exports –rav检查输入是否正确。
添加的内容表示:允许ip地址范围在192.168.0.*的计算机以读写的权限来访问/home/zht/rfsys目录。/home/work也称为服务器输出共享目录。
括号内的参数意义描述如下:
rw:读/写权限,只读权限的参数为ro;
sync:数据同步写入内存和硬盘,也可以使用async,此时数据会先暂存于内存中,而不立即写入硬盘。
no_root_squash:NFS服务器共享目录用户的属性,如果用户是 root,那么对于这个共享目录来说就具有 root 的权限。
接着执行如下命令,启动端口映射:
# /etc/rc.d/init.d/portmap start
最后执行如下命令启动NFS服务,此时NFS会激活守护进程,然后就开始监听 Client 端的请求:
# /etc/rc.d/init.d/nfs start
在NFS服务器启动后,还需要检查Linux服务器的防火墙等设置(一般需要关闭防火墙服务,执行iptables -F),确保没有屏蔽掉NFS使用的端口和允许通信的主机,主要是检查Linux服务器iptables,ipchains等选项的设置,以及/etc/hosts.deny,/etc/hosts.allow文件。
我们首先在Linux服务器上进行NFS服务器的回环测试,验证共享目录是否能够被访问。在Linux服务器上运行如下命令:
# mount –t nfs 192.168.0.79:/home/dvr/rfsys /mnt
# ls /mnt
命令将Linux服务器的NFS输出共享目录挂载到/mnt目录下,因此,如果NFS正常工作,应该能够在/mnt目录看到/home/dvr/rfsys共享目录中的内容。
五、
DHCP服务器配置(非必要步骤,可跳过)
yum install dhcp
然后,建立或编辑/etc/dhcpd.conf文件,为目标板加入一项设定:
例如:
subnet 192.168.0.0 netmask 255.255.255.0 {
option routers 192.168.0.1;
option subnet-mask 255.255.255.0;
host Hi3515_DVR {
hardware ethernet 52:54:4c:ea:fc:6d; //MAC地址用来标示目标板
fixed-address 192.168.0.76; //分配IP给指定的MAC
option host-name "Hi3515_DVR"; //为目标板指定供dhcpd.conf文件使用的主机名称
next-server 192.168.0.79; //TFTP服务器地址
filename "/tftpboot/uImage"; //指定目标板下载的内核的文件名
option root-path "/home/dvr/rfsys"; //提供NFS服务器上目标板根文件系统的完整路径
}
}
六、
OK,
重新启动目标板。
重启之前需确认内核映像文件uImage和根文件系统已经分别拷贝到/tftpboot目录和/home/dvr/rfsys目录中。