聽了 jserv 的進階嵌入式系統開發與實作之後, 知道可以將 rom.fs 合併到 elf 執行檔中。
課程是以 arm 為平台, 我花的功夫則是把 objcopy 的 x86 平台參數找出來。
objcopy -I binary -O elf32-i386 -B i386 --prefix-sections '.romfs' rom.fs test-romfs.o
這是把 rom.fs 放到 .romfs section 產生 obj file, 再 link test-romfs.o 到 elf 執行檔即可。這招程式設計師的自我修養--連結、載入、程式庫就有提過, 其中範例是把一個 jpg 圖檔塞入 elf, 不過我真的忘了。
增加如下的 linker script:
. = ALIGN(32); __romfs_start__ =.; .romfs.data : { *(.romfs.data) } __romfs_end__ = .;
linker script 很難理解的原因在於除了其怪異的語法之外, 還需要對 elf 檔有一定的理解, 而要對 elf 檔有一定的理解, 還需要能理解 elf 在記憶體中的佈局, 有了想像中的畫面, 才能通盤理解 linker script, 也才能體會其強大。若只看 gnu ld manual, 其實很難理解 linker script。我則是透過閱讀幾本書加上實作, 才達到略懂的地步。
在 C 語言裡頭, 這樣的宣告就可以抓到 romfs 在記憶體的開頭位址:
extern int __romfs_start__, __romfs_end__; int romfs_addr = &__romfs_start__
然後開心的把 p_kernel.elf 載入到 ram, 不用辛苦的載入兩次, 載入兩次雖然不難, 但也是有些小細節要注意, 能避免則避免, 我踩到好幾次地雷了。
參考 dos memory layout 之後, 我思考重新擺放 simple kernel, ramdisk 的位址, 目前在真實模式下使用 bios 0x13 載入檔案到記憶體, 進入保護模式後, 我會把 p_kernel.elf (include ramdisk) copy 到 0x100000 (真實模式達不到的位址), 這是 p_kernel.elf 的程式進入點。
程式設計師的自我修養--連結、載入、程式庫 p68 提到一個簡單的方法:
romfs.fs 為 romfs 的影像檔 (image)
descent@debian-vm:simple_os$ objcopy -I binary -O elf32-i386 -B i386 romfs.fs test-romfs.o descent@debian-vm:simple_os$ objdump -ht test-romfs.o test-romfs.o: file format elf32-i386 Sections: Idx Name Size VMA LMA File off Algn 0 .romfs.data 00000400 00000000 00000000 00000034 2**0 CONTENTS, ALLOC, LOAD, DATA SYMBOL TABLE: 00000000 l d .romfs.data 00000000 .romfs.data 00000000 g .romfs.data 00000000 _binary_rom_fs_start 00000400 g .romfs.data 00000000 _binary_rom_fs_end 00000400 g *ABS* 00000000 _binary_rom_fs_size
把 _binary_rom_fs_start, _binary_rom_fs_end, _binary_rom_fs_size 直接拿來用就好, 不用改 linker script。
PC-DOS and MS-DOS memory map
high memory
| |||
segment
|
offset
|
size
|
contents
|
0000h
|
0000h
|
1024
|
interrupt vector table
|
0400h
|
172
|
BIOS communication area
| |
04ACh
|
68
|
reserved by IBM
| |
04F0h
|
16
|
user communication area
| |
0500h
|
256
|
DOS communication area
| |
0600h
|
varies
|
operating system:
IBMBIO.COM (DOS interface to the BIOS) IBMDOS.COM (DOS interrupt handlers and interrupt 21h service routines DOS buffers, control areas, and device drivers COMMAND.COM (resident portion), interrupt 22h, 23h, and 24h handlers, routine to reload transient portion of COMMAND.COM memory-resident utilities transient applications transient portion of COMMAND.COM | |
9000h
|
FFFFh
|
highest address of user memory
| |
A000h
|
0000h
|
128K
|
reserved area of ROM
|
A000h
|
0000h
|
beginning of area used by EGA and PS/2 video systems
| |
B000h
|
0000h
|
4000
|
monochrome video memory
|
0800h
|
16K
|
color graphics adaptor (CGA) video memory
| |
C000h
|
0000h
|
192K
|
ROM expansion and control area
|
8000h
|
ROM for hard disk
| ||
D000h
|
ROM expansion and control area
| ||
E000h
|
ROM expansion and control area
| ||
F000h
|
0000h
|
16K
|
reserved ROM
|
4000h
|
40K
|
base system ROM, ROM BASIC
| |
E000h
|
8K
|
ROM BIOS
| |
low memory
|
ref:
Linux中使用C語言載入data object 檔案資料
沒有留言:
張貼留言
使用 google 的 reCAPTCHA 驗證碼, 總算可以輕鬆留言了。
我實在受不了 spam 了, 又不想讓大家的眼睛花掉, 只好放棄匿名留言。這是沒辦法中的辦法了。留言的朋友需要有 google 帳號。