我正在研究x86系统启动的过程 这是启动流程:
我的问题是,为什么我们需要先将 bootsect 本身移动到 0x90000?
为什么我们不能只移动设置和系统?
谢谢。
“影子复制”引导加载程序并跳转到它曾经是(现在仍然是)一个很好的做法。这种做法很早就开始了,当时典型的引导加载程序仅限于 x86 处理器上单个段的大小和磁盘上的单个读取扇区。一旦询问硬件,引导加载程序就可以执行更高级的工作,例如安装系统文件(调用、挂钩、TSR 等)、被病毒接管、或初始化保护模式并开始执行应用程序的硬件分页等。
“行为”的起源早于 Linux,您应该发现这种行为对于 x86 引导加载程序很常见。可能是任何基于 IBM PC 的计算机。
Linux 中目前的代码可能源自此:
FX。 https://stuff.mit.edu/afs/sipb/user/warlord/C/memtest86/bootsect.s
在这种情况下,重新定位到 0x90000 的选择可能是任意的,目标是将加载程序从默认位置移动到它自己选择的位置,这样它就不会被可能从“低内存”分配的程序篡改。 “(实际上:作为实践问题。)
我自己也想知道一个明确的原因:)很确定这确实只是 x86 平台是 DOS 平台时代的残余,随着硬件的发展,人们采用了新的技巧来保持与“不友好”的 lowmem 代码的向后兼容.
我相信将引导扇区移开主要是为了方便 - 没有“硬”技术原因表明它“不能”以其他方式完成。
也就是说,0x7c00
距内存起始位置不到 32KiB。 32KiB 通常不足以用于内核的设置阶段,更不用说内核本身了。
0x90000
位于 PC BIOS 保留的区域下方,同时也为内核留出了足够的空间。
无论如何,你所指的进程已经好几年没有被Linux内核使用了。您提到的地址由 v2.02 之前的
Linux Boot Protocol版本使用,该协议首先与 linux-2.4.0 一起使用。我认为
内核本身不再可以直接使用 linux-2.6.0 左右启动。当有人尝试直接启动内核时,该版本的 arch/i386/boot/bootsect.S
文件会输出一条消息。
如今,内核通常由单独的引导加载程序加载,只要符合引导协议,它就可以自由地使用任何它想要的方法。引导加载程序可能有多个阶段,甚至可能执行内核相关的操作,例如切换到“保护模式”本身。
这可以追溯到 Linux 0.11,它假定系统大小固定为 512K。这就是它的工作原理: (1) BIOS 加载位于 0x7c00 的引导扇区。
(3) 从0x90000开始运行,引导扇区在0x10000处加载系统。
最大系统大小:0x90000 - 0x80000 = 0x10000 512K
(4) 最后,引导扇区将加载在 0x10000 处的系统复制到 0x0,Linus 自己在评论中说,这是系统“正确”的位置。
并
覆盖引导扇区。 总之,它最初是为了防止在重新定位系统时覆盖自身。而且,是的,任何类型的自复制都是有原因的,并且主要在加载或重新定位内容时使用,同时确保被移动的内容不会覆盖移动它的代码!