initrd切入linux文件系統
initrd,典型的系統啟動順序
1. boot loader加載內核並初始化ram disk
2. 內核把initrd轉化成正常的ram disk並釋放initrd使用的內存
3. initrd作為root被掛載,賦予讀寫權限。
4. /linuxrc被執行(這可以是任何可執行文件,如腳本,運行在uid 0,可以做任何初始化)。
5. linuxrc掛載真正的根文件系統
6. linuxrc使用pivot_root系統調用把根文件系統放在根目錄。
7. 正常的啟動序列(/sbin/init)在根文件系統上執行。
8. initrd文件系統被移去。
注意,改變根目錄不牽扯卸載他。 掛載在initrd的文件系統仍然可以被訪問。
如何改變根設備
整個過程包括如下幾步:
1. 掛載新的根文件系統
2. 把他變成根文件系統
3. 刪除所有對舊(Initrd)文件系統的訪問
4. 卸載initrd文件系統,重定位ram disk
掛載新的根文件系統很容易:只需把他掛載到當前根下。例如:
# mkdir /new-root
# mount -o ro /dev/hda1 /new-root
根的轉變伴隨著pivot_root系統調用。pivot_root把當前的根轉移到新根下的一個目錄,並把新的根放到原來的地方。老根的目錄必須在調用pivot_root前退出。例如:
# cd /new-root
# mkdir initrd
# pivot_root . initrd
現在,linuxrc進程可以仍然訪問老的根。所有的這些引用可以通過如下命令釋放:
# exec chroot . what-follows dev/console 2>&1
然後執行的就是新根下的init程序,例如/sbin/init。
如果新的根文件系統使用devfs,而/dev目錄還不可用,devfs必須被掛載進來, 在使用chroot之前,只有這樣才有/dev/console設備。
注意:
privot_root執行的情況可能有所不同。為了保證兼容性,注意以下幾點:
調用pivot_root之前,調用進程的當前目錄應指向新的根 文件目錄使用”.“作為第一個參數,老根的相對路徑作為第二個參數。ch
root程序必須在就老的和新的根下都可以使用。
最後改變根到新的根下。
在執行命令中 使用dev/console的相對路徑。
注意,initrd可以被卸載,而ram disk使用的內存可以被釋放:
# umount /initrd
# blockdev --flushbufs /dev/ram0 # /dev/rd/0 if using devfs
initrd還可以使用NFS-mounted根,參考man pivot_root(8)。
示例
下面是redhat的linuxrc文件,其中用的是nash命令系統。
#!/bin/nash
echo "Loading scsi_mod.o module"
insmod /lib/scsi_mod.o
echo "Loading sd_mod.o module"
insmod /lib/sd_mod.o
echo "Loading BusLogic.o module"
insmod /lib/BusLogic.o
echo "Loading jbd.o module"
insmod /lib/jbd.o
echo "Loading ext3.o module"
insmod /lib/ext3.o
echo Mounting /proc filesystem
mount -t proc /proc /proc
echo Creating block devices
mkdevices /dev
echo Creating root device
mkrootdev /dev/root
echo 0x0100 > /proc/sys/kernel/real-root-dev
echo Mounting root filesystem
mount -o defaults --ro -t ext3 /dev/root /sysroot
pivot_root /sysroot /sysroot/initrd
umount /initrd/proc