读取CMOS数据
  Bs1dA8WZU82t 2023年11月02日 31 0

一 CMOS介绍

CMOS(Complementary Metal-Oxide Semiconductor)是一种常见的半导体芯片技术,广泛用于各种微处理器和外设中。

在PC系统中,CMOS芯片主要用于实现实时时钟(RTC)和存储BIOS设置。CMOS内含有一小块SRAM芯片和电池,可以在系统断电时保持数据。

二 CMOS数据的读取

要读取CMOS中的数据,需要访问RTC及配置存储区指定的I/O端口。在IBM PC兼容机上,主要有以下几个I/O端口:

  • 0x70 - RTC地址寄存器端口,写入要访问的RTC或CMOS内存地址
  • 0x71 - RTC数据寄存器端口,读取或写入RTC的控制数据或CMOS内存单元的数据
  • 0x72 - RTC控制寄存器端口,控制RTC及中断
  • 0x73 - RTC状态寄存器端口,读取RTC及CMOS的状态

例如,要读取CMOS内存地址0x10处的数据:

  1. 向0x70端口写地址0x10
  2. 从0x71端口读数据,得到address 0x10处的内容

CMOS内存组织为128字节,低地址部分为RTC及状态寄存器,高地址部分存储BIOS配置信息。

通过直接访问这些I/O端口,我们可以在程序中读取CMOS配置数据,获取硬件信息。但需要注意CMOS访问是比较敏感的,如果不正确可能会导致系统问题。

DOS环境下的示例代码:

#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
#include<dos.h>

typedef unsigned char BYTE;
typedef unsigned int WORD;

BYTE my_inp(BYTE port)
{
    BYTE value;
    __asm
    {
        mov al,port
        out 70h,al
        in al,71h
        mov value,al
    }
    return value;
}


void my_outp(BYTE  port,BYTE value)
{
    __asm
    {
        mov al,port
        out 0x70,al
        mov al,value
        out 0x71,al
    }
}

void out_7071(BYTE port,BYTE value)
{
    __asm
    {
        mov al,port
        out 0x70,al
        mov al,value
        out 0x71,al
    }
}

void main()
{
    BYTE addr,data;
    for(addr=0x0; addr<0xff; addr++)
    {
        data = my_inp(addr);
        for(k=0x0; k<=0xf; k++)
        {
            printf("  %02x",k);
        }		

        if(addr%16==0)
        {
            printf("\n");
            printf("%02x",addr);
        }
        printf(" %02x",data);
    }

}

读取CMOS数据_数据

读取出来的结果图

三 CMOS数据代表的含义

CMOS内存的组织格式如下:

  • 低地址部分(0x00 - 0x7F)为RTC及状态控制寄存器:
  • 0x00-0x0F: 用于RTC,包含时间日期等信息
  • 0x10-0x2F: 状态控制和状态标志寄存器
  • 0x30-0x3F: RTC控制寄存器
  • 0x40-0x7F: 扩展RTC功能
  • 高地址部分(0x80-0xFF)为BIOS配置数据:
  • 0x80-0xF0: BIOS配置参数,可配置各种主板设定
  • 0xF0-0xFF: 校验和及扩展BIOS数据区

具体一些重要的CMOS配置数据说明:

  • 0x00-0x0B: 当前时间,分别是 秒 分 时 年 月 日 星期 年的最后两位
  • 0x0C-0x0D: RTC状态控制
  • 0x0E-0x0F: 诊断状态码
  • 0x10-0x2D: 各种状态标志位
  • 0x2E-0x2F: 校验和
  • 0x14: 扩展内存大小
  • 0x15: 基本内存大小
  • 0x16: 其它内存大小
  • 0x2D: 基本内存扩展
  • 0x30: 复位代码
  • 0x31: 系统复位跳转地址高8位
  • 0x32: 系统复位跳转地址低8位
  • 0x33: Checksum 校验和
  • 0x34-0x3F: 扩展CMOS配置数据

4 清除CMOS密码

CMOS内存清除密码有两个方法:

1. 硬件跳线法

通过硬件暂时短接CMOS内存芯片上的 CLR_CMOS 引脚和地线,就可以重置CMOS的数据,从而清除密码。

2. 软件校验和法

利用CMOS内存的校验和机制可以实现软件清除密码:

CMOS地址0x10-0x2D存储了各种配置数据。

而0x2E-0x2F存储了0x10-0x2D区数据的校验和。

BIOS在启动时会计算一次0x10-0x2D的校验和,和0x2E-0x2F存储的校验和比较。

如果不匹配,则认为CMOS数据错误,重置CMOS为默认值。

也就是说我们可以通过修改0x10-0x2D区数据,导致校验和不匹配,进而达到重置CMOS清除密码的目的。

具体做法是:

  1. 读取0x2E-0x2F原始校验和
  2. 修改0x10-0x2D某字节数据,导致校验和变化
  3. 写入修改后的校验和到0x2E-0x2F
  4. 重启系统,BIOS会发现校验和错误,重置CMOS

这样就通过软件方法清除了CMOS密码。

debug
-O 70 2e
-O 71 00
-O 70 2f
-O 71 00



【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月08日 0

暂无评论

推荐阅读
Bs1dA8WZU82t
作者其他文章 更多