啓動流程與主要啓動記錄區(MBR)
CMOS 與 BIOS
- CMOS是記錄各項硬件參數且嵌入在主板上面的儲存器
- BIOS則是一個寫入到主板上的一個韌體(再次說明, 韌體就是寫入到硬件上的一個軟件程序).這個BIOS就是在啓動的時候,計算機系統會主動運行的第一個程序了!
整個啓動流程到操作系統之前的動作應該是這樣的:
- BIOS:啓動主動運行的韌體,會認識第一個可啓動的裝置(即存儲設備,如硬盤,光盤等等);
- MBR:第一個可啓動裝置的第一個磁區內的主要啓動記錄區塊,內含啓動管理程序;
- 啓動管理程序(boot loader):一支可讀取核心文件來運行的軟件;
- 核心文件:開始操作系統的功能...
由上面的說明我們會知道,BIOS與MBR都是硬件本身會支持的功能,至於Boot loader則是操作系統安裝在MBR上面的一套軟件了.由於MBR僅有446 bytes而已,因此這個啓動管理程序是非常小而美的. 這個boot loader的主要任務有底下這些項目:
- 提供菜單:使用者可以選擇不同的啓動項目,這也是多重啓動的重要功能!
- 加載核心文件:直接指向可啓動的程序區段來開始操作系統;
- 轉交其他loader:將啓動管理功能轉交給其他loader負責.
並且啓動管理程序除了可以安裝在MBR之外, 還可以安裝在每個分割槽的啓動磁區(boot sector)
我們舉一個例子來說,假設你的個人計算機只有一個硬盤,裏面切成四個分割槽,其中第一、二分割槽分別安裝了Windows及Linux, 你要如何在啓動的時候選擇用Windows還是Linux啓動呢?假設MBR內安裝的是可同時認識Windows/Linux操作系統的啓動管理程序, 那麼整個流程可以圖示如下:
在上圖中我們可以發現,MBR的啓動管理程序提供兩個菜單,菜單一(M1)可以直接加載Windows的核心文件來啓動; 菜單二(M2)則是將啓動管理工作交給第二個分割槽的啓動磁區(boot sector).當使用者在啓動的時候選擇菜單二時, 那麼整個啓動管理工作就會交給第二分割槽的啓動管理程序了. 當第二個啓動管理程序啓動後,該啓動管理程序內(上圖中)僅有一個啓動菜單,因此就能夠使用Linux的核心文件來啓動羅. 這就是多重啓動的工作情況啦!我們將上圖作個總結:
- 每個分割槽都擁有自己的啓動磁區(boot sector)
- 圖中的系統槽爲第一及第二分割槽,
- 實際可啓動的核心文件是放置到各分割槽內的!
- loader只會認識自己的系統槽內的可啓動核心文件,以及其他loader而已;
- loader可直接指向或者是間接將管理權轉交給另一個管理程序.
那現在請你想一想,爲什麼人家常常說:『如果要安裝多重啓動, 最好先安裝Windows再安裝Linux』呢?這是因爲:
- Linux在安裝的時候,你可以選擇將啓動管理程序安裝在MBR或各別分割槽的啓動磁區, 而且Linux的loader可以手動配置菜單(就是上圖的M1, M2...),所以你可以在Linux的boot loader裏面加入Windows啓動的選項;
- Windows在安裝的時候,他的安裝程序會主動的覆蓋掉MBR以及自己所在分割槽的啓動磁區,你沒有選擇的機會, 而且他沒有讓我們自己選擇菜單的功能.
因此,如果先安裝Linux再安裝Windows的話,那MBR的啓動管理程序就只會有Windows的項目,而不會有Linux的項目 (因爲原本在MBR內的Linux的啓動管理程序就會被覆蓋掉). 那需要重新安裝Linux一次嗎?當然不需要,你只要用盡各種方法來處理MBR的內容即可. 例如利用全中文的spfdisk(http://spfdisk.sourceforge.net/)軟件來安裝認識Windows/Linux的管理程序, 也能夠利用Linux的救援模式來挽救MBR即可.
文件系統
superblock,inode,block
superblock,inode,block數據簡略說明:
- superblock:記錄此 filesystem 的整體信息,包括inode/block的總量、使用量、剩餘量, 以及文件系統的格式與相關信息等;
- inode:記錄文件的權限與屬性,一個文件佔用一個inode,同時記錄此文件的數據所在的 block 號碼;
- block:實際記錄文件的內容,若文件太大時,會佔用多個 block .
每個 inode 與 block 都有編號,而每個文件都會佔用一個 inode ,inode 內則有文件數據放置的 block 號碼.所以如果能夠找到文件的 inode 的話,那麼自然就會知道這個文件所放置數據的 block 號碼, 當然也就能夠讀出該文件的實際數據了.
data block (數據區塊)
block 基本限制:
- 原則上,block 的大小與數量在格式化完就不能夠再改變了(除非重新格式化)
- 每個 block 內最多隻能夠放置一個文件的數據
- 若文件大於 block 的大小,則一個文件會佔用多個 block 數量
- 若文件小於 block ,則該 block 的剩餘容量就不能夠再被使用了(磁盤空間會浪費)
- 在 Ext2 文件系統中所支持的 block 大小有 1K, 2K 及 4K 三種而已
Block 大小 | 1KB | 2KB | 4KB |
最大單一文件限制 | 16GB | 256GB | 2TB |
最大文件系統總容量 | 2TB | 8TB | 16TB |
inode table (inode 表格)
inode 數據內容:
- 該文件的存取模式(read/write/excute)
- 該文件的擁有者與羣組(owner/group)
- 該文件的容量
- 該文件創建或狀態改變的時間(ctime)
- 最近一次的讀取時間(atime)
- 最近修改的時間(mtime)
- 定義文件特性的旗標(flag),如 SetUID...
- 該文件真正內容的指向 (pointer)
inode 的特色點:
- 每個 inode 大小均固定爲 128 bytes
- 每個文件都僅會佔用一個 inode 而已
- 承上,因此文件系統能夠創建的文件數量與 inode 的數量有關
- 系統讀取文件時需要先找到 inode,並分析 inode 所記錄的權限與用戶是否符合,若符合才能夠開始實際讀取 block 的內容
系統將 inode 記錄 block 號碼的區域定義爲12個直接,一個間接, 一個雙間接與一個三間接記錄區,如下圖所示:
- 12 個直接指向: 12*1K=12K
- 間接: 256*1K=256K
- 雙間接: 256*256*1K=2562K=64M
- 三間接: 256*256*256*1K=16777216K=16384M=16G
Superblock (超級區塊)
Superblock 是記錄整個 filesystem 相關信息的地方, 沒有 Superblock ,就沒有這個 filesystem 了.
記錄的信息主要有:
- block 與 inode 的總量
- 未使用與已使用的 inode / block 數量
- block 與 inode 的大小 (block 爲 1, 2, 4K,inode 爲 128 bytes)
- filesystem 的掛載時間、最近一次寫入數據的時間、最近一次檢驗磁盤 (fsck) 的時間等文件系統的相關信息
- 一個 valid bit 數值,若此文件系統已被掛載,則 valid bit 爲 0 ,若未被掛載,則 valid bit 爲 1
block bitmap (區塊對照表)
block bitmap 記錄使用與未使用的 block 號碼,並在進行文件添加修改時候對應的修改 block 的使用狀況
inode bitmap (inode 對照表)
inode bitmap 記錄使用與未使用的 inode 號碼,並在進行文件添加修改時候對應的修改 inode 的使用狀況
boot sector 與 superblock 的關係
block 爲 1024 bytes (1K) 時:
如果 block 大小剛好是 1024 的話,那麼 boot sector 與 superblock 各會佔用掉一個 block , 所以整個文件系統圖示就會如同圖 1.3.1 所顯示的那樣,boot sector 是獨立於 superblock 外面的!
如果 block 大於 1024 的話:
那麼 superblock 將會在 0 號,在第一個 block 內 superblock 僅佔有 1024-2047 ( 由 0 號起算的話)之間的咚咚,至於 2048bytes 以後的空間就真的是保留啦!而 0-1023 就保留給 boot sector 來使用
索引式文件系統(indexed allocation)
在索引式文件系統(indexed allocation)中將 inode 與 block 區塊用圖解來說明一下,如下圖所示,文件系統先格式化出 inode 與 block 的區塊,假設某一個文件的屬性與權限數據是放置到 inode 4 號(下圖較小方格內),而 這個 inode 記錄了文件數據的實際放置點爲 2, 7, 13, 15 這四個 block 號碼,此時我們的操作系統就能夠據此來排列磁盤的閱讀順序,可以一口氣將四個 block 內容讀出來! 那麼數據的讀取就如同下圖中的箭頭所指定的模樣了.
FAT 格式
閃盤使用的文件系統一般爲 FAT 格式.FAT 這種格式的文件系統並沒有 inode 存在,所以 FAT 沒有辦法將這個文件的所有 block 在一開始就讀取出來.每個 block 號碼都記錄在前一個
block 當中, 他的讀取方式有點像底下這樣:
上圖中我們假設文件的數據依序寫入1->7->4->15號這四個 block 號碼中, 但這個文件系統沒有辦法一口氣就知道四個 block 的號碼,他得要一個一個的將 block 讀出後,纔會知道下一個
block 在何處. 如果同一個文件數據寫入的 block 分散的太過厲害時,則我們的磁盤讀取頭將無法在磁盤轉一圈就讀到所有的數據, 因此磁盤就會多轉好幾圈才能完整的讀取到這個文件的
內容!此時文件讀取的效能將會變的很差所致. 這個時候可以透過碎片整理將同一個文件所屬的 blocks 彙整在一起.
Ext2 文件系統
件系統一開始就將 inode 與 block 規劃好了,除非重新格式化(或者利用 resize2fs 等命令變更文件系統大小),否則 inode 與 block 固定後就不再變動
Ext2 文件系統在格式化的時候基本上是區分爲多個區塊羣組 (block group) 的,每個區塊羣組都有獨立的 inode/block/superblock 系統,整個來說,Ext2 格式化後有點像底下這樣:
文件系統最前面有一個啓動扇區(boot sector),這個啓動扇區可以安裝啓動管理程序,如此一來我們就能夠將不同的啓動管理程序安裝到個別的文件系統最前端,而不用覆蓋整顆硬盤唯一的
MBR, 這樣也才能夠製作出多重引導的環境!
目錄
在 Linux 下的 ext2 文件系統創建一個目錄時, ext2 會分配一個 inode 與至少一塊 block 給該目錄.
inode 記錄該目錄的相關權限與屬性,並可記錄分配到的那塊 block 號碼
block 則是記錄在這個目錄下的文件名與該文件名佔用的 inode 號碼數據.如下圖所示:
文件
在 Linux 下的 ext2 創建一個一般文件時, ext2 會分配一個 inode 與相對於該文件大小的 block 數量給該文件
目錄樹讀取
由於目錄樹是由根目錄開始讀起,因此係統透過掛載的信息可以找到掛載點的 inode 號碼(通常一個 filesystem 的最頂層 inode 號碼會由 2 號開始喔!),此時就能夠得到根目錄的 inode 內容,並依據該 inode 讀取根目錄的 block 內的文件名數據,再一層一層的往下讀到正確的檔名.舉例來說,如果我想要讀取 /etc/passwd 這個文件時,系統是如何讀取的呢?
2 drwxr-xr-x 23 root root 4096 Sep 22 12:09 /
1912545 drwxr-xr-x 105 root root 12288 Oct 14 04:02 /etc
1914888 -rw-r--r-- 1 root root 1945 Sep 29 02:21 /etc/passwd
在鳥哥的系統上面與 /etc/passwd 有關的目錄與文件數據如上表所示,該文件的讀取流程爲(假設讀取者身份爲 vbird 這個一般身份使用者):
- / 的 inode:
透過掛載點的信息找到 /dev/hdc2 的 inode 號碼爲 2 的根目錄 inode,且 inode 規範的權限讓我們可以讀取該 block 的內容(有 r 與 x) ; - / 的 block:
經過上個步驟取得 block 的號碼,並找到該內容有 etc/ 目錄的 inode 號碼 (1912545); - etc/ 的 inode:
讀取 1912545 號 inode 得知 vbird 具有 r 與 x 的權限,因此可以讀取 etc/ 的 block 內容; - etc/ 的 block:
經過上個步驟取得 block 號碼,並找到該內容有 passwd 文件的 inode 號碼 (1914888); - passwd 的 inode:
>讀取 1914888 號 inode 得知 vbird 具有 r 的權限,因此可以讀取 passwd 的 block 內容; - passwd 的 block:
最後將該 block 內容的數據讀出來.