如何使用 APM 从保护模式关闭

How to shutdown from protected mode using APM?

本文关键字:模式 保护 何使用 APM      更新时间:2023-10-16

我的内核使用 GRUB 启动,因此它以保护模式启动,并且 A20 行已经解锁。然后,它会重新路由设备 irqs 并加载自己的 irq。现在我想关闭设备。它可以通过 APM 完成,但 APM 只能从实模式启用,所以我编写了切换到实模式然后连接到 APM 的代码,将其版本设置为 1.1/1.2,为所有设备启用它并关闭所有设备:

asm volatile("clin"
           "mov eax, cr0n"
           "and al, not 1n"
           "mov cr0, eaxn"
           "sti");
  asm volatile("mov ah, 0x53n"
           "mov al, 0x01n"
           "xor bx, bxn"
           "int 0x15");
  asm volatile("mov ah, 0x53n"
           "mov al, 0x0en"
           "mov bx, 0x0000n"
           "mov ch, 0x01n"
           "int 0x15");
  asm volatile("mov ah, 0x53n"
           "mov al, 0x08n"
           "mov bx, 0x0001n"
           "mov cx, 0x0001n"
           "int 0x15");
  asm volatile("mov ah, 0x53n"
           "mov al, 0x07n"
           "mov bx, 0x0001n"
           "mov cx, 0x3n"
           "int 0x15");

同样在运行此代码后,计算机重新启动并使用QEMU时,我收到启动错误(无效的"幻数"(,并且在使用真机时它只是重新启动。

GNU风格的内联汇编要求保留所有不在输出或clobber列表中的寄存器,同样,更改为实模式将破坏编译器生成的代码。使用单个 asm 语句或使用单独的程序集文件来解决此问题。

您尝试进入 32 位实模式,您需要先切换到 16 位模式,然后再切换到实模式。

您需要使用远跳将CS设置为适合实模式的值,否则中断的第一个返回将转到错误的地址。

您可以在 GRUB 源代码中找到从 32 位保护模式切换到实模式的示例。