PersonalCorpus 版 (精华区)
发信人: lofe ()感激生活(), 信区: Hacker
标 题: CMOS校验和算法
发信站: 哈工大紫丁香 (Tue Sep 5 19:27:03 2000), 转信
微机CMOS数据格式及检查和算法
笔者通过反复试验和分析BIOS程序, 得出了海洋主板的CMOS数据格式,以及海洋、AMI和Phoenix三种主板的CMOS检查和的计算方法。
据此,笔者编写了微机配置修改程序CMOS.CPP。该程序具有显示CMOS数据,修改CMOS数据两大功能。显示功能可在屏幕上显示CMOS中地址为10H-7FH的数据,修改功能可修改CMOS中任何地址的值。
值得指出的是,海洋主板和AMI主板的CMOS检查和均有两个,一个在地址2EH,是10H-2DH单元的按字累加和;另一个两种主板不同,海洋主板在地址3FH,是10H-3EH部分单元的字节累加和,而AMI主板在地址3EH,是34-3DH以及40H-XXH单元的按字累加和,其中XX随BIOS版本而不同。Phoenix主板只
有第一个检查和。
本文参考了求佰君主编的<<深入DOS编程>>.
海洋主板CMOS数据格式
偏移 长度 Bits 说明
10 字节 xxxx.... 软驱0类型 0001=360K 0010=1.2M
....xxxx 软驱1类型 0011=720K 0100=1.44M 0110=2.88M
11 字节 ..x..... 硬盘0Translate 1=Yes 0=No
...x.... 硬盘1Translate 1=Yes 0=No
.....x.. 1=Step rate fast 0=Step rate slow
......xx 软驱个数00=1个 01=2个 10=三个 11=四个
12 xxxx.... 硬盘驱动器0的类型 1111=使用19h单元
....xxxx 硬盘驱动器1的类型 1111=使用1Ah单元
13 字节 x....... 1=Anti-Virus 硬盘Boot区写保护 0=disable
.xxx.... 软驱2类型
....xxxx 软驱3类型
14 字节 所安装设备的类型
15 字 基本内存容量,单位K
17 字 扩充内存容量,单位K
19 字节 硬盘驱动器0的类型
1A 字节 硬盘驱动器1的类型
1B 字节 显示卡类型 VGA/monochrome
1C 字节 ....xxxx 启动顺序0=A:C: 1=C:A: 2=Screen prompt
3=Auto search 4=Network
.x...... 486-CPU Cache 0=disable 1= enable
1D 字节 x....... 1=键盘使用缺省参数 0=使用本单元值
.xx..... 键盘延时00=0.25秒01=0.5秒10=0.75秒11=1秒
...xxxxx 键盘重发速率,单位cps
1E 字 硬盘1的柱面数
20 字节 硬盘1的磁头数
21 字节 硬盘1的扇区数
22 字 硬盘0的柱面数
24 字节 硬盘0的磁头数
25 字节 硬盘0的扇区数
26 字节 AT-Bus clock 0=16.7Mhz 1=13.3Mhz 2=11.1Mhz 3=8.3Mhz 4=6.7Mhz 5=5.6Mhz 6=4.2Mhz
27 字节 memory type 00h=60nS 20h=70nS
28 字节 串口配置
29 字节 并口配置
2A-2D 双字 未使用
2E 字 10h-2Dh单元的按字检查和
30 字 扩充内存容量,单位K,同17h单元
32 字节 BCD码的世纪值19
33 字节 信息标志
34 字节 xxxx.... Shadow of D000 0=Vacant
....xxxx Shadow of C000 0=ROM
35 字节 xxxx.... Shadow of F000 0=ROM
....xxxx Shadow of E000 0=Vacant
36 字节 xxxx.... Shadow of D000 1=WP 0=Read/Write
....xxxx Shadow of C000 1=WP 0=Read/Write
37 字节 xxxx.... Shadow of F000 1=WP 0=Read/Write
....xxxx Shadow of E000 1=WP 0=Read/Write
38 字节 内存大小,单位兆
39 字节 (内存大小有关=160/前一单元 )
3A 字 口令代码Security Code
3C 字节 xx...... 口令检测方式 0=Disable 1=Setup only
2=Powerup&Setup 3=Bootup&Setup
..xxxxxx Cold-Boot Delay 冷启动延时(单位秒)*2
3D 字节 xxxx.... 4=Full test 5=Quick scan 7=Skip test
....xx.. Xfer-Mode of 硬盘0 0=Standard 1=Poll
......xx Xfer-Mode of 硬盘1 2=Block 3=32-Bit Block
3E 字 10h-3Dh部分单元的按字节检查和,不包括17h,18h,19h,1Ah,26h,27h,30h,31h,32h,38h,3Ah,3Ch,3Dh单元
// Filename CMOS.CPP
// (C) Copyright CAD Center, HUST. All Rights Reserved
// Compile with SMALL model Tel:7543973
/************************************************************
function : Show your CMOS
programmer: Jesse
date : 1994 11 11
Modify : 1996 3 2
************************************************************/
#ifndef __SMALL__
#error complile with small model
#endif
#include <stdio.h>
#include <conio.h>
#include <bios.h>
#include <dos.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#define INDEX 0x70
#define VALUE 0x71
#define BYTE unsigned char
#define WORD unsigned int
void help();
void display();
void wbyte(int port, unsigned value);
BYTE rbyte(int port);
void cal_checksum( int checklen);
int write_mrsum();
int write_amisum();
void change_bios(int port, int value);
int test_biostype(void);
struct {
char *name;
int (*sum) () ;
} biosdesc[]={
"AMMMMI", write_amisum,
"MR BIOS", write_mrsum,
"DECpc", NULL,
"Phoenix", NULL
} ;
#define cprintf printf
void help(void)
{
cprintf("\nCMOS Untity (Version 1.00) Mar 1996 Tel:7543973\n");
cprintf("(C) Copyright Jesse CAD Center, HUST. All Rights Reserved\r\n\n");
cprintf(" can deal with AMI,MR,Phoenix bios,not include AMI 1994 version!\n");
cprintf("Usage : CMOS --display cmos value directly\n");
cprintf(" or CMOS [port newvalue] --change cmos unit\n");
cprintf("\r\n");
return;
}
int biostype=0;
/*main function of cmos*/
void main(int argc, char *argv[])
{
int port, value;
clrscr();
help();
biostype=test_biostype();
if(biostype==0 )
{
printf("Your Computer is not AMI/MR/Phoenix BIOS!\n");
return;
}
printf("BIOS type: %s\n",biosdesc[biostype-1].name );
if ( argc==2 ) return ;
if (argc>=3)
{
sscanf(argv[1],"%x",&port);
sscanf(argv[2],"%x",&value);
change_bios(port,value);
}
display();
}
/* print CMOS element */
void display()
{
int i;
for (i=0x0 ;i<0x10 ;i++)
printf("%-5x",i);
for (i=0x10 ;i<0x80 ;i++)
printf("%-5x",rbyte(i));
printf("\n");
}
BYTE rbyte(int port)
{
outp(INDEX,port);
outp(0xed, port);
return inp(VALUE);
}
void wbyte(int port, unsigned value)
{
disable();
outp(INDEX,port);
outp(0xed, port);
outp(VALUE, value&0xff);
enable();
}
void outw(int port, unsigned value)
{
wbyte(port, value&0xff);
wbyte(port+1, value>>8);
}
WORD inw(int port)
{
WORD value;
outp(INDEX,port);
outp(0xed, port);
value=inp(VALUE);
outp(INDEX,port+1);
outp(0xed, port+1);
value= value+( inp(VALUE)<<8 );
return value;
}
/*cal checksum of ami bios, From addr 34 to 3d and 40 to ...,save to 3e*/
int write_amisum()
{
WORD i=0,num;
WORD sum=0;
BYTE movsi[]={0xbe,0x40,0xe0,0};//code of MOV si, e040
BYTE far *pkey=(BYTE far*)movsi;
WORD far *p;
BYTE far *ROM=(BYTE far*)MK_FP(0xf000,0);
for(i=0;i<0xa;i++)
sum+=rbyte( 0x34+i);
for (i=0;i<0xfff0;i++) //search 'MOV SI,E040'
if (_fstrncmp(ROM+i,pkey,3)==0)
break;
if (i<0xfff0)
{
ROM+=i;
p=(WORD far*)ROM+3;
p=(WORD far*)MK_FP(0xf000, *p);
num= *p;
p=(WORD far*)ROM+5;
num=num- *p;
for(i=0;i<num;i++)
sum+=rbyte(0x40+i);
}
wbyte(0x3f, sum&0xff);
wbyte(0x3e, sum>>8);
return sum;
}
//calculate checksum of mrbios, part addr of 10 to 3e, save to 3f
int write_mrsum()
{
BYTE mask[6]={
0x7f,0xf8,0x3f,0xff,0xf8,0x0a
} ;
BYTE v,cx;
register unsigned char sum=0x1f;
int i,addr;
addr=0x10;
for (i=5;i>=0;i--)
{
v=mask[i];
for (cx=0;cx<8;cx++)
{
if (v&1)
sum+= rbyte(addr);
addr++;
v >>=1;
}
}
sum= sum&0x1f;
wbyte(0x3f,sum);
return sum;
}
/*cal checksum of any bios , from addr 10 ot 2d ,save to 2e */
void cal_checksum( int checklen)
{
WORD value, sum =0,i;
for (i=0x10 ;i<checklen ;i++)
sum+= rbyte(i);
value=inw(0x3e);
printf("\nSUM (2e)=%-5x (3e)=%-5x\n", sum,value);
wbyte(checklen+1, sum&0xff);
wbyte(checklen, sum>>8);
}
//change bios setup
void change_bios( int port,int value)
{
wbyte(port, value);
if (biosdesc[biostype-1].sum )
(*biosdesc[biostype-1].sum)();
cal_checksum(0x2e);
}
/* Test your MotherBoard BIOS type */
int test_biostype(void)
{
char far *ROM;
WORD i,type;
ROM = (char far *) MK_FP(0xf000, 0);
for(i=0; i<0xfff0; i++)
{
for(type=0 ;type<sizeof(biosdesc) / sizeof(biosdesc[0]);type++)
if(! _fstrncmp(ROM+i, biosdesc[type].name, 5))
return type+1;
}
return 0;
}
华中理工大学CAD中心
--
jesse (捷思)
潇洒逛一回
--
※ 修改:.haojs 于 Sep 5 19:24:30 修改本文.[FROM: bbs.hit.edu.cn]
--
※ 转寄:.武汉白云黄鹤站 bbs.whnet.edu.cn.[FROM: bbs.hit.edu.cn]
--
☆ 来源:.哈工大紫丁香 bbs.hit.edu.cn.[FROM: haojs.bbs@bbs.whnet.]
Powered by KBS BBS 2.0 (http://dev.kcn.cn)
页面执行时间:204.777毫秒