我正在解决 x86 系统上的一个问题,即某些 PCIe 设备初始化速度不够快,无法被 BIOS 枚举。热重置允许 BIOS 枚举这些设备,因为它不会重新启动电源。然而,从启动到操作系统然后进行热重启需要花费非常长的时间。
首选行为是从 grub 引导加载程序中检测last启动是热启动还是冷启动(从关闭电源/重新启动电源开始),然后立即发出热启动或继续启动。
我已经证实,原则上这个想法是可行的。如果我停止启动 grub,然后按 ctrl-alt-del,则在重新启动周期后会成功枚举设备。
对于从 grub 发出重新启动命令,我还没有找到任何解决方案。内置的 grub 命令“reboot”会发出冷重启,这会涉及电源循环,但这并不能解决问题。有没有办法通过任何其他可以编写脚本的机制来发出热重启?
为了检测启动是热启动还是冷启动,我想读取 CMOS,它应该具有以下寄存器(取自 https://github.com/cirosantilli/ralf-brown-interrupt-list/blob/主控/inter61d/CMOS.LST):
----------R0F--------------------------------
CMOS 0Fh - IBM - RESET CODE (IBM PS/2 "Shutdown Status Byte")
(Table C0006)
Values for Reset Code / Shutdown Status Byte:
00h-03h perform power-on reset
00h software reset or unexpected reset
01h reset after memory size check in real/virtual mode
(or: chip set initialization for real mode reentry)
02h reset after successful memory test in real/virtual mode
03h reset after failed memory test in real/virtual mode
04h INT 19h reboot
05h flush keyboard (issue EOI) and jump via 40h:0067h
06h reset (after successful test in virtual mode)
(or: jump via 40h:0067h without EOI)
07h reset (after failed test in virtual mode)
08h used by POST during protected-mode RAM test (return to POST)
09h used for INT 15/87h (block move) support
0Ah resume execution by jump via 40h:0067h
0Bh resume execution via IRET via 40h:0067h
0Ch resume execution via RETF via 40h:0067h
0Dh-FFh perform power-on reset
显然,这可以使用 outb 0xf 0x70/inb ox71 读取,但无论前面的引导类型如何,它似乎总是返回 0x20。我不太确定这是最好的方法,因为它可能已经过时了?所以,你看我有两个问题要回答,一:如何检测 grub 引导加载程序启动的原因(热引导或冷引导),二是如何从 grub 引导加载程序发出热引导。
如果有任何见解,我将不胜感激。