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 ↓

发表回复

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