最近一直在專注的學習一樣技術,主要就是Linux/Unix系統的引導過程,從最基本的機器加電一直到最終系統能夠正確的使用為止,這個過程中涉及到了相當多的技術,以及各種技術的推陳出新,都在這個重要的過程中得以體現。我之所以對這部分進行了分析,主要是工作上面需要這方面的知識,同時覺得很有意思,所以廣泛的深入研究了一下。
好了,廢話不多說了,開始來點干貨吧,本文並非全部原創,參考了一些文章,具體請查看“參考”部分。
Linux/Unix系統的引導過程包含了很多階段,但是對於一個標准的系統的引導,大致的階段是類似的,不同的平台會有一些不同之處(x86平台下主要使用LILO、SYSLINUX或是grub,SPARC平台下主要使用OBP作為loader)。在接下來的章節中,我將從系統加電開始直至Linux/Unix內核被正式加載運行。
首先從高層的架構分析一下Linux/Unix引導流程,下面的圖作為一種更加形象的說明,這樣你可以從上次梗概的了解整個流程,為下面深入的分析打下基礎。
從這張圖中,總結一下大概的流程,分別是:系統啟動、階段1引導、階段2引導、內核加載和用戶態的初始化。在系統啟動階段主要用的技術包括BIOS(最新的發展為EFI),階段1引導主要用的技術包括Master Boot Record(最近的發展為GPT),階段2引導主要用的技術包括LILO、GRUB、SYSLINUX、GRUB2(x86平台下)和OBP(SPARC平台下)。這張圖屬於比較古老的一種介紹,在目前的技術發展下,每個階段都有了一些變化。
這裡。
與傳統MBR相比,GPT采用了不同的分區方式。
對於傳統MBR,其結構主要如下:
上圖即對上文中所述的很形象的說明,在圖中看到MBR被分成三個部分,分別是:Bootloader、分別表以及Magic Number。其中Bootloader部分為stage1中被執行的起始部分,程序在這裡被作為GRUB程序執行,詳細的關於GRUB的內容將再下面章節中進行詳細闡述。
相反,對於EFI系統中所采用的GPT分區方式,則采用了不同於MBR分區方式的形式,從下圖中可以發現:
如上圖所示,GPT分區表主要包括:保護MBR、首要GPT頭、首要GPT、備用GPT、備用GPT頭和磁盤數據區。保護MBR與正常的MBR區別不大,主要是分區表上的不同,在保護MBR中只要一個表示為0xEE的分區,以此來表示這塊硬盤使用GPT分區表。首要GPT頭包含了眾多信息,具體內容如下:
偏移
字節長度
說明
0x00
8
簽名,固定為ASCII碼"EFI PART",16進制表示0x5452415020494645。
0x08
4
版本號,目前的版本為V1.0,16進制表示0x00010000。
0x0C
4
分區表頭的大小(單位是字節,通常是92字節,即5C 00 00 00)
0x10
4
GPT頭中字節的CRC32校驗
0x14
4
固定值00 00 00 00
0x18
8
當前LBA(這個分區表頭的位置)
0x20
8
備份LBA(另一個分區表頭的位置)
0x28
8
第一個可用於分區的LBA(主分區表的最後一個LBA + 1)
0x30
8
最後一個可用於分區的LBA(備份分區表的最後一個LBA−1)
0x38
16
磁盤GUID
0x48
8
分區表項的起始LBA
0x50
4
分區表項的數量
0x54
4
一個分區表項的大小(通常是128)
0x58
4
分區表CRC32校驗
0x5C
420
保留,剩余的字節必須是0(對於512字節LBA的硬盤即是420個字節)
分區表頭定義了硬盤的可用空間以及組成分區表的項的大小和數量。分區表頭還記錄了這塊硬盤的GUID,記錄了分區表頭本身的位置和大小(位置總是在LBA1)以及備份分區表頭和分區表的位置和大小(在硬盤的最後)。它還存儲著它本身和分區表的CRC32校驗。固件、引導程序和操作系統在啟動時可以根據這個校驗值來判斷分區表是否有錯誤,如果出錯了,可以使用軟件從硬盤最後的備份GPT分區表恢復整個分區表,如果備份GPT也校驗錯誤,那麼磁盤將不可用,系統拒絕啟動。
接下來主要是128個分區表項,GPT分區表使用簡單而直接的方式表示分區。一個分區表項的前16字節是分區類型GUID。例如,EFI系統分區的GUID類型是{C12A7328-F81F-11D2-BA4B-00A0C93EC93B} 。接下來的16字節是該分區的唯一的GUID(這個指的是該分區本身,而之前的GUID指的是該分區的類型)。在接下來是分區其實和末尾的64位LBA編號,以及分區的名字和屬性。具體結構如下表:
偏移
字節長度
說明
0x00
16
分區類型GUID
0x10
16
唯一的分區GUID
0x20
8
開始LBA
0x28
8
結束LBA
0x30
8
分區屬性
0x38
72
分區名稱(Unicode碼)