[英]Bootloader in C won't compile
我是編寫引導加載程序的新手。 我已經在 asm 中編寫了一個 helloworld 引導加載程序,現在我正在嘗試在 C 中編寫一個。 我在 C 中編寫了一個 helloworld 引導加載程序,但我無法編譯它。
這是我的代碼。 我究竟做錯了什么? 為什么編譯不出來?
void print_char();
int main(void){
char *MSG = "Hello World!";
int i;
__asm__(
"mov %0, %%SI;"
:
:"g"(MSG)
);
for(i=0;i<12;i++){
__asm__(
"mov %0, %%AL;"
:
:"g"(MSG[i])
);
print_char();
}
return 0;
}
void print_char(){
__asm__(
"mov $0X0E, %AH;"
"mov $0x00, %BH;"
"mov $0x04, %BL;"
"int $0x10"
);
}
我建議您查看http://wiki.osdev.org/Rolling_Your_Own_Bootloader以及以下的引導加載程序部分: http://www.brokenthorn.com/Resources/OSDev2FCC675238FDC30D825
有很好的教程可以讓你自己開始制作你自己的引導加載程序。 如果您需要更多信息,也可以加入 freenode 中的#osdev 頻道以加入討論。
讓我在這里假設很多事情:您想在 x86 系統上運行引導加載程序,您在 *nix 機器上設置了 gcc 工具鏈。
編寫引導加載程序時需要考慮以下幾點:
現在如果你想要 gcc 到 output 這樣的二進制文件,你需要用它玩一些技巧。
__asm__(".code16gcc\n")
。 gcc 在 ELF 中輸出編譯對象。 我們需要一個在 7c00h 靜態鏈接的 bin。 使用以下內容創建文件linker.ld
ENTRY(main); SECTIONS {. = 0x7C00; .text: AT(0x7C00) { _text =.; *(.text); _text_end =.; }.data: { _data =.; *(.bss); *(.bss*); *(.data); *(.rodata*); *(COMMON) _data_end =.; }.sig: AT(0x7DFE) { SHORT(0xaa55); } /DISCARD/: { *(.note*); *(.iplt*); *(.igot*); *(.rel*); *(.comment); /* add any unwanted sections spewed out by your version of gcc and flags here */ } }
在bootloader.c
中編寫您的引導加載程序代碼並構建引導加載程序
$ gcc -c -g -Os -march=i686 -ffreestanding -Wall -Werror -I. -o bootloader.o bootloader.c $ ld -static -Tlinker.ld -nostdlib --nmagic -o bootloader.elf bootloader.o $ objcopy -O binary bootloader.elf bootloader.bin
由於您已經使用 ASM 構建了引導加載程序,我想 rest 對您來說是顯而易見的。
- 取自我的博客: http://dc0d32.blogspot.in/2010/06/real-mode-in-c-with-gcc-writing.html
引導加載程序是用 ASM 編寫的。
在編譯 C 代碼(或 C++ 或其他)時,編譯器會將您的人類可讀代碼“轉換”為機器代碼。 所以你不能確定結果。
當 PC 啟動時,BIOS 將執行來自特定地址的代碼。 該代碼需要直接可執行。
這就是您將使用匯編的原因。 這是擁有未經更改的代碼的唯一方法,該代碼將由處理器按編寫的方式運行。
如果您想在 C 中編寫代碼,您仍然需要編寫 ASM 引導加載程序,該引導加載程序將負責正確加載您使用的編譯器生成的機器代碼。
您需要了解每個編譯器會生成不同的機器代碼,這可能需要在執行前進行預處理。
BIOS 不會讓您預處理機器代碼。 PC 啟動只是跳轉到 memory 位置,這意味着位於該位置的機器代碼將被直接執行。
由於您使用的是 GCC,因此您應該閱讀有關不同“目標環境”的信息頁面。 您很可能想要使用-ffreestanding標志。 我還必須使用-fno-stack-protector標志來避免編譯器的一些丑陋的魔力。
然后,您將收到 linker 錯誤,說找不到memset等。 所以你應該實現你自己的版本並將它們鏈接起來。
幾年前我嘗試過這個——選項可能已經改變。
您必須使用-ffreestanding
gcc
不要鏈接),然后使用帶有標志的ld
鏈接-static
, -nostdlib
據我所知,您不能在 C 中編寫引導加載程序。 這是因為,C 需要您在 32 位保護模式下工作,而在引導加載程序中某些部分處於 16 位模式。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.