嵌入式linux网络引导


嵌入式 linux 的开发中,内核移植及根文件系统的建立过程中,为了验证内核移植是否成功,根文件系统的建立是否可行,需要将它们的映像文件烧写到 Flash 中反复试验。如此频繁地烧写 Flash ,既浪费时间,减低了开发效率,还会对 Flash 造成损伤。因此在内核移植及根文件系统的建立过程中一般采用网络引导。具体操作过程如下:


一 Boot Loader 环境变量及内核参数设置


我的开发板的 boot loader 采用的是 U-boot ,其环境变量设置如下:


Uboot> printenv
 
bootdelay=3
 
baudrate=115200
 
ethaddr=00:12:34:56:78:9a
 
ipaddr=192.168.0.9            
 ①
 
serverip=192.168.0.1          
 ②
 
netmask=255.255.255.0
 
rootpath=/home/zht/rfsys        
 ③
 
stdin=serial
 
stdout=serial
 
stderr=serial
 
bootcmd=tftp 21000000 uImage;bootm 21000000      
 ④
 
bootargs=root=/dev/nfs rw nfsroot=192.168.0.1:/home/zht/rfsys nfsaddrs=192.168.0.48: 192.168.0.1:192.168.0.1:255.255.255.0 console=ttyS0,115200 mem=32M    
 ⑤


① 设置目标板 IP 地址


② 设置服务器 IP 地址


③ 设置根文件系统在服务器上的路径,注意该路径一定要设定为服务器上的 nfs 目录。


④ bootcmd 是 u-boot 启动后执行的命令 , 命令之间用分号分隔。


   tftp 21000000 uImage 表示通过 tftp 将内核映像下载到 RAM 中地址为 0x21000000;


   bootm 21000000 启动 linux 操作系统


⑤ 定义 u-boot 传送给 linux 内核的命令行参数,该命令行指定以网络文件系统作为根文件系统。


其中 root=/dev/nfs, 并非真的设备,而是一个告诉内核经由网络取得根文件系统的旗标。


参数 nfsroot 这个参数告诉内核以那一台机器,那个目录以及那个网络文件系统选项作为根文件系统使用。参数的格式如下:


nfsroot=[<server-ip>:]<root-dir>[,<nfs-options>]


如果指令列上没有给定 nfsroot 参数,则将使用 ‘/tftpboot/%s’ 预设值。其它选项如下:


<server-ip> -- 指定网络文件系统服务端的互联网地址 (IP address) 。如果没有给定此栏位,则使用由 nfsaddrs 变量(见下面)所决定的值。此参数的用途之一是允许使用不同机器作为反向地址解析协议 (RARP) 及网络文件系统服务端。通常你可以不管它(设为空白)。


<root-dir> -- 服务端上要作为根挂入的目录名称。如果字串中有个 ‘%s’ 符记 (token) ,此符记将代换为客户端互联网地址之 ASCII 表示法。


<nfs-options> -- 标准的网络文件系统选项。所有选项都以逗号分开。如果没有给定此选项栏位则使用下列的预设值:


port            = as given by server portmap daemon
 
        rsize           = 1024
 
        wsize           = 1024
 
        timeo           = 7
 
        retrans         = 3
 
        acregmin        = 3
 
        acregmax        = 60
 
        acdirmin        = 30
 
        acdirmax        = 60
 
        flags           = hard, nointr, noposix, cto, ac


参数 nfsaddrs 设定网络通讯所需的各种网络接口地址。如果没有给定这个参数,则内核核会试著使用反向地址解析协议以及/或是启动协议 (BOOTP) 以找出这些参数。 其格式如下:


  

nfsaddrs=<my-ip>:<serv-ip>:<gw-ip>:<netmask>:<name>:<dev>:<auto>


<my-ip> -- 客户端的互联网地址。如果没设,此地址将由反向地址解析协议或启动协议来决定。使用何种协议端视配置核心时打开的选项以及 <auto> 参数而定。如果设定此参数,就不会使用反向地址解析协议或启动协议。


<serv-ip> -- 网络文件系统服务端之互联网地址。如果使用反向地址解析协议来决定客户端地址并且设定此参数,则只接受从指定之服务端传来的回应。要使用不同的机器作为反向地址解析与网络文件系统服务端的话,在此指定你的反向地址解析协议服务端(保持空白)并在 nfsroot 参数(见上述)中指定你的网络文件系统服务端。如果此项目空白则使用回答反向地址解析协议或启动协议之服务端的地址。


<gw-ip> -- 网关 (gateway) 之互联网地址,若服务端位於不同的子网络上时。 如果此项目空白则不使用任何网关并假设服务端在本地的 (local) 网络上,除非由启动协议接收到值。


<netmask> -- 本地网络界面的网络掩码。如果为空白,则网络掩码由客户端的互联网地址导出,除非由启动协议接收到值。


<name> -- 客户端的名称。如果空白,则使用客户端互联网地址之 ASCII- 标记法,或由启动协议接收的值。


<dev> -- 要使用的网络设备名称。如果为空白,所有设备都会用来发出反向地址解析请求,启动协议请求由最先找到的设备发出。网络文件系统使用接收到反向地址解析协议或启动协议回应的设备。如果你只有一个设备那你可以不管它。


<auto> -- 用以作为自动配置的方法。如果是 `rarp' 或是 `bootp' 则使用所指示的协议。如果此值为 `both' 或空白,若配置核心时有打开这两种协议则都使用。 `none' 表示不使用自动配置。这种情况下你必须指定前述栏位中所有必要的值。


此 <auto> 参数可以作为 nfsaddrs 的参数单独使用(前面没有任何 `:` 字符),这种情况下会使用自动配置。然而,此种情况不能使用 `none' 作为值。


 


二 内核配置要求


 


添加内核对 NFS 的支持:


选中 networking options -》 IP:kernel level auloconfiguralion 项


选中 file systems -》 network file systems -》下的 root file system on nfs 和 nfs file system support


 


三 TFTP 服务器的配置


以 root 用户登录,运行 setup 命令


#setup


选择 Systme services, 选择 tftp 。


打开 tftp 配置文件 /etc/xinetd.d/tftp


将 server_args 设定为内核映像文件所在目录,默认为 /tftpboot


我的内核映像在 /home/zht/sources/kernel/linux-2.4.27 目录中,设定如下:


service tftp
 
{
 
        disable = no
 
        socket_type             = dgram
 
        protocol                = udp
 
        wait                    = yes
 
        user                    = root
 
        server                  = /usr/sbin/in.tftpd
 
        server_args             = -s /home/zht/sources/kernel/linux-2.4.27
 
        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/zht/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.20: /home/zht/rfsys  /mnt 
 
# ls /mnt


命令将 Linux 服务器的 NFS 输出共享目录挂载到 /mnt 目录下,因此,如果 NFS 正常工作,应该能够在 /mnt 目录看到 /home/work 共享目录中的内容。


 


五 将内核映像文件 uImage 拷贝到 /tftpboot 目录 , 建立的根文件系统拷贝到 /home/zht/rfsys 目录中。然后重新启动目标板。