您好,登錄后才能下訂單哦!
deepin操作系統整個的啟動流程到底是怎么樣子的?
以前曾被同事纏問過類似的問題。遇到這種宏大而又不著邊際的問題,我的回復往往是“你還太嫩,現在我告訴你還是會忘掉的,等你干上個兩年,不用我說你就知道了”。我邊敲著鍵盤,邊佩服自己的聰明才智。
兩年后……
這個小伙子長大了,并且堅定地又問了同樣的問題。我一愣神,腦海中不停浮現出一個聲音“出來混,遲早是要還的”。
想想也罷,是時候該把壓箱底兒的貨拿出來了,畢竟自封了“半吊子系統工程師”的title(雖然我自封的title還有很多:半吊子客服、半吊子產品經理、半吊子研發項目經理等等),不給你們露兩手看看看來還真不行……
deepin系統啟動,從整體上看主要分為了 硬件上電、內核引導、內核啟動、系統初始化、圖形界面等幾個階段。
如果將這幾個階段分為兩個部分,那么第一部分的硬件上電、內核引導、內核啟動主要是“引導(boot)”,更偏向讓內核可以啟動;而第二部分的系統初始化、圖形界面兩個階段主要的任務則是“初始化(initialize)”了,因為對于一個系統來說僅僅有內核跑起來是不行的,還要有各種各樣的服務對系統的軟硬件進行管理,這也是平常大家說發行版跟純粹的GNU/Linux內核不是一個概念的原因之一。
下面我從一個軟件開發者的角度說一下我對每個階段的理解以及一些調試的方法。
既然說了是軟件開發者的角度,這個部分對我來說基本上相當于黑盒子了。但是大體上我們仍然知道這個部分主要是:
硬件上電
BIOS/UEFI
bootloader
當你按下電源的那一刻起,電流就會“滋滋滋”的流向主板,啟動BIOS(Basic Input Output System)系統。
BIOS系統,顧名思義就是最直接跟硬件打交道的系統,因為有標準規定,所以輸入輸出設備的基本功能都是可以使用的,一些硬件的開關配置也可以在BIOS中進行操作。
除此之外,BIOS還有兩個重要的功能,一個是硬件自檢;另外一個是加載引導。硬件自檢這個跟作為一個”半吊子系統工程師“沒什么關系,自不多說。加載引導的過程其實就是大家耳熟能詳的MBR、小蝌蚪找媽…哦不…MBR中找bootloader了。
跟BIOS對應的UEFI,要說它們之間的區別,除了加載引導的方式不大一樣以外。對我來說可能就是界面能夠用鼠標點點點了吧,嗯……哈哈哈。
這里講個段子,之前15.7搞啟動時間優化的時候,測試的同學測試系統啟動時間的優化情況,老是說效果不理想,我去看看吧,原來是他們測試系統啟動是從硬件啟動算起的,我說你們直接從內核引導開始計算,他還問我為什么。優化時間/(BIOS時間+GRUB時間+內核時間+圖形時間) 跟 優化時間/(內核時間+圖形時間)哪個大哪個小?我只能說這個測試同學的數學不大好……
BIOS在MBR中(或者UEFI在主板專有的存儲設備中)找到bootloader并加載后,bootloader就會開始加載Linux內核并啟動了。
deepin系統默認的bootloader是GRUB(GRand Unified Bootloader)。其實我一直覺得這個名字挺惡心的,大神們果然都是重口味……GRUB并不需要按照什么規則去硬盤中找系統,而是根據/boot/grub/grub.cfg中的啟動項加載內核、啟動系統,而這個配置文件則是在系統安裝或者手動執行update-grub這個命令的時候生成和更新。
update-grub這個命令其實是對grub-mkconfig的一個包裝,在非Debian系的發行版上是沒有的。grub-mkconfig會執行的動作主要是:
1.加載/etc/default/grub中的一些配置項。比如GRUB_CMDLINE_LINUX_DEFAULT配置項會控制Linux的boot param。
2.挨個執行/etc/grub.d/目錄中的腳本,用來生成最終的grub.cfg文件。比如我們平常看到update-grub命令執行時輸出的哪些啟動項,其實就是/etc/grub.d/03_os-prober這個腳本里面執行os-prober這個工具產生的。
在GRUB界面選擇啟動項,按e編輯啟動項。除了普通的上下左右鍵移動光標,還可以使用基本的Emacs快捷鍵:
Ctrl+N 下一行
Ctrl+P 上一行
Ctrl+B 左移一個字符
Ctrl+F 右移一個字符
Ctrl+A 移動光標到行首
Ctrl+E 移動光標到行尾
編輯完成后按Ctrl+X按照編輯后的結果啟動系統,但是編輯的結果不會保存,也就是說如果需要永久修改某個啟動項,就要修改grub.cfg文件或者會影響grub.cfg生成的/etc/default/grub以及/etc/grub.d/中的腳本文件了。
對于GRUB,我們一般需要知道的就這么多,關于GRUB其他一些用法和知識,可以參考GRUB與系統引導(https://blog.nanpuyue.com/2017/037.html)這篇文章。
在UEFI模式下,除了使用GRUB來引導內核以外,還可以通過UEFI直接引導內核(需要內核開啟了EFI Stub支持),具體的配置方式見Debian Wiki EFI Stub(https://wiki.debian.org/EFIStub)。需要注意的一點是在使用efibootmgr創建啟動項的時候,可能需要-d參數指定設備,否則可能會導致創建啟動項失敗。
內核啟動部分其實主要是想說initrd。initrd是一個小型的rootfs,這個rootfs保證了內核啟動過程中所需要的內核模塊和用戶態工具。同時,它還需要為下一個階段“系統初始化”做準備,也就是為init程序準備好真正的文件系統,并且啟動init程序。內核使用initrd啟動的過程主要是:
1.執行init腳本(這個不是上面說得init程序,而是生成好的initramfs中的/init這個文件。后面的步驟其實都發生在這個腳本的執行過程中);
2.解析內核啟動參數,識別關鍵的如debug、boot、break等;
3.執行/scripts/init-top/中的腳本;
4.加載內核模塊;
5.執行/scripts/init-premount/中的腳本;
6.執行/scripts/$BOOT腳本中的mountroot函數,其中的$BOOT參數就是第2步中識別到的boot參數指定的,自帶的可選項有local(本地啟動,默認)、nfs(比如PXE啟動);
7.執行/scripts/init-bottom/中的腳本;
8.執行init程序。
上面第6步提到initramfs-tools包自帶有兩種boot類型:local和nfs,我們使用live系統的時候的boot類型其實live。這個boot類型主要是live-boot這個包支撐起來的。
在啟動live系統的時候,/scripts/live中的mountroot會調用/lib/live/boot/目錄中的腳本設置根文件系統,包括掛在ISO和設置overlay等。
initrd啟動階段支持幾個特殊的啟動參數輔助調試:
1.debug 會開啟initrd啟動腳本中的調試模式;
2.break 可以講啟動停止在某個階段,例如break=premount就會在真正的根文件系統掛載前停掉啟動流程,并給你一個busybox環境;可選break的階段可以在/scripts/init腳本中看到,就是哪些使用maybe_break的行。
從這個階段開始,啟動流程就算是進入我們真實的的系統中了,init程序會啟動各種服務對系統進行配置,保證軟硬件環境可以正常使用。
deepin系統下默認的init程序是systemd,這個龐然大物太過復雜,或許將來開個坑寫一個系列才能說好……這里只簡單說明一下跟系統啟動流程相關的內容。一個是 man bootup中的一個圖:
基本涵蓋了由systemd接管系統以后,systemd所管理的服務之間的一個依賴和基本先后順序。
另外一個是systemd-analyze命令,通過systemd-analyze plog > bootup.svg可以更加直觀的看到systemd各個服務在啟動過程中啟動的時間和所存在的時間。
圖形界面階段是系統到達圖形環境后的過程,這個部分主要包括:
display-manager.service 啟動lightdm;
lightdm啟動lightdm-deepin-greeter;
用戶輸入密碼后進入圖形會話;
lightdm執行/usr/sbin/deepin-session;
/usr/sbin/deepin-session
執行/etc/X11/Xsession.d中的腳本,并最終啟動/usr/bin/startdde;
startdde啟動桌面環境的組件,系統啟動完成。
哦,對了,文章開頭的故事純屬虛構,請勿對號入座。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。