robot
最新文章(10)
Mqskit 和其它相關工具
CPython 的 GC 二、三事
寫 Mecurial Extension 是件快樂的事!
Mozilla 台灣辨公室徵人啟事
關於 Apple 的兩項專利
core dump 之前的 frame
怎麼發出 beep 聲?
先承認你要找的是奴才吧!
程式碼要清的多乾淨?
FreeBSD 的 Thread-Local Storage 實作
首頁
新編
最新留言
Entries RSS
重要關鍵字(10)
coding (122)
Python (93)
FreeBSD (71)
WEB (61)
URL (48)
hardware (46)
javascript (36)
Linux (34)
blog (30)
C++ (16)
所有關鍵字
新增 URL
FreeBSD 開機流程
by thinker
2 Columns
關鍵字:
FreeBSD
最近寫了「$FreeBSD$ 基礎建設」一系列的文章,本篇是之前的作品,在此重貼並修正一些錯字和圖片,並作為「 $FreeBSD$ 基礎建設」的一部分。 man boot 汝會看到,$FreeBSD$ boot 分成三個 stage,stage 1、2、3。stage 1 和 stage2 是自 boot sector load 進來,由 BIOS 讀取 stage 1,再由 stage 1 讀 stage2。stage 1、2 是放在 boot sectors,而 stage 3 則是放在一般的 filesystem 空間。前兩個 stage 被讀進 memory 並執行之後,就會把 stage 3 從 filesystem 讀入。stage 3 包含較豐富的功能,binary 的 size 也比較大,boot sectors 放抹落。 頭兩階段的 binary code,分別是 /boot/boot1 和 /boot/boot2。boot1 只有 512 Bytes,放在 slice 的第一個 sector (PC 的 partition),而 boot2 則放在隨後的 sectors。這些磁區就是 boot sectors,在每個 slice 的最前面。通常會為每個 slice 會保留一些 sectors,當作 boot sectors。由於 boot sector 太小,stage 3 是至 filesystem 內讀出。前兩個 stage 的主要功能,就是自 filesystem 讀出 stage 3。 stage 3,一般是 /boot/loader 這個程式,包含 script 功能(forth),因此可以提供較豐富的能力。有時,你也可以要求 stage 2,直接讀取 kernel 的 binary 執行,跳過 stage 3。 == /boot/boot0 == 除了三個 stage,/boot/boot0 是放在 PC 的 MBR,用以選擇使用哪一顆 HD 的哪一個 slice 開機。 == PC 架構 == 在 PC 架構下,一顆 HD 的格式規劃如下圖。每一顆 HD 都有一個 partition table,用以記錄硬碟的分割狀態。而第一顆硬碟($C$:)的 partition table,也被稱為 MBR。而 $FreeBSD$ 系統,則將 PC 的 partition 稱之為 slice。所以,一顆 HD 可以割成 4 個 slice。而 $FreeBSD$ 的每個 slice 又可切割成數個 partition,命名為 a ~ h。這裡的 partition 不同於 PC 的 partition,請勿混淆。以第一顆 IDE HD 而言,也就是 Windows 下的 $C$:,被命名為 ad0。而 ad0 的 4 個 slice,分別命名為 ad0s1、ad0s2、ad0s3、ad0s4。而 ad0s1 割成的 partition 而命名為 ad0s1a、ad0s1b、......、ab0s1h,其中 ad0s1c。partition c 固定用來代表整個 slice,含括整個 slice 的空間。 [attach:boot.png] PC 開機時,會自 MBR 將開機程式讀入 core memory 執行。boot0 就是安裝在 MBR 內,唯一的功用,是用來選擇用某一個 slice 來開機。譬如,咱選用第一個 slice 來開機,boot0 就會自 slice 1 load 第一個 sector 進 core memory,並執行。而,slice 的第一個 sector 就在第一個 partition 裡,也就是 ad0s1a 的第一個 sector,也就是 boot1 所儲存的所在。每一個 partition 都保有 8196 bytes 的大小,當作 boot sectors。然而,boot0 卻只支援從 partition a 開機,其它 partition 並不能用以開機。這應該是減化程式的邏輯。理論上,partition a 並不一定要自 slice 的第一個 sector 開始。但,boot0 毋管這麼多,就是讀取 slice 的第一個 sector。所以,如果要順利開機,最好是照規矩做。 boot sectors 總共有 8192 bytes,前 512 bytes,也就是第一個 sector,存放 boot1。剩的 7680 bytes 就是放 boot2。boot1 會將 boot2 讀入 core memory,合併成一個完整的程式。提供自 filesystem 讀取 loader 或者 kernel 的能力。 == BTX == BTX 是 BooT eXtender 的縮寫,在 bootstrap 時,提供程式一個簡單的 protected mode 的執行環境。[2] $FreeBSD$ 使用 BTX,提供開機時的基礎環境,開機程式較有彈性,容易維護。BTX 在 protected mode 下,提供使用 BIOS 的能力,透過 vm86 mode,執行 real mode 下的 BIOS 服務。 BTX 執行環境分成兩部分,kernel 和 client。BTX kernel 初始整個 protected mode 的執行環境,提供 vm86 mode 執行 BIOS int 的能力。BTX client 則是使用者程式,使用 BTX kernel 的 service,以完成任務。一個完整的 BTX 程式,也就是 BTX object file,包含 BTX loader、BTX kernel 和 BTX client,三者用 btxld 包裝成一個檔案,方便執行。執行一個 BTX object file,要先將 object file 讀入 core memory,然後 jmp 至 BTX loader 的進入點執行。接著 BTX loader 就會準備環境,讓 BTX kernel 執行。最後 BTX kernel 完成 protected mode 的初始,再將執行權交給 BTX client。 BTX loader (btxldr.S) 是在 real mode 執行的 16 bits 程式碼,為 BTX kernel 作準備。而 BTX kernl (btx.S) 是部分在 real mode 執行,一部分在 protected mode 執行。real mode 執行的部分,目的是為 protected mode 作準備。進入 protected mode 之後,所有的程式是以 protected mode 的 32 bits 程式碼執行。所以,在 btx.S 內,init 是以 .code16 進行 assemble,而其它部分則是用 .code32 進行 assemble。而 BTX client 一律是以 protected mode 的 32 bits 程式碼執行。 在開機過程中,boot0 和 boot1 是在 real mode 下執行,而 boot2 裡的 BTX client 是在 i386 protected mode 執行。boot2 是一個 BTX object,BTX client 包含 boot2.c 和 btx/lib 的內容。boot2 並沒使用 btxldr 作為標準的 BTX loader,而是由 boot1 充當 BTX loader。 == boot1 和 boot2 的執行 == boot0 將 boot1 載入 core memory 之後,boot1 先將自己 copy 到 MEM_REL,也將 boot sectors 的 16 個 sectors 讀入記憶體 MEM_BUF 的位置。MEM_BUF 是 nread 這個 sub-routine 存放磁碟資料的所在。boot1 將 boot2 的內容,copy 到 MEM_USR 的位置,而且執行。boot2 包含兩個部分,頭個部分是 disklabel,就是 slice 記載 disklabel 兮所在。boot1 實際上,只 copy 第二個部分 BTX client,也就是 boot2 的實際程式內容。boot2 在 link 時,被 relocate 到 0x2000 的絕對位址,而 BTX kernel 將 user space 的 segment selectors (SEL_UCODE 和 SEL_UDATA) 的起始位置,對映到 physical/linear address space 的 0xa000,也就是 MEM_USR 的位址。因此,boot2 實際上是 copy 到 0xa000 + 0x2000 = 0xc000 的位置。在 BTX kernel 進入保護模式後,boot2 的 code 就會對映到 user space 的 0x2000 的位置。 [attach:boot-in-mem.png] [attach:boot2-btx-object.png] 在執行 boot2 的 BTX client code 之前,BTX kernel 會先進入 i386 protected mode (保護模式)。 BTX kernel 為 protected mode 定義了 7 個 segment selectors,分成四組,分別是作為 system、user、real space 和 TSS 的 segment selectors。其中 real space 是用來對映 vm86 模式下的 logic address space。 [attach:boot-sel.png] == 結論 == 整體而言,bootstrap 的功能,就是提供讀取位在 filesystem 內的檔案的能力,以執行 loader 或者是 kernel。透過 boot0 在 MBR,提供多重開機選擇的能力,讓咱可以用不同的 slice 開機。透過 boot1 和 boot2,讓咱可以選擇開機的 kernel。而 BTX 系統,則提供一個簡單的環境,可以實作各種開機 boot loader 的功能。 == 參考 == # http://www.khmere.com/freebsd_book/html/ch02.html # http://tinyurl.com/jt4s
最後更新時間: 2006-12-10 14:43:10 CST |
引用
查詢:
COMMENTS: