【问题标题】:Can't load flat binary file into kernel无法将平面二进制文件加载到内核中
【发布时间】:2017-05-10 09:17:48
【问题描述】:

注意 - 我还没有设置分页,我的内核是多重引导的,ELF。我确实有 irqs 和 isrs。

所以我这里有这个 GAS 文件:

.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 但是当我去那里时,我得到了异常:INVALID OPCODE。

这似乎有帮助,但不是:(

https://littleosbook.github.io/book.pdf#page=49&zoom=auto,-100,472

EDIT - 1 所以当我 gdb'd 到调用函数时,这出现了:

【问题讨论】:

  • 您应该尝试使用调试器单步执行。 GDB 会很有用。你可以看到跳跃发生时会发生什么。一种观察是_start: mov $0xDEADBEEF, %eax 可能在 mov 之后在内存中徘徊。如果您在使用 jmp . 之类的内容后进入无限循环会发生什么?
  • 如果您创建了一个最小的完整可验证示例,它会有所帮助。我们可以构建和测试的完整的东西。
  • @MichaelPetch 请看一下编辑,顺便说一句,我刚刚意识到指针没有指向那里的任何 _start 标签。这似乎很麻烦。
  • 我只能说 0x100ac 似乎不是程序开始的地址。我希望模块会被加载到与引导加载程序不同的页面中(我从未尝试过这种方式的多重引导模块,所以我可能是错的)。没有minimal complete verifiable example,我无法说出原因
  • @MichaelPetch 我真的是新的 OSDev,你能推荐一个多启动模块的资源吗?

标签: operating-system osdev


【解决方案1】:

问题来了

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");

【讨论】:

    猜你喜欢
    • 2019-09-26
    • 2021-07-08
    • 2020-05-22
    • 2021-01-13
    • 2014-01-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多