环境介绍
- 宿主操作系统为Ubuntu18.04 (64位)
- uboot版本:U-Boot 1.1.6
- linux内核版本:Linux version 2.6.22.6 (arm-none-linux-gcc version 3.4.5)
- 开发板用的是S3C2440的SoC
- bootargs为
"root=/dev/nfs rw nfsroot=192.168.3.100:/home/macrofun/NFS_ROOT init=/linuxrc ip=192.168.3.110 console=ttySAC0,115200"
失败现象
Kernel command line: root=/dev/nfs rw nfsroot=192.168.3.100:/home/macrofun/NFS_ROOT init=/linuxrc ip=192.168.3.110 console=ttySAC0,115200
·········
IP-Config: Guessing netmask 255.255.255.0
IP-Config: Complete:
device=eth0, addr=192.168.3.110, mask=255.255.255.0, gw=255.255.255.255,
host=192.168.3.110, domain=, nis-domain=(none),
bootserver=255.255.255.255, rootserver=192.168.3.100, rootpath=
Looking up port of RPC 100003/2 on 192.168.3.100
Looking up port of RPC 100005/1 on 192.168.3.100
VFS: Unable to mount root fs via NFS, trying floppy.
VFS: Cannot open root device "nfs" or unknown-block(2,0)
Please append a correct "root=" boot option; here are the available partitions:
1f00 256 mtdblock0 (driver?)
1f01 128 mtdblock1 (driver?)
1f02 2048 mtdblock2 (driver?)
1f03 259712 mtdblock3 (driver?)
Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(2,0)
解决方法
- 比较初级的错误是因为bootargs参数格式书写错误,有人少加了分号,有人少加了逗号,还有些是单词拼写错误,这种错误已排除。继续向下分析。
- 首先,考虑是否是编译内核时没有使用NFS v3 v4版本,查看menuconfig,配置如下所示:
File systems —> Network File Systems
<*> NFS file system support
[*] Provide NFSv3 client support
[*] Provide client support for the NFSv3 ACL protocol extension
[*] Provide NFSv4 client support (EXPERIMENTAL)
[*] Allow direct I/O on NFS files
< > NFS server support
[*] Root file system on NFS
开发板内核镜像中NFS v3 v4功能以及NFS挂载根文件系统功能 确实 都已使能。
- 查看宿主系统Ubuntu中NFS服务开启情况
macrofun@WDS-Ubuntu:~$ sudo cat /proc/fs/nfsd/versions
-2 +3 +4 +4.1 +4.2
macrofun@WDS-Ubuntu:~$ rpcinfo -p WDS-Ubuntu | fgrep nfs
100003 3 tcp 2049 nfs
100003 4 tcp 2049 nfs
100003 3 udp 2049 nfs
可以看到,Ubuntu中已启用NFS v3 v4两种版本的服务。
- 考虑可能是NFS版本不兼容,尝试使用NFS v4版本
"root=/dev/nfs rw nfsroot=192.168.3.100:/home/macrofun/NFS_ROOT,nolock,proto=tcp,nfsvers=4 init=/linuxrc ip=192.168.3.110 console=ttySAC0,115200"
依旧失败,并且提示Root-NFS: unknown option: nfsvers=4。猜测可能是linux2.6.22版本对NFS v4支持不完善。
Kernel command line: root=/dev/nfs rw nfsroot=192.168.3.100:/home/macrofun/NFS_ROOT,nolock,proto=tcp,nfsvers=4 init=/linuxrc ip=192.168.3.110 console=ttySAC0,115200
·········
IP-Config: Guessing netmask 255.255.255.0
IP-Config: Complete:
device=eth0, addr=192.168.3.110, mask=255.255.255.0, gw=255.255.255.255,
host=192.168.3.110, domain=, nis-domain=(none),
bootserver=255.255.255.255, rootserver=192.168.3.100, rootpath=
Root-NFS: unknown option: nfsvers=4
Looking up port of RPC 100003/2 on 192.168.3.100
Looking up port of RPC 100005/1 on 192.168.3.100
VFS: Unable to mount root fs via NFS, trying floppy.
VFS: Cannot open root device "nfs" or unknown-block(2,0)
Please append a correct "root=" boot option; here are the available partitions:
1f00 256 mtdblock0 (driver?)
1f01 128 mtdblock1 (driver?)
1f02 2048 mtdblock2 (driver?)
1f03 259712 mtdblock3 (driver?)
Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(2,0)
- 继续尝试使用NFS v3来进行根文件系统的挂载。
"root=/dev/nfs rw nfsroot=192.168.3.100:/home/macrofun/NFS_ROOT,nolock,proto=tcp,nfsvers=3 init=/linuxrc ip=192.168.3.110 console=ttySAC0,115200"
根文件系统加载成功。问题成功解决。确认是NFS版本不兼容导致的。
- 更进一步,如果有些给定的开发板内核镜像只支持NFS v2,那么就需要在Ubuntu中启用NFS v2服务。
macrofun@WDS-Ubuntu:~$ sudo vim /etc/default/nfs-kernel-server
在该配置文件中添加如下的一行内容
RPCNFSDOPTS="--nfs-version 2,3,4 --debug --syslog"
之后,重启nfs服务
macrofun@WDS-Ubuntu:~$ sudo service nfs-kernel-server restart
macrofun@WDS-Ubuntu:~$ rpcinfo -p WDS-Ubuntu | fgrep nfs
100003 2 tcp 2049 nfs
100003 3 tcp 2049 nfs
100003 4 tcp 2049 nfs
100003 2 udp 2049 nfs
100003 3 udp 2049 nfs
可以看到,NFS v2已经启动。
此时,修改参数,使用NFS v2进行根文件系统的挂载。
"root=/dev/nfs rw nfsroot=192.168.3.100:/home/macrofun/NFS_ROOT,nolock,proto=tcp,nfsvers=2 init=/linuxrc ip=192.168.3.110 console=ttySAC0,115200"
同样成功挂载,现在即使去掉nfsvers参数,依然可以成功挂载根文件系统,因为此时不指定NFS版本,默认按照v2进行挂载。
root=/dev/nfs rw nfsroot=192.168.3.100:/home/macrofun/NFS_ROOT init=/linuxrc ip=192.168.3.110 console=ttySAC0,115200
结论
linux2.6.22内核对于NFS v4版本的支持不是非常完善,为稳妥起见,采用NFS v3进行根文件系统的挂载操作。同时为了兼容只支持NFS v2的内核,在ubuntu中启用了NFS v2服务,这样,即使不指定NFS版本,它也会按照v2版本进行成功挂载。