WinRing0如何使用

WinRing0 介绍

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

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

开发环境

主板:QOTOM Q6XXG2-P

开发工具:Visual studio 2017 Windows 10

WinRing0 请自行google下载

准备工作

  1. 新建项目,省略…

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

    WinRing0_path

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

编码

代码太多这里只贴出一些关键点

  1. 创建一个TestByWinRing0类,用来调用WinRing0的接口,先初始化

    1
    2
    3
    4
    5
    public bool Initialize()
    {
    MyOls = new OpenLibSys.Ols();
    return MyOls.GetStatus() == (uint)OpenLibSys.Ols.Status.NO_ERROR;
    }
  2. 根据SuperIO(IT8786)芯片手册查找需要的IO端口

    sio_enter_0

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

    1
    2
    3
    4
    5
    6
    7
    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芯片型号

    sio_enter_1

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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    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

    sio_enter_2

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

    sio_enter_3

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

    sio_enter_4

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

    sio_enter_5

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    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

    sio_enter_6

    sio_enter_7

    风扇转速计算公式

    sio_enter_8

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    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

------ 本文结束------