nfs挂载根文件系统失败

本文主要探讨了在Ubuntu 18.04及更高版本中,由于NFS协议版本不匹配导致的挂载根文件系统失败的问题。首先,通过`nfsstat -v`命令检查NFS版本,发现从17.04版开始,默认只支持协议3和4。当kernel仅支持协议2时,需要修改NFS配置文件并重启服务;对于kernel支持协议3的情况,可通过修改u-boot的bootargs解决。而在Ubuntu 22.04中,由于默认关闭了NFS的udp端口,挂载失败,解决方案包括使用tcp挂载或启用udp连接。

nfs挂载根文件系统失败

问题一:挂载前,需要得知nfs使用的版本

确认host端的nfs支持的版本,使用命令nfsstat -v查看

原因:

​ 以前使用的16.04版本的ubuntu没问题,现在更换了18.04版本,开始报错。从Ubuntu17.04开始,nfs默认只支持协议3和协议4,而kernel中默认支持协议2。

如何查看板子kernel支持的协议:

​ 可以通过编译内核配置查看

​ File systems —>

​ Network File Systems —>

在这里插入图片描述

这里可以看到板子作为客户端,支持2、3、4版本,默认支持协议2。

1. 如果kernel只支持协议2

  1. 修改 NFS 配置文件:
sudo vim /etc/default/nfs-kernel-server
  1. 在末尾添加:
RPCNFSDOPTS="--nfs-version 2,3,4 --debug --syslog"
  1. 重启NFS服务:
sudo /etc/init.d/nfs-kernel-server restart

2. kernel版本较高支持协议3

可以修改u-boot的bootargs,例如:

setenv bootargs root=/dev/nfs rw nfsroot=192.168.9.119:/nfs/rootfs,v3 console=ttyS0,115200 init=/linuxrc ip=192.168.9.110

添加一个v3或者nfsvers=3

问题二:Ubuntu22.04使用上述bootargs不能成功使用NFS挂载

问题就出在ubuntu 22.04默认关闭了nfs的udp端口连接

而kernel默认使用的是udp连接

方法一:

添加一个参数,使用tcp挂载:

setenv bootargs root=/dev/nfs rw nfsroot=192.168.9.119:/nfs/rootfs,v3,tcp console=ttyS0,115200 init=/linuxrc ip=192.168.9.110

方法二:

添加/etc/nfs.conf.d/udp.conf文件,启动主机的udp连接:

[nfsd]
udp=n
<think> 我们正在解决NFS挂载根文件系统失败,并出现“IP-Config: Failed to open eth0”和“IP-Config: Device `eth0' not found”的问题。根据引用[1][2][4],这通常与网络驱动(eth0)未正确初始化有关。以下是逐步解决方案: ### 步骤1: 确认内核网络驱动支持 - 确保内核编译时已启用正确的网络驱动(如DM9000、SMSC911x等)。检查内核配置: ```bash make menuconfig ``` 在配置菜单中,确认以下选项: ``` Device Drivers → Network device support → Ethernet driver support → [*] DM9000 support # 如果是DM9000网卡 ``` 或者根据实际网卡型号选择驱动(引用[5]提到DM9000的驱动问题)。 ### 步骤2: 设备树(DTS)配置 - 检查设备树是否正确描述了网络硬件。例如,对于DM9000网卡,设备树节点应包含: ```dts dm9000 { compatible = "davicom,dm9000"; reg = <0x20000000 0x2 0x20000004 0x2>; interrupt-parent = <&gpx>; interrupts = <7 4>; davicom,no-eeprom; mac-address = [00 0a 2d a6 55 a2]; }; ``` - 确认寄存器地址、中断号和MAC地址正确(引用[5]提到MAC地址问题)。 ### 步骤3: 检查MAC地址设置 - 如果MAC地址无效(如全0),内核会使用软MAC地址(如08:90:90:90:90:90)并警告(引用[5])。解决方法: - 在设备树中指定有效MAC地址(如上例的`mac-address`属性)。 - 或在驱动代码中强制设置(不推荐,应通过设备树或启动参数传递)。 ### 步骤4: U-boot环境变量配置 - 确保U-boot的`bootargs`正确设置网络参数(引用[4]): ```bash setenv bootargs 'console=ttyS0,115200 root=/dev/nfs nfsroot=192.168.1.100:/nfsroot ip=192.168.1.10:192.168.1.100:192.168.1.1:255.255.255.0::eth0:off' ``` - 特别注意`ip=`参数的格式:`<开发板IP>:<NFS服务器IP>:<网关>:<子网掩码>::<网卡>:off` - 使用`eth0`作为网卡名称(与驱动注册的名称一致)。 ### 步骤5: 检查硬件连接和初始化 - **硬件检查**:确保网线连接正常,且交换机/路由器工作正常。 - **内核启动日志**:在U-boot中添加`loglevel=8`参数,查看详细启动日志: ```bash setenv bootargs ... loglevel=8 ``` 关注: - 网卡驱动的探测和注册信息。 - 是否出现资源冲突(如内存地址、中断)。 ### 步骤6: 禁用IPv6 - 如果内核配置了IPv6,但网络环境不支持,可能导致初始化延迟。在内核启动参数中添加: ```bash ipv6.disable=1 ``` ### 步骤7: 驱动加载顺序问题 - 若网卡依赖其他驱动(如时钟、复位控制器),确保依赖驱动先加载。检查设备树中的依赖关系(如`clocks`、`resets`属性)。 ### 调试技巧 - **手动初始化网卡**:在内核启动后,尝试手动初始化: ```bash ifconfig eth0 down ifconfig eth0 up ``` - **检查网络配置**: ```bash ifconfig -a # 查看所有网络接口 dmesg | grep eth0 # 过滤相关日志 ``` > 💡 **常见原因统计**: > - 设备树配置错误(占60%以上)[^2][^5]。 > - U-boot网络参数错误(占20%)[^4]。 > - 驱动未编译进内核(占15%)[^1]。 §§相关问题§§ 1. 如何检查Linux内核是否包含特定网卡驱动? 2. 设备树中如何正确配置网络接口? 3. U-boot中如何设置网络启动参数? 4. Linux内核启动时如何调试网络驱动? </think> ### 解决 NFS 挂载根文件系统失败:`IP-Config: Device 'eth0' not found` 的完整方案 #### 步骤 1: 确认网卡驱动加载(核心问题) 问题本质是内核未初始化网卡硬件,导致找不到 `eth0` 设备(引用[1][2][4])。 **解决方法**: 1. **检查内核配置**: ```bash grep DM9000 .config # 替换为实际网卡型号(如 SMSC911x) ``` - 确保输出包含: ```config CONFIG_DM9000=y # 或 CONFIG_SMSC911X=y ``` 2. **验证设备树配置**(关键): - 检查设备树文件(如 `arch/arm/boot/dts/myboard.dts`)是否包含网卡节点: ```dts &amba { ethernet@40000000 { compatible = "davicom,dm9000"; // 匹配驱动 reg = <0x40000000 0x2 0x40000004 0x2>; // 寄存器地址 interrupts = <7 IRQ_TYPE_LEVEL_HIGH>; // 中断号 local-mac-address = [00 0a 35 00 1e 53]; // MAC地址 }; }; ``` - 编译并更新设备树: ```bash make dtbs && cp arch/arm/boot/dts/myboard.dtb /tftp/ # 复制到TFTP目录 ``` #### 步骤 2: 修复 MAC 地址问题 内核日志若提示 "Invalid MAC address",需强制指定 MAC 地址(引用[5]): - **方法 1:在设备树添加**: ```dts local-mac-address = [00 0a 35 00 1e 53]; // 替换为有效MAC ``` - **方法 2:在驱动代码修改**(临时方案): 在网卡驱动源码(如 `drivers/net/ethernet/davicom/dm9000.c`)中: ```c if (!is_valid_ether_addr(ndev->dev_addr)) { memcpy(ndev->dev_addr, "\x00\x0a\x35\x00\x1e\x53", 6); // 硬编码MAC } ``` #### 步骤 3: 优化 U-boot 启动参数 确保 `bootargs` 包含完整的网络配置(引用[4]): ```bash setenv bootargs 'console=ttyS0,115200 root=/dev/nfs \ # 关键参数 nfsroot=192.168.1.100:/nfs/rootfs \ # NFS服务器路径 ip=192.168.1.10::192.168.1.1:255.255.255.0::eth0:off \ # IP/网关/子网掩码 nfsvers=3' # 指定NFS版本 saveenv ``` - **参数说明**: - `ip=开发板IP::网关:子网掩码::网卡:off` - `nfsvers=3`:强制使用 NFS v3(避免版本兼容问题) #### 步骤 4: 检查硬件初始化顺序 若网卡依赖其他外设(如电源管理),需确保初始化顺序正确: 1. 在设备树中为网卡添加依赖: ```dts vcc3v3: regulator { // 网卡电源 compatible = "regulator-fixed"; regulator-name = "vcc3v3"; gpio = <&gpio0 12 GPIO_ACTIVE_HIGH>; // 控制引脚 }; ðernet { vin-supply = <&vcc3v3>; // 声明依赖 }; ``` 2. 在驱动代码确认资源获取: ```c int dm9000_probe(struct platform_device *pdev) { struct regulator *vcc = devm_regulator_get(&pdev->dev, "vin"); regulator_enable(vcc); // 启用电源 } ``` #### 步骤 5: 调试与验证 1. **启用内核调试日志**: ```bash setenv bootargs ... loglevel=8 # 在U-boot中设置 ``` - 查看内核启动日志,过滤网卡相关消息: ```bash dmesg | grep -E 'dm9000|eth0|MAC' ``` 2. **硬件信号测试**: - 用示波器检测网卡引脚: - `SD0~SD15`(数据总线)是否有信号 - 中断引脚(如 `EINT7`)是否触发 - 确认寄存器读写正常(通过 U-boot 命令): ```bash mw 0x40000000 0x01 1 # 向控制寄存器写入值 md 0x40000000 1 # 读取验证 ``` > 💡 **根本原因统计**: > - 设备树未配置网卡节点(占 50% 案例) > - MAC 地址无效导致驱动初始化失败(占 30%) > - U-boot 网络参数错误(占 15%)
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值