在实模式下关闭Linux内核并恢复,这是否可能?

4
假设我想在我的普通操作系统启动之前启动一个小型的Linux发行版。
1. BIOS加载MBR并执行MBR。 2. MBR定位活动分区,即我的Linux分区。 3. Linux启动并我执行所需操作。 4. Linux关闭并再次切换到实模式。 5. 加载原始分区引导扇区,然后启动普通操作系统。
据我所知,第4步将是困难的任务,需要恢复所有设备在Linux之前的状态,INT13h功能是否有效?我需要恢复中断向量表吗?只是举几个例子。
也许已经有现有项目完成了这项工作吗?

1
如果你的意图是创建一个比GRUB更强大的基于Linux的引导程序,那么这确实很困难。我曾经开始过这样的项目,但从未完全完成。然而,这绝对是可能的,可以看看Splashtop。 - Zifre
1
这真的不是(在我看来)与编程有关的。然而,如果我没记错的话,一旦x86或兼容处理器处于保护模式,就无法在没有重置的情况下切换回实模式。 - Harper Shelby
3
对我来说,这与编程有关,因为我实际上打算尝试这个,所以才会问这个问题。是的,你可以再次切换回实模式(英特尔软件手册第3章第9节)。 - Jonas Engström
@Zifre:出于好奇,你卡在哪里了?感谢关于Splashtop的提示,看起来是一个有趣的产品。 - Jonas Engström
1
我卡在了这部分(返回实模式并清除所有设备状态)。当我想要引导另一个基于Linux的操作系统时,使用kexec可以正常工作,但我需要它也支持Windows。最终我在我的电脑上得到了可行的方案,但它经常在其他电脑上无法正常工作(清除设备状态非常困难)。返回实模式肯定是可能的,但我不记得我是如何做到的,而且我现在没有代码。 - Zifre
显示剩余2条评论
3个回答

4

通常情况下,Linux不支持这种操作,特别是因为它以BIOS和DOS程序可能不希望看到的方式重新初始化硬件。然而,在某些特定情况下,例如重启(请参见arch/x86/kernel/reboot.c中的machine_real_restart),有一些基础设施可以切换回实模式,并具有重新初始化硬件以进行kexec或挂起的代码。我猜您可以通过这些组合来做些什么,但我不知道结果是否真正符合DOS或Windows在重启时所期望看到的。

一个更简单的方案是使用链式引导加载程序,该程序可以设置为仅在特定配置下启动一次,例如GRUB。您可以调用grub-set-default,然后重新启动。当GRUB出现时,它会将控制权传递给Windows。然后通过将备选操作系统设置为Linux分区,控制权将在下一次启动时返回Linux。

另一个选择可能是使用Coreboot,但我不确定是否已经准备好用于启动Windows。


3
我没有尝试过这个方法,所以不确定它是否有效,但是以下是方法:
在bzImage格式的内核文件头中有一个选项,可以指定在保护模式代码启动之前执行实模式代码的地址。 您可以创建一个最小的符合bzImage标准的文件,其中没有实际的内核,但具有使用INT 0x13将您的MBR加载到0x7c00并跳转到它的实模式代码,就像BIOS一样。
如果您使用kexec使用“-t bzImage-x86 --real-mode”选项加载bzImage,则应重置CR0中的PE位以降至实模式(如上面的bdonlan所提到的),并执行由bzImage头选项指向的代码。
bzImage头选项称为realmode_swtch,并在/usr/src/linux/Documentation/x86/boot.txt中记录,头格式代码在/usr/src/linux/arch/x86/boot/header.S中。

1

你有没有研究过kexec


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接