【发布时间】:2019-11-29 01:30:40
【问题描述】:
我的内核使用 GRUB 启动,因此它以保护模式启动,并且 A20 线已经解锁。然后它重新路由设备 irqs 并加载它自己的。现在我想关闭设备。它可以通过 APM 完成,但 APM 只能从实模式启用,所以我编写了切换到实模式然后连接到 APM 的代码,将其版本设置为 1.1/1.2,为所有设备启用它并关闭所有设备:
asm volatile("cli\n"
"mov eax, cr0\n"
"and al, not 1\n"
"mov cr0, eax\n"
"sti");
asm volatile("mov ah, 0x53\n"
"mov al, 0x01\n"
"xor bx, bx\n"
"int 0x15");
asm volatile("mov ah, 0x53\n"
"mov al, 0x0e\n"
"mov bx, 0x0000\n"
"mov ch, 0x01\n"
"int 0x15");
asm volatile("mov ah, 0x53\n"
"mov al, 0x08\n"
"mov bx, 0x0001\n"
"mov cx, 0x0001\n"
"int 0x15");
asm volatile("mov ah, 0x53\n"
"mov al, 0x07\n"
"mov bx, 0x0001\n"
"mov cx, 0x3\n"
"int 0x15");
同样在运行此代码后计算机会重新启动,并且在使用 QEMU 时我收到启动错误(无效的“幻数”),而在使用真机时它只是重新启动。
【问题讨论】:
-
您是否使用 LIDT 重置了实模式中断?
-
它要复杂得多。此答案中有一个完整的 Multiboot 示例,它切换到实模式以执行一些 vbe 调用(然后返回到保护模式)。 stackoverflow.com/a/41731180/3857942 。当然,您不必担心在关闭时恢复状态以返回保护模式的所有代码。
标签: c++ assembly kernel power-management