学习Linux很长时间了,一直没有时间把经验和挖掘的一些技巧整理出来,这个暑假在家没事,整理了一些与大家分享。由于都是自己的理解和实验产物,所以肯定有些不当之处,期待交流指正! 这个系列文章将以Ubuntu探秘命名,内容涉及到整个开机流程及GNOME桌面的hack . 今天发表第一篇心得:BIOS到底干啥用?
BIOS(basic input/output system,基本输入输出系统)是一组被固化到电脑中,为电脑提供最低级、最直接的硬件控制的程序,它是连接软件程序和硬件设备的枢纽。
1. BIOS存在的目的
包括:检测硬件、初始化硬件、分配资源(如IO地址、IRQ号、DMA通道等)以及协助加载操作系统。 首先了解两个概念:北桥(north bridge)、南桥(south bridge). 北桥和南桥组成了主板上的芯片组。北桥主要控制CPU和内存,是系统总线和一级PCI总线的桥接设备,也称host bridge ;南桥负责PCI,PCI-E,USB,VGA等外围总线设备,这些外围设备挂在PCI总线上,通过各自的控制器与PCI总线接口,不同类型的总线通过bridge接口。
在内存的低端640KB地址空间被称为基本内存,一般用于固定用途,如A0000H~BFFFFH保留给显卡的显存使用,C0000H~C7FFFH为显卡的BIOS,C0000H~FFFFFH保留给系统中各设备的BIOS,IDE,SATA等BIOS也都在这一段空间中,其中" 系统BIOS"一般占用最后的64KB或更多。(这些信息可以用 cat /proc/iomem | head 查看到) 通常,计算机的启动过程是在主板的BIOS控制下进行的,这个BIOS也称为“系统BIOS”,它的内容在南桥芯片的一块特殊区域CMOS中,主板上的电池就是为CMOS保存资料而提供电源的。除了这个“系统BIOS”以外,各PCI设备也都提供各自的BIOS,它们的功能是直接访问所在设备的PCI配置寄存器,以获得PCI设备的信息、配置PCI设备的参数、完成PCI设备的初始化等。
系统BIOS在激活时会校验CMOS中的资料是否正确,若正确则会将这些资料和已找到的硬件信息整合成一张表格,写到内存中,也就是所谓的SMBIOS(System Management BIOS),若错误则用默认的值取代CMOS提供的资料。SMBIOS扮演的主要角色是将主板或X86架构的系统通过BIOS呈现在用户面前。通过dmidecode命令可以查看该表格,其中有许多Type,每个Type代表一类信息,可以在dmidecode的man page中找到相关定义。
当计算机电源开关被按下时,电源就开始向主板和其它设备供电,此时电压还不稳定,主板控制芯片组(北桥芯片)会向CPU发出一个Reset信号,让CPU复位初始化。当电源开始稳定供电后,芯片组便撤去Reset信号,CPU马上开始从地址FFFF0H处执行指令,这个地址在“系统BIOS”的地址范围内,放在这里的一般是一个跳转指令,跳到系统BIOS的真正开始代码处。
2.bios经历的三个阶段
从主机上电到加载bootloader这个过程中,系统BIOS主要经历了三个阶段:Pown On ,POST ,加载bootloader .
Pown On 阶段 这一阶段从上电开始到屏幕出现信息结束,也就是所谓的激活电源阶段。这一阶段的主要任务是校验CMOS中的内容是否正确、检查主机上某些硬件的状态以确定下一步的自检,因此,用户无法在屏幕上看到BIOS信息(要等硬件确认后才激活VGA) ,若这个阶段出现错误一般都是致命的(通常为黑屏),只能通过喇叭声来判断错误类型。这个阶段只是检查系统上都有哪些设备,并不初始化。
POST(power on self test)阶段 检查一些关键设备如内存、显卡能否正常工作,并提供简易的内存测试,只要测试没问题,就在屏幕上显示该硬件的基本信息。这个阶段的基本过程如下:系统BIOS查找显卡的BIOS,存放显卡BIOS的ROM芯片的起始地址通常在C0000H处,然后调用其初始化代码,由显卡的BIOS完成显卡的初始化,然后屏幕就可以显示信息了,大多数的显卡会在这时显示显卡的一些信息,但是通常只是一闪而过。依次类推,系统BIOS调用在前一个阶段找到的设备的BIOS代码,以完成相应设备的初始化。查完其它所有设备后,BIOS将显示自己的启动画面,接着检查CPU的类型和工作频率、主机的内存容量,然后系统BIOS开始测试和配置系统中安装的一些标准硬件设备如硬盘、光驱、COM口、并口等,然后BIOS开始检查并配置系统中的即插即用设备。开机时和开机后所有需要用到的设备都是在这个阶段被激活的。
加载bootloader阶段 当所有的硬件都检测完毕并没有问题后,BIOS退居幕后的办法是将加载OS的主控权交给硬盘的主引导扇区MBR即硬盘的物理扇区0柱0面1扇区上的内容,让藏匿于此的开机管理程序(bootloader)将指针带到系统核心的地方。linux常见的开机管理程序为Grub.(以后会分享grub的配置及除错方法^_^)
综上,系统激活流程为:打开电源开关—CPU初始化—BIOS激活—读取并校验CMOS资料、检测硬件状态(此时BIOS代码在flash memo中运行)—生成SMBIOS表格—检测、配置并初始化各硬件—加载bootloader 。
3.查看BIOS信息的命令:
另外查看系统BIOS信息的命令主要有两个:dmidecode 和 biosdecode .它们可以显示cpu 、内存、主板型号、OEM信息、主板插槽等信息,这些信息对于查看系统硬件配置非常有用。
引言
对于经常使用电脑的用户(来CFAN的都应该包括在这一行列吧)来说,每天当你按下Power Button等待电脑进入系统开始一天正常工作的时候,你有没有想过在这一段时间内电脑内部都发生了什么?当电脑发生故障不能启动的时候你是否不知所措, 不知道是哪里出了问题?如果你还没有想过这个问题,或者这是你老早就在思考的问题,却苦苦得不到答案,那么请继续往下看。
概述
整个电脑的启动过程大概可以分为三个阶段:
一 从按下Power Button到CPU Reset
这一阶段是通过硬件逻辑电路来完成CPU Reset,并且台式机与笔记本又有所区别。
二 BIOS引导阶段(从CPU Reset到操作系统引导)
这一阶段完全在BIOS的控制之下,由BIOS完成微机硬件的自检(POST)与初始化,BIOS还提供BIOS设置和Runtime Service服务(微机原理课学过的BIOS中断服务),最后BIOS将从可引导介质上引导操作系统。
三 操作系统引导阶段
第一阶段:CPU Reset
很多文章里都会忽略这一阶段,直接从CPU Reset读取BIOS代码开始自检讲起,可能是这一步经过的时间太短了,用户根本觉察不到,所以没有必要讲:( 。但是这是必需的一步,不经过这一阶段PC不可能启动!
注意:台式机与笔记本在这一阶段有很大的区别,这是由于笔记本有KBC的存在(后面会讲到)。
先看台式机:
由于台式机的开机与PC电源有密切关系,先看一下电源部分:
首先是电源插头定义:
![[BIOS]pc <wbr>启动过程 <wbr>-- <wbr>加载MBR之前的过程,即加电到bios启动过程 BIOS 工作流程解析_第1张图片](http://img.e-com-net.com/image/info8/bbaf988dfd564d398e6db8263ada171e.jpg)
下面为有卡扣那一边
(看不清楚?没事 拆了机箱拿出电源自己慢慢看 看熟悉就好了)
这个就是主板供电插头的pin脚定义图,这是ATX 12V 规范之前的定义,最新的ATX 12V 规范pin脚已经变成24针(主要是加强了了对CPU的供电电压 ,如果想了解更多的电源规范可以参考ATX 电源规范 ,这个不在本文的探讨之列),但是这个变化对开机流程没有影响,所以这张图依然适用(手头只有这张图,懒的找了)。
说明一下,其中,8引脚为PG(Power Good)信号。9引脚为待机供电。14引脚为PW-ON(Power-On)信号,14引脚与GND(Ground)短接后即可触发电源工作(这一点非 常重要!),未触发前9、14引脚输出电压均为+5V,其它引脚无输出电压。
还有,根据电源的两种结构,主板触发也采用两种方式。AT结构电源采用硬开机方式(触发后PW-ON为常闭状态),ATX结构电源采用软开机方式(触发后 PW-ON为常开状态)。由于软开机是目前绝大多数主板采用的触发方式,因此我们主要针对这种触发方式进行分析。这个有时分析是要用到的 所以我想想还是说一下。
主板触发电路
看一下几种典型的主板触发电路:
1. 经过南桥的触发电路(见下图)
![[BIOS]pc <wbr>启动过程 <wbr>-- <wbr>加载MBR之前的过程,即加电到bios启动过程 BIOS 工作流程解析_第2张图片](http://img.e-com-net.com/image/info8/db4e8bb186c840e2a8c6313d6badb438.jpg)
在触发电路中凡是参加开机的元件均由电源9引脚(紫)提供+5V供电。+5V高电位经电阻R1、R2,在PW-ON非接地端形成+3.3V高电位。当 PW-ON(机箱开机按纽)被触发(即闭合)瞬间,+3.3V高电位信号被拉低,变为低电位,南桥接收到低电位信号向电源14引脚(绿)发出低电位信号, 将POWER(14)+5V高电位拉低,触发电源工作,实现开机。
2. 用反向器式,不同与上面的接地式。
![[BIOS]pc <wbr>启动过程 <wbr>-- <wbr>加载MBR之前的过程,即加电到bios启动过程 BIOS 工作流程解析_第3张图片](http://img.e-com-net.com/image/info8/c4f68ad9334747a1bfddb154c56acd04.jpg)
当PW-ON被触发(即闭合)瞬间,+3.3V高电位信号经反向器(如7404等)转换为低电位,南桥接收到低电位信号向电源14引脚(绿)发出低电位信号,将POWER(14)+5V高电位拉低,触发电源工作,实现开机。
3. IO控制芯片型
过程与经过南桥相似,只是由南桥控制I/O芯片,通过I/O芯片发出低电位信号将POWER(14)+5V高电位拉低,触发电源工作。
上面列举了三种常用开机电路,当然,不同的PC厂商可能会采取不同的设计,基本原理应该都和上面的电路相同。
至此,ATX电源开始正常工作,就会输出+12V,-12V.+5V ,-5V,+3.3V电压,包括8引脚PG(Power Good)信号,这时候主板上的用电已经全部输出。输出PG信号后会触发南桥,经过一系列的触发动作,最终由北桥发送CPURST#给CPU,使CPU Reset.
至此,PC开机过程的第一步完成(应该是台式机,还有笔记本的没讲 :))。需要说明的是,这一过程在极短的时间内(微秒级)完成,用户根本感觉不到(好复杂啊!还有更复杂的呢,CPU内部的每秒G次级操作!)。
再看笔记本
笔记本由于有KBC的存在,这一阶段和台式机又有不同。KBC(Keyboard Controller,键盘控制器)从字面上我们就可以看出来它的作用。这只是它当初的定义,现在的KBC的功能已经远远超出它当初的定义了,现在笔记本 上的电源管理,状态LED的显示,Panel背光亮度的调节,Fn键的控制,CPU Throttle的开关,无线蓝牙红外等外设的控制,电池充放电的控制等等功能都由KBC来接手,应该说KBC接手了台式机上南桥的一部分功能。现在常用 的KBC芯片主要有Hitachi的H8和Winbond系列(如W83L941D)。
KBC在NB的开机过程中也起着很大的作用,下面我们来看:
在系统关机的时候,只有RTC部分和KBC部分在运行,明白这一点很重要!很多笔记本用户会问为什么笔记本即使不开机过一段时间电池电量也会减少?这正是 KBC还在用电的原因,当然,电池的自然陨耗也不可忽略。RTC部分维持着计算机的时钟和CMOS设置信息,而KBC则在等待用户按开机键。在检测到用户 按开机键后,KBC会通知整个系统把电源打开(这部分在下面详细介绍)。CPU被RESET后,会去读BIOS内一个特定地址内的指令(其实是一个跳转指 令,这个地址是由CPU硬件设定的),接下来就是第二阶段讨论的内容了!
(以下一段从权威揭密 笔记本硬件结构终极教程 (下)一文摘录)
那我们现在就讲解一下笔记本电脑在硬件上的逻辑开机过程。
首先我们做一些预习工作,以方便读者的理解。在笔记本内部的电压有好几种,我们分别看一下。
首先是RTC电源,这部分电力是永远不关闭的,除非电池(纽扣电池)没电并且没接任何外部电源(比如电池和电源适配器)。RTC用以保持机器内部时钟的运 转和保证CMOS配置信息在断电的情况下不丢失;其次,在你插上电池或者电源适配器,但还没按power键的时候(S5),机器内部的开启的电称为 ALWAYS电,主要用以保证EC的正常运行;再次,你开机以后,所有的电力都开启,这时候,我们称为MAIN电(S0),以供整机的运行;在你进待机的 时候(S3),机器内部的电成为SUS电,主要是DDR的电力供应,以保证RAM内部的资料不丢失;而休眠(S4)和关机(S5)的电是一样的,都是 Always电。其中,上文中括号内的是表示计算机的状态(S0-开机,S3-待机,S4-休眠,S5-关机)。
上图是对上面这段话的总结,我想应该很容易明白。其中最后一列指的是其电压开启的控制信号,这点下面会讲到。至于为什么这里没有S4,即休眠状态,是因为在S4状态和S5状态下,系统开启的电是一样的,所以就没必要增加一组控制电路。
OK,现在我们假设没有任何的电力设备在供电(没电池和电源),这时候,机器内部只有RTC电路在运作,南桥上会接有一个3V的纽扣电池来供给RTC电力,以保持内部时间的运行和CMOS信息。
我们来分析一下开机的过程。在插上电池或者电源的时候,机器内部的单片机KBC就Reset并开始工作,等待用户按下Power键。在此期间的时序 是:ALWAYS电开启以后,KBC Reset并开始运行,随后发给南桥一个称为‘RSMRST#’的信号。这时候南桥的部分功能开始初始化并等待开机信号。这里要注意,这时候的南桥并没有 打开全部电源,只有很少一部分的功能可用,比如供检测开机信号的PWRBTN#信号。
在用户按下Power键的时候,KBC检测到一个电平变化(一般时序是:高-低-高),然后发送一个开机信号(PWRBTN#)给南桥,南桥收到 PWRBTN#信号后依次拉高SLP_S5#,SLP_S4#,SLP_S3#信号,开启了所有的外围电压,主要是+3V,+5V以及DDR2.5V等, 并发送PM PWROK信号,这信号表明外围电源正常开启。
PM PWROK将作为一个使能信号发送到CPU外围VCCP的电压Generator,并开启VCCP。在此之后,VCCP Generator会发出CORE_VR_ON来开启CORE VR(即CPU的核心电压)。至此,整机的电压已经全部开启。
在用VR_PWRGD_ICH这个信号通知南桥CORE VR成功开启后,南桥会发出PCI RST#信号到PCI总线,于是总线上的设备都被初始化(包括北桥),并同时发出H_PWRGD来通知CPU它的核心电压已经成功开启。然后北桥发 H_CPURST#信号给CPU,CPU被RESET,并正式开始工作。
至此,PC开机过程的第一阶段全部完成(台式机,笔记本)。
我们跟随微机进入第二阶段。
第二阶段: BIOS引导
从这一阶段开始,我们就可以“看”到这一过程了(显卡开始工作之后)。在这一阶段,BIOS是绝对的主角!基本上一切都在它的控制之下。
可以说BIOS是一个很大的话题,不要说一篇文章,就是一本书,一门课程都不可能讲的很透彻!这里我主要是根据自己的理解,对BIOS在微机启动过程中的作用作一下梳理。
CPU Reset后就会通过北桥,南桥,寻找BIOS, 生成片选信号,开始读取资料,进行自检(POST, Power On Self Test).
为了便于理解,先给不熟悉BIOS的兄弟(当然还有姐妹:))们补补课(之前听到有人说BOIS,还有的称BOSS!)。BIOS的全称是Basic Input And Output System,中文名就是基本输入输出系统,从名称上我们不能获得更多的信息,它到底是硬件还是软件? 既然称为系统我怎么看不到?应该说BIOS是名符其实的软件(先别急着反驳,听我讲完),它本身是一段程序,只不过这段程序和我们平时接触的程序有一点不 同。它不像我们常见的程序那样工作于操作系统下,因为它本身就可以说是一个简单的小型操作系统(不好理解?就当我没说过上面的这段话,继续往下看)。这段 程序是固化在一块芯片当中的――这块芯片就是我们学说的BIOS芯片,而这块芯片又焊接在主板上。如果你细心找的话,在主板上你肯定能找到这块芯片(没有 BIOS的PC偶还么的见过)。而正是由于BIOS是固化在芯片中的才会导致某些人说BIOS是硬件。整理一下,应该说BIOS是软件,如果我们说 BIOS芯片(保存BIOS程序的那块芯片),那么它就是硬件(芯片当然是硬件拉)。
要想了解更多关于BIOS的信息,大家可以去 www.biosdiy.net ,从上面可以获得更多的资料,从基本的BIOS设置到怎么刷BIOS到替换BIOS的开机画面,应有尽有。
再说一下BIOS在微机中的基本作用:
1. POST(Power On Self Test,开机自检) CPU Reset后将从BIOS读取第一条指令,接下来BIOS会对CPU各项寄存器,先检查是否运行正常,接下来会检查8254 Timer(可编程计数器),8259A(可编程中断控制器),8237DMA Controller(DMA 控制器)的状态。
2. Initial――针对动态内存(DRAM),主板芯片组,显卡以及相关外围的寄存器做初始化设置,并检测是否能够工作。
所谓初始化设置,就是依照该芯片组的技术文件检定,做一些寄存器的填值,改位的动作,使得主板/芯片组和内存,I/O的功能得以正常运行。
3. 记录系统的设置值,并且存储在非挥发性内存(Non-Volatile RAM),像CMOS或Flash Memory(ESCD区域)等。
4.将常驻程序库(Runtime Program)常驻于某一段内存内,提供给操作系统或应用程序调用,像Int 10H, Int 13H, Int 15H之类的函数(这个功能在Windows系统下已经不存在了,在DOS下还会用到,就是我们常说的BIOS 中断)
继续讨论BIOS在开机过程中的作用,我们看下面的图:
好了,今天就写这么多,以后有空再写。。。。。。
Go on
当CPU Reset后,根据X86架构的特性,(386以后)CPU会从4G地址的最顶端FFFFFFF0处获得第一条指令来执行,而这一地址被定位在BIOS 里。由于FFFFFFF0到FFFFFFFF只有短短的16字节,根本不可能放下一段程序,所以这里会放一条跳转(Jump)指令让BIOS跳到更低的地 址去执行。而这个地址就是上图的Boot Block模块的入口地址。这个Boot Block(启动模块)是IBM PC遗留下来的规范,基本上每一个BIOS厂家都会有这么一个Boot Block。它的作用就是完成BIOS的最初引导(比如说测试很小的一块内存来供临时使用),如果你对BIOS DIY比较熟的话,它的另一项功能你可能会比较熟悉,就是当刷BIOS由于不慎导致失败的时候,我们可以通过Boot Block的拯救功能来救回BIOS,一般是在软驱里放入两个文件,一个是特殊的刷BIOS工具另一个是BIOS文件。然后用这个软驱启动,如果Boot Block模块没有损坏的话,用这个方法可以救活BIOS.
Boot Block完成引导后就会解压缩出Runtime模块,到这里可能你会问,什么是解压缩Runtime模块?莫非BIOS里还藏有 Winrar,winzip这样的程序,答案当然是否定的。用到解压缩功能完全是因为BIOS可以利用的地址空间太小了,而随着芯片组功能和外设功能的增 强,BIOS里还要加入起来越多的功能,为了解决地址空间不足的问题,BIOS就引入了压缩模块的方法,将一些固定功能的BIOS模块通过压缩算法压缩, 挤出一些空间来让更多的扩展功能使用。当然,这些压缩算法肯定没有Winrar等压缩软件那么复杂了,否则光是压缩算法就占据了大部分空间,还不如不引入 压缩功能来的划算。到这里还有一个问题,就是有人可能要问,之前不是讲过BIOS刚开始执行就会进行POST吗?怎么前面还会解压Runtime模块?这 是因为在POST过程中要用到中断调用等功能,而这些功能是由Runtime模块提供的。
Runtime模块解压后就会解压POST模块,可以看到连POST也被压缩了,可见BIOS空间是多么宝贵!在POST过程中如果用户有按键(比如常见 的DEL键)想进行BIOS设定,那么BIOS会解压出BIOS SetUp模块,来提供BIOS设定界面并保存用户设定结果。在POST过程中BIOS还会进行芯片组,内存,显卡,外设等的初始化工作。
上面的只是一个初略的BIOS执行流程,BIOS实际执行的过程要比上面说的复杂的多。并且不同的厂商会在BIOS里加入许多特定的功能(比如一键杀毒,还原等),这更会增加BIOS的复杂度!
造成BIOS过于复杂的另一原因是BIOS开发主要是用一般人不熟悉的汇编语言。面对复杂的BIOS,不要说普通的用户,就连BIOS开发人员有时都会被 搞焦头烂额。还好,Intel终于开发出了EFI(Extended Firmware Interface,扩展固件接口)准备用来取代BIOS。EFI用流行的C语言开发,可以做出比较好的图形界面,使用起来更加直观。EFI还加入了一些 比较实用的功能,比如说可以不进系统,在EFI里就可以进行文件操作,在EFI里使用网络功能等。有兴趣的可以在网上找一下EFI的相关资料,毕竟EFI 离我们也不太远了,之前Microsoft承诺会在Windows Vista里启用EFI的支持,可后来又跳票了,最近MS又表示2007年会启用EFI支持,MS是否会再忽悠我们一把,我们只有到2007年再下结论 了。
至此,PC开机过程的第二阶段完成。
第三阶段: 操作系统引导
BIOS自检过程中,如果没有错误,接下来就会进行操作系统引导。
BIOS会根据CMOS里记录的启动顺序一个个地来尝试加载启动代码。具体的过程是BIOS将磁盘的第一扇区(磁盘最开始的512字节)载入内存,放在 0X0000:0X7C00处,然后检查这个扇区的最后两个字节是不是“55AA”,如果是则认为这是一个有效的启动扇区,如果不是就会尝试下一个启动介 质,如果找到可以启动的程序就会从这一介质启动,如果所有的启动介质都判断过后仍然没有找到可启动的程序那么BIOS会给出错误提示。
第一个原因只会“吃掉”您一小部分的内存
众所周知,电脑中二进制中的换算关系是 1GB=1024MB,实际生产时,硬件厂商厂商的换算单位是1GB=1000MB,当电脑厂商告诉您,您电脑中的内存是1GB的时候,其实您的内存是1000MB,系统识别时,用1000处以1024,也就显示您的内存是0.976GB,同理您安装了4G的内存,系统会显示您的内存是3.9GB。这并不是硬件厂商欺骗您。
第二个原因可能会“吃掉”您数量可观的一部分内存
内存(RAM,也就是您的系统的寻址总空间)=内存条(物理内存,您的内存条是4GB的)+bios内存+缓存+显存+...,,32位的电脑的寻址空间是2的32次方,也就是4G,系统将这4GB的地址分配给内存条,缓存,显存,硬件等。
系统分配寻址空间时是有优先级的, bios的内存,cpu的缓存,各个硬件的内存,显卡的显存等,他们的优先级比物理内存(也就是内存条)高,所以系统先将寻址空间分配给bios的内存,cpu的缓存,各个硬件的内存,显卡的显存,最后才将剩余的寻址空间分配给内存条。比如您的显卡有500MB,那么可以分配的内存也就只剩下4GB-0.5GB=3.5GB了。
相当于一条街上有1000户居民,但是门牌号码确实只有800个,于是还有200户居民没能获得门牌号码,但是这200户居民并未消失。
如果在32位电脑上装上4G内存条依照优先级关系,你只能使用3G多的的内存条空间,因为前面的几百MB空间是给了各个硬件(包括显存),4GB的内存条只有其中的3.31GB获得了寻址空间,此时您只可以看到获得了寻址空间的那一部分内存条(见下图.)
如果是2G的内存条,因为电脑本身寻址能里是4G,前面几百MB给了硬件,依旧剩余3G多的寻址空间, 2G的内存条可以完全获得2G的寻址空间,您也就能看到2G的内存条了
(见下图)
当 按下电源键,主板的电源系统供电,南桥启动,北桥启动,复位CPU的reset针脚(具体叫什么,到不知道了),执行已经设置好的地址上的程序。一般到最 后地址的后十六个字节的起始地址,8086为ffff:fff0即ffff0H,即使现在的Intel CPU也会到最的地址空间FFFFFFF0处执行,因为这时就剩余16个字节可以放数据,同时又放不下什么程序,一般在此处放一条跳转指令。
看看8086/8088芯片24根地址线1M地址空间的分配情况,如下图
看现在的Intel的官方手册可以查到,在页面http://www.intel.com/support/cn/mt/mt_win.htm 上
Intel® 64 and IA-32 Architectures Software Developer’s Manual Volume 3A, System Programming Guide, Part 1 [PDF]
的第9章 Chapter 9 Processor Management and Initialization。
以后盛行20多年的bios可能就要退出历史的舞台了,接下来就是UEFI粉墨登场了,现在都2.1b版本了,要看的还真是不少。以后等看了再说。先记录到这吧。
【Flexibility in ROM: A Stackable Open Source BIOS】
LinuxBIOS首先要做的是建立和初始化内存,建立串口控制台(因为BIOS经常会有一些错误信息,需要将这些信息输出、以便调试使用)。接着,BIOS可以执行C代码,从这一刻起,LinuxBIOS便能建立CPU上的MTRRs(Memory Type Range Registers),从而使能CPU的cache、并因此而提升运行速度。然后,其负责建立IRQ路由表、初始化主板上的单个硬件(包括IDE控制器、键盘、南桥等)。其他的初始化工作便交给了Linux做。(这是因为,Linux和BIOS会做一些重复性的工作)
初始化工作完成之后,LinuxBIOS便巡检各个ROM的内容、以发现启动过程的下一个阶段工作。BIOS还有有一些其他功能模块,比如,流行的做法是加载Etherboot、操作系统自身等。
ADLO负责却行bochs和vga的BIOS在ROM指定位置,并且将bochs的bios信息拷贝进入“shadow ram”。另外,adlo将memory map和IRQ路由表转换为特定格式工bochs使用。最后,还负责将模拟的cmos数据传递给bochs使用。
Bochs bios的主要职责是建立中断向量表,并提供BIOS服务的入口点。该表共包含256个,每项4bytes。
![BIOS 工作流程解析_第10张图片](http://img.e-com-net.com/image/info8/be5f78b1ce9c47dfae9e38c715fc320e.jpg)
LinuxBIOS的工作过程主要包括以下五步:
Protected mode setup:
1. 在16bit模式下执行0xffff0的跳转指令,jump至bios执行;这是一个x86处理器重置的标准部分;
2. 下面5条指令:关中断、清空TLB、设置代码和数据段寄存器至已知数值;
3. 下面1条指令:加载gdt表指针,(此时的gdt表位于nvram内)gdt是在段模式下负责地址管理的;
4. 下面五条指令:设置剩余的段寄存器以适应保护模式;
5. 下面17条指令:已经位于保护模式,可以解析4G内存。
DRAM setup:Dram需要一些不同层次的配置;
Transition to C:建立栈,然后调用函数以进行后续硬件修正;
Mainboard fixup:对部分必要的加载内核有关的硬件进行初始化:包括a开启caching(建立MTRR寄存器)以加快解压kernel的速度;b使能CPU能使用所有的flash内存,这主要是操纵寄存器;c使能电力设备管理硬件;d对完全未初始化且Linux无法操纵的PCI总线进行初始化;e设置基地址寄存器至合理值,以便后续Linux使用,比如建立中断、关闭ROM选项;f重置键盘至特定状态;设置时钟中断
Inflate the kernel:由Linuxbios向Linux的参数需要拷贝至Linux kernel的标准位置;命令行业需要拷贝;为了能让Linux 解压程序在ROM环境中运行,需要做一些变化,包括将初始化的数组声明为const、以便将其将其放入只读段内,比如flash而非ram中;初始化的自动和全局变量也需要改正、以便在运行时已经初始化。
Jump to the kernel:这只是简单的jump指令,跳转至kernel的开始位置:startup_32函数。