cpubbs论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

LabVIEW+单片机学习套件全套教程资料下载[免费]LabVIEW论坛精华列表贴USB0816数据采集卡《LabVIEW宝典》
LabWindows/CVI论坛精华贴NET0816以太网数据采集卡RC0210远程设备授权系统 关闭关停锁定打开设备 户外分布式数据采集
NET1624低速高精度以太网数据采集卡WIFI0824SD无线WIFI网络数据采集卡脱机运行 SD存储 小尺寸微型 串口采集远程采集 安卓 手持移动采集 纪录仪
查看: 1622|回复: 0

如何编写PC机上的BIOS在线升级程序[转贴]

[复制链接]
发表于 2005-7-21 21:55:16 | 显示全部楼层 |阅读模式
<>对于一个PC DIY来讲,升级BIOS是一件很平常的事情,但是作为一个程序员来讲,或许你会有想,能不能自己编写一个BIOS在线升级程序呢,其实这个想法是很有用的,特别是在很多嵌入式设备领域中,如果没有BIOS在线升级程序,对于最终的用户和技术支持人员来讲,那只能将BIOS ROM片子从机器上拔下来,然后拿到烧片机上去烧写BIOS,这样不但是操作复杂,而且很多地方没有条件烧写。</P>
<>现代的PC机上的BIOS 一般都是使用的Flash ROM作为存储介质。Flash ROM可以支持电擦除,对于我们来讲是一种福音,可以直接使用程序来控制擦写了,再也不用像EPROM那样每次写入前,都要用紫外线擦除器花费20分钟左右的等待。Flash ROM被大规模用作BIOS主要的存储介质,为我们实现在线升级BIOS提供了必要的基础。</P>
<>下面我就从一个程序员的角度介绍一个如何实现x86平台上的在线升级BIOS。需要指出的是主要的硬件平台为386以上CPU,因为80386以下的机器配置基本上已经不多见了,故不再涉及。</P>
<P>首先,我们要对BIOS的硬件特性简单介绍一下:大家知道X86(386以上) CPU最大寻址空间是从0~4Gbyte,而BIOS的绝对物理地址是分配在地址空间的最高端,比如说BIOS ROM大小为256KB,那么BIOS ROM的绝对物理地址范围为:0xFFFC0000~0xFFFFFFFF。对此地址空间进行读写操作,实际上就是对BIOS的ROM进行操作。</P>
<P>我们知道,在DOS下或者Option Rom(即扩展BIOS)中,是无法存取640KB 以上的内存的,如何实现存取1MB以上的内存呢? 大家知道,BIOS代码其实绝大部分是在实模式下运行的,但是它是如何实现内存检测的呢?其实这里面就使用到了Big real mode,或者有些资料上讲的Flat Mode,其技术核心是可以在实模式下可以访问4GB范围中所有的内存,现在基本上所有的BIOS都利用其来检测内存大小,访问4GB范围中的内存。现代BIOS中,此方法已成了业界标准。其主要的实现思路是,切换到保护模式下,选择一个Data Select(DS,ES,FS,GS) ,把他的段极限从64KB(0xFFFF)加大到4GB(0xFFFFFFFF),同时索引地址设置为000000h,然后切换到实模式下,选择这个Segment,并且把它设置为0000h,再利用一个32bit的寄存器做偏移量来寻址,即可以访问所有的4GB范围所有的内存了。</P>
<P>另外需要了解的所用机器的南桥(South Bridge)芯片的资料,南桥芯片主要负责SuperIO,外设等配置,相对应的北桥芯片主要负责内存和AGP总线接口的配置。一般的Flash ROM芯片有写保护功能,在进行擦除和读写之前需要打开写保护,这就需要查阅相关的南桥芯片手册,以常见的VIA的VT82C686B南桥芯片为例:</P>
<P>PCI Function 0,index = 0x40, 其中,bit0 = 1,表示ROM Write Enable,为0则不可写。如果要实现在线升级BIOS则需要将此位设置为1,否则擦写操作会失败。相关的需要了解下PCI配置的知识,基本上PCI总线知识对于一个需要做底层的程序员来讲是条脊梁,掌握了它相当于抓住了整个系统的脊梁,特别是BIOS中对外设的配置,基本上都是对PCI寄存器的配置,如果立志想做系统底层的人,就需要熟练掌握PCI总线的读写和配置。我这里仅仅简单介绍一下PCI总线的知识,详细的资料请自行参考相关资料。PCI总线上有两组寄存器,0xCF8~0xCFB为配置地址寄存器,0xCFC~0xCFF为配置数据寄存器,对PCI的操作主要通过这两组寄存器来实现的,需要注意的是,这些端口都是四字节读写的,单字节或者双字节将被忽略。</P>
<P>
设置ROM Write Enable为1,然后进入Flat Mode,就已经为BIOS在线升级设置了必要的基础,接下来就可以对Flash ROM进行读写操作了。</P>
<P>
当然不同的芯片相关的读写命令和时序都有一定的差距,这就需要查阅相关的芯片厂商提供的芯片手册了,在此,我仅仅以最常见的SST39SF020为例,简单介绍一下其基本的操作过程。</P>
<P>
SST39SF020是一种常见的256KB的Flash ROM,其工作电压为5V, 其厂商ID为0xBF,设备ID为:0xB6,每扇区大小为4Kbytes。其基本操作命令如下:</P>
<P>
下面以读取Flash ROM ID为例,简单的描述一下过程,设FlashRomAddrBase为Flash ROM的基地址,则</P>
<P>void GetDeviceID(BYTE* ManufacturerID,BYTE* DeviceID)</P>
<P>{</P>
<P>// 发出读设备ID指令0x90</P>
<P>FlashRomAddrBase[0x5555] = 0xAA;</P>
<P>FlashRomAddrBase[0x2AAA] = 0x55;</P>
<P>FlashRomAddrBase[0x5555] = 0x90;</P>
<P>//读厂商ID和设备ID</P>
<P>*ManufacturerID = FlashRomAddrBase[0];</P>
<P>*DeviceID = FlashRomAddrBase[1];</P>
<P>//退出读设备ID</P>
<P>FlashRomAddrBase[0x0000] = 0xF0;</P>
<P>}</P>
<P>其他操作可以依此类推。需要指出的是:这种芯片支持两种擦写方式,建议使用整块擦除指令,不但可以节省代码,还可以节省时间。根据手册可以看出,整片擦写需要70ms,而每扇区擦除需要18ms,256KByte有256/4=64个扇区,64*18 = 1024ms,远远大于70ms.</P>
<P>
至此,BIOS升级的基本知识我们都已经掌握了,下面描述一下升级的过程,首先设置进入Flat Mode,关闭CPU读写Cache,然后读出Flash ROM的厂商ID和设备ID,然后根据Flash ROM ID来判断芯片有多少扇区或者块,然后擦除整个芯片,校验是否擦除成功,如果擦除成功则继续,否则报错,退出。然后将数据按照扇区或者块写入到Flash ROM中,同时写完后需要做数据校验,一切都通过后,则OK。</P>
<P>
到目前为止,我们已经实现了简单的BIOS在线升级的,但是BIOS在线升级远没有这么简单,需要考虑的东西还有很多东西,例如,BOOTBLOCK是否被锁住(不可擦写),如何实现只升级BOOTBLOCK外的部分,同时很多BIOS升级是锁定640KB以下的一个64KB的窗口例如E000:0 ~ F000:0,然后将整个Flash ROM 依次映射到这个窗口上,进行读写操作等,同时有些系统还需要考虑关闭USB Host Controller等,避免升级失败等。如果能够从网络上下载BIOS文件,则完全可以实现远程升级BIOS。我们已经将其实现了在”升腾”系列window终端中,在实际应用中得到了取得了很好的效果。</P>
<P>
需要说明的BIOS升级是个危险的过程,升级的过程中不能断电,如果万一发生了意外,那只好拿到烧片机上重新烧写了,否则机器是无法正常启动。所以,在做试验之前一定要把原来的BIOS ROM的内容先保存下来,防止后来发生意外。</P>
<P>
BIOS升级的过程看似复杂,只要理解了相关的原理后,并掌握了其涉及的其他知识,其实也不是一件难事。掌握了此技术,相信对于每一个程序员来讲的,都是一次水平极大的提高和飞跃,同时以此打好基础,对相关的系统了解更多的知识,以后配置任何硬件设备,相信都是得心应手,游刃有余。如果此文能够对提高中国程序员的水平有所帮助,也不枉我写此文的初衷。
</P>
您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|手机版|cpubbs论坛. ( 粤ICP备09171248号 )

GMT+8, 2025-5-4 12:49 , Processed in 1.715965 second(s), 7 queries , Gzip On, File On.

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表