我正在编写一个启动加载程序,我已经掌握了大部分细节,但我不确定为什么有些启动加载程序会在开始大量执行之前将它们重新定位到内存中。
任何人都能解释一下吗?
此行为的一个示例是original v0.01 Linux kernel bootloader,其中包含以下注释:
boot.s由bios-startup例程加载到0x7c00,并自行移动到地址0x90000,并跳转到那里。
答案 0 :(得分:7)
CookieOfFortune本质上是正确的(因为他想将某些内容移动到初始引导程序所在的位置),但它不适用于第二个引导加载程序,而是内核本身。
从他的评论:
然后将系统加载到0x10000, 使用BIOS中断。之后呢 禁用所有中断,移动 系统降至0x0000,更改为 保护模式,并调用开始 系统。系统然后必须 重新初始化保护模式 它是自己的表,并启用 根据需要中断。
他希望内核位于0x0000 ... 0xKERNEL_SIZE-1,但是初始引导加载程序当前为0x7C00,因此如果内核超过~32 KB,它将覆盖引导加载程序,因为它正在移动它。内核位于0x0000的事实也解释了这个评论:
“注意!目前系统最多 8 * 65536字节长。“
如果从0开始长度超过512 KB,则存在命中x86地址空间的保留区域的风险。
我相信这段代码部分包含实际的内核跳转
mov ax,#0x0001 | protected mode (PE) bit
lmsw ax | This is it!
jmpi 0,8 | jmp offset 0 of segment 8 (cs)
答案 1 :(得分:3)
来自链接文章:
实际上,MBR通常包含一个引导加载程序,其目的是加载另一个引导加载程序 - 可以在其中一个分区的开头找到。这通常是一个非常简单的程序,它找到标记为Active的第一个分区,将其第一个扇区加载到RAM中,然后开始执行。由于按照惯例,新的引导加载程序也被加载到地址7C00h,旧的加载程序可能需要在执行此操作之前将其全部或部分重定位到不同的位置。此外,ES:SI预计包含分区表的RAM中的地址,DL包含引导驱动器号。打破这些约定可能会导致引导加载程序与其他引导加载程序不兼容。
答案 2 :(得分:0)
有时引导加载程序在ROM中,需要在某些时候复制到RAM中。