实验1前篇——BIOS编程空间

Posted yiye_01

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了实验1前篇——BIOS编程空间相关的知识,希望对你有一定的参考价值。

      从此篇开始更多的注重技术细节了。细节决定成败的故事太多了,而且对于编程者肯定都有这样的经历 —— 自信满满的认为自己写得程序天衣无缝,但是当运行调试之后,才发现bug无处不在,更可气的是很多的bug却是因为语法细节或者指尖上的失误导致。而且编码效率的提升,更多的是建立在已经存在的可信代码的基础上,而可信代码却是经历过无数次的折腾的结晶。

       实验1的内容是启动PC系统”——一个从开机到运行到OS的流程;看似一个很复杂的流程,为了很好的解剖这样的流程,需要充分的知识准备,而且更重要的是从代码的角度去解释该过程。所以我们将这一篇的内容定位与介绍一些概念与模拟代码,保证理解过程的顺利。换句话说,如果在理解实验1的内容有什么问题,可以参考该篇给出的内容或者相关资源。

       本篇主要通过两个部分来做出详细的介绍:其一为Bios编程空间;其一为C与汇编的互调。

一)BIOS编程空间

       这里有一个很陌生的名词——编程空间,其实,这是我对编程环境的一个定义,一般用编程环境来描述,但是它强调的是编码的工具与使用的api等概念;但是用编码空间来代替它,因为它不仅仅包含这些内容,更多的是强调编程时更关心其代码运行的环境(内存空间,处理器状态,外设的资源使用),而且是在一个固定的环境中。

        对于BIOS的编程空间,我们关注的点主要有如下几个方面:

   1.处理器的状态

    寄存器的长度为16位,处于8086的处理器状态,详情参考《64-ia-32-architectures-software-developer-manual-325462.pdf》20.1REAL-ADDRESS MODE

       2.内存的使用

    内存空间为0-1M的连续空间,地址访问方式为(DS<<4|BX);详情参考《64-ia-32-architectures-software-developer-manual-325462.pdf》20.1REAL-ADDRESS MODE

        然而不是1M空间都能被任意使用,所以需要理解内存映像——内存地址区域的实际使用情况:


start 

end 

size 

type 

description 

Low Memory (the first MiB) 

0x00000000 

0x000003FF 

1 KiB 

RAM - partially unusable (see above) 

Real Mode IVT (Interrupt Vector Table) 

0x00000400 

0x000004FF 

256 bytes 

RAM - partially unusable (see above) 

BDA (BIOS data area) 

0x00000500 

0x00007BFF 

almost 30 KiB 

RAM (guaranteed free for use) 

Conventional memory 

0x00007C00 (typical location) 

0x00007DFF 

512 bytes 

RAM - partially unusable (see above) 

Your OS BootSector 

0x00007E00 

0x0007FFFF 

480.5 KiB 

RAM (guaranteed free for use) 

Conventional memory 

0x00080000 

0x0009FBFF 

approximately 120 KiB, depending on EBDA size 

RAM (free for use, if it exists

Conventional memory 

0x0009FC00 (typical location) 

0x0009FFFF 

1 KiB 

RAM (unusable) 

EBDA (Extended BIOS Data Area) 

0x000A0000 

0x000FFFFF 

384 KiB 

various (unusable) 

Video memory, ROM Area 


        由上表可以发现,目前0-0x4FF,0x9FC00-0xfffff这两段内存是被系统占用了,不能被我们编程使用。

         3.外设的使用

     BIOS对于外设资源的使用,主要提供了两种方式:其一为中断服务,其二为外设io地址空间。对于外设我们主要关注点为显示器,键盘,串口,硬盘。

        对于外设的使用与控制,我觉得一个很有用的观点是来之于《PC内幕技术》——资料的来源:

        大多数情况下,我首先回顾了一下制造商为子系统提供的ic数据源清单,然后仔细察看这些芯片在标准主板上是如何具体连接的,做到这一点需要用到系统的原理图,在某些情况下,还要查看系统的电路图。我也仔细研究了不同制造商提供的反汇编BIOS代码,以便在这些较低的层次上考察它们与子系统的联系。我还生成了一些测试程序来检验某西子系统的操作。最后,我才去看那些正式的文档,包括IBM的技术参考资料,当然它也是许多其他技术书籍的资料来源。

        上面的一段话对如何认识与学习ic子系统提供了基本而且严谨的步骤与方法,很值得我们每个人向前辈学习。也幸好有前辈们的铺垫,我们只需要在已经有的文档中与代码中,理解相关核心而基本的概念,然后使用总结好的代码,保证我们能够对系统有更好的理解与实现。

     如下为详细的介绍相关外设的知识:

     A)键盘——PS/2 keyboards

作为分析的一个最简单的外设——主要作为输入设备,它的控制芯片为Intel 8042 microcontroller。默认了qemu是模拟的IBM PC/XT Keyboard 的键盘按键,其扫描码详情见:http://www.computer-engineering.org/ps2keyboard/scancodes1.html

系统组织结构图如下,详情可见《PC内幕》8.1图:

键盘的基本工作原理:键盘检测到按键按下,然后将按键扫描码通过串口发送给主板的8042,接着被翻译为系统扫描码,放入输出缓存中,最后通过IRQ9给处理器。

        另外,读取键盘按键发送给主板的时序如下:

    

如上所述,读取按键的方法有两种,一种就是通过中断服务IRQ 9;另一种为通过io指令读取8042缓存的按键值。

如下提供一种通过io指令读取按键的方法——参考8042提供的io口寄存器配置如下表:

    

Port

Read /  
Write

Function

0x60

Read

Read Input Buffer

0x60

Write

Write Output Buffer

0x64

Read

Read Status Register

0x64

Write

Send Command

如下为读取按键的代码示例:

kbRead: 
     1:
        in $0x64,%al#读取通讯状态
        andb %al,0x01#检测接收按键扫描码是否ok
        jz 1b
        in $0x60,%al #读取键值

     由以上参考读取按键的流程,在读取键值之前需要读取按键是否准备好,因为由一个通信的过程。

         如果想进一步了解,请参考如下的内容:

http://www.computer-engineering.org/ps2keyboard/

http://retired.beyondlogic.org/keyboard/keybrd.htm#1

   或者参考《IBM.PC.汇编语言程序设计(第五版)完整版》第10章,《PC内幕技术》第8章。

  B)串口——UART

   对于串口的理解,我们可以通过两种方式去理解,其一是属于数据通信的范畴,数据通信一般需要考虑的问题:数据(帧)格式(数据位序LSB),数据传输速率,出错控制,流量控制;另外,串口又作为系统的外设,又需要中断控制,一般由如下芯片实现其功能:

芯片编号

描述

8250

基本UART功能支持,最早的串口芯片

8250A/B

比8250更快

16450

8250的改进,IBM-AT上使用,支持38.4KBPS

16550

在16450基础上,加入接收与发送的FIFO

16552

支持2个16550UART

16C454/16C1450/16C1550

支持4路16550UART,同时支持程序可控的掉电与重起

16650/17650

支持更多的FIFO

   所以根据如上的描述可以得出串口的属性:

      (1)波特率——最小波特率,最大波特率

   根据标准的串口的频率表,可以得到最大的波特率如下:

串口频率

1.8432Mhz

2.4546Mhz

最大波特率

115.2 KBPS

153.6 KBPS

       如果设置其他的波特只需要直接分频即可。

    比如:0x03 =  38,400 BPS

   (2)数据格式——数据长度,字节序(LSB),终止位,奇偶校验

       

     (3)流控——FIFO的支持——常见的模式没有使用

     (4)传输状态——是否传输成功与出错

python学习之前篇---理论知识

实验2前篇——X86内存管理

实验2前篇——X86内存管理

实验3前篇——X86的中断管理

实验3前篇——X86的中断管理

使用更多空间编程珍珠的恒定时间初始化 - 第 1 列