用C语言开发BIOS程序的实现方法

1 BIOS开发语言分析

1. 1 汇编语言与C语言比较

传统BIOS程序的开发一般以汇编语言作为开发工具. 它的优点是:代码精简,时间效率与空间效率高,比较适合于BIOS程序开发. 缺点是:源程序代码冗长,使用大量标号,定义与区分工作量大,容易混淆,寄存器使用容易冲突,模块化设计功能差,软件的开发周期长.

C语言具备如下优点:模块化的设计语言易于实现算法,缩短软件的开发周期,提高软件的开发质量,便于维护、升级,易于实现图形化用户界面,实现仿真Windows界面操作,比较适合于系统软件的开发. 其缺点是:对于Intel架构的C编译器,Borland C + +,代码的运行必须有操作系统的支持,因此,很难应用于BIOS程序开发.

目前,专门用于单片机及嵌入式系统开发的C语言已经成熟,然而还没有专门用于微机系统BIOS程序开发的C语言,使得BIOS程序的开发仍停留在使用汇编语言阶段.

然而, C语言产生的代码十分精炼,非常接近于汇编语言,如能脱离对操作系统的依赖,并与嵌入式汇编结合,更适合快速的BIOS开发. 我们通过对Borland C + +产生代码进行分析找出了解决方案.

1. 2 C语言编译代码分析

Borland C + +大部分函数使用了操作系统的功能调用,BIOS程序往往运行于操作系统装入之前,此时是无法调用操作系统功能的. 因此,一般情况下,C语言编写的程序代码是不能脱离开操作系统支持而运行的.

BIOS程序一般都固化在ROM器件中. 由于器件容量小的限制,要求BIOS程序的代码要尽可能地短,而用C语言设计的程序最短也要几KB. : Borland C + +空语句main ( ) { }在微模式下编译链接后产生的代码长度为4KB.

程序中一条有用的语句都没有,为什么会产生出4KB的代码呢? 我们经过分析发现,在编译系统的lib目录下有多个扩展名为. obj的文件. 其中c0 t. obj的机器码与空C程序产生的目标代码几乎一致,只是空C程序产生的可执行程序代码比c0 t. obj多了几条语句:

push bp

mov bp, sp

pop bp

ret

由此看来,任何C程序中都将包含lib目录下对应编译模式启动代码文件的代码. 其中c0 t.obj为微模式的启动代码. 只要将启动代码替换成适合BIOS程序设计的自编启动代码,我们称之为“BIOS启动代码”,即可实现用C语言进行BIOS程序的开发.

2 用C语言实现BIOS编程

2. 1 创建BIOS启动代码汇编源文件

扩展BIOS程序量一般在几十KB左右,可选用微模式来进行设计. 其好处在于,微模式无堆栈段,可直接使用EXE2B IN. EXE. EXE类型的文件转换为. COM类型. . COM类型的文件无文件头PSP (程序段前缀) ,因此,便于作为固件进行固化. 本题目的BIOS相关程序设计过程均采用了微模式.

为了降低代码长度,本文用自己设计的简短BIOS启动代码模块替换了Borland C + +的原有启动代码模块. 方法为:c: \borlandc \ lib \ startup目录下原启动代码汇编原文件c0. asm更名为c0. bak,重新建立扩展BIOS启动代码汇编源文件c0. asm.

为了使BIOS启动代码适合于ISAPC I兼容的扩展BIOS设计,必须按PC I标准给出相应的PCI配置数据. 例如,PCI网卡为载体的扩展BIOS需在BIOS 代码中包含网卡的类别号(020000H) 、扩展BIOS大小及PC I指针. 以下为扩展BIOS启动代码汇编源程序:

; c0. asm

; startup code for ISA & PCI Extended BIOS.

  Locals

;定义调用的C程序主函数为外部类型

extrn main: near

code seg segment byte public ’code’

  assume cs: code_seg, ds: code_seg

  org 0

start p roc p roc far

;扩展BIOS有效标志

  db 055h, 0aah

;累加和范围: ? =ROM器件容量/512

sum range db ?

jmp begin

  org 8

;扩展卡标识

  db ’PCI EXTANDED BIOS’

  org 18h

; PC I数据配置指针

  dw offset pcir

pcir  db ’PCIR’; PC I数据配置

venderid  dw 0000h; PCI厂商ID

deviceid  dw ?;用户自定设备ID

data pointer dw 0000h;产品数据指针

pci data len dw 0018h; PC I数据长度

pci version  db 00h ; PCI版本号

;扩展卡类别为网卡

class  db 00h, 00h, 02h

map len  dw 0040h; BIOS代码长度

code ver  dw 0000h;代码数据版本

code type  db 00h;代码类型

indicator  db 80h;指示器

reserved  dw 0000h;保留字

;调用C程序主函数main ( )

begin:   call main

;返回BIOS调用程序

  retf

;累加和凑0单元,应根据计算给出该值:

; ? = 0 – 所有字节之对256求余

check sum  db ?

start p roc  endp

code seg  ends

  end start p roc

2. 2 生成BIOS启动代码目标文件

c: \ borlandc \ lib \ startup 目录中有一个文件build2c0. bat,它是用来生成启动代码obj文件的,使用方法:

build2c0 libtype [ srcdir [ objdir ] ]

其中: libtype可取clib (DOS)winlib (Windows) , srcdir为原文件目录(默认“. ) , objdir为产生的obj文件目录(默认“. ).

首先将c: \borlandc \ lib目录下原有3 . obj文件更名为3 . bak,再运行如下可产生DOSstartup模块的命令:

build – c0clib c: \borlandc \ lib \ startup c: \borlandc \lib

这样便产生了适合BIOS编程的启动模块,我们称之为BIOS启动模块. 此后,即可在Borland

C + +IDE环境下用C语言编写BIOS程序了

此条目发表在程序设计分类目录,贴了, 标签。将固定链接加入收藏夹。