探索Linux系統的啟動過程

來源:互聯網
上載者:User

探索Linux系統的啟動過程

閱讀目錄

  • 引言
  • Linux啟動過程概述
  • Grub載入Linux核心和initramfs
  • 探索initramfs檔案的方法
  • 基於systemd的init系統
  • 進入圖形介面

這篇文章有點長,我花了大約兩個星期的時間才完成,雖然不是寫得巨細無遺,但是我認為還是很有價值的,求推薦。不管你是不是 Linux 愛好者,也不管你是否能耐心讀完,請果斷 mark 之,你值得擁有。

引言

  這一篇可能是我這系列隨筆除總結之外的最後一篇,也可能不是。為什麼這麼說呢?因為我覺得在 Linux 應用環境方面再寫下去也可能不會有什麼新意了,至少以我的水平寫不出什麼新意了。我的這一個系列,基本上不涉及到編程,而是真真正正地將 Linux 案頭系統當成日常使用的工具,即使在我的這個系列中有探討 C 語言或者 Bash 語言的部分,我也是展示的相關的開發工具,比如 binutils 工具包和 autotools 工具鏈。我曾經說過,折騰 Linux 就是折騰 Linux 系統下的軟體,Linux 世界軟體之多,可寫的應該還有不少,但是我覺得已經沒有辦法寫得很好了。比如有一些工作我還沒有找到適當的工具,像 JavaScript 和 CSS 開發,對於部落格園中的廣大前端攻城獅來說,肯定是各有神通,但是我確實不知道用什麼工具可以做到即順手又高效率,我只會簡單地用用 Firefox 提供的開發人員工具。還有 3D 開發、遊戲編程、移動開發等等,雖然可以寫的領域比較廣闊,但是畢竟我不是做這些的,沒什麼經驗,不能說光寫某某軟體試用體驗吧。再說,程式員終歸還是程式員,以後寫部落格應該還是介紹編程經驗比較好。

  之所以想到寫這些東西,那是因為我確實想讓大家也和我一樣,把 Linux 案頭系統打造成真真正正日常使用的工具,而不是安裝之後試用幾把再刪掉。我是真的在日常生活和工作中都使用 Linux,比如在 Linux 下編程、寫部落格、寫論文和做幻燈。當然,對於 LibreOffice 這樣的軟體使用起來都不會有什麼困難,所以在我的部落格中就基本沒有提到,就像 Windows 下的程式員不會去寫 MS Office 的使用指南一樣。如果有人不能堅持使用 Linux,那一定是 Linux 中的某些困難打敗了他。剛使用 Linux 時確實會碰到很多困難,比如介面不夠美觀啊、字型不夠順眼啊、IME太難用啊,還有就是想做某個工作找不到工具、想改一個屬性找不到入口、系統崩潰了無法恢複等等,甚至是剛安裝一個軟體包或者下載一個檔案,卻不知道放到檔案系統的什麼地方了。所以,我的這一個系列就是在向大家展示我的方法論,用什麼軟體不重要,怎麼用好也不重要,而是碰到問題了,用什麼思路去找答案,到哪裡去找答案。經過這二十幾篇的展示,我的方法論也基本上講完了。所以我決定,寫完這一篇探索 Linux 系統的啟動過程之後,我將開始另外一個系列的工作。

  關於 Linux 系統的啟動過程也是幾經變革。首先是作業系統從磁碟載入的過程發生了變化,很老舊的作業系統需要自己寫開機磁區,現在的作業系統早就將這個過程交給了專門的啟動工具。最常用的作業系統載入程式是 Grub,這個名字大家肯定早就如雷灌耳了,而且 Grub 也已經從第1版發展到了第2版,我們稱之為 Grub2。 Grub2 和 Grub1 有很大的差別,網路上有很多講 Linux 的文章動不動就拿 Grub1 說事兒,比如讓大家修改 menu.lst 檔案這樣的,都是很過時的內容了。關於 Grub2 的詳細資料可以閱讀文檔info grub或者info grub2。Grub 的優點是支援多作業系統的啟動,Windows、Linux、BSD都不在話下,但是它們的啟動協議是不一樣的,啟動 Windows 靠的是 chainloader,啟動 Linux 直接使用 linux 命令,而 BSD 系統好像是使用的 multiboot,特別是 Grub 的 multiboot 規範對那些很想自己寫作業系統的程式員很有用,因為再也不用從開機磁區的代碼開始寫了,可以直接進入保護模式用 C 語言寫作業系統。Linux 系統在啟動的時候還有 initrd 或 initramfs 機制,這個也需要 Linux 使用者特別注意。initrd 或 initramfs 也經曆過一次技術革新,最開始採用的是 RamDisk 技術,目前採用的 tmpfs 技術。最後,核心載入入記憶體後,會將系統初始化的控制權交給 init 程式,而 init 程式也不是一成不變的,最開始使用的是 SysVinit,後來又改成 Upstart,現在最流行的又變成了 systemd。現在仍然有很多書和網文講的還是 SysVinit 時代的做法,當然這些文章只能以 RedHat EL 5 以及之前的發行版作為樣本,而對於最新的發行版,這些文章中講的方法又會給新入門的使用者造成困難。

  探索 Linux 系統的啟動過程是每一個 Linux 使用者進步到一定程度後必然要去做的一件事。有的人可能只是好奇,也有的人可能確實需要從啟動過程中去解決某一個特定的問題。這種探索我進行過多次,也早就想寫一寫,但是總是寫不好。這一次是藉著 systemd 普及的東風,讓這個探索過程成為我這一系列的壓軸之作。為什麼說是藉著 systemd 普及的東風呢?因為聽說本月即將發布的 Ubuntu 15.04 版本將會從 upstart 更換為 systemd,目前正在緊張地測試中。當然,一下子遷移過來對開發人員來講還是有點難度的,但是只要確定目標,即使 Ubuntu 15.04 不使用 systemd,到 15.10 也肯定是它了。因此,對於我這個喜歡折騰多個 Linux 發行版的人來說,就不用多線作戰了,只需要學好 systemd 即可。

Linux啟動過程概述

  這裡先簡單列一下 Linux 作業系統啟動的全過程:

  1. 按下電腦的電源鍵後,電腦通電,BIOS啟動;
  2. BIOS讀取硬碟的MBR,運行開機磁區中的代碼,舊系統往往需要自己寫開機磁區,而新系統基本上由專用的啟動軟體接管了,在 Linux 世界中,目前都是用的 Grub2。由於開機磁區空間太小,放不下太複雜的代碼邏輯,所以 Grub2 也使用了多階段啟動的策略;
  3. Grub2 負責將作業系統核心載入到記憶體,如果有必要,也會把 initramfs 檔案載入到記憶體,然後將控制權交給核心;
  4. 核心進行初始化,核心的初始化過程結束後,就會把控制權交給/init程式,從此進入使用者空間;
  5. 因為核心先是將 initramfs 檔案掛在為根檔案系統,所以剛開始啟動並執行/init程式其實是 initramfs 檔案中的,所以該檔案需要的重要的初始化指令碼、核心模組、設定檔等,都位於 initramfs 檔案中,這也是為什麼很多時候我們修改了某些設定檔後,需要先更新 initramfs 檔案再重啟作業系統才會生效;
  6. initramfs 檔案中的/init程式負責掛載硬碟上的檔案系統,然後再把根檔案系統切換到硬碟上的根分區,再運行/sbin/init程式,這時所有程式、設定檔、指令碼都是使用的硬碟上的了,當然,網路檔案系統也是同理。可以看出 init 程式的運行也是一個分階段的過程;
  7. /sbin/init程式負責系統的初始化、各種服務的運行、使用者的登陸等等;
  8. 如果需要運行圖形介面,則/sbin/init程式會運行 Display Manager,在 Fedora 中是 gdm,在 Ubuntu 中是 lightdm。然後 Display Manager 負責啟動整個圖形介面。
Grub載入Linux核心和initramfs

  研究 Linux 啟動過程的第一站就是要研究 Grub。大部分時候我們不用考慮 Grub 的安裝,因為安裝 Linux 案頭系統的時候已經幫我們自動安裝好了,我們要做的,最多就是改改 Grub 的設定檔。只有在一種情況下需要手動安裝 Grub,那就是在系統崩潰後急救的時候,當然,需要先運行一個光碟片版或 USB 磁碟機版的 Linux 系統,然後運行grub-install命令,這個命令需要指定將 Grub 安裝到那個硬碟的 MBR,具體操作看文檔即可。

  Grub2 和 Grub 相比,有了很多改進,改進到 Grub2 都相當於一個小型的作業系統了,比如 Grub2 能識別各種格式的硬碟分區及檔案系統,能識別各種格式的映像,甚至還能動態載入模組。其中最重要的改變是設定檔由 Grub1 時代的/boot/menu.lst檔案變成 Grub2 時代的/boot/grub/grub.cfg檔案了(注意,有的系統中是/boot/grub2/grub.cfg,比如 Fedora),設定檔的文法也變複雜了很多。雖然 Grub2 設定檔的文法比較複雜,但是我們一般不需要直接修改該檔案,而是修改/etc/default/grub檔案後,再使用update-grub命令自動組建組態檔案。當然,要完成一些簡單任務時對/boot/grub/grub.cfg檔案進行直接修改也是可以的,只是一旦系統更新,則對該檔案的修改有可能被覆蓋。

  Grub 最重要的任務就是載入 Linux 核心以及 initramfs 檔案了,這幾個命令是非常簡單易懂的,在/boot/grub/grub.cfg檔案中也非常容易找到,如:

  主要是展示 Grub 載入 Linux 核心並且給 Linux 核心傳遞參數的過程,同時展示載入 initramfs 檔案的過程。

探索initramfs檔案的方法

  Grub 將 Linux 核心和 initramfs 檔案載入記憶體後,就把控制權交給核心,核心會將記憶體中的 initramfs 檔案掛載為根檔案系統,當核心初始化完成後需要進入使用者空間時,會運行/init,其實這個/init是在 initramfs 檔案中的,所以如果想知道系統啟動後都幹了些什麼,研究一下 initramfs 檔案中的內容是有必要的。

  在/boot目錄下,一般都有一個/boot/initrd.img檔案或一個/boot/initramfs.img檔案,但是要看裡面的內容還得有點技巧。先得學習一下曆史。第一個問題就是為什麼要有 initrd 或者 initramfs,答案是這樣的,為了減小 Linux 核心的大小,有一些驅動並沒有編譯進核心,而是以模組的形式存在於檔案系統中,但是有些檔案系統呢又需要��核載入了相應的驅動模組才能讀取,這樣就形成了一個是先有雞還是先有蛋這樣的一個矛盾的問題,為瞭解決這個問題,就是把這些驅動模組放到 initrd 或 initramfs 檔案中,由啟動器將其載入記憶體,然後核心載入記憶體中的驅動模組,再驅動其它的檔案系統,然後進行更多的工作。同時,對於很多嵌入式作業系統而言,可能載入記憶體的 initrd 或 initramfs 就是最終的檔案系統。第二個問題就是 initrd 檔案和 initramfs 檔案是什麼格式的,怎麼建立和開啟。這個問題有點複雜,且看我下面細細道來。

  其實在 Linux 的曆史中,記憶體中的檔案系統使用的技術還不一樣。在很老的系統中,是將某一塊記憶體類比成磁碟,稱之為 RamDisk,這個技術效率不高,為什麼不高呢,那是因為將記憶體類比成磁碟後,依然需要像對待磁碟一樣對待它,需要給它建立特定格式的檔案系統,讀取或寫入檔案的時候還是要用到核心的緩衝系統,這樣同一份資料就在記憶體中存在了兩份,所以很浪費。老系統中使用的 initrd 檔案其實就相當於是一個磁碟的鏡像,所以要讀取或寫入它的內容,就需要將它掛在到系統中,然後進行讀寫。

  現在我們用的都是新系統,initrd 已經被 initramfs 取代了,雖然很多系統中仍然用initrd.img作為檔案名稱,其實使用的是 initramfs 技術。initramfs 技術不使用 RamDisk,而是使用 tempfs,也就是複用了核心中的緩衝系統,所以 tempfs 中的內容在記憶體中只存在一份,那就是在核心的緩衝中,不僅節約了記憶體開銷,也提高了效率。那麼 initramfs 檔案是什麼格式呢?它就是經過壓縮的 CPIO 格式,只要會cpio,開啟它就不是問題。

  其實也不是完全沒有問題,我在研究 Fedora 21 的 initramfs.img 檔案時就碰到了困難。如果大家使用cat initramfs.img | cpio -imd將該 CPIO 檔案解開,會發現只有少許幾個檔案,檔案數量和檔案大小都遠遠低於我們的預期,如:

  問題究竟出在哪裡呢?這是因為 Fedora 21 採用了最新的 Early User Space 技術。這個問題在網上還暫時搜不到答案,我也是看到解壓出的檔案中有一個early_cpio,然後以 early 為關鍵詞去看核心的代碼,才知道的。但是關於該技術的具體資訊,我也沒搞懂。不過這不是重點,重點是如何正確地將該檔案解包。首先,我找到了 Fedora 21 系統中用來構建 initramfs 檔案的工具是 dracut,採用的方法論請看我該系列的第一篇,如:

  然後,我發現 dracut 軟體包中提供的lsinitrd工具可以查看 initramfs 中的內容,而且該工具是一個指令碼。所以我就把它開啟看了一下,如:

  在這個指令碼中,我發現它需要用到一個skipcpio程式,跳過 initramfs 檔案的頭部後,再將剩下的部分當成壓縮的 CPIO 檔案進行解包。看來,會讀指令碼程式有時也很重要,所以我的《Bash指令碼程式設計語言中的美學與哲學》這一篇沒有白寫。最後,解包 initramfs 檔案的命令是這樣的:

sudo /usr/lib/dracut/skipcpio initramfs-$(uname -r).img | zcat | cpio -imd

  如:

  接下來,我們就可以愉快地研究/init程式都幹些什麼了。

更多詳情見請繼續閱讀下一頁的精彩內容:

  • 1
  • 2
  • 下一頁

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.