2019年3月26日

Linux啟動流程

前言:
這篇主要描述Linux啟動流程,並從啟動流程帶出現代作業系統的開機流程設計,
並進一步延伸non-OS系統的設計概念。


Linux啟動流程:
Linux啟動的完整流程原則上如下圖:


硬體:
不論電腦使用哪種CPU,CPU在通電做完硬體極少的工作後,就會跳到某個固定的記憶體位址執行。
對於PC來說,PC有BIOS,CPU通電後會執行BIOS,BIOS做完系統檢查後,
會根據CMOS中選擇的開機裝置(軟碟、光碟、硬碟、USB光碟、USB硬碟...等),
跳到特定位址執行。
對於嵌入式系統來說,就是跳到固定位址,BootLoader接手執行。


BootLoader:
BootLoader中文就是「開機程式」,在PC Linux上,常見的就是GRUB,
在嵌入式系統上有幾套常見的BootLoader,目前來說,uboot是最常見的BootLoader。
BootLoader主要工作其實只有2個:
  1. 將Kernel從各種奇怪的媒體裝置(光碟、硬碟、網路)讀取到記憶體(RAM)中
  2. 跳到Kernel在記憶體中的位址執行


這邊標注一下,嵌入式系統中,牽涉到開機部份,經常看到「跳躍」、「跳到」之類的名詞,
實際意義是,CPU就是不斷執行下個指令的裝置,要讓它到某個位址執行,
就直接用組合語言的JUMP 0xoooooo,它就會跳過去執行了,
所以會用「跳躍」、「跳到」某個位址執行來描述。


initrd/initramfs:
這是Linux特有的設計,它其實跟rootfs是一樣的東西,可以把它看作是小rootfs。
在Linux上,initrd/initramfs用途是:
在正式進入系統前的特殊操作,都可以放入initrd/initramfs中處理。
例如:
  • Linux Kernel module載入工作
  • 系統硬體檢查
  • 系統故障時的處置


在Linux上,不一定需要有initrd/initramfs,
可以在Kernel載入後,直接跳入rootfs,並沒有硬性規定一定要有initrd/initramfs;
同樣的,Linux上也沒有硬性規定一定要有rootfs,
可以直接把initrd/initramfs當rootfs直接使用。
initrd和initramfs這2個稱呼都有人使用,早期的Linux是稱叫initrd,
在Linux 2.6版將它重新設計,重新設計後稱為initramfs,
所以有人繼續沿用initrd稱呼,有人稱initramfs,但不論哪種稱呼,都是描述這個東西。
initrd/initramfs和rootfs有項最大的不同,initrd/initramfs整個是執行在RAM當中,
它的執行環境直接是RAM Disk,這有2項特色:
  1. 執行週期(在initrd/initramfs中執行過程)的檔案變動,都不會影響initrd/initramfs的內容
  2. initrd/initramfs越大,佔用RAM越大
  3. 因為執行在RAM中,可以在此時對Linux各部份進行修改、變動, 不會有媒體佔用(disk busy...等)的問題。
例如:重新燒錄Kernel、rootfs、initrd/initramfs


rootfs:
在Linux中,rootfs有2項含意:
  1. rootfs是實際的系統所在,它的概念等同於Windows的C磁碟或系統碟
  2. 在啟動流程中,rootfs代表系統實際進入rootfs(系統碟), 並由rootfs(系統碟)內的啟動程序接手執行


當rootfs的啟動程序完成後,就是我們看到的Linux畫面,此時所有的操作,都是在rootfs中進行。
rootfs不一定需要,嵌入式系統中,很可能因為Flash太小,直接捨棄rootfs,
將initrd/initramfs當rootfs使用。


現代作業系統的開機流程:
前面描述了Linux的開機流程,大致系統開機,所以這邊簡單的描述現代作業系統的開機流程。


現代作業系統的開機流程圖:

目前主流的作業系統,開機都是類似的流程,去除Linux特有的initrd/initramfs後,
就是大部分作業系統的開機流程,以Windows為例:


Windows的動作流程其實一致,但名稱不同。


BootLoader:
Windows稱為NTLDR。
在開機時,如果有多個OS,會出現一個中文的選單,
像是WinXP會顯示「Microsoft Windows XP」,這個就是Windows的BootLoader。
在以前MCSE課程中,關於開機啟動的Troubleshooting部份,
就有提到NTLDR missing時的處理,這其實就等於GRUB出現找不到開機程式時的問題解決方式。


Kernel:
Windows的Kernel稱為ntoskrnl.exe,早期放在C:\,並用系統檔案屬性隱藏。


rootfs:
Windows的rootfs稱為「系統碟」。
在安裝Windows時,一個部份是選擇安裝磁碟,你可以將系統裝在D:\、E:\,
系統碟的最重要辨識方式是,Windows資料夾和Program Files資料夾在哪個磁碟,
這個磁碟就是系統碟。

non-OS系統的設計概念:
所謂non-OS系統的意思,就是這個電腦系統沒有作業系統,一個盲點就出現了,
電腦沒有作業系統可以跑?
答案是肯定的,電腦沒有作業系統也是可以跑的,在很多低階單晶片系統中,
沒有作業系統一樣跑得很開心。


non-OS系統有什麼不同?從執行流程來看,如下:


有前面作業系統執行流程的理解後,這邊再看看non-OS系統的執行流程,
此時會發現,其實啟動概念相同。
在non-OS系統中同樣有硬體、BootLoader,
但Kernel和rootfs都沒有,而是自行撰寫的嵌入式程式。
嵌入式程式:
嵌入式程式最重要的關鍵是Loop,因為CPU的功能就是不斷地執行下個指令,
因此嵌入式程式內的設計就是要設計個while-loop,
讓CPU在執行到最後時,會回到while開頭重頭執行。

更低階的單晶片系統設計更簡化,連BootLoader都沒有,因此執行流程變為:

最基本的Kernel設計:
Kernel內設計很複雜,詳細的細節原則上就是參考「作業系統」教科書,
裡面大致區分了Scheduler、Memory Manager...等一堆設計。
其實我們把Kernel單純化到極限,從non-OS系統的角度來看Kernel設計,
其實Kernel就是個超大型的while-loop程式,如下圖:

看起來其實和non-OS系統差不多,最主要就是Kernel內多了Scheduler這個元件,
透過它動態選擇不同的Task(在Linux上就是Process)執行。

沒有留言: