Operating system Can';t将平面二进制文件加载到内核中
注意-我还没有设置分页,我的内核是多引导的ELF。我确实做了IRQ和ISR 我这里有一个气体文件:Operating system Can';t将平面二进制文件加载到内核中,operating-system,osdev,Operating System,Osdev,注意-我还没有设置分页,我的内核是多引导的ELF。我确实做了IRQ和ISR 我这里有一个气体文件: .section .text .global _start _start: mov $0xDEADBEEF, %eax 和GRUB2设置以加载平面二进制文件: menuentry "fOS-Terminal (25x80)" { multiboot /boot/fos.elf module /modules/program.bin set gfxmode=80x
.section .text
.global _start
_start:
mov $0xDEADBEEF, %eax
和GRUB2设置以加载平面二进制文件:
menuentry "fOS-Terminal (25x80)" {
multiboot /boot/fos.elf
module /modules/program.bin
set gfxmode=80x25
}
在我的kernel.c中,我可以解析multiboot头来获取模块的地址,我调用它:
typedef void (*call_module_t)(void);
call_module_t start_program = (call_module_t)mbd->mods_addr;
start_program();
现在,我正试图使用以下命令将GAS文件编译成一个简单的二进制文件:
i686-elf-as --32 ./iso/modules/program.s -o ./iso/modules/program.o
i686-elf-ld -fPIC -shared --oformat binary ./iso/modules/program.o -o ./iso/modules/program.bin
问题-GRUB2肯定正在加载内核,多引导头告诉我它位于地址0x100ac,但当我去那里时,我得到了一个异常:无效操作码
这似乎有帮助,但不是:(
编辑-1,这样当我对调用函数进行gdb时,会出现以下情况:
问题出在这里
typedef void (*call_module_t)(void);
call_module_t start_program = (call_module_t)mbd->mods_addr;
start_program();
mbd->mods_addr
是模块结构表的地址,而不是模块本身的地址。
那么解决方案是什么呢
unsigned int* modules = (unsigned int*)mbd->mods_addr;
if (mbd->mods_count > 0)
{
unsigned int addr = modules[0];
unsigned int size = modules[1];
call_module_t start_program = (call_module_t)addr;
start_program();
}
else
painc("module wasn't loaded");
问题就在这里
typedef void (*call_module_t)(void);
call_module_t start_program = (call_module_t)mbd->mods_addr;
start_program();
mbd->mods_addr
是模块结构表的地址,而不是模块本身的地址。
那么解决方案是什么呢
unsigned int* modules = (unsigned int*)mbd->mods_addr;
if (mbd->mods_count > 0)
{
unsigned int addr = modules[0];
unsigned int size = modules[1];
call_module_t start_program = (call_module_t)addr;
start_program();
}
else
painc("module wasn't loaded");
您应该尝试使用调试器单步执行。GDB会很有用。您可以看到跳转发生时会发生什么。一个观察结果是,
\u start:mov$0xDEADBEEF,%eax
可能会在mov之后在内存中游荡。如果使用类似jmp的东西进入无限循环会发生什么情况。
?如果您创建了一个最小的completee可验证的示例它会有所帮助。我们可以构建和测试一些完整的内容。@MichaelPetch请查看编辑,顺便说一句,我刚刚意识到指针没有指向任何开始标签。这似乎有问题。我只能说0x100ac似乎不是程序开始的地址。我希望会加载一个模块与引导加载程序不同的是,它被加载到一个单独的页面中(我从未以这种方式尝试过多引导模块,所以我可能是错的).没有一个我不能说why@MichaelPetch我真的是一个新的OSDev,你能推荐一个用于多引导模块的资源吗?你应该尝试使用调试器。GDB会很有用。你可以看到跳转发生时会发生什么。一个观察结果是,\u start:mov$0xDEADBEEF,%eax
可能会在mov之后在内存中徘徊。这是什么如果你在使用类似于jmp的东西之后进入无限循环。
?如果你创建了一个最小的完整的可验证示例,它会有所帮助。一些我们可以构建和测试的完整的东西。@MichaelPetch请看一下编辑,顺便说一句,我刚刚意识到指针没有指向任何开始标签。这似乎很麻烦。我只能说0x100ac似乎不是程序开始的地址。我希望模块会加载到一个单独的页面,而不是引导加载程序(我从未尝试过这种方式的多引导模块,所以我可能是错的)。如果没有why@MichaelPetch我是一个新的OSDev,你能推荐一个多引导模块的资源吗?