通过NFS(nfsroot)挂载根文件系统¶
- 作者:
由 Gero Kuhlmann <gero@gkminix.han.de> 于 1996 年编写
由 Martin Mares <mj@atrey.karlin.mff.cuni.cz> 于 1997 年更新
由 Nico Schottelius <nico-kernel-nfsroot@schottelius.org> 于 2006 年更新
由 Horms <horms@verge.net.au> 于 2006 年更新
由 Chris Novakovic <chris@chrisn.me.uk> 于 2018 年更新
为了使用无盘系统,例如X终端或打印服务器,根文件系统必须存在于非磁盘设备上。这可以是initramfs(参见Ramfs、rootfs和initramfs),ramdisk(参见使用初始RAM盘(initrd))或通过NFS挂载的文件系统。以下文本描述了如何将NFS用于根文件系统。在本文的其余部分中,“客户端”指无盘系统,“服务器”指NFS服务器。
启用nfsroot功能¶
为了使用nfsroot,在配置过程中需要选择将NFS客户端支持作为内置功能。一旦选择此项,nfsroot选项将可用,也应将其选中。
在网络选项中,可以选择内核级别的自动配置,以及支持的自动配置类型。同时选择DHCP、BOOTP和RARP是安全的。
内核命令行¶
当内核被引导加载程序(见下文)加载后,需要告知它使用哪个根文件系统设备。对于nfsroot,还需要告知服务器位置以及服务器上要挂载为根目录的名称。这可以通过使用以下内核命令行参数来建立:
- root=/dev/nfs
这是启用伪NFS设备所必需的。请注意,它不是一个真实的设备,而只是一个告诉内核使用NFS而非真实设备的同义词。
- nfsroot=[<server-ip>:]<root-dir>[,<nfs-options>]
如果命令行中未提供nfsroot参数,将使用默认值
"/tftpboot/%s"
。- <server-ip> 指定NFS服务器的IP地址。
默认地址由ip参数(见下文)决定。此参数允许为IP自动配置和NFS使用不同的服务器。
- <root-dir> 服务器上要挂载为根目录的名称。
如果字符串中存在“%s”标记,它将被客户端IP地址的ASCII表示替换。
- <nfs-options> 标准NFS选项。所有选项用逗号分隔。
使用以下默认值:
port = as given by server portmap daemon rsize = 4096 wsize = 4096 timeo = 7 retrans = 3 acregmin = 3 acregmax = 60 acdirmin = 30 acdirmax = 60 flags = hard, nointr, noposix, cto, ac
- ip=<client-ip>:<server-ip>:<gw-ip>:<netmask>:<hostname>:<device>:<autoconf>:<dns0-ip>:<dns1-ip>:<ntp0-ip>
此参数告诉内核如何配置设备的IP地址以及如何设置IP路由表。它最初被称为nfsaddrs,但现在启动时的IP配置独立于NFS工作,因此它被重命名为ip,旧名称保留作为兼容性别名。
如果内核命令行中缺少此参数,则所有字段都假定为空,并应用下面提到的默认值。通常这意味着内核会尝试使用自动配置来配置所有内容。
<autoconf>
参数可以单独作为ip参数的值出现(前面不带所有‘:’字符)。如果值为“ip=off”或“ip=none”,则不会进行自动配置,否则将进行自动配置。最常见的用法是“ip=dhcp”。- <client-ip> 客户端的IP地址。
默认值:通过自动配置确定。
- <server-ip> NFS服务器的IP地址。
如果使用RARP确定客户端地址,并且此参数不为空,则只接受来自指定服务器的回复。
仅NFS根文件系统需要。也就是说,如果缺少此参数且NFS根文件系统未在运行,则不会触发自动配置。
值将以“bootserver ”为前缀导出到 /proc/net/pnp(见下文)。
默认值:通过自动配置确定。使用自动配置服务器的地址。
- <gw-ip> 如果服务器在不同的子网,则为网关的IP地址。
默认值:通过自动配置确定。
- <netmask> 本地网络接口的子网掩码。
如果未指定,则子网掩码将根据客户端IP地址(假设为有类地址)推导得出。
默认值:通过自动配置确定。
- <hostname> 客户端名称。
如果存在“.”字符,则第一个“.”之前的部分用作客户端的主机名,之后的部分用作其NIS域名。它可以由自动配置提供,但其缺失不会触发自动配置。如果指定且使用DHCP,则用户提供的主机名(以及NIS域名,如果存在)将包含在DHCP请求中;这可能会导致为客户端创建或更新DNS记录。
默认值:客户端IP地址以ASCII表示法使用。
- <device> 要使用的网络设备名称。
默认值:如果主机只有一个设备,则使用该设备。否则,设备通过自动配置确定。这是通过向所有设备发送自动配置请求,并使用第一个收到回复的设备来完成的。
- <autoconf> 自动配置使用的方法。
对于指定多个自动配置协议的选项,将使用所有协议发送请求,并使用第一个回复的协议。
无论此选项的值如何,只会使用已编译到内核中的自动配置协议。
off or none: don't use autoconfiguration (do static IP assignment instead) on or any: use any protocol available in the kernel (default) dhcp: use DHCP bootp: use BOOTP rarp: use RARP both: use both BOOTP and RARP but not DHCP (old option kept for backwards compatibility)
如果使用dhcp,客户端标识符可以使用以下格式“ip=dhcp,client-id-type,client-id-value”
默认值:any
- <dns0-ip> 主域名服务器的IP地址。
值将以“nameserver ”为前缀导出到 /proc/net/pnp(见下文)。
默认值:如果未使用自动配置则为无;如果使用自动配置则自动确定。
- <dns1-ip> 辅助域名服务器的IP地址。
参见 <dns0-ip>。
- <ntp0-ip> 网络时间协议 (NTP) 服务器的IP地址。
值将导出到 /proc/net/ipconfig/ntp_servers,但除此之外未被使用(见下文)。
默认值:如果未使用自动配置则为无;如果使用自动配置则自动确定。
配置(无论是手动还是自动)完成后,将创建两个文件,格式如下;如果相应值在配置后为空,则省略该行
/proc/net/pnp
#PROTO: <DHCP|BOOTP|RARP|MANUAL> (取决于配置方法) domain <dns-domain> (如果自动配置,则为DNS域) nameserver <dns0-ip> (主域名服务器IP) nameserver <dns1-ip> (辅助域名服务器IP) nameserver <dns2-ip> (第三域名服务器IP) bootserver <server-ip> (NFS服务器IP)
/proc/net/ipconfig/ntp_servers
<ntp0-ip> (NTP服务器IP) <ntp1-ip> (NTP服务器IP) <ntp2-ip> (NTP服务器IP)
<dns-domain> 和 <dns2-ip>(在 /proc/net/pnp 中)以及 <ntp1-ip> 和 <ntp2-ip>(在 /proc/net/ipconfig/ntp_servers 中)在自动配置期间被请求;它们不能作为“ip=”内核命令行参数的一部分指定。
由于“domain”和“nameserver”选项被DNS解析器识别,因此在使用NFS根文件系统的系统上,/etc/resolv.conf 通常链接到 /proc/net/pnp。
请注意,内核不会将其发现的任何NTP服务器同步系统时间;这是用户空间进程的责任(例如,如果真实根文件系统在NFS上,initrd/initramfs脚本会在挂载真实根文件系统之前将 /proc/net/ipconfig/ntp_servers 中列出的IP地址传递给NTP客户端)。
- nfsrootdebug
此参数启用在启动时在内核日志中显示调试消息,以便管理员可以验证正确的NFS挂载选项、服务器地址和根路径是否传递给了NFS客户端。
- rdinit=<executable file>
为了指定哪个文件包含启动系统初始化的程序,管理员可以使用此命令行参数。此参数的默认值为“/init”。如果指定的文件存在且内核可以执行它,则与根文件系统相关的内核命令行参数(包括“nfsroot=”)将被忽略。
挂载根文件系统的过程描述可以在早期用户空间支持中找到。
引导加载程序¶
要将内核加载到内存中,可以使用不同的方法。它们取决于各种可用功能
使用syslinux从软盘引导
构建内核时,创建使用syslinux的引导软盘的简单方法是使用zdisk或bzdisk make目标,它们分别使用zimage和bzimage镜像。这两个目标都接受FDARGS参数,可用于设置内核命令行。
例如
make bzdisk FDARGS="root=/dev/nfs"
请注意,运行此命令的用户需要有权访问软盘驱动器设备,即 /dev/fd0。
有关syslinux的更多信息,包括如何为预构建的内核创建引导盘,请参见https://syslinux.zytor.com/
注意
以前,可以直接使用dd将内核写入软盘,使用rdev配置引导设备,并使用生成的软盘引导。Linux不再支持这种引导方法。
使用isolinux从光盘引导
构建内核时,创建使用isolinux的可引导光盘的简单方法是使用isoimage目标,它使用bzimage镜像。与zdisk和bzdisk类似,此目标接受FDARGS参数,可用于设置内核命令行。
例如
make isoimage FDARGS="root=/dev/nfs"
生成的ISO镜像将是 arch/<ARCH>/boot/image.iso。可以使用包括cdrecord在内的各种工具将其写入光盘。
例如
cdrecord dev=ATAPI:1,0,0 arch/x86/boot/image.iso
有关isolinux的更多信息,包括如何为预构建的内核创建引导盘,请参见https://syslinux.zytor.com/
使用LILO
使用LILO时,所有必要的命令行参数都可以使用LILO配置文件中的“append=”指令指定。
但是,要使用“root=”指令,您还需要创建一个虚拟根设备,该设备可以在LILO运行后删除。
例如
mknod /dev/boot255 c 0 255
有关配置LILO的信息,请参阅其文档。
使用GRUB
使用GRUB时,内核参数只需在内核规范后附加即可:kernel <kernel> <parameters>
使用loadlin
loadlin可用于从DOS命令行引导Linux,而无需将本地硬盘挂载为根目录。本文作者尚未对此进行彻底测试,但一般来说,应该可以像配置LILO一样配置内核命令行。
有关更多信息,请参阅loadlin文档。
使用引导ROM
这可能是引导无盘客户端最优雅的方式。使用引导ROM,内核通过TFTP协议加载。本文作者不知道有任何支持通过网络引导Linux的商业引导ROM。但是,有两个免费的引导ROM实现:netboot-nfs和etherboot,它们都可以在sunsite.unc.edu上找到,并且都包含引导无盘Linux客户端所需的一切。
使用pxelinux
Pxelinux可用于使用许多现代网卡上存在的PXE引导加载程序引导Linux。
使用pxelinux时,内核镜像使用“kernel <relative-path-below /tftpboot>”指定。nfsroot参数通过添加到“append”行传递给内核。通常将串口控制台与pxelinux结合使用,有关更多信息,请参见Linux串口控制台。
有关isolinux的更多信息,包括如何为预构建的内核创建引导盘,请参见https://syslinux.zytor.com/
致谢¶
内核中的nfsroot代码和RARP支持由 Gero Kuhlmann <gero@gkminix.han.de> 编写。
IP层自动配置代码的其余部分由 Martin Mares <mj@atrey.karlin.mff.cuni.cz> 编写。
为了编写nfsroot的初始版本,我要感谢 Jens-Uwe Mager <jum@anubis.han.de> 的帮助。