WinRing0如何使用

By | 2019-10-12

源码地址

WinRing0 是一个完全免费开源的组件( BSD License ), 允许windows程序直接对I/O端口进行存取操作。
通过使用一种内核模式的设备驱动器和其它几种底层编程技巧,它绕过了Windows系统的保护机制。

这里利用WinRing0简单写一个读取SuperIO芯片型号、CPU风扇转速的小程序作为例子

下载WinRing0,准备开发环境

1.新建项目,省略…

2.将下载好的WinRing0驱动文件放到项目/bin/Debug目录

WinRing0

3.将OpenLibSys.cs放到项目根目录

开始编写代码,这里只贴出核心代码

先创建一个TestByWinRing0类,用来调用WinRing0的接口

1. 初始化 WinRing0

public bool Initialize()
{
	MyOls = new OpenLibSys.Ols();
	return MyOls.GetStatus() == (uint)OpenLibSys.Ols.Status.NO_ERROR;
}

2. 根据SIO芯片手册查找需要的IO端口号
主板型号QOTOM Q6XXG2-P, SuperIO芯片型号:IT8772I-E

Enter MB PnP Mode

sio芯片入口地址(87,01,55,55)

public void InitSuperIO()
{
	MyOls.WriteIoPortByte(SuperIO.REG, 0x87);
	MyOls.WriteIoPortByte(SuperIO.REG, 0x01);
	MyOls.WriteIoPortByte(SuperIO.REG, 0x55);
	MyOls.WriteIoPortByte(SuperIO.REG, 0x55);
}

3. 读取SIO芯片型号

Chip ID

芯片型号是16位,由两个字节组成地址20h,21h

private static int SuperIo_Inw(byte data)
{
	int val;
	MyOls.WriteIoPortByte(0x2e, data++);
	val = MyOls.ReadIoPortByte(0x2f) << 8;
	MyOls.WriteIoPortByte(0x2e, data);
	val |= MyOls.ReadIoPortByte(0x2f);
	return val;
}

4. 配置风扇控制寄存器
风扇属于环境控制器,LDN=04h,控制器激活地址30h

Environment

EC控制器基地址16位,两个字节,由高位60h,低位61h组成

配置寄存器地址Base+05h,配置寄存器数据地址Base+06h

EC Base Address

配置风扇转速控制寄存器,地址0C

Fan Register
public void InitEc()
{
	MyOls.WriteIoPortByte(0x2e, 0x07);
	MyOls.WriteIoPortByte(0x2f, 0x04);
	MyOls.WriteIoPortByte(0x2e, 0x30);
	MyOls.WriteIoPortByte(0x2f, 0x01);
	ushort ec_base = (ushort)SuperIo_Inw(0x60);
	ec_addr_port = (ushort)(ec_base + 0x05);
	ec_data_port = (ushort)(ec_base + 0x06);
	MyOls.WriteIoPortByte(ec_addr_port, 0x0c);
	MyOls.WriteIoPortByte(ec_data_port, 0x00);
}

5. 读取风扇转速
风扇转速保存在一个16位数据里,由两个8位数据保存
上面提到转速控制寄存器,使用的第一组风扇,地址0e


Fan Read Register

风扇转速计算公式
不同的芯片计算方式各不相同,需要参照芯片手册

fan 转速计算公式
public int GetFanRpm()
{
	int fan_speed = 0;
	int fan_rpm = 0;
	//2-3 Reading Registers[7:0] (Index=0Eh-0Fh)
	MyOls.WriteIoPortByte(ec_addr_port, 0x0e);
	byte lval = MyOls.ReadIoPortByte(ec_data_port);

	//2-3 Extended Reading Registers [15:8] (Index=19h-1Ah)
	MyOls.WriteIoPortByte(ec_addr_port, 0x19);
	byte mval = MyOls.ReadIoPortByte(ec_data_port);

	fan_speed = (mval << 8) | lval;
	Console.WriteLine("fan_speed:" + fan_speed);
	fan_rpm = (int)(1.35 * Math.Pow(10, 6) / (fan_speed * 2));

	return fan_rpm;
}

6. 运行界面

WinRing0 test

转速跟aida64对比有个几十转的差距

17 thoughts on “WinRing0如何使用

  1. alibo

    您好!下载WinRing0,准备开发环境,可以一起发一份给我吗 谢谢您了!

    Reply
  2. peterp

    您好!能否把WinRing0开发环境,和您的开发代码发送我一份学习? 谢谢您了!

    Reply
  3. jnuer

    博主,我运行你的工程,发现初始化失败,可能是什么原因呢?

    Reply
  4. jnuer

    博主,我运行你的工程发现初始化失败,这可能是什么原因呢?

    Reply
  5. jnuer

    找到原因了,win10的Windows Defender会阻止WinRing0 driver,我换了台win7的设备就运行ok

    Reply
  6. chris

    Hi, Would you send me the source?
    It is too hard to get the information of WinRing0.
    You can save me.

    Reply

发表评论

邮箱地址不会被公开。 必填项已用*标注