2016-12-25 55 views
1

注 - 我还没有分页设置,我的内核是多引导的ELF。我有irqs和isrs完成。无法将平面二进制文件加载到内核中

所以我这里有这种气体文件:

.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

在这里,我可以分析多重头获取模块的地址,我打电话给它:

typedef void (*call_module_t)(void); 
call_module_t start_program = (call_module_t)mbd->mods_addr; 
start_program(); 

现在我想编译我的GAS文件到FL牛逼二元这些命令:

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但是当我去那里,我得到异常:无效的操作码。

这似乎是有用的,但不是:(

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

编辑 - 1所以,当我gdb'd调用函数,这出现: The pointer seems to point nowhere

+1

您应该尝试使用调试器。 _GDB_会很有用。你可以看到跳转发生时会发生什么。一个观察结果是,在mov之后,_start:mov $ 0xDEADBEEF,%eax'可能在内存中漫游。如果你用'jmp .'之类的东西进入无限循环会发生什么? –

+0

如果您创建了一个最小的完整可验证示例,它将有所帮助。完成我们可以构建和测试的东西。 –

+0

@MichaelPetch请看看编辑,顺便说一句,我刚刚意识到指针并没有指向任何_start标签。这似乎麻烦。 –

回答

0

这是问题所在

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