为什么启动加载器重新定位在内存中?

icS*_*tic 5 assembly system bios bootloader

我正在编写一个启动加载程序,我已经掌握了大部分细节,但我不确定为什么有些启动加载程序会在开始大量执行之前将它们重新定位在内存中.

有谁能解释一下?

此行为的一个示例是原始的v0.01 Linux内核引导加载程序,其中包含以下注释:

boot.s由bios-startup例程加载到0x7c00,并自行移动到地址0x90000,并跳转到那里.

Fal*_*ina 7

CookieOfFortune本质上是正确的(因为他想将某些内容移动到初始引导加载程序所在的位置),但它不适用于第二个引导加载程序,而是内核本身.

从他的评论:

然后使用BIOS中断将系统加载到0x10000.此后,它会禁用所有中断,将系统移至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)
Run Code Online (Sandbox Code Playgroud)


Coo*_*une 3

来自链接的文章:

实际上,MBR 通常包含一个引导加载程序,其目的是加载另一个引导加载程序 - 可在其中一个分区的开头找到。这通常是一个非常简单的程序,它找到第一个标记为“活动”的分区,将其第一个扇区加载到 RAM 中,然后开始执行。由于按照惯例,新的引导加载程序也会加载到地址 7C00h,因此旧加载程序可能需要在执行此操作之前将其全部或部分重新定位到不同的位置。另外,ES:SI 预计包含分区表在 RAM 中的地址,DL 包含引导驱动器号。打破此类约定可能会导致引导加载程序与其他引导加载程序不兼容。