操作系统---A20地址线概念及如何打开

本文详细介绍了A20地址线在处理器内存寻址中的作用,以及如何通过内联汇编技术在不同的模式下开启它。重点讲述了如何通过读写0x92端口来控制A20线,从而改变内存访问范围。
摘要由CSDN通过智能技术生成

一、A20地址线是什么

        A20地址线是一种处理器内部的地址线,用于在实模式和保护模式之间进行内存寻址的切换。简单来说,当A20地址线打开时,表示只能访问1MB以内的空间,而当A20地址线打开时,可以访问4GB的内存空间。

        注意:是否进入保护模式仅由CR0寄存器的第一位是否置1有关,与A20地址线无直接关系


二、如何开启A20地址线

        打开A20地址线,只需要将0x92端口第一个位置置1就完成了。

**(其中uint8_t为unsigned char类型,uint16_t为unsigned short类型)**

        具体步骤如下:

        首先通过内联汇编方式封装读端口的c函数:

//读端口函数
static inline uint8_t inb(uint16_t port){
    //返回参数
    uint8_t rv;
    //内联汇编形式读取端口
    __asm__ __volatile__(
        "inb %[p], %[v]"
        :[v]"=a"(rv) : [p]"d"(port)
        );
    return rv;
    /*注意的是:
    inb al, dx是intel的汇编语法,而下面的
    inb %[p], %[v]是GCC的汇编语法
    两者表示同一指令,但是写法不一样。源,目的操作数位置正好相反
    */
}

        然后封装写端口的c函数用于修改0x92端口的值:

//写端口函数
static inline void outb(uint16_t port, uint8_t data){
    /*指令格式为
    outb al(数据), dx(端口)
    */
    __asm__ __volatile__(
        "outb %[v], %[p]"
        ::[v]"a"(data), [p]"d"(port)
    );
    /*注意的是:
    outb al, dx是intel的汇编语法,而下面的
    outb %[v], %[p]是GCC的汇编语法
    两者表示同一指令,但是写法不一样。源,目的操作数位置正好相反
    */
}

        最后在需要打开A20地址线的地方通过调用这两个函数实现打开A20地址线,如:

    //开A20地址线
    uint8_t v = inb(0x92);
    outb(0x92, v | 0x2);

        即可完成A20地址线的开启。

  • 11
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
///////////////////////////////////////////////////////////////////// //功 能:寻卡 //参数说明: req_code[IN]:寻卡方式 // 0x52 = 寻感应区内所有符合14443A标准的卡 // 0x26 = 寻未进入休眠状态的卡 // pTagType[OUT]:卡片类型代码 // 0x4400 = Mifare_UltraLight // 0x0400 = Mifare_One(S50) // 0x0200 = Mifare_One(S70) // 0x0800 = Mifare_Pro(X) // 0x4403 = Mifare_DESFire //返 回: 成功返回MI_OK ///////////////////////////////////////////////////////////////////// signed char PcdRequest(unsigned char req_code,unsigned char *pTagType) { signed char status; unsigned int unLen; unsigned char ucComMF522Buf[MAXRLEN]; ClearBitMask(Status2Reg,0x08); WriteRawRC(BitFramingReg,0x07); SetBitMask(TxControlReg,0x03); ucComMF522Buf[0] = req_code; status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,1,ucComMF522Buf,&unLen;); if ((status == MI_OK) && (unLen == 0x10)) { *pTagType = ucComMF522Buf[0]; *(pTagType+1) = ucComMF522Buf[1]; } else { status = MI_ERR; } return status; } ///////////////////////////////////////////////////////////////////// //功 能:防冲撞 //参数说明: pSnr[OUT]:卡片序列号,4字节 //返 回: 成功返回MI_OK ///////////////////////////////////////////////////////////////////// signed char PcdAnticoll(unsigned char *pSnr) { signed char status; unsigned char i,snr_check=0; unsigned int unLen; unsigned char ucComMF522Buf[MAXRLEN]; ClearBitMask(Status2Reg,0x08); WriteRawRC(BitFramingReg,0x00); ClearBitMask(CollReg,0x80); ucComMF522Buf[0] = PICC_ANTICOLL1; ucComMF522Buf[1] = 0x20; status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,2,ucComMF522Buf,&unLen;); if (status == MI_OK) { for (i=0; i<4; i++) { *(pSnr+i) = ucComMF522Buf[i]; snr_check ^= ucComMF522Buf[i]; } if (snr_check != ucComMF522Buf[i]) { status = MI_ERR; } } SetBitMask(CollReg,0x80); return status; } ///////////////////////////////////////////////////////////////////// //功 能:选定卡片 //参数说明: pSnr[IN]:卡片序列号,4字节 //返 回: 成功返回MI_OK ///////////////////////////////////////////////////////////////////// signed char PcdSelect(unsigned char *pSnr) { signed char status; unsigned char i; unsigned int unLen; unsigned char ucComMF522Buf[MAXRLEN]; ucComMF522Buf[0] = PICC_ANTICOLL1; ucComMF522Buf[1] = 0x70; ucComMF522Buf[6] = 0; for (i=0; i<4; i++) { ucComMF522Buf[i+2] = *(pSnr+i); ucComMF522Buf[6] ^= *(pSnr+i); } CalulateCRC(ucComMF522Buf,7,&ucComMF522Buf;[7]); ClearBitMask(Status2Reg,0x08); status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,9,ucComMF522Buf,&unLen;); if ((status == MI_OK) && (unLen == 0x18)) { status = MI_OK; } else { status = MI_ERR; } return status; } ///////////////////////////////////////////////////////////////////// //功 能:验证卡片密码 //参数说明: auth_mode[IN]: 密码验证模式 // 0x60 = 验证A密钥 // 0x61 = 验证B密钥 // addr[IN]:块地址 // pKey[IN]:密码 // pSnr[IN]:卡片序列号,4字节 //返 回: 成功返回MI_OK ///////////////////////////////////////////////////////////////////// signed char PcdAuthState(unsigned char auth_mode,unsigned char addr,unsigned char *pKey,unsigned char *pSnr) { signed char status; unsigned int unLen; unsigned char i,ucComMF522Buf[MAXRLEN]; ucComMF522Buf[0] = auth_mode; ucComMF522Buf[1] = addr; for (i=0; i<6; i++) { ucComMF522Buf[i+2] = *(pKey+i); } for (i=0; i<6; i++) { ucComMF522Buf[i+8] = *(pSnr+i); } // memcpy(&ucComMF522Buf;[2], pKey, 6); // memcpy(&ucComMF522Buf;[8], pSnr, 4); status = PcdComMF522(PCD_AUTHENT,ucComMF522Buf,12,ucComMF522Buf,&unLen;); if ((status != MI_OK) || (!(ReadRawRC(Status2Reg) & 0x08))) { status = MI_ERR; } return status; }
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值