nfs也就是网络文件系统,在嵌入式开发中为什么需要nfs呢?主要是因为在开发过程中,根文件系统里面的内容要经常改动,那么就会频繁的调试,如果不使用nfs那么,一旦根文件系统内的文件有改动的时候,就要重新烧录flash分区,这样重复烧写会对缩短flash的使用寿命;由于上述原因,所以可以使用网络文件系统,这样根文件系统使用网络文件系统nfs的话,根文件系统中有改动的时候不需要重新烧录flash即可,常用于开发调试过程。
首先在Ubuntu环境中安装NFS的环境,安装过程如下:
$ sudo apt-get install nfs-kernel-server
$ sudo apt-get install nfs-common
(1)$ sudo vi /etc/exports
文本末添加
(2)$/root/rootfs *(rw,sync,no_root_squash,no_subtree_check) ,这个命令的作用是确定根文件系统的在Ubuntu中的文件夹位置
(3)$chmod 777 -R /root/rootfs ,修改上面确定的根文件系统的权限,方便接下来读写操作的时候不会发生异常
(4)sudo showmount -e
(5)$ sudo exportfs -r 更新
(6)$ sudo showmount localhost -e ,显示文件系统根文件系统的全路径,判断和在/etc/exports 设置的是否一致,正确的情况因该是一致的
(1)$ sudo /etc/init.d/nfs-kernel-server restart 重启 nfs 服务
(2)$ mount -t nfs -o nolock localhost:/root/rootfs /mnt 挂载测试
执行后,进入/mnt 目录中,如果可以看到/root/rootfs 中的内容,则说明 nfs 搭建成功!
(3)使用结束后,命令umount /mnt/ 来取消挂载,注意这里的mnt后面的“/”不可省略,省略后取消挂载会失败
注意:这里我们测试的时候最好不要使用/mnt目录,因为在搭建环境的时候,使用/mnt目录挂载了共享文件夹,如果将根文件系统挂载到/mnt目录上的时候可能导致共享文件夹无法使用,这里可以挂载到/opt目录。
在我们开发板中如何使用挂载nfs呢?实际上内核启动的时候并不知道根文件系统在什么地方,我们是通过uboot给kernel传参来告知kernel根文件系统在什么位置。通过设置uboot环境变量bootargs来设置传参。
环境变量bootargs一般有两种设置方法,分别适用两种不同的使用场景:
(1)set bootargs console=ttySAC2,115200 root=/dev/mmcblk0p2 rw init=/linuxrc rootfstype=ext3
(2)setenv bootargs root=/dev/nfs nfsroot=192.168.1.141:/root/rootfs ip=192.168.1.10:192.168.1.141:192.168.1.1:255.255.255.0::eth0:off init=/linuxrc console=ttySAC0,115200
(1)适用于根文件系统烧录到flash中的,(2)适用于根文件系统使用的是nfs挂载的。
下面介绍一下(2)根文件系统通过nfs挂载的这种情况参数的含义
①/dev/nfs nfsroot=192.168.1.141 代表挂载的是nfs,且nfs服务器的地址是:192.168.1.141
②/root/rootfs 根文件系统的文件夹所在主机中的位置
③ip=192.168.1.10:192.168.1.141:192.168.1.1:255.255.255.0
192.168.1.10为开发板临时设置的IP地址;192.168.1.141为nfs服务器主机的IP地址;192.168.1.1 为网关的IP地址;255.255.255.0 为网络的子网掩码
④eth0 为主机Ubuntu使用的网卡
⑤off 关闭DHCP服务
⑥init=/linuxrc 指定第一个用户态的进程
⑦console=ttySAC2,115200 指定控制台输出的串口号和波特率
这里其中每个参数之前用“:”分隔开,其中有两个“::”相邻,说明中间有一个参数省略掉了,这里我们可以忽略不计;如果以后设置这个环境变量,参照这个格式就可以,只需要改动部分即可。
经过上面操作后,重启开发板后会发现,根文件系统还是会挂载失败,原因可能就是内核没有配置支持nfs功能,下面介绍一下配置内核支持nfs功能。首先makemenuconfig进行配置。
1、配置网络部分,主要是使能CONFIG_IP_PNP以在2中能够看到Root file system on NFS选项
Networking support
Networking options
TCP/IP networking
IP: kernel level autoconfiguration
[*] IP: DHCP support
[*] IP: BOOTP support
2、配置开启nfs服务
File systems --->
Network File Systems --->
<*> NFS client support
[*] NFS client support for NFS version 3 [*] NFS client support for the NFSv3 ACL protocol extension
[*] NFS client support for NFS version 4 (EXPERIMENTAL)
[*] NFS client support for NFSv4.1 (DEVELOPER ONLY)
[*] Root file system on NFS
配置完之后重新make内核,然后将内核重新烧录到SD卡后插入到开发板再次启动,根文件系统就会挂载成功。
建议:这里为了以后操作方便起见,可以将编译完成的内核镜像拷贝到tftp服务器对应的文件夹里面,然后修改uboot的bootcmd参数,使其从主机Ubuntu的tftp服务器下载内核到内存,这样就省去了反复烧录SD卡原来bootcmd参数如下:
bootcmd=movi read kernel 30008000; movi read rootfs 30B00000 300000; bootm 30008000
这个bootcmd参数是从SD卡读取内核和根文件系统等到内存中所使用的,现在修改成从tftp服务器上下载内核镜像到内存中,设置如下:
set bootcmd “tftpboot 0x30008000 zImage ; movi read rootfs 30B00000 300000; bootm 30008000 ”
saveenv
这样设置好之后下次启动的时候内核就是自动从tftp服务器下载了,省去了修改内核就烧录SD卡的步骤,既节省了时间,又会延长SD卡寿命。
1、nfs方式启动相当于开发板上的内核远程挂载到主机上的rootfs
2、nfs方式启动不用制作rootfs镜像
3、nfs方式不适合真正的产品,一般作为产品开发阶段调试使用