操作系统的自我修养-02-玩你妹的“BIOS”

  作者:K_Linux_Man    转载请注明出处

   结合已经搭建好的环境,知道明白BIOS的机理,利用BIOS中断,制作出你的第一个系统img镜像出来。

你可以欣喜若狂,因为,每一次的欣喜若狂总是推动你更进一步。言归正传.....我的妹妹,喜欢玩BIOS,

这么好的东西,我怎么肯能让她自己一个人寂寞孤单的玩呢!嘿嘿。偷偷的趁她不注意,抢来玩妹子的BIOS。

不过,玩你妹的BIOS之前,一定得搞懂BIOS呦,要不然,玩火自焚就不好收拾了!

BIOS的简单介绍

       BIOS是英文"Basic Input Output System"的缩略语。看定义就知道是基本输入输出的意思。BIOS芯片嵌在电脑主板上,保存在

主板上的一块EPROM或EEPROM芯片中,只读格式。它保存着计算机最重要的基本输入输出的程序、系统设置信息、开机后自检程序和

系统自启动程序,其主要功能是为计算机提供最底层的、最直接的硬件设置和控制。BIOS是连接软件程序与硬件设备的一座"桥梁",

负责解决硬件的及时要求。

     BIOS包括有系统BIOS(即常说的主板BIOS)、显卡BIOS和其它设备(例如IDE控制器、SCSI卡或网卡等)BIOS,其中系统BIOS是我们

将要讨论的主角。

 

Computer(Intel X86体系)  -----BIOS启动顺序

     1.当电源一通电,整个计算机包括RAM在内的几乎所有部件,都处于一种随机的混乱状态.这时CPU的Reset的管脚拉低,CPU重置,

促使CPU将自己的主要寄存器(包括cs和eip)设置为启动状态──实际上就是把这些cpu内的寄存器内容设置成一些预定值。

 

     2.我们都知道指令寄存器(eip)决定cpu下一步要执行什么,所以指令寄存器都被预置成一个固定值(寄存器cs=0xFFFFFFF, IP=0000),

那么该固定位置上的指令就会被执行——intel x86系统的eip都指向了地址0xFFFFFFF0上的指令,所以该指令便作为系统加电后执行第一条指令了。

 

    3.硬件系统会把BIOS只读芯片的存储区地址映射到这两个位置上(0xFFFFFFF0-0xFFFFFFFF)和(0xFFFF0-0xFFFFF),也就是说cpu要

访问这两段地址,都会去访问同一个BIOS ROM。这就是所谓的BIOS地址映射(具体的原理是比较复杂的,在此不是咱们研究的重点) 

所以ROM中存放的程序就会被调用执行——换句话说就是机器加电后首先执行ROM中存放的程序,该程序被称为BIOS(Basic Input/Output System)

。当然这个ROM也就被人们叫为 “系统BIOS芯片”(或主板BIOS芯片)。

 

    4.无论是Award BIOS还是AMI BIOS(两种主流BIOS厂商)放在这里的只是一条跳转指令,跳到各自厂家的BIOS程序中POST加电自检程序地址。

 

    5.首先BIOS里的自检程序开始运行,进行POST上电自检(Power On Self Test),检测系统中一些关键设备是否存在和能否正常工作,

例如内存(只检测了64k大小的基本内存)和显卡等设备。由于POST是最早进行的检测过程,此时显卡还没有初始化,如果系统BIOS在进行

POST的过程中发现了一些致命错误,例如没有找到内存或者内存有问题,那么系统BIOS就会直接控制喇叭发声来报告错误,声音的长短和次数

代表了错误的类型。在正常情况下,POST过程进行得非常快,我们几乎无法感觉到它的存在,POST结束之后就会调用其它代码来进行更完整

的硬件检测。

 

    6.BIOS接下来要进行显卡的检测并初始化。显卡BIOS也有其固定的地址,其地址存放在0xC00000000处,在这个地址运行检测和初始化

显卡代码。初始化显卡的时候,通常显示显卡的图标以及生产厂商等信息,只不过是一闪而过,我们几乎肉眼看不到。

 

    7.返回到系统BIOS(主板BIOS)代码处,继续依次执行其他BIOS检测代码,至此忽略。

 

    8.执行完所有检测代码之后,BIOS显示出自己生产厂商的图片、名称、BIOS程序版本号以及生产日期。紧接着显示检测到的CPU信息,

并测试所有的RAM(内存),你插了多大的内存条,就开始检测了。当然这个速度是很快的,在屏幕上显示测试的进度。马上你就能看到,

你的内存容量是多少以及“OK”的字样。这说明内存检测完毕,一切OK!

 

    9.内存检测完成之后,就开始检测电脑标准IO设备。IO设备包括,硬盘、CD-ROM、FLoppy(软驱)、USB设备、串口、并口等等,

并显示出这些信息来。接着,系统BIOS程序将即插即用设备(主要是usb设备)进行初始化,分配端口号以及中断号等资源,使其可以使用

一般显示“Initializing Usb Controller.....Done”。并紧随其后显示电脑启动顺序(启动顺序是从CMOS里读取出来的),“Master HardDisk......First....Second.....”(嘿嘿,此处省略一万行!赵本山笑话)。假如硬盘出现问题,会有类似“hard disk status bad”等

信息提示。

 

    10.至此所有硬件设备都已经初始化并配置完毕。同时,系统BIOS将更新ESCD(Extended System Configuration Data,扩展系统配置数据)ESCD是系统BIOS用来与操作系统交换硬件配置信息的一种手段,这些信息将存储到CMOS中,CMOS是一块非常特殊的RAM芯片,以主板上的

CMOS纽扣电池为其供电。好不容易BIOS检测并配置完的信息就要这样付诸东流了吗? 不是的,CMOS是为以后系统调取硬件信息和配置信息打下伏笔。这里必须强调一下,CMOS与BIOS是两个完全不同的概念,CMOS是存储BIOS检测和配置信息的地方,而BIOS是基本输入输出程序,是程序!

 

    11.CMOS里面的内容是可以去修改的。BIOS提供图形界面程序,并以一个键盘按键(通常是“del”)来设置CMOS里面的内容。CMOS里面

存放着好多内容,常见的比如,系统时间、启动顺序、硬盘接口等等。知道了吗?这就是人们经常把BIOS与CMOS混为一谈的原因,修改时

CMOS的内容,提供画面配置的是BIOS。之后多数BIOS厂商都会清屏,以表格的形式显示BIOS检测并配置的信息,其中概略地列出了系统中

安装的各种标准硬件设备,以及它们使用的资源和一些相关工作参数。

 

    12.系统BIOS的使命还没有结束,它需要从内存 0x00000000地址处开始--至0x000003FFF 初始化中断向量表。通过调用中断来对硬件进行操作。

 

    13.读取启动设备信息,以启动设备号为参数调用系统BIOS启动装载程序(我们也可以称为“字节搬移程序”或自举程序,更便于理解)。

这个装载程序通过BIOS的0x19中断,从启动设备(硬盘或者软盘)的第0个扇区(一个扇区为512字节),读取这512字节内容,将其装载到

内存物理地址0x7C00处。这512字节的内容,常常被人们称为Boot Sector(启动扇区或引导扇区)。为什么偏偏是这个0x7c00地址呢?  

稍后解释一下。

    14.BIOS在此还要做一项很重要的工作。“BIOS兄弟”不知道从启动设备上读取的这段512字节的内容是不是专门用来加载操作系统

内核任务的,换句话说,不能确定512字节内容的合法性。BIOS规定这512字节的内容中,最后的第511和第512字节字节内容分别为0x55和0xAA

如果是以0x55和0xAA结束的512字节内容,都被视为合法的引导扇区程序,否则,提示引导扇区失败。合法性验证通过之后,cpu指向0x7c00处的指令,开始执行那里的代码。我们第一行代码就要从0x7c00那里编写。

 

  15.之后,引导扇区加载操作系统内核,初始化环境等等。

 

引导程序为何从0x7c00处开始?

英文原文及翻译  

"0x7C00" is the memory address which BIOS loads MBR(Master Boot Record, a first sector in hdd/fdd) into. OS or bootloader developer must assume that their assembler codes are loaded and start from 0x7C00.(0x7c00 是BIOS加载MBR的内存地址,操作系统

或者引导程序开发者必须确保你的汇编代码从0x7c00开始加载)


"I read all of Intel x86(32bit) programmers manual, but did not found the magic number 0x7C00." 
Yes.0x7C00 is NOT related to x86 CPU. It's natural that you couldn't find out it in cpu specifications from intel. 

Then, you wonder, "Who decided it ?" (我读了所有的x86编程手册,没有发现0x7c00这个地址。是的,0x7c00与x86 cpu没有关系,自然你不能

从intel的手册中查到。)


you may wonder: 
"0x7C00 is 32KiB - 1024B at decimal number. What's this number means ?" (你可能疑惑,0x7c00这个地址,正好是32K-1024B,它意味什么?

Anyone decided it. But, why he/she decided such a halfway address?(任何人可以决定地址。但为什么选了一个地址不算高也不低的地址呢?)


Hum...There're TWO questions(mysteries) arround the magic number "0x7C00". 
Who decided "0x7C00" ?
What "0x7C00 = 32KiB - 1024B" means ?

(围绕这两个问题,谁决定的0x7c00地址?为什么0x7c00恰好是32Kb-1024B?)


Okay, let's dive into the secret of BIOS for "IBM PC 5150", ancestor of modern x86(32bit) PCs, with me...!! 

(让我解开IBM PC 5150的BIOS神秘面纱, IBM PC 5150 是现在x86的原始模型)


0x7C00" First appeared in IBM PC 5150 ROM BIOS INT 19h handler.

(0x7c00 第一次出现在IBM PC 5150 ROM BIOS 的第19号中断程序里)


Wandering arround the history of x86 IBM Compatible PC, you know IBM PC 5150 is the ancestor of modern x86(32bit) 

IBM PC/AT Compatible PCs.(遵循IBM x86 PC机的历史,你可以知道IBM PC5150 是现在x86(32位)机的始祖)


This PC was released at 1981 August, with Intel 8088(16bit) and 16KiB RAM(for minimum memory model). 

BIOS and Microsoft BASIC was stored in ROM. (这种PC发布于1981年8月,cpu用英特尔8088(16位)和16KiB的RAM(最小内存模型)。

 BIOS和微软BASIC是存储在ROM中。)


When power on, BIOS processes "POST"(Power On Self Test) procedure, and after, call INT 19h. 
In INT 19h handler, BIOS checks that PC has any of floppy/hard/fixed diskette or not have. 
If PC has any of available diskkete, BIOS loads a first sector(512B) of diskette into 0x7C00.

(POST上电自检之后,调用19号中断,在19号中断中,BIOS 检查PC机的软盘、硬盘或磁盘是否存在,如果可用,

讲加载第一个扇区(512字节)到0x7c00地址)


Now, you understand why you couldn't find out this magic number in x86 documents. This magic number belongs to 

BIOS specification. (你现在明白了为什么在x86的文档中找不到这个神奇的数字了吧,这个数字是属于BIOS的规格范围内的)


Stories surrounding IBM PC DOS, Microsoft, and SCP's 86-DOS are famous stories.

(故事围绕IBM PC DOS系统和SCP的 86-DOS系统展开的)


SCP's "86-DOS"(at 1980) is the reference OS for IBM PC DOS 1.0.

(86-DOS 参照IBM PC DOS1.0系统) 


86-DOS(early called "QDOS") is CP/M compatible OS for 8086/8088 cpu. At 1979, Digital Research Inc didn't have developed CP/M for 8086/8088 cpu yet. (86-DOS 兼容8086/8088 CPU,但在1979年,数字研究厂商还没为8086/8088 CPU 作出兼容)

SCP sold two S-100 bus board, one is 8086 CPU board, two is "CPU Monitor" rom board.

(SCP 卖两块板子,一块是8086 cpu板,另一个是 CPU 监测板) 


"CPU Monitor" program provided bootloader and debugger. This "CPU Monitor" bootloader loaded MBR into "0x200",

 NOT "0x7C00". In 1981, IBM PC DOS was the NEXT CP/M like OS for 8086/8088.(cpu监测板提供了bootloader和debugger,

cpu监测板的bootloader加载MBR到0x200地址,而不是0x7c00地址。)


 So, I told you that "0x7C00 FIRST appeared in IBM PC 5150 ROM BIOS". 
Previous one, SCP's CPU Monitor bootloader loads into 0x200, not 0x7C00.

(所以我告诉你,0x7c00第一次出现是在IBM PC 5150 ROM BIOS中) 


Why that CPU Monitor's bootloader loeded MBR into "0x200" ?
There're THREE reasons about "0x200". 
8086 Interrupts Vector use 0x0 - 0x3FF.
86-DOS was loaded from 0x400.
86-DOS didn't use interrupts vectors between 0x200 - 0x3FF.
These reasons mean 0x200 - 0x3FF needed to be reserved and couldn't be in the way of an OS, no matter where 86-DOS or user application wanted to load. 
So Tim Paterson (86-DOS developer) chose 0x200 for MBR load address. 

(为什么CPU 监测板中的Bootloader 加载MBR 到0x200地址呢?有三个原因,8086cpu中断使用0x0-0x3FF地址段中,

86-DOS系统将被加载到0x400地址处,86-DOS 不使用0x200-0x3FF之间的中断向量。这些原因意味着0x200-0x3FF之间的地址必须被保留,

操作系统或应用程序都加载不到这里,所以Tim就选择从0x200加载512字节的引导程序了。


Q:Who decided "0x7C00" ? - A: IBM PC 5150 BIOS Developer Team.
"0x7C00" was decided by IBM PC 5150 BIOS developer team (Dr. David Bradley). 
As mentioned above, this magic number was born at 1981 and "IBM PC/AT Compat" PC/BIOS vendors did not change this value for BIOS and OS's backward compatibility. 
Not Intel(8086/8088 vendor) nor Microsoft(OS vendor) decided it. 

(谁决定0x7c00,IBM PC 5150 开发团队决定的。综上所述,这个神奇的数字诞生于1981, 并且IBM PC/BIOS 供应商没有改变这个值,为了以后的操作系统的兼容,并不是intel或者是微软决定的)


Q:What "0x7C00 = 32KiB - 1024B" means ? A: Affected by OS requirements and CPU memory layout.
IBM PC 5150 minimum memory model had only 16KiB RAM. So, you may have a question. 
"Could minimum memory model (16KiB) load OS from diskette ? BIOS loads MBR into 32KiB - 1024B address, but physical RAM is not enough..." 
No, that case was out of consideration. One of IBM PC 5150 ROM BIOS Developer Team Members, Dr. David Bradley says: 
"DOS 1.0 required a minimum of 32KB, so we weren't concerned about attempting a boot in 16KB." 
(Note: DOS 1.0 required 16KiB minimum ? or 32KiB ? I couldn't find out which correct. But, at least, in 1981's early BIOS development, they supposed that 32KiB is DOS minimum requirements.) 

(为什么0x7c00=32K-1024B? 由于操作系统的需要和CPU的内存分配。 IBM PC 5150 最小内存模块要求仅仅是16K的RAM.所以你可能会有一个问题。 “最小内存16K的RAM可以加载操作系统吗? BIOS 加载MBR 到32K-1024B的位置,但是物理RAM没有那么大的空间呀?! “不,这样你考虑的太多” IBM 5150 BIOS开发团队成员说。

DOS1.0 最少需要32KB的内存,所以我们更没有必要去关心在16KB处的启动问题了。记:DOS1.0到底最小需要16KB还是32KB,我至今也没有找到相关资料。但是,至少在

1981年的早起BIOS开发中就已经假设DOS使用32KB内存容量)


BIOS developer team decided 0x7C00 because: 
They wanted to leave as much room as possible for the OS to load itself within the 32KiB.
8086/8088 used 0x0 - 0x3FF for interrupts vector, and BIOS data area was after it.
The boot sector was 512 bytes, and stack/data area for boot program needed more 512 bytes.
So, 0x7C00, the last 1024B of 32KiB was chosen.

Once OS loaded and started, boot sector is never used until power reset. So, OS and application can use the last 1024B of 32KiB freely. 

After OS loaded, memory layout will be: 

(BIOS 开发团队决定使用0x7c00这个地址是因为: 

他们想留出尽可能多的空间给操作系统去加载在32KB的空间范围内。

8086/8088 使用0x-0x3FF地址范围构建中断向量表,紧接着后面是BIOS的数据区域。

启动扇区是512字节,对于引导程序的堆栈数据区域需要512字节还多。所以,0x7C00地址被决定使用

一旦操作系统加载,引导扇区不会再被使用,直到电源复位,所以,操作系统和应用程序可以使用32KB-1024B的这段空闲区域。)


+--------------------- 0x0
| Interrupts vectors
+--------------------- 0x400
| BIOS data area
+--------------------- 0x5??
| OS load area
+--------------------- 0x7C00
| Boot sector
+--------------------- 0x7E00
| Boot data/stack
+--------------------- 0x7FFF
| (not used)
+--------------------- (...)

小结


BIOS系统是一门非常深的学问,核心技术还是掌握在几家大公司手中,大体流程已经介绍了。对于深究BIOS的人来说,有的地方讲的很模糊。

但是,对于我们要编写操作系统的人来说,我们只需要知道我们编写的第一行代码要从0x7c00处执行,并且第一个扇区以55AA结尾就可以了。+

我们以后要写引导扇区程序,那时候我们将要告诉汇编编译器,我们这段代码要从0x7c00地址处运行。所以,到时候你可要知道这个地址的意义所在。


  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值