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毫秒