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 基礎建設 - BTX
by thinker
2 Columns
關鍵字:
coding
FreeBSD
* Loader * Kernel * Client BTX 為 $FreeBSD$ boot loader 使用的執行檔格式,以載入 loader(8) 或直接載入 kernel ,因此 loader(8) 和 kernel 都 compile 成 BTX 格式。 一個 BTX 執行檔包括三個部分, BTX loader 、 BTX kernel 、 BTX client 。 三者被 btxld(8) 包裝成一個 bin 、 aout 或 ELF 格式的執行檔。這個執行檔的 text segment 只存放 BTX loader 的全部內容,而 data segment 則依序包括 BTX kernel 和 BTX client 。 BTX loader 的程式碼,被 relocate 到固定的位址 (0x200000)。當一個 BTX 執行檔被載入記憶體後,固定放在 address space 的 0x200000 的位址,其後接著 data segment。載入 BTX 執行檔的程式,會直接跳到 BTX 執行檔的進入點,也就是 BTX loader 的進入點,直接執行。 == BTX Loader == * MEM_TBL = 0x5000 * MEM_ENTRY = 0x9010 * MEM_DATA = start+0x1000 * start is start address of BTX loader. BTX loader 的功能是將 BTX kernel 和 BTX client , relocate 到指定的位置。在 BTX kernel 的一開頭有一個 header ,其中有一個欄位 btx_hdr::btx_pgctl ,指定 loader 要包留多少空間給 page table 。page table 的位址固定在 MEM_TBL (0x5000) ,而 BTX kernel 則被 BTX loader 放在隨之在後的位址,目前固定在 0x9000 位址。BTX loader 在完成載入後,會跳到 btx header 後面的位置 MEM_ENTRY (0x9010) 執行,也就是 BTX kernel 程式碼的進入點。 BTX client 位在 BTX kernel 之後,可由 BTX kernel 的 size , btx_hdr::btx_textsz 算出來。 BTX client 必需是一個 ELF 格式的 object file ,BTX loader 將依 BTX client 的 ELF program header 中的 ELF32_Phdr::p_vaddr , relocate 到以 0xa000 (0x9000 + PAGE_SIZE) 為始的相對位址 。而 BTX client 的 entry point 會記錄在 btx_hdr::btx_entry 。由於 BTX client 以 user privilege 執行,其 virtual address space 是以 physical address space 的 0xa000 開始,因此 btx_hdr::btx_entry 是 BTX client 在 virtual address space 中進入點位址。 [attach:btx_exec.png] == Kernel == BTX kernel 分成兩個部分,第一部分的 code 是 x86 16 bits 模式的 code ,第二部分是 32 bits 模式的 code 。16 bits 的 code 為進入 32 bits 模式做準備, initial GDT 、 LDT 、 IDT 甚至 page table 。但因為目前 default 並沒有啟用 paging ,而且 page table 的初始程式碼似乎也有 bug ,所以並沒有真的設定 page table 。設定完這些環境後,一個 long jump (ljmp) , 直接進入 32 bits mode 的 code 執行。 BTX loader 的 code 基本上是 32 bits mode ,但是為了執行 BTX kernel ,必需先回到 16 bits mode 。所以, BTX loader 其實有一小段 code 是 16 bits mode ,當作 BTX loader 回到 16 bits mode 的進入點。回到 16 bits mode 也是透過一個 long jump (ljmp) ,原因是基於 CPU 的設計,這裡不多述。 BTX kernel 初始了硬體環境,保括一些 register 和 project mode 的設定。並提供 BTX client 一些基本功能,包括 BIOS 的呼叫和執行其它的 BTX client 能力。 BTX client 可以透過呼叫 BIOS ,完成一些基本的 IO 動作。例如: 螢幕輸出。 == BTX Client == BTX 提供 csu 和 syscall 介面,讓 $C$ 程式可以直接執行,並可呼叫 BTX kernel 的 service ,包括 v86 mode 執行 BIOS 和執行其它 BTX client 。 以下是一個 hello world: {{{ /* helloworld.c */ #include "btxv86.h" void putc(unsigned char c) { __v86.ctl = 0; __v86.addr = 0x10; __v86.eax = 0x0e00 | c; __v86.ebx = 0x0000; v86int(); } int main(int argc, char **argv) { int i; unsigned char *s = "hello world!!\r\n"; for(i = 0; s[i] != 0; i++) { putc(s[i]); } for(i = 0;; i++); return 0; } int exit(int status) { } }}} 下面是 makefile,可在 $FreeBSD$ 環境下 make 出一個名為 helloworld 的 BTX client。 {{{ # Makefile PROG= helloworld.sym SRCS= helloworld.c CFLAGS= -I/usr/src/sys/boot/i386/btx/lib LDFLAGS= -static -Ttext 0x0 -nostdlib OBJS= /usr/obj/usr/src/sys/boot/i386/btx/lib/crt0.o MAN= BTXLDR= /usr/obj/usr/src/sys/boot/i386/btx/btxldr/btxldr BTXKERN= /usr/obj/usr/src/sys/boot/i386/btx/btx/btx CLEANFILES= helloworld helloworld.bin all: helloworld helloworld: helloworld.bin btxld -v -f aout -e 0x200000 -o $${.TARGET} -l $${BTXLDR} \ -b $${BTXKERN} helloworld.bin helloworld.bin: helloworld.sym cp $${.ALLSRC} $${.TARGET} strip -R .comment -R .note $${.TARGET} .include <bsd.prog.mk> }}} /usr/obj/usr/src/sys/ 底下的檔案,都是屬於 $FreeBSD$ make kernel 後所產生的 object file 。因此,若你的 $FreeBSD$ 無法找到這些檔案時,請安裝 $FreeBSD$ 的 kernel source ,並且到 /usr/src 下面 make kernel 。這個 makefile 在 link crt0.o 和 helloworld.o 時,下了 -nostdlib 的參數,目的是讓 ld 不去 link libc 。 crt0.o 則是 BTX 的 csu ,用來初始 $C$ 所需要的執行環,然後執行 main() 。因此,你需將這個檔案當作第一個 object file ,使之位於 executable 的開頭位置,作為程式的進入點。ld 產生的 executable 為 helloworld.sym , strip 之後改名為 helloworld.bin 。使用 btxld 將之和 BTX loader 、 BTX client 包裝成 BTX executable ,取名為 helloworld。 將 helloworld copy 到 root filesystem ,開機時以 boot loader 載入執行,不需透過作業系統。以下是 Bochs PC 模擬器的執行畫面: [attach:btx_helloworld.png] == 結語 == hello world 看起來並不是這麼難,沒 OS 的環境也不是那麼複雜。但,對於硬體的運作必需有更進一步的了解,才能從 hello world 進入有實際功能的$應用$。
最後更新時間: 2006-12-14 12:09:21 CST |
引用
查詢:
COMMENTS: