网络文件系统(NFS,Network File System)是一种将远程主机上的分区(目录)经网络挂载到本地系统的一种机制,通过对网络文件系统的支持,用户可以在本地系统上像操作本地分区一样来对远程主机的共享分区(目录)进行操作。
在嵌入式Linux 的开发过程中,开发者需要在Linux 服务器上进行所有的软件开发,交叉编译后,通用FTP 方式将可执行文件下载到嵌入式系统运行,但这种方式不但效率低下,且无法实现在线的调试。因此,可以通过建立NFS,把Linux 服务器上的特定分区共享到待调试的嵌入式目标系统上,就可以直接在嵌入式目标系统上操作Linux 服务器,同时可以在线对程序进行调试和修改,大大的方便了软件的开发。
一、在Ubuntu12.04下安装、配置Ubuntu nfs服务的步骤如下:
安装nfs,Ubuntu上默认是没有安装Ubuntu nfs服务器的,因此我们首先安装Ubuntu nfs服务器端:$sudo apt-get install nfs-kernel-server在一些文档中,提出还需要使用apt-get来手动安装nfs的客户端nfs-common,以及端口映射器portmap,但其实这是没有必要的,因为在安装nfs-kernel-server时,apt会自动为我们把它们安装好。
配置/etc/exports
Ubuntu nfs允许挂载的目录及权限在文件/etc/exports中进行了定义。
例如,我们要将/nfsboot/lrootfs目录共享出来,那么我们需要在/etc/exports文件末尾添加如下一行:/nfsboot/lrootfs*(rw,sync,no_root_squash)其中:/rootfs是要共享的目录,*代表允许所有的网络段访问,rw是可读写权限,sync是资料同步写入内存和硬盘,no_root_squash是Ubuntu nfs客户端分享目录使用者的权限,如果客户端使用的是root用户,那么对于该共享目录而言,该客户端就具有root权限。
其它Ubuntu nfs常用的参数有:
ro 只读访问
rw 读写访问sync 所有数据在请求时写入共享
async nfs在写入数据前可以响应请求
secure nfs通过1024以下的安全TCP/IP端口发送
insecure nfs通过1024以上的端口发送
wdelay 如果多个用户要写入nfs目录,则归组写入(默认)
no_wdelay 如果多个用户要写入nfs目录,则立即写入,当使用async时,无需此设置。
hide 在nfs共享目录中不共享其子目录
no_hide 共享nfs目录的子目录
subtree_check 如果共享/usr/bin之类的子目录时,强制nfs检查父目录的权限(默认)
no_subtree_check 和上面相对,不检查父目录权限
all_squash 共享文件的UID和GID映射匿名用户anonymous,适合公用目录。
no_all_squash 保留共享文件的UID和GID(默认)
root_squash root用户的所有请求映射成如anonymous用户一样的权限(默认)
no_root_squas root用户具有根目录的完全管理访问权限
anonuid=xxx 指定nfs服务器/etc/passwd文件中匿名用户的UID
anongid=xxx 指定nfs服务器/etc/passwd文件中匿名用户的GID
其他常用项
secure 限制客户端只能从小于 1024 TCP/IP端口连接 NFS 服务器(默认设置)
insecur 允许客户端从大于 1024 TCP/IP端口连接 NFS 服务器
subtree_check 若输出目录是一个子目录,则 NFS将检查其父目录的权限(默认设置)
no_subtree_check 即使输出的目录是一个子目录, NFS也不检查其父目录的权限
每当修改了 /etc/export 文件后,不需要重启 NFS 服务,使用 exportfs 就可以使设置立即生效
exportfs 命令就是用来维护 NFS服务的输出目录列表的
exportfs -r 重新读取/etc/export文件设置,并使设置立即生效
exportf – ra
重新导出全部
exportf – v
将当前系统导出项显示在屏幕上
exportf – au
关闭服务
exportf – a
开启所有的全部导出
showmount 命令检查 NFS服务器上的共享信息
showmount – e localhost检查当前主机共享的文件系统 只在服务端执行
showmount – a
检查所有被挂载信息 服务端执行)
showmount – d
只显示被挂载目录
showmount – e IP检查该 IP 共享的信息(客户端)
Ubuntu nfs重启服务
$sudo /etc/init.d/portmap restart
$sudo /etc/init.d/nfs-kernel-server restart
测试Ubuntu nfs
此时可以运行以下命令来显示一下共享出来的目录:
$showmount -e
或者可以使用以下命令把它挂载在本地磁盘上,例如将/nfsboot/lrootfs挂载到/mnt下:
$ sudo mount -t nfs localhost:/nfsboot/lrootfs /mnt
可以运行df命令查看是否挂载成功。查看后可以使用以下命令卸载:
$ sudo umount /mnt
运行$ sudo mount -t nfslocalhost:/nfsboot/lrootfs /mnt时出现了一个问题:
mount.nfs: accessdenied by server while mounting
百度得知,解决办法http://liuzhigong.blog.163.com/blog/static/17827237520115305226932/
修改配置文件/etc/exports,加入insecure选项
/nfsboot/lrootfs *(
insecure,rw,sync,no_root_squash)
重启服务解决 :
$sudo /etc/init.d/portmap restart
$sudo /etc/init.d/nfs-kernel-server restart
二、用VMware虚拟机装的ubuntu12.04连接本地win7系统和arm开发板
一般说来,要想用VMware虚拟机装的ubuntu12.04如何连接本地win7系统和arm开发板,那么本地XP必须要有两个网卡,一般就是一个无线网卡,一个有线网卡。
在开始操作之前,把有线网卡,无线网卡(这个网卡是给win7系统上网用的)的IP信息都看一下,发现两个网卡是同一网段的,都是192.168.0.x,一会要想ubuntu和WIN7和arm开发板互联的话,就不能和无线网卡同一网段,所以先把有线网卡的IP信息设置成(IP地址192.168.1.118、子网掩码255.255.255.0、默认网关192.168.1.2、DNS服务器202.96.128.166, 202.96.134.133)。
启动VMware,在edit->virtualnetwork editor里面,新增一个网络我这里是VMnet2,然后把VMnet2的网卡设置为桥接到有线网卡如上图,把VMnet0桥接到无线网卡(这个网卡是给VMware 里面的系统上网用的),然后选择OK。
选择VM中的setting选项,添加另一块网卡,选择Custom-Vmnet2(bridged)
启动VM中的ubuntu,启动完毕之后,启动终端,输入ifconfig,查看两个网卡分别是什么名称,我这里无线网卡是eth0,有线网卡是eth1。
在屏幕右上角有一个网络连接的图标,鼠标左键单击该图标,选中edit connections,弹出菜单之后,选中Wired,然后选择 add ,添加Connection name(随便添加)。
选择“IPV4 setting”,“Method”里面选择的是manual(手动设置),然后在把第一步记录下来的IP信息,填写到Address这里,注意,这里填写的IP地址和刚才记录的是不一样的,我的是192.168.1.118,如图然后确认。
在终端输入ping 192.168.1.99,在WIN7系统的cmd里面输入ping 192.168.1.118,都ping的通的话,说明设置正确了,ping不同就检查以上的步骤。
我的开发板的IP是192.168.1.121,所以,我可以从ubuntu和WIN7下ping192.168.1.118都能ping的通
根据上面的步骤使用的时候发现,在WIN7下经常上不了网,ping www.baidu.com也ping不通,google了一下,说是有线网卡和无线网卡同时连通网络的时候,优先级是先使用有线网卡,但是我现在的有线网卡是连接到arm开发板上的,是和外网不相通的,所以ping不同。有个修正方法,就是把无线网卡的优先级提高。在WIN7系统桌面上“右键网上邻居--->属性--->弹出网络连接后,右键无线网络连接--->属性--->常规--->左键Internet协议(TCP/IP)--->属性--->高级--->IP设置--->去掉
自动跃点计数 的勾--->接口跃点数 设置为1--->然后一路确定”。这些设置完了之后,发现一切网络都正常了。
三、重新配置编译内核支持NFS启动
在ubuntu nfs 服务设置好后,还需要对开发板内核相关配置(内核版本2.6.35.7)。
选择Networking support--àNewworking options--à IP:kernel level auloconfiguralion项
(*)IP: DHCP support
(*)IP: Bootp support
(*)IP: Rarp support
选中File systems --->[*] Network File Systems ---><*> NFS client support
[*] NFS client support for NFS version 3
[ ] NFS client support for the NFSv3 ACLprotocol extension
[ ] NFS client support for NFS version 4(EXPERIMENTAL)
[*] Root file system on NFS
四、进入U-boot命令行,设置启动参数。
如果你的内核配置了DHCP,内核会在启动时会默认用DHCP获取IP,使内核启动到这一阶段时ip被换掉,最终导致NFS挂载失败,所以我们在写内核启动参数是要注意一下ip=这个参数的写法,具体格式介绍如下:
ip参数的格式如下:
ip=::::::
client-ip:
你正在使用的这块板子,你要为它设置的ip
server-ip:
提供nfs服务的服务器的ip地址。如不需要NFS服务于板子,则此项可以空置
gw-ip:
网关的ip地址,如果nfs与目标板在同一个网段内,则此项可以空置
netmask:
子网掩码,如此项为空,则子网掩码为默认值255.255.255.0
hostname:
你希望给目标板设置的主机名,在linux的shell中的如bash,命令行最开始有一个形如blacksword@laptop2:~
$ 这样的一个提示符,blacksword指当前的用户,而laptop2就是一个hostname.此项可以留空
device:
如果目标板上仅一个网卡,且只接了一个PHY,同时电路的设计没有将PHY拉出两个地址来,则此项为空。如果不指有一个网卡,则可以指定要设置的ip地址是作用于哪一个网卡的。如指定给第一块网卡,则该参数为eth0.第二块为eth1,依此类推。
autoconf:
自动配置未明确指定参数的方式,可以是dhcp,rarp, bootp。如果不希望使用自动配置则可以使用off值来关闭 autoconf参数可以独立作用于ip参数,如ip=dhcp即表示由dhcp服务器给内核的ip参数提供所有数据。
ip=off则表示所有参数都不配置,留待系统启动进行配置。
指定静态ip的方法为 ip=::::eth0:off 请注意中间冒号的个数。其他各项可以根据自己的实际情况来指定相应的值。
下面是我的启动参数,注意红字部分,配置后禁用了DHCP。
set bootargs "noinitrdroot=/dev/nfs rw nfsroot=192.168.1.118:/nfsboot/lrootfsip=192.168.1.121:192.168.1.118:192.168.1.1:255.255.255.0:QT210:eth0:offconsole=ttySAC0"
输入save保存参数,输入boot启动开发板,最后成功挂载启动。
nfsroot 后面是自己开发主机的 IP地址。“ip=”后面:
第一项(192.168.1.121)是目标板的临时 IP(注意不要和局域网内其他 IP 冲突);
第二项(192.168.1.118)是开发主机的 IP;
第三项(192.168.1.1)是目标板上网关(GW)的设置;
第四项(255.255.255.0)是子网掩码;
第五项是开发主机的名字(一般无关紧要,可随便填写) eth0 是网卡设备的名称