学习了韦东山老师的视频才知道能够经过设置内核启动参数来从NFS 挂载rootfs ,因而我在NanoPi M1 Plus 开发板上实际试了下,过程当中也终于到一些问题,这里整理一下:linux
apt-get install nfs-kernel-server /etc/init.d/nfs-kernel-server start
能够在 /etc/exports 里修改可挂载的目录 ,修改后记得重启服务web
/home *(rw,sync,no_subtree_check)
如上表示/home 可挂载,* 表示全部ip 均可以挂载shell
Location:
-> Kernel modules
–> Filesystems
—> kmod-fs-nfs <y>
—> kmod-fs-nfs-v3 <y>
—> kmod-fs-nfs-v4 <y>less
已看出KERNEL_ROOT_NFS 依赖于KERNEL_IP_PNP
因此 在Global build settings -> Kernel build options 里选中 Compile the kernel with rootfs on NFS 便可。dom
由于OpenWRT里会根据 openwrt\package\boot\uboot-sunxi\uEnv-default.txt 生成boot.scr ,因此内核启动参数在这里修改。svg
修改openwrt\package\boot\uboot-sunxi\uEnv-default.txt
root=/dev/mmcblk0p2 rootwait
改成
root=/dev/nfs nfsroot=172.16.10.67:/home/lql/my_rootfs/rootfs ip=172.16.10.69:172.16.10.67:172.16.0.1:255.255.0.0::eth0:off rootwaitoop
这里的172.16.10.67:/home/lql/my_rootfs/rootfs 是我从 build_dir/target-arm_cortex-a7+neon-vfpv4_musl_eabi/root-sunxi 里copy过来学习
参考:linux/Documentation/filesystems/nfs/nfsroot.txt 里面有对nfsroot 的参数说明测试
root=/dev/nfs
This is necessary to enable the pseudo-NFS-device. Note that it’s not a
real device but just a synonym to tell the kernel to use NFS instead of
a real device.
nfsroot=[<server-ip>:]<root-dir>[,<nfs-options>]
ip=<client-ip>:<server-ip>:<gw-ip>:<netmask>:<hostname>:<device>:<autoconf>:<dns0-ip>:<dns1-ip>ui
[ 6.408050] dwmac-sun8i 1c30000.ethernet eth0: Link is Up - 100Mbps/Full - flow control rx/tx [ 6.437281] IPv6: ADDRCONF(NETDEV_CHANGE): eth0: link becomes ready [ 6.467345] IP-Config: Complete: [ 6.470578] device=eth0, hwaddr=00:00:00:f0:08:80, ipaddr=172.16.10.69, mask=255.255.0.0, gw=172.16.0.1 [ 6.480414] host=172.16.10.69, domain=, nis-domain=(none) [ 6.486240] bootserver=172.16.10.67, rootserver=172.16.10.67, rootpath= [ 6.493634] vcc3v0: disabling [ 6.496605] vcc5v0: disabling [ 6.499592] ALSA device list: [ 6.502555] No soundcards found. [ 6.507254] NOHZ: local_softirq_pending 80 [ 6.511363] NOHZ: local_softirq_pending 88 [ 6.520386] VFS: Mounted root (nfs filesystem) readonly on device 0:10. [ 6.529150] Freeing unused kernel memory: 2048K [ 6.537255] NOHZ: local_softirq_pending 80 [ 6.541361] NOHZ: local_softirq_pending 88 [ 6.547269] NOHZ: local_softirq_pending 08 [ 6.557257] NOHZ: local_softirq_pending 80 [ 6.567261] NOHZ: local_softirq_pending 08 [ 6.577251] NOHZ: local_softirq_pending 82 [ 6.583300] random: fast init done [ 6.597265] NOHZ: local_softirq_pending 82 [ 6.617266] NOHZ: local_softirq_pending 08 [ 6.652067] init: Console is alive [ 6.655694] init: - watchdog - [ 6.828851] kmodloader: loading kernel modules from /etc/modules-boot.d/* [ 6.850805] JFS: nTxBlock = 8049, nTxLock = 64399 [ 6.866231] kmodloader: done loading kernel modules from /etc/modules-boot.d/* [ 6.882747] init: - preinit - [ 7.058118] random: jshn: uninitialized urandom read (4 bytes read) [ 7.094100] random: jshn: uninitialized urandom read (4 bytes read) [ 7.118780] random: jshn: uninitialized urandom read (4 bytes read) ip: RTNETLINK answers: File exists Press the [f] key and hit [enter] to enter failsafe mode Press the [1], [2], [3] or [4] key and hit [enter] to select the debug level [ 10.269838] mount_root: mounting /dev/root [ 10.283215] urandom-seed: Seed file not found (/etc/urandom.seed) [ 19.447267] nfs: server 172.16.10.67 not responding, still trying
坑1:nfs: server 172.16.10.67 not responding, still trying
缘由分析:
设备ip配置的是172.16.10.69,ping 172.16.10.69 结果
root@localhost:~# ping 172.16.10.69 PING 172.16.10.69 (172.16.10.69) 56(84) bytes of data. From 172.16.6.128 icmp_seq=1 Destination Host Unreachable From 172.16.6.128 icmp_seq=2 Destination Host Unreachable From 172.16.6.128 icmp_seq=3 Destination Host Unreachable From 172.16.6.128 icmp_seq=4 Destination Host Unreachable From 172.16.6.128 icmp_seq=5 Destination Host Unreachable From 172.16.6.128 icmp_seq=6 Destination Host Unreachable From 172.16.6.128 icmp_seq=7 Destination Host Unreachable From 172.16.6.128 icmp_seq=8 Destination Host Unreachable From 172.16.6.128 icmp_seq=9 Destination Host Unreachable 64 bytes from 172.16.10.69: icmp_seq=10 ttl=64 time=972 ms 64 bytes from 172.16.10.69: icmp_seq=11 ttl=64 time=0.657 ms 64 bytes from 172.16.10.69: icmp_seq=12 ttl=64 time=0.546 ms 64 bytes from 172.16.10.69: icmp_seq=13 ttl=64 time=0.653 ms 64 bytes from 172.16.10.69: icmp_seq=14 ttl=64 time=0.646 ms From 172.16.6.128 icmp_seq=66 Destination Host Unreachable From 172.16.6.128 icmp_seq=67 Destination Host Unreachable
发现中途链接成功了,后面又断开了,猜想是设备ip 变动致使。
结合前面打印,init: - preinit - 以后开始感受不太对劲。
跟踪一下 preinit ,就是个启动脚本,位于
172.16.10.67:/home/lql/my_rootfs/rootfs/etc/preinit
首行添加 set -xv ,这样能够展开命令行,方便跟踪.
重新上电后,发现卡在这里。
install_bin() { local src files src=$1 files=$1 [ -x "$src" ] && files="$src $(libs $src)" install_file + '[' -e ] + return 1 + boot_hook_shift preinit_mount_root fu+ return + uci -q get 'system.@system[0].urandom_seed' + SEED= + '[' '==' / -a '!=' /etc/urandom.seed ] + boot_hook_shift preinit_main func + local 'hook=preinit_main_hook' + local 'rv+ local netdev vid + netdev=eth0 + vid=eth0 + '[' eth0 '=' et+ ip link set dev eth0 down [ 20.480996] nfs: server 172.16.10.67 not responding, still trying
root@debian:rootfs# grep "ip link set dev" . -rn ./lib/netifd/wireless/mac80211.sh:513: ip link set dev "$ifname" address "$macaddr" ./lib/netifd/wireless/mac80211.sh:670: ip link set dev "$ifname" up || { ./lib/netifd/wireless/mac80211.sh:729: ip link set dev "$wdev" down 2>/dev/null ./lib/preinit/10_indicate_preinit:21: ip link set dev $netdev up ./lib/preinit/10_indicate_preinit:133: ip link set dev $netdev down
查看rootfs/lib/preinit/10_indicate_preinit 发现里面确实对eth0 有down 操做。这里须要修改
我修改后的 rootfs/lib/preinit/10_indicate_preinit
118 119 preinit_ip_deconfig() { 120 #boot from NFS,should return here 121 return 0 122 [ -n "$pi_ifname" ] && grep -q "$pi_ifname" /proc/net/dev && { 123 local netdev vid 124 125 netdev=${pi_ifname%\.*} 126 vid=${pi_ifname#*\.} 127 128 if [ "$vid" = "$netdev" ]; then 129 vid= 130 fi 131 132 ip -4 address flush dev $pi_ifname 133 ip link set dev $netdev down 134 135 if [ -n "$vid" ]; then 136 ip link delete $pi_ifname 137 fi 138 } 139 }
从新上电,运行OK。
BusyBox v1.28.3 () built-in shell (ash) _______ ________ __ | |.-----.-----.-----.| | | |.----.| |_ | - || _ | -__| || | | || _|| _| |_______|| __|_____|__|__||________||__| |____| |__| W I R E L E S S F R E E D O M ----------------------------------------------------- OpenWrt 18.06.1, r7258-5eb055306f ----------------------------------------------------- root@172:/# root@172:/# root@172:/# ifconfig -a eth0 Link encap:Ethernet HWaddr xx:xx:xx:35:4A:71 inet addr:172.16.10.69 Bcast:172.16.255.255 Mask:255.255.0.0 inet6 addr: fd45:3a5d:aef5::d813:14ff:fe35:4a71/64 Scope:Global inet6 addr: fe80::d813:14ff:fe35:4a71/64 Scope:Link inet6 addr: fdd0:b256:b6ca::d813:14ff:fe35:4a71/64 Scope:Global UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:2616 errors:0 dropped:5 overruns:0 frame:0 TX packets:1268 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:2470844 (2.3 MiB) TX bytes:196349 (191.7 KiB) Interrupt:34 lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 inet6 addr: ::1/128 Scope:Host UP LOOPBACK RUNNING MTU:65536 Metric:1 RX packets:0 errors:0 dropped:0 overruns:0 frame:0 TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:0 (0.0 B) TX bytes:0 (0.0 B) root@172:/# [ 190.176558] random: crng init done [ 190.179978] random: 4 urandom warning(s) missed due to ratelimiting root@172:/# root@172:/#
root@OpenWrt:/# mount -t nfs -o nolock 172.16.10.67:/home /mnt/nfs/ mount: mounting 172.16.10.67:/home on /mnt/nfs/ failed: Protocol not supported
缘由分析:nfs 有多种协议 nfs-v3 nfs-v4 等,内核支持的协议不匹配
解决办法:配置内核时,增长 kmod-fs-nfs-v3 kmod-fs-nfs-v4 的支持
[ 110.565339] VFS: Unable to mount root fs via NFS, trying floppy. [ 110.571675] VFS: Cannot open root device "nfs" or unknown-block(2,0): error -6
解决办法:配置内核时,开启对KERNEL_ROOT_NFS 的支持
已经KERNEL_ROOT_NFS =y ? 仍有上述问题? 须要制定 nfs version
root=/dev/nfs nfsroot=172.16.10.67:/home/lql/my_rootfs/rootfs,vers=3 xxxx
挂载NFS 根文件系统必需要使用静态ip,挂载成功后也不容许ip 发生更改,不然就会报nfs: server 172.16.10.67 not responding 的错误。