NFS文件系统制作与移植

1.NFS文件系统简介:

NFS是由Sun开发并发展起来的一项在不同机器、不同操作系统之间通过网络共享文件的技术。在嵌入式Linux系统的开发调试阶段,可以利用该技术在主机上建立基于NFS 的根文件系统,挂载到嵌入式设备,可以很方便地修改根文件系统的内容。以上讨论的都是基于存储设备的文件系统(memory-based file system),它们都可用作Linux的根文件系统。实际上,Linux还支持逻辑的或伪文件系统(logical or pseudo file system),例如procfs(proc文件系统),用于获取系统信息,以及devfs(设备文件系统)和sysfs,用于维护设备文件。


2.在内核中添加对nfs的支持:

Networking  --->

    Networking options  --->

         [*]   IP: kernel level autoconfiguration  

         [ ]     IP: DHCP support

         [ ]     IP: BOOTP support

         [ ]     IP: RARP support   

File systems  --->

    Network File Systems  ---> 

        <*> NFS file system support

         [ ]   Provide NFSv3 client support 

         [ ]   Provide NFSv4 client support (EXPERIMENTAL)  

         [ ]   Allow direct I/O on NFS files

         < > NFS server support

        [*] Root file system on NFS  

注:对于nfs文件系统,上面红色标注的要选上,其余选项根据自身的情况而言。


3.参考根文件系统制作的文档,制作用于系统启动的NFS文件系统:

[lingyun@localhost opt]$ ls rootfs

apps    bin   dev  home  init  linuxrc  media  opt   root  stat  tmp  var

backup  data  etc  info  lib   logs     mnt    proc  sbin  sys   usr

[lingyun@localhost opt]$


确认并安装NFS服务依赖软件包

一般NFS服务器要提供服务,必须启动inet,nfs, mount,portmaprpcbind这些守护进程并保持在后台状态运行这里需要提示的是从RHEL6开始系统使用rpcbind替换了以前早期版本中NFS依赖的portmap服务。

在使用NFS共享文件之前,我们首先使用rpm命令确认我们安装了这些应用程序。如果没有安装,则从安装光盘中找到他们并安装,或者使用yum安装。下面显示我们在安装系统时,已经选择安装了NFS服务相关软件

[lingyun@localhost opt]$ rpm -qa | grep nfs

nfs4-acl-tools-0.3.3-6.el6.x86_64

nfs-utils-lib-1.1.5-4.el6.x86_64

nfs-utils-1.2.3-36.el6.x86_64

[lingyun@localhost opt]$ rpm -qa | grep rpcbind

rpcbind-0.2.0-11.el6.x86_64

[lingyun@localhost opt]$ 


修改主机上的NFS配置文件,导出/opt目录使用NFS共享:

backup  data  etc  info  lib   logs     mnt    proc  sbin  sys   usr  xxx

[lingyun@localhost opt]$ sudo vim /etc/exports 

/opt/ *(rw,sync,no_root_squash)

下面是一些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 共享文件的UIDGID映射匿名用户anonymous,适合公用目录。

no_all_squash 保留共享文件的UIDGID(默认)

root_squash root用户的所有请求映射成如anonymous用户一样的权限(默认)

no_root_squas root用户具有根目录的完全管理访问权限

anonuid=xxx 指定NFS服务器/etc/passwd文件中匿名用户的UID

anongid=xxx 指定NFS服务器/etc/passwd文件中匿名用户的GID

关于/etc/exports文件的更加详细的配置说明,我们可以使用man exports命令来查看帮助手册。

重新启动rpcbindportmapnfs服务

使用root权限运行“service rpcbind restart(RHEL高于6.0版本)或“service portmap restart(RHEL5及以下版本)命令重启NFS依赖的服务:

[lingyun@localhost opt]$ sudo service rpcbind restart

Stopping rpcbind:                                          [  OK  ]

Starting rpcbind:                                            [ OK  ]

使用root权限运行“service nfs restart”命令重启NFS服务,让其生效:

[lingyun@localhost opt]$ sudo service nfs restart

Shutting down NFS daemon:                         [  OK  ]

Shutting down NFS mountd:                          [  OK  ]

Shutting down NFS quotas:                           [  OK  ]

Shutting down NFS services:                         [  OK  ]

Starting NFS services:                                    [ OK  ]

Starting NFS quotas:                                      [  OK ]

Starting NFS mountd:                                     [  OK  ]

Starting NFS daemon:                                    [  OK  ]

[lingyun@localhost opt]$ 

使用service rpcbind status命令和“service nfs status”命令查看相关服务的运行状态,同时可以使用“showmount –e”命令可以查看我们通过NFS服务共享的文件:

[lingyun@localhost opt]$ service rpcbind status

rpcbind (pid  3719) is running...

[lingyun@localhost opt]$ service nfs status

rpc.svcgssd is stopped

rpc.mountd (pid 7935) is running...

nfsd (pid 7962 7961 7960 7959 7958 7957 7956 7955) is running...

rpc.rquotad (pid 7931) is running...

[lingyun@localhost opt]$ showmount -e

Export list for localhost.localdomain:

/opt           *

/usr/local/src *

[lingyun@localhost opt]$ 

测试NFS访问

在另外一个Linux机器上,或者在本机上通过mount命令挂载并测试如下:

[lingyun@localhost opt]$ sudo mkdir -p /mnt/nfs

[lingyun@localhost opt]$ sudo mount -t nfs 192.168.1.3:/opt /mnt/nfs

[lingyun@localhost opt]$ mount

/dev/sda2 on / type ext4 (rw)

proc on /proc type proc (rw)

sysfs on /sys type sysfs (rw)

devpts on /dev/pts type devpts (rw,gid=5,mode=620)

tmpfs on /dev/shm type tmpfs (rw)

none on /proc/sys/fs/binfmt_misc type binfmt_misc (rw)

sunrpc on /var/lib/nfs/rpc_pipefs type rpc_pipefs (rw)

nfsd on /proc/fs/nfsd type nfsd (rw)

192.168.1.2:/var/ftp/pub on /opt/pub type nfs (rw,nolock,vers=4,addr=192.168.1.2,clientaddr=192.168.1.3)

192.168.1.3:/opt on /mnt/nfs1 type nfs (rw,vers=4,addr=192.168.1.3,clientaddr=192.168.1.3)

[lingyun@localhost opt]$ ls /mnt/nfs/

buildroot-2012.08  mtd  pub  rootfs

[lingyun@localhost opt]$ ls /mnt/nfs1/rootfs/

apps    bin   dev  home  init  linuxrc  media  opt   root  stat  tmp  var

backup  data  etc  info  lib   logs     mnt    proc  sbin  sys   usr xxx

[lingyun@localhost opt]$ ls /opt/rootfs/

apps    bin   dev  home  init  linuxrc  media  opt   root  stat  tmp  var

backup  data  etc  info  lib   logs     mnt    proc  sbin  sys   usr  xxx

[lingyun@localhost opt]$ rm /mnt/nfs1/rootfs/xxx 

rm: remove write-protected regular empty file `/mnt/nfs1/rootfs/xxx'? y

[lingyun@localhost opt]$ ls /mnt/nfs/rootfs/    

apps    bin   dev  home  init  linuxrc  media  opt   root  stat  tmp  var

backup  data  etc  info  lib   logs     mnt    proc  sbin  sys   usr

[lingyun@localhost opt]$ ls /opt/rootfs/         

apps    bin   dev  home  init  linuxrc  media  opt   root  stat  tmp  var

backup  data  etc  info  lib   logs     mnt    proc  sbin  sys   usr

[lingyun@localhost opt]$ 


4.uboot设置和映像烧录启动

[ s3c2440@fulinux ]# set bootcmd_rootfs 'nand read 30008000 100000 400000;bootm 30008000'

[ s3c2440@fulinux ]# set bootcmd 'run bootcmd_rootfs'

注:下面这个设置只为保存nfs的启动bootargs参数

[ s3c2440@fulinux ]# set bootargs_nfs 'noinitrd console=ttyS0,115200 init=/linuxrc mem=64M loglevel=7 root=/dev/nfs rw nfsroot=192.168.1.3:/opt/rootfs ip=192.168.1.111:192.168.1.3:192.168.1.1:255.255.255.0:localhost.com:eth0:off'

[ s3c2440@fulinux ]# set bootargs 'noinitrd console=ttyS0,115200 init=/linuxrc mem=64M loglevel=7 root=/dev/nfs rw nfsroot=192.168.1.3:/opt/rootfs ip=192.168.1.111:192.168.1.3:192.168.1.1:255.255.255.0:localhost.com:eth0:off'

注:上面的设置中ip=<my-ip>:<serv-ip>这两个是必须在bootargs中出现,不然可能无法启动。

[ s3c2440@fulinux ]# set bkr 'tftp 30008000 linuxrom-fulinux.bin;nand erase 100000 400000;nand write 30008000 100000 400000'


[ s3c2440@fulinux ]# pri

bbl=nand erase 0 100000;tftp 30008000 u-boot-$cpu.bin;nand write 30008000 0 $filesize

norbbl=erase bank 1;tftp 30008000 u-boot-$cpu.bin;cp.b 30008000 0 $filesize

bkr=tftp 30008000 uImage-$cpu.gz;nand erase 100000 400000;nand write 30008000 100000 $filesize

bootcmd_rootfs=nand read 30008000 100000 400000;bootm 30008000

tpb=tftp 30008000 uImage-$cpu.gz;tftp 30800000 ramdisk-$cpu.gz;bootm 30008000 

mtdids=nand0=nand0

mtdparts=mtdparts=nand0:1M@0x0(u-boot),5M@0x100000(kernel),10M@0x600000(ramdisk),10M@0x1000000(cramfs),20M@0x1a00000(yaffs2),20M@0x2e00000(ubifs),-(users)

bootdelay=1

baudrate=115200

ethaddr=08:00:3e:26:0a:6b

ethact=dm9000

bcramfs=tftp 30800000 rootfs.cramfs;nand erase f00000 600000;nand write 30800000 f00000 600000

bjffs2=tftp 30008000 rootfs.jffs2;nand erase 1e00000 1400000;nand write.jffs2 30008000 1e00000 1400000

bootargs_jffs2=noinitrd root=/dev/mtdblock4 rootfstype=jffs2 init=/linuxrc console=ttyS0,115200

bootargs_cramfs=noinitrd root=/dev/mtdblock3 rootfstype=cramfs init=/linuxrc console=ttyS0,115200

bootargs_ubifs=console=ttyS0,115200 mem=64M ubi.mtd=6 root=ubi0:rootfs rootwait rootfstype=ubifs rw

bubifs=tftp 30008000 ubifs-$cpu.img;nand erase 6e00000 900000;nand write 30008000 6e00000 900000

cpu=arm920t

brdfs=tftp 30008000 ramdisk.gz;nand erase 500000 a00000;nand write 30008000 500000 500000

filesize=4B065C

fileaddr=30008000

netmask=255.255.255.0

ipaddr=192.168.1.111

serverip=192.168.1.3

bootcmd_ramdisk=nand read 30008000 100000 400000;nand read 30800000 500000 500000;bootm 30008000

bootargs_ramdisk=console=ttyS0,115200 mem=64M initrd=0x30800000,16M root=/dev/ram0 rw loglevel=7

ip=192.168.1.111:192.168.1.3:192.168.1.1:255.255.255.0:localhost.com:eth0:off

bootcmd=run bootcmd_rootfs

bootargs_nfs=noinitrd console=ttyS0,115200 init=/linuxrc mem=64M loglevel=7 root=/dev/nfs rw nfsroot=192.168.1.3:/opt/rootfs ip=192.168.1.111:192.168.1.3:192.168.1.1:255.255.255.0:localhost.com:eth0:off

bootargs=noinitrd console=ttyS0,115200 init=/linuxrc mem=64M loglevel=7 root=/dev/nfs rw nfsroot=192.168.1.3:/opt/rootfs ip=192.168.1.111:192.168.1.3:192.168.1.1:255.255.255.0:localhost.com:eth0:off

注:也可以是下面这样

bootargs=noinitrd console=ttyS0,115200 init=/linuxrc mem=64M loglevel=7 root=/dev/nfs rw nfsroot=192.168.1.3:/opt/rootfs ip=192.168.1.111:192.168.1.3

stdin=serial

stdout=serial

stderr=serial

Environment size: 2123/131068 bytes

[ s3c2440@guowenxue ]#

上面的bootargs参数解析:

initrd, noinitrd:

当你没有使用ramdisk启动系统的时候,你需要使用noinitrd这个参数,但是如果使用了的话,就需要指定initrd=r_addr,size, r_addr表示initrd在内存中的位置,size表示initrd的大小。


console=ttyS?[,options] 使用特定的串口,options可以是这样的形式bbbbpnx,这里bbbb是指串口的波特率,p是奇偶位,n是指的bits。不过我们一般默认会使用console=ttyS0,115200作为参数;有时,在s3c24x0的u-boot环境变量中,我们会看到



console=ttySAC0,115200,这时因为在Linux-2.6以后的某个版本开始(如我们移植的linux-2.6.24),将drivers/serial/s3c2410.c中设置:

#define S3C24XX_SERIAL_NAME    "ttySAC"

另外,在struct uart_driver s3c24xx_uart_drv中定义

.dev_name   = "s3c2410_serial",



这时,我们将上面的两处定义分别修改为下面值就OK了:

#define S3C24XX_SERIAL_NAME    "ttyS"


static struct uart_driver s3c24xx_uart_drv = {

{

  ****

  .dev_name   = "ttyS",

  ****

}


init指定的是内核启起来后,进入系统中运行的第一个脚本,一般init=/linuxrc, 或者init=/etc/preinit,preinit的内容

一般是创建console,null设备节点,运行init程序,挂载一些文件系统等等操作。请注意,很多初学者以为init=/linuxrc

是固定写法,其实不然,/linuxrc指的是/目录下面的linuxrc脚本,一般是一个连接罢了。如果内核找不到linurc文件,

将会依次搜索/sbin/init,/etc/init,bin/init,/bin/sh

mem:        指定内存大小,非必须的

loglevel:   设置内核的调试打印级别,非必须的;

lpj:   该选项为启动时间优化选项,非必须。LPJ值在硬件条件不变的情况下不会变化,这里我们强制设置LPJ的值,

可以节约启动时间。如果没有预设该值的话,内核启动后,使用dmesg可以看到启动过程打印:

>: dmesg | grep BogoMIPS

Calibrating delay loop... 201.93 BogoMIPS (lpj=504832)

如果设置该值后,dmesg则会显示:

>: dmesg | grep BogoMIPS

Calibrating delay loop (skipped)... 201.93 BogoMIPS preset

root:

用来指定rootfs的位置, 常见的情况有: 

ramdisk文件系统使用:root=/dev/ram0 rw

cramfs文件系统使用: root=/dev/mtdblock3 rootfstype=cramfs

jffs2文件系统使用:   root=/dev/mtdblock5 rootfstype=jffs2

yaffs2文件系统使用:  root=/dev/mtdblock4 rootfstype=yaffs2

NFS文件系统使用:  root=/dev/nfs



在文件系统为基于NFS的文件系统时。指定root=/dev/nfs之后,还需要指定nfsroot。

这里的/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)以找出这些参数。其格式如下:

ip:

下面是U-boot官方文档提供的IP参数解析:

setenv bootargs ${bootargs}

ip=${ipaddr}:${serverip}:\

${gatewayip}:${netmask}:\

${hostname:${netdev}:off

 

注意,上面换行的地方均有空格。其中 192.168.1.244是开发板的IP,192.168.1.155

是PC端(或虚拟机)的 IP,上面的IP根据自己的实际情况修改,不要弄错了。

 

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

<my-ip> -- 客户端的互联网地址。如果没设,此地址将由反向地址解析协议(RARP)或启动协议来决定。使用何种协议端

视配置核心时打开的选项以及 参数而定。如果设定此参数,就不会使用反向地址解析协议或启动协议。

<serv-ip> -- 网络文件系统服务端之互联网地址。如果使用反向地址解析协议来决定客户端地址并且设定此参数,则只

接受从指定之服务端传来的回应。要使用不同的机器作为反向地址解析与网络文件系统服务端的话,在此指定你的反向

地址解析协议服务端(保持空白)并在 nfsroot 参数(见上述)中指定你的网络文件系统服务端。如果此项目空白则

使用回答反向地址解析协议或启动协议之服务端的地址。

<gw-ip> -- 网关(gateway)之互联网地址,若服务端位于不同的子网络上时。如果此项目空白则不使用任何网关并假设

服务端在本地的(local)网络上,除非由启动协议接收到值。

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

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

<dev> -- 要使用的网络设备名称。如果为空白,所有设备都会用来发出反向地址解析请求,启动协议请求由最先找到的

设备发出。网络文件系统使用接收到反向地址解析协议或启动协议回应的设备。如果你只有一个设备那你可以不管它。

<suto> -- 用以作为自动配置的方法。如果是 `rarp' 或是 `bootp' 则使用所指示的协议。如果此值为`both' 或空白,

若配置核心时有打开这两种协议则都使用。 `none' 表示不使用自动配置。这种情况下你必须指定前述栏位中所有必要的值。

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

不能使用 `none'作为值。

下载内核:

[ s3c2440@fulinux ]# run bkr

启动:

[ s3c2440@fulinux ]# boot


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章