Windows驱动开发学习记录-驱动中快速重启关闭计算机之二
前言
之前在《Windows驱动开发学习记录-驱动中快速重启关闭计算机之一》中使用Windows内核函数进行快速重启和关机,这次使用更快速直接的IO端口操作来进行。这里做个总结,分析可见参考资料1、2。
一、IO92h(重启)
1、Intel文档(Page445):
2、AMD文档(Page676):
3、实现
1 mov al, 1h
2 mov dx, 092h
3 out dx, al
二、IO64h(重启)
1、AMD文档(Page667):
2、实现
1 mov al, 0feh
2 mov dx, 064h
3 out dx, al
三、IO0CF9(重启和关闭)
1、Intel文档(Page446):
2、AMD文档(Page684):
3、实现
重启:
mov al, 06h
mov dx, 0cf9h
out dx, al
关闭:(该实现依赖于硬件的作法,在本人虚拟机XP 32位、Win7 x64、Win7 x86下表现为重启,在一台x58主板的物理上表现为断电5秒后又启动,而在新的笔记本上UEFI主板加Win10 x64的环境下可以实现秒关机)
mov al, 0eh
mov dx, 0cf9h
out dx, al
四、 代码实现的选择
在每种方法中的后边都使用的汇编代码,因为读写端口数据用到 in和out指令。但本人编译驱动时使用的是VS2019,不支持内联汇编,所以可以使用WRITE_PORT_UCHAR来实现,例如最后一个:
PUSHORT nPort = (PUSHORT)0xCF9;
USHORT nData = 0x6;
WRITE_PORT_USHORT(nPort, nData);
不过在VS2019中可以把实现写成一个汇编asm文件,然后链接时直接调用具体的实现。
五、最终实现
Implementation.asm文件
1 ifndef X64
2 .model FLAT,STDCALL
3 endif
4
5
6 .const
7 RESET_BY_092_PORT DW 092H
8 RESET_BY_092_CODE DB 01H
9 RESET_BY_0CF9_PORT DW 0CF9H
10 RESET_BY_0CF9_CODE DB 06H
11 RESET_BY_I8042_PORT DW 64H
12 RESET_BY_I8042_CODE DB 0FEH
13 POWEROFF_BY_0CF9_PORT DW 0CF9H
14 POWEROFF_BY_0CF9_CODE DB 0EH
15
16 .data
17
18 .code
19
20 ComputerResetByPort092 proc
21 mov al, RESET_BY_092_CODE
22 mov dx, RESET_BY_092_PORT
23 out dx, al
24 jmp $
25 ComputerResetByPort092 endp
26
27 ComputerResetByPort0CF9 proc
28 mov al, RESET_BY_0CF9_CODE
29 mov dx, RESET_BY_0CF9_PORT
30 out dx, al
31 jmp $
32 ComputerResetByPort0CF9 endp
33
34 ComputerResetByI8042 proc
35 mov al, RESET_BY_I8042_CODE
36 mov dx, RESET_BY_I8042_PORT
37 out dx, al
38 jmp $
39 ComputerResetByI8042 endp
40
41 ComputerPowerOffByPort0CF9 proc
42 mov al, POWEROFF_BY_0CF9_CODE
43 mov dx, POWEROFF_BY_0CF9_PORT
44 out dx, al
45 jmp $
46 ComputerPowerOffByPort0CF9 endp
47
48 end
.h文件
EXTERN_C VOID ComputerResetByPort092();
EXTERN_C VOID ComputerResetByPort0CF9();
EXTERN_C VOID ComputerResetByI8042();
EXTERN_C VOID ComputerPowerOffByPort0CF9();
.cpp文件
1 EXTERN_C NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject,
2 PUNICODE_STRING pRegistryPath)
3 {
4 NTSTATUS ntStatus = STATUS_SUCCESS;
5
6 //ComputerResetByPort092();
7 //ComputerResetByPort0CF9();
8 //ComputerResetByI8042();
9 ComputerPowerOffByPort0CF9();
10
11 return ntStatus;
12 }
六、参考资料
1.《我的内核学习笔记13:x86平台linux系统重启流程跟踪》
3.《Intel® IO Controller Hub 10 (ICH10) Family》
4.《BIOS and Kernel Developer’s Guide (BKDG) for AMD Family 15h Models 70h-7Fh Processors》