Mounting the root filesystem via NFS (nfsroot)
英文原文位於inux內核源代碼中的"Documentation/filesystems/nfs/nfsroot.txt"。
1996年由Gero Kuhlmann <gero@gkminix.han.de>初次編寫,
1997年經Martin Mares <mj@atrey.karlin.mff.cuni.cz>,
2006年經Nico Schottelius <nico-kernel-nfsroot@schottelius.org>和Horms <horms@verge.net.au>更新。
為了使用一個無磁盤的系統(例如一個X終端或打印機),將根文件系統存放在非磁盤設備是必要的。它可以是通過NFS掛載的一個initramfs文件(參考Documentation/filesystems/ramfs-rootfs-initramfs.txt),或者一個ramdisk文件(參考Documentation/initrd.txt)或者一個文件系統。以下內容描述了如何通過NFS獲取linux的根文件系統來啟動系統。下文的客戶端('client')表示無磁盤系統,服務器端('server')表示NFS服務器。
1.)啟動nfsroot功能
為了使用nfsroot功能,在編譯配置時,NFS客戶端必須被選擇為內置(built-in, 非模塊)文件系統。NFS客戶端被設置為內置,nfsroot選項將變為可選項,選擇后才支持nfsroot功能(譯者注:在沒有將NFS客戶端設置為內置文件系統時,nfsroot選項是不可見的)。
對於網絡配置選項,選擇內核自動配置,以及相應的自動配置類型。將DHCP,BOOTP和RARP三種類型全部選擇上是最靠譜的。
2.)內核命令行參數
當引導加載程序(bootloader)加載一個linux內核時,需要知道使用的是什么根文件設備(root fs device)。在使用nfsroot時,需要知道從哪兒獲取服務器地址和可掛載為根文件的目錄名。可以通過以下內核命令行參數來設置nfsroot:
root=/dev/nfs
啟動虛擬NFS設備(pseudo-NFS-device)所必需的參數。需要注意,/dev/nfs不是一個真實的設備,它只是一個告訴內核使用NFS功能來替換真實設備的一個符號。
nfsroot=[<server-ip>:]<root-dir>[,<nfs-options>]
如果在內核啟動命令行中沒有指定'nfsroot'參數,內核將使用默認的"/tftpboot/%s"參數。
<server-ip> 指定NFS服務器的IP地址。默認IP地址是從'ip'參數中獲取的(參見下一個參數)。該參數允許IP自動配置與NFS使用不同的服務器。
<root-dir> 將掛載為根文件系統的服務器端目錄名。如果有"%s"標記在配置字符串中,它將被ASCII表示的客戶端IP地址所替代。
<nfs-options> 規范的NFS選項。所有選項通過逗號(',')來分隔。默認使用以下配置,
port | 由服務器端的端口映射進程所給定 (centos7以前版本叫portmap,以后叫rpcbind) |
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>
該行參數告訴內核如何配置設備的IP地址以及如何配置IP路由表。起初被叫做'nfsaddrs',但是現在啟動時IP配置已經獨立於NFS,所以被重命名為'ip'並且為了兼容性舊名稱'nfsaddrs'將作為別名存在。
如果沒有在內核命令行參數中設置該參數,所有項將被視為空處理,所有默認值將按后面具體項中說明。通常是內核嘗試自動配置所有項。
其中<autoconf>項可以單獨地存在於'ip'參數中(沒有任何的':')。如果值被設置為"ip=off"或者"ip=none",將不會被替換成自動配置,否則會被替換為自動配置。使用得最多的設置是"ip=dhcp"。
<client-ip> 客戶端的IP地址。默認:通過自動配置獲取。
<server-ip> NFS服務器的IP地址。如果使用RARP來獲取客戶端地址,並且該參數不為空時所指定的服務器才會被接受。
只有NFS root需要該參數。如果沒有設置該參數或者不是使用的NFS root,那么自動配置將不會被觸發。
默認:通過自動配置獲取。將使用用於自動配置的服務器地址。
<gw-ip> 如果服務器位於不同的網段,那么需要通向IP地址相應的網關。默認:通過自動配置獲取。
<netmask> 本地網絡設備的子網掩碼。如果沒有指定,設備的子網掩碼將從客戶端IP地址的派生地址獲取。默認:通過自動配置獲取。
<hostname> 客戶端名。可以通過自動配置來支持,但是如果不指定將不會觸發自動配置。如果指定了該參數並且是使用的DHCP方式,用戶指定的hostname將被應用於DHCP請求中進行DNS記錄的更新。默認:所使用客戶端IP地址的ASCII形式。
<device> 所使用的網絡設備名。默認:如果本地只有一個設備,那么將直接使用它。否則將通過自動配置決定。它將通過所有設備發送自動配置請求,然后使用最先收到回復的那個設備。
<autoconf> 使用自動配置。如果設備了多個自動配置協議(DHCP/BOOTP/RARP),將使用所有協議都發送自動配置請求,然后使用最先收到回復的那個協議。
該選項中設置的協議只有被編譯進內核的才能夠使用。
off或者none:不使用自動配置(使用指定的IP地址)
on或者any:使用內核中任一可用的協議
dhcp: 使用DHCP
bootp: 使用BOOTP
rarp: 使用RARP
both: 使用BOOTP和RARP但不使用DHCP (為了向后兼容所保留的舊選項)
如果使用dhcp協議,客戶端可以按以下格式使用“ip=dhcp,client-id-type,client-id-value”。默認:any
<dns0-ip> IP地址的第一個命名服務器。從/proc/net/pnp(在嵌入式系統中通常鏈接到/et/resolv.conf)中獲取導出的值。
<dns1-ip> IP地址的第二個命名服務器。同上。
nfsrootdebug
該選項將開啟內核輸出調試信息。在啟動時,管理員可以通過輸出的信息來檢查傳入NFS客戶端的NFS掛載選項,服務器地址和根路徑等是否正確。
rdinit=<executable file>
管理員可以通過該參數指定包含有系統初始化程序的文件名。默認值是"/init"。如果指定的文件有效,並且內核可以運行,那么根文件系統相關的內核命令行參數(包括'nfsroot=')將被忽略。
[譯者注] 該方法已經過時,dracut支持但不推薦使用。更多詳情可參考man dracut.cmdline中關於NFS的描述。
關於處理掛載根文件系統的描述可以在該文件中獲得:Documentation/early-userspace/README
3.) 引導程序
加載內核程序到內存有很多不同的方法。主要依賴於可供選擇的設施:
3.1) 使用syslinux從軟盤啟動
在編譯內核時,使用syslinux來創建一個可啟動軟盤的簡單方式是,使用zdisk或者bzdisk來生成使用zimage或bzimage鏡像的目標文件。兩種目錄文件都可以接收FDARGS參數,該參數可以用於指定內核命令行參數。例如:
make bzdisk FDARGS="root=/dev/nfs"
注意,運行該命令進需要訪問磁盤設備/dev/fd0。
關於syslinux的更多詳情以及如何創建基於磁盤的預先編譯內核可參考http://syslinux.zytor.com/。
注意:以前可以通過dd命令將內核直接寫入到軟盤,通過rdev管理啟動設備,然后使用生成的軟盤啟動系統。linux不再支持該方法的內核啟動。
3.2) 使用isolinux從cdrom啟動
當編譯內核時,使用isolinux來創建一個可啟動cdrom的簡單方式是,使用bzimage鏡像的isoimage目標文件。與zdisk和bzdisk類似,目錄文件可接收FDARGS參數,該參數可以用於指定內核命令行參數。例如:
make isoimage FDARGS="root=/dev/nfs"
生成的iso鏡像文件位於arch/<ARCH>/boot/image.iso。可以通過類似cdrecord的工具將iso文件寫入到cdrom。例如:
cdrecord dev=ATAPI:1,0,0 arch/x86/boot/image.iso
關於isolinux的更多詳細信息,以及如何創建基於磁盤的預先編譯內核可參考http://syslinux.zytor.com/。
3.3) 使用LILO
當使用LILO時,所有需要的命令行參數可以通過位於LILO配置文件中的'append='項進行設置。
但是,為了使用'root='來指定內核命令行啟動參數,仍然需要創建一個臨時的root設備,它可以在LILO運行后被刪除。
mknod /dev/boot255 c 0 255
關於配置LILO的詳細信息可以參考其相關的文件。
3.4) 使用GRUB
當使用GRUB時,內核參數可以簡單地添加到內核設置的后面:
kernel <kernel> <parameters>
3.5) 使用loadlin
loadin可以用於從一個DOS命令提示符啟動Linux,而不需要掛載本地磁盤作為root。雖然該方法沒有經過作者的確認,但是它的配置方式應該與LILO相類似。
更多詳情請參考loadin的文檔。
3.6) 使用啟動ROM
這可能是無磁盤啟動最優雅的方式。可以使用TFTP協議來加載基於啟動ROM的內核。該文檔作者不知道任何支持通過網絡加載linux的非商業啟動ROM。但是,有啟動ROM的兩種自由實現,netboot-nfs和etherboot,兩者都位於sunsite.unc.edu並且兩者都包含了無磁盤linux客戶端啟動的所有信息。
3.7) 使用pxelinux
Pxelinux可以通過PXE引導程序(眾多現代網卡都包含該功能)啟動linux。
當使用pxelinux時,內核鏡像可以通過"kernel <relative-path-below /tftpboot>"進行指定。nfsroot參數將通過"append"項被添加到內核中。通常使用串行控制台與pxelinux進行連接,更多詳情請參考Documentation/serial-console.txt。
關於pxelinux的更多詳情以及如何創建基於磁盤的預先編譯內核可參考http://syslinux.zytor.com/。
4.) 致謝
內核中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>的幫助。