我已经很长一段时间没有使用 C 和汇编语言进行编程了(大约 2 年)。现在我决定重新开始,但我想做一些更复杂的事情。我考虑过创建一个简单的内核。现在我在网上找到了这个源代码:
启动.asm:
global loader
extern kernel_main
MAGIC equ 0xbad
FLAGS equ 0x3
CHECKSUM equ -(MAGIC+FLAGS)
section .text
align 4
dd MAGIC
dd FLAGS
dd CHECKSUM
loader:
call kernel_main
cli
quit:
hlt
jmp quit
内核.c:
void print(char *text) {
char *memory = (char*)0xb8000;
while(*text) {
*memory++ = *text++;
*memory++ = 0x3;
}
}
void kernel_main() {
print("My cat sometimes smells like cafe. I love it.");
}
链接器.ld:
ENTRY(loader)
SECTIONS {
. = 0x100000;
.text : { *(.text) }
}
注意:我用“GCC”编译了C文件,用“NASM”编译了汇编文件。
如果我尝试这个命令:
ld -T linker.ld -elf_i386 -o final.bin boot.o kernel.o
它说:“boot.asm:(.text+0xd): 对‘kernel_main’的未定义引用”。
我怎样才能解决这个问题?
我在 Windows 上工作,不想运行带有 Linux 或其他任何东西的虚拟机。提前致谢!
编辑:
这是我的海湾合作委员会命令:
gcc -m32 -o kernel.o srckernel.c -nostdlib -nostartfiles -nodefaultlibs
这是我的 NASM 命令:
nasm -f elf32 -o boot.o boot.asm
有很多事情是错误的。我假设给出错误:
boot.asm:(.text+0xd): 未定义的引用kernel_main
您没有使用 ELF 交叉编译器,而是使用生成本机 Windows 可执行文件的 GCC 编译器(即 Cygwin 和 MinGW)。我强烈建议使用 i686(或 x86_64)ELF交叉编译器 https://wiki.osdev.org/GCC_Cross-Compiler#Windows_Users用于操作系统开发,尤其是 Windows 上的操作系统开发。
您的主要问题是:
-
选项-elf_i386
可能本来就是-melf_i386
但这是不正确的。有了针对 Windows 的 GCC,您将需要使用-mi386pe
输出为 Win32 PE/COFF 格式。 Windows GCC 链接器通常不知道如何生成 ELF 可执行文件。我还建议使用-N
使用 LD 输出 i386pe 格式时的选项。将链接器命令更改为:
ld -N -T linker.ld -mi386pe -o final.bin boot.o kernel.o
-
With Win32 PE/COFF objects1: functions that use the CDECL calling convention have to have an underscore (_) prepended https://devblogs.microsoft.com/oldnewthing/20040108-00/?p=41163 to them. kernel_main
needs to be _kernel_main
. You need to change these lines in boot.asm
from:
extern kernel_main
call kernel_main
to:
extern _kernel_main
call _kernel_main
-
你没有显示你是如何编译的kernel.c
以及你如何组装boot.asm
但它们应该类似于:
nasm -f win32 boot.asm -o boot.o
gcc -g -c -m32 -ffreestanding kernel.c -o kernel.o
-
当你设法生成时final.bin
它是一个 Windows PE 可执行文件。这多重启动规范 https://www.gnu.org/software/grub/manual/multiboot/multiboot.html需要 ELF 可执行文件。链接到后final.bin
使用LD,您可以转换final.bin
转换为 ELF 格式:
objcopy -O elf32-i386 final.bin final.elf
final.elf
现在应该可以用作 Multiboot ELF 可执行文件。
-
您的多重引导标头存在问题boot.asm
。 Multiboot 的神奇值为0x1badb002
not 0xbad
。由于您尚未在 Multiboot 标头中指定视频配置FLAGS
不应设置位 1,FLAGS
应该是 0x1 而不是 0x3。将您的多重引导标头更改为:
MAGIC equ 0xbad
FLAGS equ 0x3
to:
MAGIC equ 0x1badb002
FLAGS equ 0x1
通过上述更改,我能够生成一个名为的 ELF 可执行文件final.elf
。当使用 QEMU 运行时,使用以下命令:
qemu-system-i386 -kernel final.elf
我得到的输出是:
脚注:
-
1The extra underscore on function names doesn't apply when generating Win64 PE32+ objects.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)