微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在C中写入Bootloader

我是一个新手在写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" ); }

内核的参数

为什么x86的引导程序首先使用16位代码

以编程方式编辑Windows 8上的BCD商店?

在哪里可以find所有参数可以通过内核启动cmdline传递文档?

NTLDR技术信息

引导程序如何在“使用命令重新启动系统”之后提取命令?

Linux启动过程 – iniramfs&root()

强制机器从Live CD启动

如何将一个二进制文件刻录到通过Windows 10专业版64位上的软盘USB插入的软盘扇区0

自定义操作系统的bootloader不能跳转到内核

我建议你看看http://wiki.osdev.org/Rolling_Your_Own_Bootloader以及Bootloader部分&#xFF1A; http : //www.brokenthorn.com/Resources/OSDevIndex.html

有很好的教程让自己开始做自己的引导程序。 如果您需要更多信息,您也可以加入freenode的#osdev频道加入讨论。

让我在这里假设很多东西:你想在x86系统上运行你的引导程序,你在* nix框上安装了gcc toolchain。

编写引导程序时需要注意以下几点:

一个VBR的510字节限制,由于分区表的MBR更小(如果你的系统需要的话)

实模式 – 16位寄存器和seg:关闭寻址

引导程序必须是平面二进制,必须链接到物理地址7c00h运行

没有外部的“图书馆”参考(杜!)

现在如果你想要gcc输出这样一个二进制文件,你需要玩一些技巧。

gcc认分割出32位的代码。 要让gcc输出代码在真实模式下运行,请在每个C文件的顶部添加__asm__(".code16gccn") 。

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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐