最近在学习操作系统。我想写一个简单的引导加载程序,将实模式更改为保护模式,然后加载简单的内核。
但我无法弄清楚入口地址问题。
首先我将引导加载程序放在 OS.img(qemu) 的第一个扇区中,然后内核从第二个扇区开始。
这是我的内核的 readelf 结果:
入口点地址是0x800c。
LMA 和 VMA 如下:
bootloader的一部分,读取elf类型的内核,然后进入entry(),即入口点地址。
然而,当我反汇编引导加载程序时,entry()如下:
调用*0x8018,而不是*0x800c。
我不知道为什么会发生这种情况。
你能帮我吗?
call *0x8018
对存储在 0x8018
的地址执行调用,这是正确的,因为 ELFHDR
是 0x8000
并且 e_entry
在标头中的偏移量是 0x18
。
真正的问题在于将段加载到内存中的方式。每个段应从文件偏移量
p_vaddr
加载到地址 p_offset
。请注意,在您的情况下, p_vaddr
是 0x8000
,即您将 elf 标头加载到的内存中的同一位置,这就是 ELFHDR->e_entry
被覆盖的原因。最简单的解决方案是在不同的地址加载 elf 标头。
你可以做这样的事情
uint8_t* 内核 = (uint8_t*)MEMORY_KERNEL_ADDR;
typedef void (*KernelStart)();
加载时
KernelStart kernelStart = (KernelStart)Kernel;
内核启动();