我是一个新手在写bootloaders。 我已经写了一个helloworld bootloader在asm中,现在我正在用C写一个。我用C编写了一个helloworld bootloader,但是我不能编译它。
这是我的代码。 我究竟做错了什么? 我完全采取错误的做法吗?
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以及Bootloader部分: http : //www.brokenthorn.com/Resources/OSDevIndex.html
有很好的教程让自己开始做自己的引导程序。 如果您需要更多信息,您也可以加入freenode的#osdev频道加入讨论。
让我在这里假设很多东西:你想在x86系统上运行你的引导程序,你在* nix框上安装了gcc toolchain。
编写引导程序时需要注意以下几点:
现在如果你想要gcc输出这样一个二进制文件,你需要玩一些技巧。
__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中编写自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构建了引导装载程序,我想其余的对你来说是显而易见的。
– 取自我的博客: http : //dc0d32.blogspot.in/2010/06/real-mode-in-c-with-gcc-writing.html
引导程序是用ASM编写的。
编译C代码(或C ++,或其他)时,编译器会将您的可读代码“转换”为机器代码。 所以你不能确定结果。
当PC启动时,BIOS将执行特定地址的代码。 该代码需要直接执行。
这就是为什么你要使用程序集。 这是处理器未经修改的代码的唯一方式,它将以书面形式运行。
如果您想用C语言编写代码,您仍然需要编写一个ASM引导加载程序,它将负责正确加载您使用的编译器生成的机器代码。
您需要了解每个编译器将生成不同的机器代码,这可能需要在执行之前进行预处理。
BIOS不会让您预先处理机器码。 PC启动只是跳转到内存位置,这意味着位于此位置的机器代码将被直接执行。
由于您使用的是GCC,因此您应该阅读关于不同“目标环境”的信息页面。 你很可能想要使用–旗帜。 此外,我不得不使用-fno-stack-protector标志来避免编译器的一些难题。
然后,你会得到连接器错误,说memset等没有找到。 所以你应该实现你自己的版本并链接它们。
几年前我尝试过这种方法 – 选项可能已经改变了。
你必须运行gcc
-ffreestanding
(不要链接)然后用ld
和标志链接-static
, -nostdlib