Linux原來也就這麼回事

來源:互聯網
上載者:User

    在部落格裡早就轉載了 手把手教你如何建立自己的Linux系統(LFS速成手冊)但實際上並沒有耐心和時間把LFS完成。最近終於有機會和時間再次進行LFS之旅。用VMWare虛擬機器按步驟進行了差不多一步不差的實踐(呵呵,還是有很多的測試沒有進行),除了參考手把手教你如何建立自己的Linux系統(LFS速成手冊)外,還參考了最新英文原版的LFS,主要通過它能明白各個命令的具體含義,速成中並沒有給出太詳細的解釋。

    時斷時續大約花了兩天的時間終於完成了整個LFS的編譯,但還是留下了些許遺憾:GRUB怎麼安裝都有問題,不能自動載入編譯好的LFS,只能手工輸入命令載入。但無論如何還是非常高興的,:-)。

    回頭來看LFS的製作過程,明顯的進步就是對Linux的命令明顯的熟練,參數也理解的更加深入了。對Linux的內部原理也有了比以前更清晰的理解,有一種茅塞頓開的感覺。下面說說自己現在對Linux的理解(比以前進步,但可能依舊有不正確,一直在進步^_^)。

1、Linux整個作業系統的構成

    Linux作為作業系統,內容相當的多,但從外部表格現來講我覺得也就兩層:核心層、應用程式層。核心層主要包括進程管理、儲存管理和IO管理,IO管理其實就是各種驅動,我把檔案管理也歸到IO管理。

    核心層具體到檔案主要是兩類:核心(鏡像)檔案和驅動程式檔案。核心檔案包含進程管理等作業系統基本模組,也可以把部分驅動程式編譯進來,如檔案驅動。核心檔案在作業系統運行時全部載入到記憶體。驅動程式檔案是針對於特定IO裝置的驅動模組,可以編譯成單獨的核心模組也可以編譯進核心檔案,作為單獨的模組可以由核心在檢測到裝置時自動載入或手動載入(modprobe)。極端情況下核心層只有一個較大的核心檔案而沒有任何其他驅動檔案,這在嵌入式系統中應用廣泛,因為嵌入式系統的硬體系統固定,硬體模組需要的驅動也固定,一般是系統運行時就全部載入到記憶體,提高系統的運行速度。

    核心層運行在核心態(ring0)。應用程式層程式運行在ring3,不能直接運行核心態的代碼,只能通過CPU的調用門等機制同核心態通訊。因此核心層一般以庫檔案的函數調用API同應用程式層進行通訊,應用程式層程式只需調用API即可而不用擔心具體的調用細節,細節都被封裝在API函數實現中。

    應用程式層主要是各種應用程式,其中包括特殊的Init和Shell。Init是系統的第一個應用程式,Shell只是一個特殊的用於解釋和調用其他程式的應用程式。他們都是調用庫函數來完成自己的任務,和其他我們自己寫的程式沒有什麼本質差別。

    LFS在編譯的過程中就是從現有的宿主作業系統,逐漸的產生目標系統的工具鏈(編譯器等),去掉對現有系統的依賴性並逐漸讓系統適應新的系統,這和交叉編譯相似。LFS大部分的時間都在調整工具鏈,然後編譯各種使用工具(包括庫),這些工具都是應用程式層的;而在LFS的最後才進行了核心的編譯。所以回過頭來感覺好像沒必要花那麼多時間去編譯那些應用程式,但沒有那些應用程式,核心還是沒有辦法純淨的編譯出來。

2、Linux的引導

    在準備好核心檔案、應用程式後,重要的是把這些檔案“啟用”,讓硬體按照新的核心檔案來運行,這就是系統的引導部分。這可以通過Lilo、GRUB等引導器完成,具體的過程就略了,可以參考手把手教你如何建立自己的Linux系統(LFS速成手冊)後面GRUB安裝部分。

3、小結

    通過上面的分析就可以看出來,Linux就是由核心檔案、應用程式組成,然後由引導程式將核心檔案“啟用”的過程。以前總搞不清楚Linux安裝下來那麼多的空間究竟都用來幹什麼了,分不清哪些檔案是必須的哪些可以省略。通過LFS總算明白了,最簡單的Linux系統其實只需要一個核心檔案就可以運行了(宏核心的好處:-)),但可能什麼任務也完成不了,而其他那麼多檔案是為了具體應用的,可以根據應用來定製了。

    但是說著簡單,真要發揮Linux強大的功能,應用的複雜性還是必要的。

4、Linux裁減

既然一個核心檔案加上必要的庫檔案、必要的程式就可以滿足我們的要求,我們可以嘗試把現有的巨大的Linux作業系統裁減成非常小的系統。

4.1建立root檔案系統

    組建root檔案系統更簡單:第一步,格式化容納root檔案系統的宿主裝置(按照所需的檔案系統格式來格式化裝置);第二步,拷貝所需檔案到root檔案系統中。

Linux檔案系統的詳細結構可以在網上查到,這裡就不多講了。我們這裡著手搭建的root檔案系統,不必包含太多內容,僅僅提供最基本的目錄結構、系統命令就可以了;並且設定檔也應該盡量修改得簡潔明了。

root檔案系統必須包含的內容如下:

  • 包含/dev 、/proc、/bin 、/sbin 、/etc 、/lib 、/usr 、/root 等目錄。
  • 包含一組基本命令,如ls這樣的檔案管理命令,insmod這樣的系統管理命令。
  • 支援上述命令的運行庫函數和系統登陸認證的相關庫函數。
  • 包括編譯核心產生的模組。
  • 必須的裝置檔案。
  • 一些必要的設定檔和服務管理指令碼。

4.2建立root檔案系統的內容

第一步:掛載目的主機硬碟到宿主機系統,我們假設我沒將在第二塊硬碟上安裝。mount /dev/hdb1 /rootfs
第二步:在rootfs目錄下建立檔案系統根目錄下必需的子目錄:
#cd rootfs
#mkdir dev, proc, bin, etc, lib, usr,sbin, root, usr/bin, usr/sbin, usr/lib

第三步:向rootfs中拷貝核心檔案和你需要的命令,比如ls 命令。

    核心檔案一般是/boot/kernel-2.6.x,我們只需將/boot下的所有檔案(map檔案、鏡像檔案、initd檔案等)拷貝到目標目錄的/boot下即可。

    對於應用程式或命令,我們要先確定它在系統中的位置(使用命令whereis ls,發現它在/bin/ls目錄下),然後將該命令拷貝到rootfs下相同的目錄結構下(cp /bin/ls /rootfs/bin/ls)。僅僅拷貝命令檔案並不夠,還必須拷貝該命令所用到的動態連結程式庫。如何尋找命令用到了那些動態連結程式庫呢?很簡單,利用命令ldd /bin/ls可以完成這種工作,如下所輸出:

libtermcap.so.2 => /lib/libtermcap.so.2 (0x4001f000)
libacl.so.1 => /lib/libacl.so.1 (0x40023000)
libc.so.6 => /lib/libc.so.6 (0x40029000)
libattr.so.1 => /lib/libattr.so.1 (0x40149000)
/lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)

    名字中有.so的那些檔案就是用到的動態連結程式庫。找到這些動態連結程式庫後,就將它們拷貝到rootfs下與原來位置對應的地方,一般應該在rootfs目錄下的lib或lib/i386中。(使用者所用到的命令多集中在/bin和/sbin下;此外,一些指令碼會用到一些出現在/usr/bin和/usr/sbin下的命令和工具。如果要使用這些指令碼,這些命令工具和它們要用的庫一個都不能少)。

 

    但是先別忙,這些檔案名稱可並非我們實際想要的,它們只是實際庫檔案的一個符號連結而已,系統之所以要使用符號連結,是為了便於庫檔案升級換代過程中不直接影響到使用它的應用程式(應用程式中用到的庫路徑指向的是庫的串連檔案,串連檔案名稱輕易不會改變)。因此我們如果單拷貝符號連結是沒有意義,必須將符號連結指向的實際庫檔案一同拷貝到workdir/lib錄下面去。

    /lib目錄中還有一個重要組成部分,modules目錄。它裡麵包含了核心編譯產生的模組,不同版本核心對應的模組存放在以版本號碼命名的檔案中。可別忘了拷貝我們新核心模組到我們的rootfs/lib/modules下。

    在很久很久以前,擁有/lib下的這些庫就足夠用了,但現在的Linux系統相比過去多了許多新要求,尤其是系統從網路安全性考慮,增加了許多驗證手段,因此你還必須擁有這些與安全驗證相關的附加庫。這些庫雖然不會在命令中直接使用,但卻間接地要被系統的安全機制調用。多數情況下,安全機制使用的具體庫會在設定檔中定義,安全架構通過查看設定檔,選擇調用具體是何種驗證庫。安全架構方面的話題,就不多介紹了,有興趣的話可以查查 pam 和 nss等的用法, 它們都是系統登陸時必須使用的與安全相關的庫。在這裡,我們就不管它三七二十一,將所有在/lib/security/下和pam相關的庫,以及在/lib下與nss相關的所有libnss*庫,都拷貝到rootfs/lib下的/security和/lib中(如果沒有這些驗證庫,你就無法登陸,系統不斷重複地給你登陸提示,但卻不給你輸入密碼的機會)。方法很笨,但卻比較省事。

    在Linux系統中,那些會被應用程式頻繁使用的庫函數,多數都不會以靜態方式編譯串連到應用程式中,而通常會採取動態連結的方式,進行集中儲存管理。這樣如果多個程式都用到某個共用庫,那麼該庫檔案只會被調入記憶體一次,駐留在記憶體供所有應用程式調用。因此利用共用庫能顯著地節約記憶體空間,縮減執行檔案的體積。當然,天下沒有免費的午餐,雖然共用庫相比靜態庫來說靈活得多,但卻需要進行路徑搜尋,而且調入時也更耗時。

    連結檔案是Unix風格作業系統提供的一個特色之一,其中具體又可分為軟連結和永久連結。軟連結又稱為符號連結,這種檔案唯一的內容就是包含實際檔案系統的路徑,因此,即使實際檔案已經被刪除或轉移,符號連結仍然存在,當然,它不再有效了。相反,永久連結則是和被連結檔案分享權限設定索引節點的,刪除硬鏈對應的檔案則會使索引節點計數減少,而不會破壞永久連結檔案。

第四步:該建立裝置檔案了,這點很重要,但相當容易。Linux繼承了Unix的一個優良特性,將裝置抽象成特殊檔案來使用和管理,想使用系統的外設,比如軟硬碟,時鐘,系統終端甚至記憶體,都可以通過裝置檔案來進行訪問。因此我們要建立系統可能會用到的所有裝置對應的裝置檔案。至於你具體需要哪些裝置檔案不能一概而論,你可以開啟/dev/目錄看看,當然,裡面的檔案肯定會多得讓你眼花繚亂。

不過也別怕,因為多數都沒什麼用處。對於我們要建立的實驗系統來說,用到的裝置檔案就屈指可數:

console ——控制台裝置;
tty* ——由控制台管理的虛擬終端(我們用ctrl-[1-7]切換的就是這個裝置);
sda1 ——SCSI介面裝置;
ram ——記憶體虛擬盤裝置;
null ——空裝置(是一個非常有用的字元裝置檔案,送入這個裝置的所有東西都被忽略。如果將任何程式的輸出結果重新導向到/dev/null,則看不到任何輸出資訊,因此指令碼中常用它來消除本該顯示在螢幕上的資訊);
zero——零裝置 (讀取這個裝置,只會得到空的內容,所以有時為了獲得高壓縮率,需要對某空間用全零添充時往往就會用到它);
initrd ——這是一個特殊的字元裝置,它被用來從使用者空間向系統核心發送切換運行層級的資訊,屬於一個虛擬字元裝置(比如改變運行層級的init 1-6命令,都是通過該裝置傳遞給核心的)。

必須的裝置檔案,大概就是這麼多了,明確了你需要所有裝置檔案,就可以利用mknod命令挨個建立這些需要的裝置檔案。如果採取這種方式,那麼注意mknod是需要參數的。你可以通過命令ls ??Cla /dev/裝置名稱來查看裝置是屬於塊裝置還是字元裝置,查看裝置的主從裝置號。如果你覺得這樣太煩,就用拷貝命令直接從標準系統的/dev/目錄下拷貝這些檔案吧,不過要配合參數-R使用,否則,你拷過來的就是裝置的所有檔案,即裝置中的整個內容,而不僅僅是一個裝置檔案了。拷貝裝置內容就如同把自己往自己衣服口袋裡塞,你是永遠塞不進去的。

 

Linux系統將裝置分為塊裝置和字元裝置,塊裝置可以隨機訪問(用符號B描述),字元裝置只能按順序訪問(用符號C描述)。另外,一個驅動程式可能會控制多個裝置,所以有主裝置號和從裝置號之分。主裝置號對應驅動程式,從裝置號用來區分具體裝置。

第五步:該建立系統運行需要的設定檔和指令碼了。我們還是從簡出發,拷貝標準系統現有的檔案,然後針對需要進行修改。下面是具體需要的設定檔和指令檔。

    我們的實驗系統必須滿足多任務、多使用者的需求,因此要有使用者登陸和使用者分組的能力,所以我們需要首先要拷貝/etc下的passwd和group這兩個檔案,如果系統通過shadow保護使用者密碼,那麼shadow檔案也要隨同拷過來。

    系統啟動後最先執行的就是init程式,它需要的設定檔可不算少。首當其衝的便是inittab檔案,它規定了系統啟動並執行許多基本屬性。接下來init程式會去執行inittab中引用的rc.sysinit指令碼,進行系統引導後期的初始化工作,其中又會使用到fstab設定檔,它包含了系統啟動後需要安裝的檔案系統以及安裝到的目錄位置;對於我們的系統來說只有兩項:一個是將/dev/ram作為root檔案系統安裝到/下,另一個是將proc檔案系統安裝到/proc目錄下,這可以根據你的需要自己進行調整。

    init執行完rc.sysinit後,依照inittab中定義的運行層級進入對應的/etc/rc?.d/(1就是/etc/rc1.d/,當然,最常見的是3級,/etc/rc3.d/)目錄下執行其中S開頭的系統服務指令碼。這裡面的細節就不多說了,可以使用man init獲得相關資料。現在要做的就是把/etc/下initab,rc.sysinit和rc.d目錄的所有東西拷貝到新root檔案系統的對應位置上。

    我們假設系統的運行層級為3,只需要啟動網路服務,因此可以把除了S?Network和S?Local外的S指令碼都統統刪除。(當然你也可以改變系統預設的啟動流程,讓它執行你自己定義的初始化指令碼,要做的只是去inittab中修改“sysinit:XXX”中的指令碼名稱)。

    執行了上述初始化,啟動了相關服務後,系統會執行rc.local檔案,這裡可以放一些你自己希望在開機時執行的命令,我們這裡放一句“ ok you are welcome !!!”作為你進入系統前的問候(由於我們系統初始化工作沒有什麼太多操作,所以啟動過程很快,系統中的虛擬終端裝置(tty?)往往還來不及初始化完全,所以可能出現系統起來後提示(”Id xxx respawning too fast:disabled for 5 minutes”)一類的話 ,為了避免這個錯誤,我們在local中還讓系統睡眠了20秒)。

    另外,登陸程式login往往要使用pam驗證模組認證使用者合法性,所以pam的設定檔也要拷貝到新系統。很多系統還會用到NSS(名稱服務開關,在前面已經提到它要用到的庫檔案。這個服務來協助客戶機器或應用程式獲得網路資訊,可從本地或從網路某處取得——從DNS或NIS等。諸如getXbyY()等函數都往往會用到這種服務,使用者登陸時login很可能就要使用,這取決於你的libc的版本),所以nss的設定檔/etc/nsswitch.conf也需要拷貝,至於該指令碼的內容等細節問題,可通過man nsswitch.conf來瞭解。

    你還要拷貝terminfo/termcap(新舊版本有別)檔案,設定TERM終端環境變數要用到該檔案。

    最後別忘記拷貝模組設定檔modules.conf,它包含了模組相關的資訊。

    把/root/目錄下的那些.開頭的用於bash配置的隱藏檔案也拷到新系統的root目錄下,這些都是bash的環境參數(如果沒有,關係也不大,就是不大方便而已)。

    最後:ldconfig ??Cr rootfs(目標檔案系統目錄) 建立庫檔案路徑緩衝 ,從此我們新root檔案系統上的命令再使用動態連結程式庫時就不必指定庫的目錄了,因為它們的路徑都被緩衝了。(ldconfig 要用到動態庫設定檔ld.so.conf,它其中指定了需要用的庫路徑。比如你的程式用到kerberos庫,那麼就需要在ld.so.conf裡麵包含/usr/lkerberos/lib路徑)。

4.3系統引導

    假設用GRUB進行系統引導,可以依據手把手教你如何建立自己的Linux系統(LFS速成手冊)最後GRUB引導部分進行。

grub

輸入root (hd1,1)
輸入setup (hd1)
quit

設定grub啟動菜單

代碼:

cat > /boot/grub/menu.lst << "EOF"
# Begin /boot/grub/menu.lst
# By default boot the first menu entry.
default 0
# Allow 30 seconds before booting the default.
timeout 30
# Use prettier colors.
color green/black light-green/black
# The first entry is for LFS.
title LFS 6.3
root (hd0,1)
kernel /boot/lfskernel-2.6.22.5 root=/dev/hda2
EOF

注意:這裡root後面的磁碟分割需要根據實際情況調整。
將menu.lst串連到/etc目錄下
代碼:
mkdir -v /etc/grub
ln -sv /boot/grub/menu.lst /etc/grub
到此重啟系統,應該可以從新配置的核心引導,並且是我們剛剛夠用的系統,:-)

5、總結     用自己摸索的觀點解釋了Linux的系統本質構成,並給出了從現有系統裁減出最小系統的途徑和方法。為什麼用摸索呢?因為很多書上都用大量的篇幅在講Linux核心的特點、結構、原始碼等等,但沒有用宏觀的角度展示Linux“系統”本身宏核心的特點,沒有強調讓人暈倒的so多的C原始碼最後只產生了一個核心檔案,我們學了半天核心的原始碼都沒有搞清楚產生的二進位代碼到底在什麼地方,到底是如何被系統使用的,這些只有通過實踐才能真正體會到。當我們從直觀上清楚了核心的地位和表現,再去學習、修改原始碼才能更加有的放矢!

6、參考文獻

    手把手教你如何建立自己的Linux系統(LFS速成手冊)
    安得倚天抽寶劍——搭建實驗系統
    手把手教你如何建立自己的Linux系統 第二版

 

    感謝為我們美好網路生活無私奉獻的人們!

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.