如何使用 APM 从保护模式关机?
How to shutdown from protected mode using APM?
我的内核使用 GRUB 启动,因此它以保护模式启动并且 A20 行已经解锁。然后它重新路由设备 irq 并加载它自己的。现在我想关闭设备。它可以用 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 时我收到启动错误(无效 "magic number"),而在使用真实机器时它只是重新启动。
GNU 风格的内联汇编要求保留所有不在输出或破坏列表中的寄存器,同样,更改为实模式会破坏编译器生成的代码。使用单个 asm 语句或使用单独的程序集文件解决此问题。
您尝试进入32位实模式,需要先切换到16位模式再切换到实模式。
您需要将 CS
设置为适合使用远跳转的实模式的值,否则来自中断的第一个 return 将转到错误的地址。
您可以在 GRUB 源代码中找到从 32 位保护模式切换到实模式的示例。
我的内核使用 GRUB 启动,因此它以保护模式启动并且 A20 行已经解锁。然后它重新路由设备 irq 并加载它自己的。现在我想关闭设备。它可以用 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 时我收到启动错误(无效 "magic number"),而在使用真实机器时它只是重新启动。
GNU 风格的内联汇编要求保留所有不在输出或破坏列表中的寄存器,同样,更改为实模式会破坏编译器生成的代码。使用单个 asm 语句或使用单独的程序集文件解决此问题。
您尝试进入32位实模式,需要先切换到16位模式再切换到实模式。
您需要将 CS
设置为适合使用远跳转的实模式的值,否则来自中断的第一个 return 将转到错误的地址。
您可以在 GRUB 源代码中找到从 32 位保护模式切换到实模式的示例。