Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Operating system Can';t将平面二进制文件加载到内核中_Operating System_Osdev - Fatal编程技术网

Operating system Can';t将平面二进制文件加载到内核中

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

注意-我还没有设置分页,我的内核是多引导的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=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,你能推荐一个多引导模块的资源吗?