【发布时间】:2019-03-21 01:47:06
【问题描述】:
我在这里组装了一个简单的引导加载程序:
;initialization type stuff
[bits 16]
[org 0x7c00]
;make message and print it
mov si, MESSAGE
call print
;infinite loop to stall
jmp $
;print "method"
print:
pusha
print_loop:
mov al, [si]
cmp al, 0
jne print_char
popa
ret
print_char:
mov ah, 0x0e
int 0x10
add si, 1
jmp print_loop
;actual assigning of message
MESSAGE: db "Hello World!", 0
;padding & magic number (end)
times 510-($-$$) db 0
dw 0xaa55
我的目标是用 C 语言编写大部分操作系统,目前我正在尝试用 C 语言正确链接引导加载程序和内核:
void kernel_main()
{
printf("Hello World!");
}
我如何将这些链接在一起并将它们编译成可以在 qemu/任何普通计算机中打开的东西?
【问题讨论】:
-
你使用什么编译器、汇编器、链接、工具链?什么提供了
printf实现? -
链接器 是一个程序,它接收多个目标文件并将它们链接到一个大程序中。通常,您使用编译器生成汇编文件,使用汇编器将它们汇编成目标文件,并使用链接器将所有这些目标文件链接到一个程序中。在深入了解您的内核项目之前,我建议您熟悉链接的工作原理,因为它是这个难题中非常重要的一部分。
-
请注意,GCC 并不能真正生成正确的 16 位代码。如果您要使用 GCC,我建议您的引导加载程序进入保护模式并编写 32 位内核(或从引导加载程序进入 64 位长模式以获取 64 位内核)。如果您想创建 16 位实模式内核,请考虑 Alexey 的 Small C Compiler、Openwatcom C 或 BCC(Bruce 的 C 编译器)。
-
这是一个非常简单的引导加载程序,它与在保护模式下运行的 32 位 C 内核链接。引导加载程序在调用内核之前进入 32 位保护模式。内核在 0x7e00 的引导加载程序之后加载。大多数繁重的工作都是通过专门的链接器脚本完成的。 capp-sysware.com/misc/osdev/linkedboot_kreloc
-
@liaquore 没错。决定程序的哪些部分最终到哪里是链接器的工作,并且可以通过 链接器脚本来控制。 如果您生成目标文件,则使用
org指令毫无意义.
标签: c assembly x86 bootloader osdev