Linux中linuxrc的作用

2021-07-10 05:35:42 字數 4638 閱讀 5331

乙個典型完整的引導linux的命令如下:

title 51base

root(hd0,0)

kernel /bzimage ro root=/dev/ram0

initrd /initrd.img

這裡有必要注意一下幾個問題:

(1)grub的磁碟以及分割槽的命名方式和linux有所區別,第乙個磁碟是從0開始,第乙個分割槽也是從0開始.譬如第乙個硬碟的第5分割槽在linux下面是/dev/hda5 ,而在grub裡面是(hd0,4).再如/dev/fd0在grub裡面是(fd0,0).

(2)不管是ide硬碟hda,hdb還是scsi硬碟sda,sdb在grub裡面都是以hd方式命名.譬如虛擬機器裡面的/dev/sda2在grub裡面是(hd0,1),再如/dev/hdb7在grub裡面以(hd1,6)命名.

(3)要搞清楚上面兩個root的關係,root (hd0,0)中的root是grub命令,它用來指定boot所在的分割槽作為grub的根目錄.而root=/dev/ram0是kernel的引數,它告訴作業系統核心載入完畢之後,真實的檔案系統所在的裝置.

要注意grub的根目錄和檔案系統的根

目錄的區別.

再回到上面的幾行命令.

kernel命令用來指定核心所在的位置,"/"代表(hd0,0),也就是grub的根目錄

initrd命令用來指定初始化ram的img檔案所在位置.

grub載入核心bzimage並展開到指定位置(應該是0x100000這個地方),同時載入

initrd.img到記憶體(不知道是什麼地方).

ps:grub的任務至此就結束了,下面grub將機器的控制權轉交給作業系統(linux).

作業系統接到控制權之後,開始start_kernel,接著核心將initrd.img展開到/dev/ram0

為臨時根檔案系統,執行裡面的linuxrc檔案.

initrd是inital ram disk的宿寫.

當存在initrd的時候,機器啟動的過程大概是以下幾個步驟(當initrd這一行用noinitrd 命令代替後,就不存在initrd了)

1)boot loader(grub)載入核心和initrd.img

2)核心將壓縮的initrd.img解壓成正常的ram disk並且釋放initrd所佔的記憶體空間

3)initrd作為根目錄以讀寫方式被掛載

4)initrd裡面的檔案linuxrc被執行

5)linuxrc掛載新的檔案系統

6)linuxrc使用pivot_root系統呼叫指定新的根目錄並將現有的根目錄place到指定位置.

7)在新的檔案系統下正式init

8)initrd被解除安裝.

為了便於理解將red hat linnux9 裡面的initrd-2.4.20-8.img拿出來分析.

[root@localhost ram]cat linuxrc

#!/bin/nash

1.echo "loading scsi_mod.o module"

2.insmod /lib/scsi_mod.o

3.echo "loading sd_mod.o module"

4.insmod /lib/sd_mod.o

5.echo "loading buslogic.o module"

6.insmod /lib/buslogic.o

7.echo "loading jbd.o module"

8.insmod /lib/jbd.o

9.echo "loading ext3.o module"

10.insmod /lib/ext3.o

11.echo mounting /proc filesystem

12.mount -t proc /proc /proc

13.echo creating block devices

14.mkdevices /dev

15.echo creating root device

16.mkrootdev /dev/root

17.echo 0x0100 > /proc/sys/kernel/real-root-dev

18.echo mounting root filesystem

19.mount -o defaults --ro -t ext3 /dev/root /sysroot

20.pivot_root /sysroot /sysroot/initrd

21.umount /initrd/proc

首先必須注意的是這裡使用的shell是nash而不是bash,nash是專門為linuxrc可執行指令碼設計的,因此你有必要看一看nash的man文件.

1-10行是載入一些必要的模快.

11-12行載入proc核心檔案系統,

13-14行利用nash內建的

命令mkdevices建立塊裝置,mkdevices是根據/proc/partitions檔案建立裡面列出的所有

塊裝置.

15-16行利用nash內建的命令mkrootdev,mkrootdev使它後面的引數/dev/root成

為乙個塊節點從而使得根分割槽裝置被掛載,其中根分割槽裝置由grub.conf裡面的kernel命

令後面所帶的引數root=決定,如果root=引數沒有被指定,/proc/sys/kernel/real-root-

dev檔案將提供根分割槽裝置號.

17行將數字256寫入到後面的檔案裡面去.

18-19行掛載根文

件系統到/sysroot目錄下,/dev/root裡面的內容就是root=引數所指定的裝置裡面的內容

20行呼叫pivot_root改變根目錄所在地並place舊的根目錄到指定的位置.21行解除安裝舊的

根目錄裡面的proc核心檔案系統.

這裡面總結一下linuxrc的作用: (參考/usr/src/linux-2.4/documenta

tion/initrd.txt文件)

1)/linuxrc檔案決定在掛載真正的檔案系統之前所需完成的事情(譬如載入必要的網路驅動或者載入ext3檔案系統).

2)/linuxrc載入必要的模組.

3)/linuxrc掛載根檔案系統

4)/linuxrc呼叫pivot_root來改變根目錄

既然linuxrc的主要目的是載入模快用的,那如果我們的核心沒有動態的模組而所需的功能都是靜態編譯進核心的,那麼是不是可以不用linuxrc檔案呢?

答案是可以不用,在普通的linux作業系統裡面可以加入noinitrd選項以告知boot 

loader 不使用initrd.

如果我們做閘道器,因為ram是我們的檔案系統的載體,所以initrd

一行當然不能去掉,但是我們可以不用linuxrc檔案,sysroot資料夾和initrd資料夾.

linuxrc執行完畢之後,系統就會以真正的根目錄正式init.

系統在/bin/或者/sbin目錄下找到init程式,然後根據它的配置檔案/etc/fstab進行初始化,最後呼叫mingetty程式啟動login完成引導.

ps:init這一部分網上有很多的詳細資料,在這裡並沒有展開來說.

(/linuxrc 執行init 程序初始化檔案。主要工作是把已安裝根檔案系統中的/etc 安裝為ramfs,並拷貝/mnt/etc/目錄下所有檔案到/etc,這裡存放系統啟動後的許多特殊檔案;接著linuxrc 重新構建檔案分配表inittab;之後執行系統初始化程序/sbin/init。

/mnt/etc/init.d/rcs 完成各個檔案系統的 mount,再執行/usr/etc/rc.local;通過rcs 可以呼叫 dhcp 程式配置網路。rcs 執行完了以後,init 就會在乙個 console 上,按照 inittab 的指示開乙個 shell,或者是開 getty + login,這樣使用者就會看到提示輸入使用者名稱的提示符。

/usr/etc/rc.local 這是被init.d/rcs 檔案呼叫執行的特殊檔案,與linux 系統硬體平台相關,如安裝核心模組、進行網路配置、執行應用程式、啟**形介面等。

/usr/etc/profile rc.local 首先執行該檔案配置應用程式需要的環境變數等。

linuxrc 

#!/bin/sh

echo "mount /etc as ramfs"

/bin/mount -n -t ramfs ramfs /etc

/bin/cp -a /mnt/etc/* /etc

echo "re-create the /etc/mtab entries"

# re-create the /etc/mtab entries

/bin/mount -f -t cramfs -o remount,ro /dev/mtdblock/3 /

/bin/mount -f -t ramfs ramfs /etc

exec /sbin/init

rcs/mnt/etc/init.

d/#!/bin/sh

/bin/mount -a

exec /usr/etc/rc.local

rc.local

/usr/etc/

#!/bin/sh

. /usr/etc/profile

echo "hello! embest"

echo "ifconfig eth0 192.168.0.10"

ifconfig eth0 192.168.0.10

oracle中sql rowcount的作用

起因 新開發個儲存過程,需要當乙個使用者呼叫儲存過程操作一行資料時,另外的使用者不允許呼叫過程操作該資料。解決辦法 先將該記錄的狀態改為處理中,當別的使用者看到為處理中時則跳出過程。此時用到了sql rowcount來判斷是否更新了記錄的狀態 update table t set t.status ...

CSS中 overflow hidden 的作用

本文 功能1 隱藏溢位 在ie6下,當子容器的寬高超出父容器時,父容器就會被撐開來。要想解決這個問題,在父容器中除定義寬和高的值以外,還必須寫overflow hidden,這樣就能把子容器的其它內容隱藏。但是在火狐或者其他瀏覽器裡面,我們發現問題並非如此簡單。我們發現,當子容器這個div的寬度和高...

outputstream中flush的作用

部分outputstream的子類實現了快取機制,為了提高效率當write 的時候不一定直接發過去,有可能先快取起來一起發。flush 的作用就是強制性地將快取中的資料發出去 以下是outputstream原始碼注釋 方法重新整理此輸出流並強制將所有緩衝的輸出位元組被寫出。重新整理的常規協定是,呼叫...