安全使用基本输入输出系统服务的系统和方法

文档序号:6546076阅读:274来源:国知局
专利名称:安全使用基本输入输出系统服务的系统和方法
技术领域
本发明涉及安全使用基本输入输出系统(BIOS)报务的系统和方法。
背景技术
在虚拟存储器子系统中,采用“虚拟”存储器寻址方法,在该方法中,软件程序中利用的存储器地址间接映射到物理存储器的存储单元上。翻译成物理地址一般由处理器完成,这种物理地址不能访问用户模式软件和基本输入/输出系统(BIOS)。
这种虚拟存储器子系统的一个例子是由Windows NT使用、由微软公司生产和销售的子系统。尤其是,Windows NT包含了请求分页式虚拟存储器子系统。为在Windows NT操作系统上运行的程序所提供的存储器地址空间被保护以防止其他用户模式程序,正如其他程序也受到保护一样。这保证了用户模式服务程序和应用程序不覆盖彼此的存储器或者执行彼此的指令。核心模式服务程序和应用程序以类似的方式受到保护。如果出现试图访问程序指定的虚拟空间之外的存储器的情况,则终止程序并通知用户。虚拟存储器子系统还防止以用户模式软件直接访问物理存储器地址和作为计算机一部分的输入/输出设备。
目前的趋势日益朝着使用能用虚拟存储器子系统执行操作系统的计算机系统上的输入/输出设备方向发展。在这些系统中,没有访问程序虚拟存储空间之外的存储器的装置,例如BIOS功能。解决这种问题的一个方法是为设备安装读包含指令的文件的设备驱动程序。驱动程序读出文件并将这些指令写(或下载)到设备存储器中。但是,这种类型的设备驱动程序仅具有存储器和输入/输出操作的有限寻址能力。此外,它不允许执行物理存储空间中的系统处理器指令。
因此,在技术上需要一种通过虚拟存储器子系统访问和执行物理存储器内容的系统和方法,以便于提高存储器和输入/输出操作的寻址能力和允许直接通过物理存储器执行处理器指令。
而且,能更新或配置存储在计算机系统或平台上的数据。在特定情况下,数据是十分敏感的。可配置的敏感数据(sensitive data)的一个好例子是计算机系统的基本输入输出系统(BIOS)。通常存储在某种非易失性存储器中,BIOS是机器代码,通常是操作系统(OS)的一部分,它使中央处理单元(CPU)能完成各种任务,例如初始化、诊断、从大容量存储器装载操作系统核心和常规输入/输出(“I/O”)功能。一旦加电,CPU通过取驻留在BIOS中的指令代码“引导”。在没有任何安全保护的情况下,BIOS容易通过捕获和重现服务请求调用BIOS提供的函数。
因此,还需要提供一种系统和方法来校验访问或修改BIOS中数据的服务请求的安全性以及实施那些远程请求消息的正确权限。

发明内容
本发明提供了一种安全利用基本输入输出系统(BIOS)服务的系统和方法。
根据本发明的一个方面,系统包括存储指令序列的存储器,通过指令序列处理基于处理器的系统,其中存储器包括物理存储器和虚拟存储器。系统还包括执行所存储的指令序列的处理器。存储的指令序列包括的过程使处理器将多个预定指令从物理存储器映射到虚拟存储器中,确定对虚拟存储器中多个预定指令序列之一的补偿,接收指令执行多个预定指令序列其中之一,将控制传送到多个预定指令序列其中之一,以及处理来自虚拟存储器的多个预定指令序列其中之一。
系统的另一个方面包括访问驱动程序产生使用BIOS服务的服务请求,使得服务请求包含用密钥对中的密钥建立的服务请求签名。系统还包括校验使用密钥对中的公开密钥的服务请求签名的接口以保证服务请求的安全性。


图1是信息分配系统的一个实施例的系统方框图,其中使用了本发明的方法。
图2示出了实现本发明实施例的一个示范性处理器系统或用户计算机系统。
图3示出了图2计算机系统的一个实施例图,其中使用了本发明的系统和方法。
图4示出了利用本发明系统和方法的操作系统结构的全功能框图。
图5是方框图,示出了根据本发明原理提供的访问驱动程序46初始化过程。
图6A示出了本发明初始化过程的一个实施例的流程图。
图6B示出了图6A的过程块610的详细流程图。
图6C示出了图6A的过程块630的详细流程图。
图7A示出了本发明执行过程的流程图。
图7B示出了图7A的过程块640的详细流程图。
图8示出了利用本发明系统和方法的操作系统结构的另一个全功能框图。
图9示出了根据本发明一个实施例的两个系统组件之间的交互序列的序列。
图10略述了根据本发明一个实施例的会话请求的产生。
图11示出了根据本发明一个实施例的权限证明。
图12示出了根据本发明一个实施例的会话请求。
图13示出了根据本发明一个实施例的服务请求。
图14略述了根据本发明一个实施例请求建立工作会话的条款(acts)。
图15略述了根据本发明一个实施例的服务请求的产生。
图16示出了根据本发明一个实施例处理服务请求中所需的条款。
图17示出了根据本发明一个实施例涉及终止当前工作会话的条款。
图18示出了根据本发明实施例产生权限证明的过程。
具体实施例方式
定义正如本文所讨论的,“计算机系统”是一个包括能处理数据的电路的产品。计算机系统可以包括但不限于以下产品通用计算机系统(例如服务器、便携式电脑、台式电脑、掌上电脑、个人电子设备等)、个人计算机(PC)、硬拷贝设备(例如打印机、绘图仪、传真机等)、银行设备(例如自动取款机)以及类似产品。信息介质是提供代表货物和服务的生产商信息的WEB站点,为供应者和其他商业所提供的产品和/或服务交易提供相应的信息。内容指应用程序、驱动程序、实用程序、文件、有效负载等以及其中一些的组合,也指图形、信息材料(文章、股票报价(stock quotes)等)以及类似物,既可以是单一的也可以是任何一种组合。另外,“通信链接”指通信的媒体或通道。通信链接可以包括、但不限于电话线、调制解调器连接、Internet连接、综合业务数字网(ISDN)连接、异步转移模式(ATM)连接、帧中断连接、以太网连接、同轴连接、光纤连接、卫星连接(例如数字卫星服务等)、无线连接、无线电频率(RF)链接、电动链接、双向传呼连接等,以及这些连接的组合。加电自检(POST)指在装入OS前执行配置和检测系统硬件的指令。
系统综述下面描述的是对结合本发明实施例的示例性系统的说明。
图1示出了信息分配系统10的一个实施例的系统方框图,其中使用了本发明的设备和方法。系统10涉及提供信息介质。它包括安全的构建和维护、Internet用户的私人知识库以及系统性状,主要通过保证书服务注册、Internet服务注册,系统性状以及用户选择来收集。最初,该信息被用来由所购硬件和软件产品的制造商、以及在线或其它服务的提供者对用户进行注册。随着时间的推移,利用用户数据建立用户性状或通知用户有关软件的更新和升级,从而鼓励在线购买相关产品以及使一对一交易和其它服务成为可能。
在一个实施例中,使用两个软件模块实现本发明的不同实施例。一个常驻用户系统,用来访问预定WEB站点。例如,在一个实施例中,操作系统及基本输入输出系统(BIOS)预装在计算机系统内,当计算机系统随后被首次加电时,为便于讨论,将应用程序称为第一软件模块(在一个实施例中,第一软件模块为初始启动应用程序(ISUA),这将在以下加以讨论),该应用程序允许在预引导环境下启动一个或多个可执行程序。在一个实施例中,第一软件模块便于在OS装入、引导、执行和/或运行之前启动一个或多个可执行程序。在一个实施例中,鼓励用户选择使用这样的程序(例如使用第一软件模块),在另一个实施例中,自动启动该程序。包含在第一软件模块中的程序可作为在适当时间运行的工具和效用,通过正确的用户授权,也允许用户通过连接到PC上的Internet下载包括驱动程序、应用程序以及附加文件或有效负载的第二软件模块。如果OS不能成功启动,这些程序也可用来提供系统的遥控管理。
一旦第二软件模块被发送,它就变成存储驻留,并不能传送第一软件模块的拷贝。在第二软件模块不能运行并变得不可靠或被删除前,一旦最初的第一软件模块如上所述被再次传送,仍驻留在系统非易失性存储器中的第一软件模块的原始拷贝保持空闲。第二软件模块可包括将用户连接到Internet上的特殊服务器的应用程序,以及指导用户至预定WEB站点查找授权以下载更多的预约材料。第二软件模块也可以包括与第一软件模块内容相同或机似的内容。
在一个实施例中,系统也可以包括存储在只读存储器BIOS(ROM BIOS)中的初始有效负载。在一个实施例中,初始有效负载是第一软件模(例如ISUA)的一部分。在另一个实施例中,初始有效负载作为模块存储在ROM BIOS中,且与第一软件模块分开。在一个实施例中,在加电自检(POST)之后但在引导、装入和/或执行OS之前,从ROM BIOS启动初始有效负载并在屏幕上显示出来。这可以发生在预定时间内,例如当建立、装配和检测系统时,或当最终用户首次激活系统时。在另一个实施例中,该初始有效负载在预定时间内被复制至预定位置(例如系统的硬盘上),例如当建立、装配和检测系统时,或当最终用户首次激活系统时。一旦被复制,在POST后但OS运行前执行有效负载,并在屏幕上显示图形、广告、动画、联合照相专家组(JPEG)/活动图像专家组(MPEG)格式的材料。当发送附加程序和/或有效负载时(通过Internet或其它的外部连接),在OS引导前以及引导期间可用显示屏幕以消息或图形的形式来提供可定制屏幕。此外,可利用在第一软件模块中发送的可执行程序以及从Web站点下载的后续程序(例如第二软件模块)来测量PC以确定安装的不同类型的设备、驱动程序及应用程序。在一个实施例中,本文结合题为“用于计算机上自动安装及配置软件的方法及设备”的未决的申请序列号为__的美国专利进行描述,利用第一软件模块识别及为用户自动产生快捷方式和/或书签。从Web站点下载的程序可包括收集和维护基于用户选择的用户性状的软件。这些信息可提供给信息介质,随后将部分信息和/或基于该信息的已编译数据给供应者和其它商业以获得供应者和其它商业所提供的信息升级或修订。
参考图1,信息分配系统10包括将一个或多个通信链接301-30N连接到一个或多个用户计算机系统401-40N(“40”)的服务中心20。该服务中心20包括一个或多个服务器22、一个或多个数据库24以及一个或多个计算机261-26M。多个用户计算机系统401-40N能同时访问一个或多个计算机261-26M。如果使用多个计算机,则可通过局域网(LAN)或其它类似的连接技术连接计算机261-26M。然而,服务中心20也可能有其他配置。例如,具有许多运行在大型计算机上的内部程序或过程的更少量的大型计算机(即少数大型机、小型计算机等计算机)能够与用户计算机建立通信链接。
服务中心20也可以连接到远程网络50(例如Internet)或远程站点(例如图1中未示出的卫星)。远程网络50或远程站点允许服务中心20提供更多种类的可存储在服务中心20上的计算机软件、内容等。可使用连接到服务中心计算机(例如计算机26)上的一个或多个数据库24将由计算机软件组成的数据库入口存储在计算机26上。在一个实施例中,每个用户计算机系统401-40N具有使其他计算机无法访问的自身的安全数据库(未示出)。通信链接301-30N允许一个或多个用户计算机系统401-40N同时与计算机261-26M相连接。该连接由服务器22控制。
在用户计算机系统40与信息服务计算机26建立双向通信后,以下文所述的方式将内容发送到用户计算机系统40中。下载的内容包括测量用户和/或用户计算机系统的硬件和/或软件以开发用户性状及用户系统性状的应用程序。随后将从用户和/或用户计算机系统中收集的信息提供给服务中心20,服务中心20将附加内容提供给基于用户及系统性状的用户计算机40。从连接到服务计算机26上的数据库的数据库入口包含关于计算机软件、硬件以及用户可用的第三方服务及产品的信息。基于用户和/或系统性状,该内容进一步被发送至用户计算机上显示。该内容也可以包括诸如对现有计算机软件、现有计算机软件的新版本、商标新的计算机软件、新的帮助文件等修订和纠错的信息摘要。该内容还可包括有关用户感兴趣的硬件及第三方产器和服务的信息。然后用户能够从可得到的产品和服务的摘要中进行一个或多个选择,并请求将产品从服务计算机26上传送到用户计算机上。用户也可以选择从可得到的产品和服务的摘要中购买所需的产品或服务。
图2示出了实现本发明实施例的示例性计算机系统100。尽管其它的实施例可能易于使用,但该计算机系统100示出了用户计算机系统401-40N和/或计算机261-26M的一个实施例(图1)。
参考图2,计算机系统100包括处理器或中央处理器(CPU)104。示出的CPU104包括用于执行计算算术逻辑部件(ALU)、收集用于暂时存储数据和指令的寄存器以及控制系统100运行的控制器。在一个实施例中,CPU104包括由IntelTM公司销售的任何一种X86、PentiumTM、PentiumLITM以及Pentium ProTM微处理器,由AMDTM公司销售的K-6微处理器或CyrixTM公司销售的6X86MX微处理器。其他还包括由数字设备公司TM销售的AlphaTM处理器、MotorolaTM销售的680X0处理器或IBMTM销售的Power PCTM处理器。此外,还包括任何一种其它的处理器,包括那些来自于Microsystems、MIPS、IBM、Motorola、NEC、Cyrix、AMD、Nexgen及其它公司的可执行CPU104的处理器。CPU104不限于微处理器,还可以是诸如微控制器、数字信号处理器、精简指令集计算机(RIS)、应用专用集成电路及类似的形式。尽管示出的只有一个CPU104,但计算机系统100可以有多个处理装置。
CPU104通过CPU总线108与总路控制器112相连。总线控制器112包括集成在其中的存储控制器116,而存储控制器116在总线控制器112的外部。存储控制器116设有CPU104或其它设备通过存储器总线120访问系统存储器124的接口。在一个实施例中,系统存储器124包括同步动态随机存取存储器(SDRAM)。系统存储器124可随意包括任何附加或可选择的高速存储设备或存储电路。总线控制器112与系统总线128相连,该系统总线可以是外围部件互连(PCI)总线、工业标准结构(ISA)总线等。与系统总线128相连的是图形控制器、图形引擎或视频控制器132、大容量存储器152、通信接口设备156、一个或多个输入/输出(I/O)设备1681-168N以及扩展总线控制器172。视频控制器132与视频存储器136(例如8兆字节)和视频BIOS140相连,所有这些都可以集成到一块卡或设备上,如数字144所示。视频存储器136用于包含在显示屏幕148上显示信息的显示数据,视频BIOS140包括控制视频控制器132的编码和视频服务。在另一个实施例中,视频控制器132通过加速图形端口(AGP)总线连接到CPU104上。
大容量存储器152包括(但不限于)硬盘、软盘、CD-ROM、DVD-ROM、磁带、高密度软盘、大容量可移动介质、低容量可移动介质、固态存储设备等,及其组合。大容量存储器152可以包括任何其他大容量存储介质。通信接口设备156包括网卡、调制解调器接口等,以通过通信链路160访问网络164。I/O设备1681-168N包括键盘、鼠标、声频/语音卡、打印机和类似设备。I/O设备1681-168N可以是盘驱动器,例如光盘驱动器、数字磁盘驱动器、磁带驱动器、zip驱动器、jazz驱动器、大容量可移动介质驱动器、低容量介质设备,和/或它们的任意组合。扩展总线控制器172与非易失性存储器175连接,非易失性存储器175包括系统固件176。系统固件176包括系统BIOS82,用于控制在其他物品中计算机系统100中的硬件设备。系统固件176还包括ROM180和快速(或EEPROM)184。扩展总线控制器172还与具有RAM、ROM和/或快速存储器(未示出)的扩展存储器188a连接。此外系统100可以包括与总线控制器112连接的存储器模块190。在一个实施例中,存储器模块190包括ROM192和快速(或EEPROM)194。
正如本领域技术人员所熟悉的,计算机系统100还包括操作系统(OS)和至少一个应用程序,在一个实施例中,在POST之后从大容量存储器152将所述操作系统和应用程序装入系统存储器124中并启动它们。OS可以包括任何类型的OS,包括但不限制于或局限于DOS、WindowTM(例如Window95TM,Window98TM,WindowNTTM),Unix、Linux、OS/2、OS/9、Xenix等。操作系统是一组控制计算机系统操作和资源分配的一个或多个程序。应用程序是一组执行用户所期望的任务的一个或多个软件程序。
根据计算机编程领域技术人员的实践,下面参考用符号表示的操作来描述本发明,除非特别指出,否则这些操作都是由计算机系统100执行的。这种操作有时称为计算机执行的操作。应当理解,用符号表示的这些操作包括通过CPU104操作表示数据位的电信号的和将数据位保持在系统存储器124中的存储单元中,其他信号的处理也一样。保持数据位的存储单元是物理单元,这些物理单元具有与数据位相对应的特殊的电、磁、光或有机特性。
当以软件实现时,本发明的部件实质上是执行所需任务的代码段。程序或代码段可以存储在处理器可读介质中或通过传输媒介或通信链路由包含在载波中的计算机数据信号传输。“处理器可读介质”可以包括能存储或传送信息的任何介质。处理器可读介质的例子包括电子电路、半导体存储器设备、ROM、快速存储器、可擦除ROM(EROM)、软盘、CD-ROM、光盘、硬盘、光纤介质、射频(RF)链路等。计算机数据信号可以包括能通过传输媒介传播的任何信号,传输媒介例如电子网络信道、光纤、空气、电磁、RF链路等。代码段可以通过计算机网络例如Internet、Intranet等下载。图3示出了计算机系统100的逻辑框图。参考图2和3,系统固件176包括在POST期间装入系统存储器124并随后由处理器104执行的软件模块和数据。在一个实施例中,系统固件176包括具有系统BIOS处理程序、硬件例行程序等的系统BIOS模块,ROM应用程序接口(RAPI)模块84,初始启动应用程序(ISUA)模块86,初始有效负载88a,密钥90,加密引擎92和显示引擎94。上述模块和部分系统固件176可以包含在ROM180和/或闪存184中。或者,上述模块和部分系统固件176可以包含在ROM190和/或闪存194中。RAPI84,ISUA86和初始有效负载88a可以独立开发并在首次使用计算机系统100之前存储在系统固件176中。在一个实施例中,RAPI84,ISUA86和初始有效负载88a中每一个都包括Phoenix技术有限公司开发的专用软件。
RAPI84通常在ROM应用程序和系统BIOS82之间提供安全接口。RAPI84的一个实施例在以下图8-18中有所描述并伴有文字说明。ISUA86的一个实施例在申请序列号为__、题目为“在计算机上自动安装和配置软件的方法和设备”、申请日为1999年6月18日、转让给Phoenix技术有限公司的未决美国专利申请中做了描述,本文在此通过参考结合该专利申请的内容。
从虚拟存储器访问和执行物理存储器的内容参考图2所示的安装在处理系统100上的操作系统描述本发明的一个方面。图4是示出了利用本发明系统和方法的操作系统结构的全功能框图。处理系统100包括支持应用程序232和服务程序2234的操作系统2230,基本输入/输出系统(“BIOS”)236和系统硬件238。BIOS236是硬件设备驱动程序或软件接口的集合,硬件设备如控制台(键盘和显示器),打印机类、辅助设备(串口)、计算机时钟和引导磁盘设备。BIOS236通常嵌入可编程的只读存储器(ROM)中。通常,BIOS函数本身实际上是利用访问物理存储器更快的优点从ROM拷贝到物理存储器中。这就是所知道的“阴影”BIOS236,因为BIOS236的两个副本导致一个在ROM(不再被使用)中,而另一个在物理存储器中。存储BIOS236的物理存储器部分称为BIOS阴影空间。Windows NT这样的操作系统在操作系统已经被引导并正在运行之后不使用BIOS236。Windows NT操作系统中的核心级驱动操作直接与系统硬件接口。本发明便于用BIOS236作为系统硬件238和操作232之间的接口。
操作系统230包括与应用程序232和服务程序2234接口的分类驱动程序240以及I/O管理程序242。I/O管理程序242将从应用程序232和服务程序234(经分类驱动程序240产生的)到正常定序的调用中的I/O请求转换为位于核心244中的不同驱动程序。尤其是,当I/O管理程序242接收I/O请求时,它用请求的函数代码调用位于核心244中的驱动程序中的若干调度程序方法其中之一。内核244提供与硬件无关的功能,称为系统功能,这些功能是通过软件中断来访问的。内核244提供的功能包括文件和目录管理、存储器管理、字符设备输入/输出和时间及数据支持等。在一个实施例中,操作系统是Windows NT操作系统。在另一个实施例中,操作系统230包括Solaris或AIX操作系统或基于请求分页的虚拟存储器子系统的其他操作系统。
本发明提供位于核心244中的访问驱动程序246,它负责访问位于BIOS236中的BIOS数据或者经BIOS236访问系统硬件238数据。访问驱动程序246也负责访问BIOS函数地址的位置和执行相关的BIOS功能。在一个最佳实施例中,核心244包括用C语言编写的源代码。可以理解,可以用其他汇编语言实现内核244的函数。BIOS数据和地址通常位于物理存储器250中并经BIOS接口248被访问驱动程序246访问。在一个实施例中,访问驱动程序246执行BIOS阴影空间中的代码,该空间的物理地址通常为0x000E0000-0x000FFFFF。
通过举例,如果访问驱动程序246需要访问位于地址为0x00000000的物理存储器中的BIOS函数。它调用I/O管理程序242,请求它将物理地址0x00000000到0x00000FFF的存储空间映射到其虚拟存储空间上。然后I/O管理程序242将指针返回到访问驱动程序246的虚拟存储空间,例如0xfd268000。访问驱动程序现在可以通过基于或访问其虚拟地址0xfd268000来访问物理地址为0x00000000的地址空间。因此,为了访问位于物理地址0x2400上的函数,所用虚拟地址为0xfd2682400。
在一个最佳实施例中,利用访问驱动程序246的应用程序230、服务232或分类驱动程序240可以使用一组入口点或函数调用。访问驱动程序246通过这些入口点可以被打开、关闭,并且能接收输入/输出(“I/O”)控制代码(“IOCTLs”)。表1示出了访问驱动程序246的结构、入口点和应用程序。
图5是显示根据本发明原理所提供的访问驱动程序246初始化过程的方框图。通常,当初次装载访问驱动程序246时,执行其DriverEntry函数(见表1)。尽管在该函数中出现了大量其他初始化(例如为访问驱动程序246的正常操作分配不同的资源或对象),出现两个尤其重要的初始化(a)位于物理存储器250中的BIOS阴影区260(包括BIOS服务目录62)和(b)也位于物理存储器250中的BIOS数据区264,两者都被映射到访问驱动程序246的虚拟存储器(包括BIOS服务目录272和BIOS数据区74)270中。结果,应用程序232或服务程序2234可以通过分类驱动程序240利用虚拟地址访问或执行BIOS函数。应注意,BIOS函数的执行必须通过访问驱动程序246来实现,原因是BIOS236的物理地址空间仅映射到访问驱动程序246。此外,可以通过附录A中详细描述的32位BIOS电源管理服务接口的实现来利用访问驱动程序246。显然,本领域的技术人员知道BIOS电源管理服务接口也可以用64位、128伴和256位配置来实现。
尤其是,在初始化过程中,访问驱动程序246寻址位于物理存储器250中的BIOS阴影区260和BIOS数据区264。BIOS阴影区260和BIOS数据区264被映射到访问驱动程序246的虚拟地址空间。接着,访问驱动程序246检索BIOS服务目录272头部。一旦发现并确认BIOS服务目录,访问驱动程序246获得BIOS服务目录272的虚拟地址,这提供了BIOS服务目录272头部虚拟地址对BIOS阴影区270的基准虚拟地址的补偿。
在另一个实施例中,在初始化过程中,访问驱动程序寻址位于物理存储器250中的BIOS阴影区260、BIOS数据区264和BIOS ROM区。BIOS阴影区260、BIOS数据区264和BIOS ROM区被映射到访问驱动程序246的虚拟地址空间。接着,访问驱动程序246检索BIOS服务目录272头部。一旦发现并确认BIOS服务目录,访问驱动程序246获得BIOS服务目录272的虚拟地址。在该实施例中,访问驱动程序246的虚拟存储器空间中BIOS ROM区的可用性使访问驱动程序246能在闪存ROM中读和/或写数据。结果,BIOS ROM能被二次扩容或再写。此外,与硬件接口的外部应用程序能通过软件机制访问BIOS ROM区,软件机制例如附录B中所提供的PhoenixPhlash NT说明书中所描述的。
随后,调用访问驱动程序246中的执行函数将利用BIOS阴影区270的基准虚拟地址和补偿以激活BIOS本身中的被请求的入口点。应注意,应用程序232或服务程序234可以再BIOS的虚拟地址空间中的任何地方执行BIOS函数,且不仅仅通过BIOS服务目录272。
在一个实施例中,被调用以激活BIOS中被请求的入口点的执行函数是IOCTL-BIOS-EXEC函数,如表1所述。IOCTL-BIOS-EXEC函数在位于主存储器或DRAM中的缓冲器(通过调用应用程序232或服务234)中建立寄存器堆栈。堆栈的内容是调用BIOS函数时的寄存器值。访问驱动程序246通过调用应用程序232或服务程序234传递寄存器堆栈。利用BIOS服务目录272中指定的函数指针完成程序调用本身。在一个实施例中,IOCIL-BIOS-EXEC所调用的BIOS函数接受4-字节签名作为参数(argument)并定址与签名有关的BIOS函数。传送回调用应用程序232或服务程序234的值包括BIOS功能的基准虚拟地址,以及对服务程序入口点的基址的补偿。
下面提供了访问驱动程序246的结构、入口功能和应用程序的概述。
表1.访问驱动程序246函数


A.访问驱动程序246函数的详细描述1.“DriverEntry”函数该入口点使驱动程序初始化其变量,在BIOS阴影和数据区中映射,并为其正常操作分配资源。当每个资源或对象定位时,将其列表形成变量“phResAndFlags”;允许单一函数(“freeResources”)释放驱动程序使用的资源,而不论驱动程序被卸载原因。被定位或连接的资源如下a.产生设备对象-建立系统的设备对象及名称。
b.初始化错误记录-产生与事件日志服务的链接。
c.建立主函数入口点。
d.产生符号连接-服务程序或应用程序层使用e.在BIOS阴影中的映射-使驱动程序可访问虚拟内存上的内存空间。
f.在BIOS ROM中的映射-使虚拟内存地址空间中的ROM区可以访问。
g.在BIOS数据中的映射-使驱动程序可访问虚拟内存上的内存空间。
h.为该驱动程序使用定位BIOS 232位入口点。
在一个实施例中,设备对象名称为“Laptop”,需要其服务微软OEM适应开发包(OAK)所需的连接函数。该相应符号连接名称为“PhoenixAD”。
2.AcessDriverCreateClose当应用程序232或服务程序234向系统请求进行设备处理时,或当其关闭已经获得的处理时,利用该函数通知驱动程序246。该访问驱动程序246通过成功实现请求来响应调度入口点,但不改变驱动程序246的其他模式变量。
3.AcessDriverUnload当需要将驱动程序从系统(从(SCM)关闭设备)中移动时,由代表服务控制管理程序(SCM)或其它应用程序的核心调用该调度入口点。该函数调用的结果是列表于“phResAndFlags”中的所有资源对系统均为空闲并成功完成请求。
4.AccessDriverReg访问驱动程序246的驱动程序具有对作为部分OEM适应开发包(OAK)的电源控制模式执行“连结处理”的函数。该函数与知道并请求使用OAK控制方法的OEM和标准设备的仿真电源管理为一整体。AccessDriverReg函数将设备注册到链接清单中。也可请求可选择的“再注册”设备。当执行DriverEntry函数(当首次安装时),典型的OAK适应设备驱动程序会调用注册。作为DriverEntry函数的一部分,每个注册设备必须调用以将其本身从需要电源控制服务程序的设备的访问驱动程序246链接清单中移走。
5.LOCTLF函数在服务程序或应用程序层和BIOS之间的每一个接口都由访问驱动程序246的驱动程序中的LOCTL函数来处理。以缓冲区模式执行每个LOCTL传送,以使驱动程序的输入数据及其输出程序通过共用系统缓冲区来进行传送。在作为Irp>AssociatedIrp.SystemBuffer的输入/输出(I/O)请求包中给出该缓冲区空间的指针。一旦被控制,IOCTL(在驱动程序内)会得到系统缓冲区地址并利用其内容来执行请求。在输入给时,IOCTL函数的执行结果会在相同的系统缓冲区内被替换。
在访问驱动程序246的驱动程序中执行的每个IOCTL都有唯一用于IOCTL输入数据和输出数据的数据模式。该函数如下所述,给出其数据缓冲区模式及每个区域的说明。缓冲区补偿以字节给出。建议malloc()大小为给每个函数的最小缓冲区大小供应用程序用户缓冲区所使用。从用户缓冲区中会自动得出系统缓冲区大小。
6.LOCTL_Locate在驱动程序246初始化后,该LOCTL_Locate函数是由应用程序232或服务程序234调用的首次调度入口点。该函数返回以可置平模式虚拟地址格式(232位地址)的BIOS232服务程序接口地址,BIOS阴影的基址以及BIOS数据区的基址。需要注意的是,BIOS服务程序接口是从驱动程序层或内核线程(见附录A)执行所有BIOS函数的唯一入口点。在装入访问驱动程序246期间,保证仅该驱动程序可以到达这些地址空间。
输入数据无,不依靠缓冲区内容输出数据补偿0PUCHAR-进入阴影的BIOS服务目录补偿。
补偿4PUCHAR-BIOS阴影基本虚拟地址。
补偿8PUCHAR-BIOS数据区基本虚拟地址。
补偿8PUCHAR-BIOS数据区基本虚拟地址。
补偿12PUCHAR-BIOS ROM数据区基本虚拟地址。
最小缓冲区大小16位7.LOCTL BIOS Read该LOCTL_BIOS Read函数为BIOS ROM、阴影或数据区的通用阅读程序。输入数据补偿0ULONG-模式标志位01=阴影,0=数据区。
位21=ROM区(超过位0)补偿4PUCHAR-进入BIOS区的补偿开始读取补偿8ULONG-读出字节长度输出数据补偿0ULONG-实际读出长度补偿4UCHAR数组-实际数据读出最小缓冲区大小16位注意如果因为进入指定与映射BIOS存储器的末端相重叠的BIOS区的补偿而发生“短读出”时,不返回错误。“实际数据读出”区域正确指出在系统缓冲区有多少有效数据。
8.LOCTL BIOS Write该LOCTL_BIOS_Write函数为BIOS ROM、阴影或数据区的通用写程序。
输入数据补偿0ULONG-模式标志位01=阴影区,0=数据区。
位21=ROM区(覆盖位0)补偿4PUCHAR-进入BIOS区的补偿开始写位-移8ULONG-写字节长度输出数据补偿0ULONG-实际写长度(零或请求大小)补偿4UCHAR数组-实际数据读出最小缓冲区大小16位注意由于数据可能讹误禁止缩写。
9.LOCTL BIOS Exec该LOCTL_BIOS_Exec函数被用来通过BIOS232服务程序接口执行BIOS函数。活动记录经过系统缓冲区中的值。一旦调用BIOS的入口点,则AR确定基本体系结构寄存器内容。一旦成功完成,AR包含通常已返BIOS调用程序的基本体系结构内容。
输入数据补偿0ULONG-函数入口点虚拟地址。
补偿4ULONG-标志寄存器补偿8ULONG-保留补偿12ULONG-保留补偿16ULONG-保留补偿20ULONG-保留补偿24ULONG-保留补偿28ULONG-保留补偿232ULONG-保留补偿236ULONG-保留补偿240ULONG-保留补偿244ULONG-ECX保留补偿48ULONG-EDI保留补偿52ULONG-ESI保留补偿56ULONG-EDX保留补偿260ULONG-ECX保留补偿64ULONG-EBX保留补偿68ULONG-EAX保留输出数据系统缓冲区内容在结构上相同。寄存器内容可能已经受到所请求的BIOS函数的影响。
最小缓冲区大小80字节。
100.LOCTL RTC Read该LOCTL_RTC_Read函数用于读出CMOS RAM中的RTC寄存器的内容。自动读出的数据格式与SYSTEMTIME结构相类似并返回到系统缓冲区的用户中。
输入数据无,不依靠缓冲区容量输出数据<如下所示使用SYSTEMTIME模板>
补偿0字 当前年份补偿2字 当前月分(一月=1)补偿4字 当前星期几(星期日=0)补偿6字 当前月日(日历)补偿8字 当前小时补偿100字 当前分钟补偿12字 当前秒补偿14字 当前毫秒最小缓冲区大小32位。
注意在RTC中的年份区域为8位宽度。在RTC中年份区域的内容会重新计算到包含当前年份、公元的全部值的SYSTEMTIM.Year16位区域中。例如RTC=00,Year=1980;RTC=23,Year=2003。还要注意LegacyRTC设备在其寄存器设备中不能提供毫秒区域。因此,在输出数据中该函数的当前毫秒区域始终设定为零。
11.LOCTL VERSIONLOCTL_VERSION函数将访问驱动程序246驱动程序的主、次版本返回到调用程序。另外,由这个版本驱动程序实现的该函数以位图计算。该位图的目的是使服务程序或更高级的驱动程序估计是否该版本的驱动程序可以实现其目的(通常在安装时间)。
输入数据无,不依赖缓冲区内容输出数据补偿0字 大版本(X)补偿2字 小版本(.x)补偿4ULONG被执行函数的位图(见下面)位31如果LOCTL_Locate被执行位230如果LOCTL_BIOS_Read被执行位29如果LOCTL_BIOS_Write被执行位28如果LOCTL_BIOS_Exec被执行位27保留位26保留位25保留位24如果LOCTL_RTC_Read被执行位23保留位22保留给Phlash互锁位21保留给在线设置(NVRAM写程序)位20-0保留给将来扩展位2301如果LOCTL_BIOS_Read执行最小缓冲区大小16字节12.LOCTL PM Suspend该LOCTL_PM_Suspend函数使IRP_MJ_PNP_POWER、IRP_MN_LTRESUME IR被发送到使用Access Driver DriverReg入口点注册本身的每个设备。
输入数据无,不依赖缓冲区内容输出数据无,不依赖缓冲区内容B.访问驱动程序246返回的错误代码下表定义了当IRP失败或仅部分完成时返回的错误模式。也给出了该函数终止的条件。因为在操作系统已知的NTSTATUS值和访问驱动程序246设备驱动程序之间不需要存在一对一的对应,因此就需要该表。为了将代码还原翻译成应用写程序或最终用户可用的串,强制仅使用NTSTATUS错误代码。
表2.从访问驱动程序246返回的NTSTATUS代码


C.BIOS232位入口点说明为使IOCTL_Locate发现BIOS的入口点,使用BIOS232位服务目录。在附录C中描述BIOS232-位服务目录。当查找和执行BIOS函数时,访问驱动程序246所使用的签名为“_32_”。
如果受上述规定的条件影响未发现WinntEntry(BIOS232服务目录)结构,则访问驱动程序246驱动程序在装入时间失败,DriverEntry显示不能进行如每个表2中的初始化。
D.实时时钟硬件访问为执行IOCTL_RTC Read函数,需要定义RTC寄存器和访问的方法。该RTC寄存器定位于CMOS RAM的I/O地址空间。在表3中仅示出了RTC寄存器。通过将CMOS物理存储器地址输出到端口0x70来访问该寄存器,然后读取端口0x70上的源(subject)8位寄存器。读取所有RTC寄存器后,设定该CMOS物理存储器地址指向0x0D。
表3RTC寄存器

图6A是本发明初始化过程的一个实施例的流程图。从起动模式开始,过程600开始进行块610,初始化调用程序的变量(例如I/O管理程序242)。图6B和配套的文字描述了该初始化过程6100的细节。然后过程600开始进行块620,在620上装入访问驱动程序246。然后发生访问驱动程序变量的初始化。在初始化过程期间,发生两个特别必要的初始化(a)位于物理存储器250的BIOS阴影260(包括BIOS服务目录)以及(b)同样位于物理存储250的BIOS数据区264,均映射到访问驱动程序246的访问驱动程序的246虚拟存储器(如图5中BIOS阴影270(包括BIOS服务目录272)和BIOS数据区274所示)。
然后过程600前进到块 630,在630上发生指针初始化。图6C和配套文字描述了块630的细节。然后过程600前进到块640,在640上初始化结束。然后过程600终止。
图6B是块610的细节流程图。从起动模式开始,过程610开始进行块612,在612上来自I/O管理程序242的调用程序为系统缓冲区上指定的存储器结构分配存储器。然后过程610前进到过程块614,在614上来自I/O管理程序242的调用程序确定许多BIOS函数的位置、相应的入口点、长度和补偿。在一个实施例中,通过进入具有BIOS函数的虚拟地址的相应BIOS函数的指定存储器结构的地址区域,以及通过提供识别每个BIOS函数的4位ASCII串来完成的。然后终止调用程序的初始化。
图6C是图6A的过程块630的详细流程图。从起动模式开始,调用应用程序232或服务程序234通过分类驱动程序调用IOCTL_Locate,如块632所示。相应地,访问驱动程序246执行查找BIOS服务目录272的头部,如过程块634所示。一旦找到并确认BIOS服务目录272,访问驱动程序246获得BIOS服务目录272头部的虚拟地址,其提供从BIOS阴影270的基本虚拟地址的BIOS服务目录272头部虚拟地址的补偿。然后过程630将控制返回到调用应用程序232或服务程序234。
图7A是本发明的调用执行过程的流程图。从起动模式开始,过程700开始进行过程块710,在710上调用程序通过提供给访问驱动程序246来调用BIOS函数,它想在BIOS函数的地址开始执行。然后过程700前进到过程块720,在720上访问驱动程序246通过来自I/O管理程序242的IOCTL命令接收BIOS函数的调度调用(见图4)。然后过程700前进到过程块730,在730上访问驱动程序246实行入口点地址的范围检查。特别地,访问驱动程序246确定入口点地址是否处在映射BIOS阴影地址的范围内,不包括服务目录头部。如果不是,则访问驱动程序246指示开始虚拟地址未处于从物理存储器映射到虚拟存储器的的地址范围内。可以通过使用标志来进行指示。如果范围检查成功,则过程700开始进行过程块740,在740上访问驱动程序246执行调用的BIOS函数。然后过程700终止。
图7B是图7A中过程块740的细节的流程图。从起动模式开始,过程740开始进行过程块742,在742上访问驱动程序246在先前由I/O管理程序242的程序规定的系统缓冲区中产生寄存器堆栈。然后过程730前进到过程块744,在744上访问驱动程序246提供指向保存将要执行的BIOS函数地址的寄存器堆栈的指针。然后过程740前进到过程块746,在746上来自I/O管理程序242的调用程序调用并执行该函数,该函数的开始地址由指针指示,将其物理地址作为虚拟存储器的映射。然后过程740终止。
现在提供一个在访问驱动程序246中使用IOCTL_BIOS_EXEC函数的示例。最初,应用程序232或服务程序234访问使用命令IOCTL_Locate访问驱动程序246。从访问驱动程序246返回的数据包括BIOS阴影基本虚拟地址、从BIOS阴影基本虚拟地址的BIOS服务目录补偿以及BIOS数据区基本虚拟地址。
然后利用随后的动作确定BIOS服务程序、其入口点、长度和地址补偿的存在。来自I/O管理程序242的调用程序首先为诸如IOC_EXEC1的寄存器结构分配存储器,然后将IOCTL_Locate给出的虚拟地址填充到该结构的biosFunction区域。其他寄存器值按如下填充识别BIOS服务程序的4位ASCII串被装入eax寄存器,零被装入ebx寄存器。
接着,调用程序调用具有IOC_EXEC1结构内容的访问驱动程序246的IOCTL_BIOS_Exec函数,该IOCTL_BIOS_Exec函数被拷贝到系统缓冲区用于IOCTL调用。然后执行BIOS函数。访问驱动程序246的IOCTL_BIOSExec函数返回每个都包含来自服务目录响应的eax、ebx、ecx和edx寄存器值。然后I/O管理程序242的调用程序得到从服务目录返回的信息并在系统缓冲区产生biosFunction入口点和结构。然后其调用在访问驱动程序246中使用IOCTLBIOS_Exec函数的BIOS函数。返回的数据经过相同的IOC_EXEX1结构。
在附录D1-D3中示出了图6A、6B和7B所示过程的示例。特别地,附录D1示出了应用程序232、服务程序234或通过分类驱动程序246在调用BIOS函数中使用的分类驱动程序240的示范性源代码。附录D2和D3示出了访问驱动程序246的示范性源代码。附录D2示出了在阴影执行BIOS函数的示范性源代码,而附录D3示出了产生寄存器堆栈及调用执行BIOS函数的入口点的示范性源代码。
通过使用本发明,提供了用于访问和执行来自虚拟存储器子系统的物理存储器内容的系统和方法。该系统和方法易于增加存储器的寻址能力和输入/输出操作,也允许在物理存储空间中执行处理器指令。
BIOS服务程序的安全应用本发明的另一方面包括安全利用基本输入和输出系统(BIOS)服务程序的系统和方法。在下面的细节描述中,使用下面的术语来描述当前发明。
“密钥”是按照传统的数据加密标准(DES)诸如Rivest、Shamir和Adleman(RSA)、数据加密算法(DEA)以及类似的加密算法编码和/或解码参数。
“密钥对”包括“专用”密钥和“公用”密钥。“专用密钥”为关键对的属主所有并用来产生数字签名。“公用”密钥被普遍公布并用来改变数字签名。公用密钥通常以数字“证书”的形式公布。
“数字签名”是使用数字消息和专用密钥的数字量。不知道专用密钥不能计算数字签名。通过使用数字消息和与专用密钥相对应的公用密钥可以改变数字签名。成功校验证实数字消息的确是被签名的,且签名是利用与公用密钥相对应的专用密钥产生的。
“证书”是至少包括公用密钥、专用密钥以及使用专用密钥的数字签名的数字消息。
图8是示出了利用本发明的系统和方法的处理系统1500的结构的全部功能框图。该处理系统1500包括支持应用程序1510和服务程序1515、基本输入/输出系统(BIOS)1520以及系统硬件1525的操作系统1505。BIOS1520是硬件设备的驱动程序或软件接口的集合,这些硬件设备诸如控制台(键盘和显示器)、普通打印机、辅助设备(串行端口)、计算机时钟以及引导磁盘设备。BIOS1520通常嵌入非易失性存储器中。
操作系统1505包括与应用程序1510、服务程序1515以及I/O管理程序1535相连接的分类驱动程序1530。I/O管理程序1535将应用程序1510和服务程序1515(通过分类驱动程序1530进行)中的请求转换成位于核心1540内的不同驱动程序的适当的序列调用。特别地,当I/O管理程序1535接收I/O请求时,使用请求的函数代码来调用位于核心1540内的驱动程序的几个分配程序中的一个。核心1540提供通过软件中断方式来访问的独立的硬件函数、调用系统函数。核心1540所提供的函数通常包括文件和目录管理、存储器管理、字符设备输入/输出及时间和日期支持等。在一个实施例中,操作系统1505为Windows操作系统。在另一个实施例中,操作系统1505包括Solaris或AIX操作系统或基于请求分页的虚拟存储器子系统的其它操作系统。
本发明提供位于核心1540内的访问驱动程序1545,访问驱动程序1545负责与ROM应用程序接口(RAPI)1550相接连以访问或升级位于BIOS1520的数据或通过BIOS访问系统硬件数据。RAPI1550通常提供安全利用BIOS服务程序或函数的接口。下面对RAPI进行更详细地描述。
在最佳实施例中,访问驱动程序1545包括用C语言编写的源代码。我们知道利用其它的汇编语言也可以实现访问驱动程序1545的功能。在最佳实施例中,利用访问驱动程序1545的应用程序1510、服务程序1515或分类驱动程序1530都可能得到一组入口点或函数调用。访问驱动程序1545可以通过这些入口点打开、关闭并能够接收输入/输入/输出(“I/O”)控制代码(“IOCTLs”)。
图9所示为根据本发明的一个实施例的访问驱动程序1545和RAPI1550之间的交互序列的序列说明。在现有系统中,在访问驱动程序1545可能将一个或多个服务请求发送到RAPI1550以利用BIOS服务程序之前,必须要在访问驱动程序1545和RAPI1550之间建立工作会话。为建立与RAPI1550的工作会话,访问驱动程序1545产生工作会话(块1605)并将请求发送到RAPI1550(块1610)。
图12所示为会话请求900的一个实施例的格式。每个会话请求900包括会话操作代码905、参数910清单以及会话签名915。会话操作代码905是表示会话操作一个类型的数值。在一个实施例中的会话操作的说明性示例可以包括开始或建立会话的操作以及结束或终止会话的操作。每种会话操作类型都可以请求一个或更多外参数910清单。在一个实施例中,该参数910清单可以是驻留参数的存储器位置的指针。每个会话请求900也包括会话请求签名915以防止诸如计算机病毒的外来代码段,从而捕捉和应答该请求并中断BIOS。
图10概述了会话请求的产生。在块1705和1710中,会话操作代码表示所需会话操作及所需会话操作插入到会话请求中的所需参数清单。块1715、1720和1725显示了会话请求签名的产生。在现在密码技术中,消息的数字签名的产生动作称为“签名”消息。要注意的是,对消息进行签名消息或产生数字签名的算法在现有技术中是公知的。还要注意的是,为产生数字签名的现有算法通常包括计算将要被签名消息的散列值和加密使用专用密钥的散列值,如块1715、1720和1725所示。
设想全国科学技术学会提出的数字签名加密(“DSA”)可被使用。也可以设想使用Rivest,Shamir和Adleman(“RSA”)算法。然而,需要注意的是,产生数字签名的其它算法也可以在本发明中使用。
如图10中块1715所示,形成会话消息以使其包括会话操作代码和参数清单。在块1720中,计算会话消息的散列值。要注意的是,计算散列值的算法在现有技术中是公知的。本领域技术人员会认识到适合于本发明实施例的散列函数是一个可以单向计算并无冲突散列值的函数。在块1725中,通过将计算出的使用存储在当前权限证书中的专用密钥的会话消息的散列值加密来产生会话请求签名。
权限证书通常包含使诸如访问驱动程序1545和RAPI1550(图9所示)的系统部件产生安全会话或服务请示并改变那些请求完整性的足够的信息。图11所示为根据本发明的一个实施例的权限证书800的格式。示范性权限证书至少包括下列范围共用密钥805、专用密钥810和证书签名815。如后面所述,存储在权限证书中的信息也用来实施会话和服务请求的安全限制。
返回到图9中的块1615,RAPI1550建立如块1610中访问驱动程序1545发送的会话请求所规定的会话。图14概述了所需动作建立会话。在块1105中,消息根据会话操作代码以及在从访问驱动程序接收到的有效会话请求清单而建立。计算所建立消息的散列值(块110)。会话请求签名从会话请求中抽取并利用包括在当前权限证书的RAPI的拷贝中的共用密钥来解密(块1115)。如后面所示,RAPI负责产生和支持访问驱动程序的权限证书。然而,RAPI也保留了为其自己使用的大多数当前权限证书的拷贝。在块1120中,解密的会话签名与计算出的所构建消息的散列值相比较。如果被计算的散列值等于解密会话请求签名,则RAPI开始着手起动会话(块1125)。
返回到图9,建立会话后,RAPI1550产生新的权限证书(块1620)。如上所述,RAPI1550保留了为其自己使用的新的权限证书的拷贝。RAPI1550用新的权限证书代替现有的权限证书。替换后新的证书变成当前的证书。
图18所示为产生权限证书的过程。为产生权限证书,从加密引擎获得新的密钥对。如上所述,新密钥对包括共用密钥和专用密钥。新密钥被插入到新权限证书中(块2510和2515)。形成证书消息以使其既包括新共用密钥又包括专用密钥(块2520)。计算证书消息的散列值(块2525)。使用证书消息和新的专用密钥产生散列值证书签名(块2530)。然后将证书签名插入到新的权限证书中(块2535)。
返回到图9,RAPI1550将新的权限证书发送回访问驱动程序1545(块1625)。一旦接收到新的权限证书,访问驱动程序1545用新证书中的信息将当前权限证书更新(块1630)。因此,在新权限证书中的信息被用来产生后续的服务请求。在块1635中,访问驱动程序1545产生服务请求以调用RAPI1550的函数。
图13显示了根据当前发明的一个实施例的服务请求100的格式。每个服务请求包括服务操作代码1005、参数1010的清单以及服务请求签名1015。服务操作代码1005是表示服务操作类型的数值。在一个实施例中的服务操作的说明性示例可以包括读或写存储在非易失性存储器中的数据的操作。每种服务操作的类型可能需要一个或多个包括在参数清单中的参数。在一个实施例中,参数清单可以是指向参数束驻留的存储器位置的指针。每个服务请求1000还包括服务请求签名1015以防止诸如计算机病毒的外来代码段,从而捕捉和应答该服务请求使得不能对系统造成严重损坏。
图15概述了按照当前发明的一个实施例产生服务请求。在块1205和1210中,在服务请求中插入服务操作代码,该服务操作代码表示将要执行的所需服务操作和所需操作所需的参数清单。块1215、1220和1225示出了服务请求签名的产生。一旦产生,就在服务请求中插入服务请求签名(块1230)。
返回到图9,访问驱动程序1545将块1635中产生的服务请求发送到RAPI1550中(块1640)。一旦接收到服务请求,则RAPI1550处理该请求(块1645)。图16示出了根据当前发明的一个实施例在处理服务请求中所需的动作。在块1305中,从服务操作代码和从访问驱动程序中接收的服务请求中可得到的参数清单中构建出消息。计算构建消息的散列值(块1310)。服务请求签名从会话请求中抽取并利用包括在当前权限证书的RAPI的拷贝中的共用密钥来解密(块1315)。在块1320中,解密的会话签名与被计算的构建消息的散列值相比较。如果被计算的散列值等于解密会话请求签名,则RAPI执行服务请求中指定的服务(块1325)。否则,不能执行指定的服务。
返回到图9,处理服务请求后,RAPI1550产生新的权限证书(块1650)。如上所述,图15所示为产生权限证书的过程。RAPI1550保留了为其自己使用的新的权限证书的拷贝。RAPI1550也交新的权限证书的拷贝发送回访问驱动程序1545。
一旦接收到新的权限证书,访问驱动程序1545用新证书中的信息更新当前授仅证书(块1630)。因此,在新权限证书中的信息会用来产生后续的服务请求。在块1635中,访问驱动程序1545产生会话请求以请求RAPI1550结束当前会话。如上所述,图10概述了包括产生会话请求的动作。随着会话请求的产生,访问驱动程序1545将请求发送到RAPI1550。
一旦收到结束或终止会话的会话请求,RAPI1550就结束会话(块1680)。图17所示为包括结束当前会话的动作。在块1405中,从会话操作代码和从访问驱动程序中接收的会话请求中可得到的参数清单中构建出消息。计算构建消息的散列值(块1410)。会话请求签名从会话请求中抽取并利用包括在当前权限证书的RAPI的拷贝中的共用密钥来解密(块1415)。在块1420中,解密的会话签名与被计算的构建消息的散列值相比较。如果被计算的散列值等于解密会话请求签名,则RAPI开始进行结束当前会话(块1425)。
返回到图9,结束会话后,RAPI1550产生新的权限证书(块1685)。如上所述,图15所示为产生权限证书的过程。然后RAPI1550将新的权限证书发送回访问驱动程序1545(块1690)。一旦接收新的权限证书,访问驱动程序1545用新证书中的信息更新当前权限证书(块1695)。因此,在新的权限证书中的信息可用来在后续会话中产生请求。
图9显示在工作会话中访问驱动程序仅产生一个服务请求。实际上,在每个工作会话中间可产生多个服务请求并发送到RAPI1550。
总之,本发明在会话和服务请求中需要包括数字签名来作为安全措施防止系统外来组件(例如病毒)调用BIOS函数或服务程序。而且,每个连续会话或服务请求包括利用新的专用密钥产生数字签名以防止外来组件捕捉和应答会话和/或服务请求和对系统造成不利影响。因此,本发明中采用的安全措施保证安全、可靠地利用BIOS函数。
虽然本发明的优选实施例已经进行了表示和说明,但是,应当知道,本领域的技术人员可以在不背离本发明的精神的条件下进行变化和变型,本发明的范围由权利要求书限定。
附录A
用于视窗NT4.0的BIOS电源管理服务简介本文件提供32位BIOS电源管理服务接口(BPMSI)的接口。该接口用于视窗NT电源管理内核驱动程序为知道APM的程序提供电源管理服务。
术语APM BIOS系统BIOS,提供附加于APM标准(当前为再版1.2)的电源管理功能。
内核模式一种NT系统代码运行的专用处理器模式。内核模式线程访问所有的I/O和系统存储器。
电源管理内核驱动程序(PM驱动程序)为服务提供对BIOS ROM,BIOS数据和32位服务的访问。
电源管理服务(PM服务)为应用程序和其他驱动程序提供电源管理服务。使用电源管理内核驱动程序(PM驱动程序)提供的接口将它们的请求翻译成对BIOS电源管理服务接口的查询。
PowerPAL凤凰公司APM BIOS扩展,提供系统和设备电源管理功能的应用程序级访问。
系统空闲PM服务检测到的在应用程序级最小处理的状态。在这个状态下,只有在空闲优先级下运行的线程才被执行并且它们被任何在更高优先级类运行的线程所抢占。
用户模式一种应用程序代码运行的非专用处理器模式。用户模式线程不能访问I/O和系统存储器。
结构概述支撑视窗NT电源管理的BIOS扩展分为两部分(a)BIOS32服务目录的修改。增加了一个入口,它允许PM驱动程序找到BIOS电源管理服务接口的入口点。
(b)新的32位BIOS电源管理服务,它模仿APM32位接口而稍有不同,以下将说明。新的接口提供0:32位调用方法,它们更安全和对视窗NT更友好。
当PM内核希望使用BIOS服务时,它必须进行以下步骤1.找到BIOS32服务目录头部。
2.调用BIOS32服务目录调用接口,它指定32位BIOS电源管理服务接口入口点。
3.调用BIOS32位BIOS电源管理服务接口入口点,请求APM连接。
BIOS32服务目录修改32位BIOS服务目录是凤凰BIOS中已有的结构,它允许32位保护模式应用程序或操作系统找到特定的32位服务的入口点。该标准定义了新的标准32位BIOS服务。
BIOS32服务目录包括一个可以被PM驱动程序检测的固定结构和返回特定服务地址的单个函数。
BIOS32服务目录头部实现BIOS32服务目录的BIOS必须在物理地址0E000h-0FFFFFh的范围内的某处嵌入一个特定的连续16字节结构。该结构必须是分段对准的(即,它必须在16字节边界开始)。该结构已知为BIOS32服务目录头部。
该头部由六个独立的字段组成。以下是每个字段的描述。

BIOS32服务目录的客户应首先通过定位头部而确定它的存在。这是通过扫描段增量中0E0000h至0FFFF0h和在每个段的首4字节中查找签名匹配(“_32_”)而确定。当,和如果,检测到签名,客户应进行头部所有字节的校验求和。(段中头部长度在偏移9h中找到。)头部的所有字节相加到一起应为0h。如果校验求和有效则32位入口点字段可以用作BIOS服务目录调用接口的地址。如果头部未找到,则BIOS32服务目录在平台中不存在。
BIOS32服务目录入口点它的相关代码和数据可能定位在4GB物理地址空间内的任何地方。然而,它必须保证为物理连续的(即,它将分配在ROM或闪存空间)并容纳在两页中(即,它不跨过3页)。
BIOS服务目录为了找到BIOS32位电源管理服务接口的入口点,PM驱动程序必须带以下参数调用BIOS服务目录INEAX “NTPM”0X4e54504DEBX0x00000000OUTAL错误代码0x00=空,0x81=服务不存在EBX 32位电源管理服务代码基地址ECX 32位电源管理服务代码入口点长度(从EBX)EDX 32位电源管理服务代码入口点偏移(从EBX)32位电源管理服务代码入口点是FAR(即,需要段和偏移两者压入堆栈)CS基地址必须小于或等于包含入口点的页的(4KB)页地址。例如,如果入口点是0FFF81234H,则基地址必须小于或等于0FFF81000h。该范围必须使基地址加该范围生成一个地址大于或等于包含入口点的页之后的(4kB)页的最后地址。例如,如果入口点是0FFF81234H则基地址加范围必须大于或等于0FFF82FFFH。简而言之,基地址和范围必须“包围”包含入口点的页和随后页。
段类型必须是100b(代码,只能可执行)或101b(代码,可执行/读)。但是,服务目录的实现不能假设CS代码段的读访问。系统位必须是1(非系统段)。推荐描述符专用级(DPL)为0。(CS描述符DPL成为当前专用级,或CPL)。如果CPL是非0,则OS必须提供环0专用指令(例如访问CRx的那些指令)的捕获和虚拟服务。还请注意位于EFLAGS中的IOPL字段上的该字段的依赖性(见段0)。
缺省大小位必须为1(32位)。
DS基地址必须等于CS基地址。范围必须大于或等于CS范围。
段类型必须是000b(数据,只读)或001(数据,读/写)。但是,服务目录的实现不能假设DS数据段的写访问。系统位必须为1(非系统段)。描述符专用级(DPL)必须大于或等于CPL(见段0DPL字段)。SS段类型必须是011b(数据,读/写,向下扩展)或001b数据,读/写,向上扩展)。系统位必须为1(非系统段)。描述符专用级(DPL)必须等于CPL(见段0中的DPL字段)。缺省大小位必须是1(32位)。
间隔位必须是1(4KB)。
注意以上设置保证至少4kB的堆栈大小。调用者有责任保证有至少1kB的可用的没被使用的堆栈PagingPaging可以或不使能。如果paging使能,由CS和DS选择器描述的地址空间必须是线性连续。即,在ROM或FLASH中找到的调用接口的原始物理连续性必须保持。(调用接口代码和数据被写成与位置无关和EIP相关)。
IOPL为使调用接口执行I/O指令,EFLAGS中的I/O专用级(IOPL)字段必须大于或等于CPL(见段0中DPL字段)。
OtherBIOS数据区,扩展BIOS数据区和固定位置ROM数据表不能假设因为paging可用于执行代码。BDA可使用由调用者提供的指针而被访问。
32位BIOS电源管理服务接口总的来说,32位BIOS电源管理接口提供32位APM入口点相同的功能。有两个区别的地方调用参数传递的方式和支持某些APM连接函数的方式。
调用参数APM32位接口传递CPU寄存器中所有的参数。BIOS电源管理服务接口传递参数至堆栈。等效C形式声明可以是
typedef struct{ULONGreserved0;/*00*/ULONGpBDA; /*04*/ULONGregFlags; /*08*/ULONGreserved1;/*0C*/ULONGreserved2;/*10*/ULONGreserved3;/*14*/ULONGreserved4;/*18*/ULONGreserved5;/*1C*/ULONGreserved6;/*20*/ULONGreserved7;/*24*/ULONGreserved8;/*28*/ULONGreserved9;/*2C*/ULONGregEBP; /*30*/ULONGregEDI; /*34*/ULONGregESI; /*38*/ULONGregEDX; /*3C*/ULONGregECX; /*40*/ULONGregEBX; /*44*/ULONGregEAX; /*48*/}regStruct;unsigned char BPMSI(regStruct* parameters);活动APM函数和它的动作由写入相应的寄存器字段中的值决定。PDBA字段是指向内核驱动程序映射BIOS数据区使它可被服务入口访问的虚拟地址的指针。
如果发生错误,regFlags的位0将是1和错误码将是regEAX的位8-15,否则它将是0和regEAX的位8-15将为0。错误码与APM1.2标准中的相同。
软件要求开发软件要求建立PM服务要求的以下软件开发工具MASM 6.11C汇编器,微软公司凤凰PhDebug,用于跟踪代码软件要求PM服务要求在以下环境运行视窗NT4.0凤凰NoteBIOS系统,支持至PowerPAL的NT BIOS接口系统中安装的PM驱动程序端口变化以下部分描述在Core,Miser和芯片组代码中修改的文件。它还描述为正常BIOS接口至包含NT支持所需的变化。
附录B
PhoneixPhlash NT视窗NT的闪存ROM编程工具附录B中的PhoenixAD驱动程序是指访问驱动程序46。
1.0PhoenixPhlash闪存工具将用于将BIOS映象编程入AT兼容系统的闪存ROM中。该工具包括以下文件PHLASHNT.EXE 用于对闪存ROM编程PLATFORM.DLL 用于执行平台无关的函数BIOS.ROM 被编程入闪存ROM的实际BIOS映象这份说明提供了PHLASHNT.EXE程序功能的详细说明。因为PLATFORM.DLL和BIOS.ROM是与平台有关的,在这份文件中只覆盖了这两个文件的一般格式。
PhoenixPhlash将作为Win32控制台应用程序执行。
这个设计工程的灵活性,适应性和支持性是非常优先的。在PLATFORM.DLL文件中尽可能放入更多的定制功能使得可以不修改PHLASHNT.EXE而支持许多不同的平台和配置。PhoenixPhlash将支持有单一闪存ROM部件的平台以及带多个闪存ROM的平台。1Mb-4Mb的闪存ROM可以容纳包括引导块设备和有多个可擦区的任何配置的设备。
对于每个支持的部分,指定给特定闪存ROM部分的所有代码(例如,英特尔28Fxxxx)将是PHLASHNT.EXE模块的一部分。与平台有关的所有代码和参数(例如,擦除使能代码和闪存ROM地址区)将是PLATFORM.DLL模块的一部分。
PHLASHNT.EXE,Phoenixhlash工具的主要模块,将包含与平台无关的所有代码。它将包含用户界面代码,加载和确认PLATFORM.DLL文件的代码和与平台无关代码以对闪存设备编程。
PHLASHNT.EXE将是一个Win32可执行文件,用微软C+ +V4。2或其后版本生成。
使用Cdriver访问硬件PHLASHNT.EXE使用Cdriver C++类,它与PhoenixAD驱动程序一起使视窗NT用户模式应用程序能够访问I/O端口,访问BIOS设计和代码区;和执行BIOS32服务。Cdriver类提供一个简单和灵活的在应用程序和PhoenixAD驱动程序之间的接口。
Cdriver与PhoenixAD驱动程序一起为用户模式应用程序提供以下功能访问I/O端口执行BIOS32服务访问BIOS映象访问BIOS数据区读取相同实时时钟Cdriver类作为视窗NT应用程序和PhoenixAD驱动程序之间的一个薄包装接口。它封装了驱动程序的接口和提供应用程序和内核驱动程序设计两者的灵活性。
为保证将来的兼容性,PHLASHNT.EXE不直接调用PhoenixAD驱动程序;相反,它调用Cdriver类中的方法。
2.0运行模式2.1Win32控制台PHLASHNT.EXE在一个视窗NT中的窗口中开始,之后是可选的命令行标志(如果有)。
命令行标志将包括(大小写都可接受)/AAUTODETECT OFF-不从该部分读取ID。缺省的,程序确认制造者ID和和从部件中读取的部件ID,比较PLATFORM.DLL文件中指定的ID和当两个ID不同时,使用从部件读取的ID。这使得多个不同部件采用相同的PLATFORM.DLL和BIOS.ROM而不需要修改这两个文件。当该标记不被设置时,假设ID是从部件“可读”的。当该标记被设置,来自部件的ID不被使用,相反使用PLATFORM.DLL中指定的值。
/B=文件名BINARY FILE-覆盖缺省平台特定二进制文件。当需要全路径指定时和/或二进制文件有一个不是PLATEFORM.DLL的文件名时,这个选项是必须的。
/BU=filenameBACKUP-在被删除之前将BIOS映象的以前版本存入文件filename。Filename是可选的;如果未指定,以前的映象存入BIOS.BAK。因为BIOS的多个版本使用与平台有关的特性,如阴影存储器和解压缩,所以经常需要使用PLATFORM.DLL中与平台有关的代码而在它被写入文件前取回BIOS映象。
/CCMOS UPDATE-在闪存被更新后清除CMOS校验求和。如果AUTO_UPDATE特性安装在新的BIOS映象中,在下一次引导时BIOS自动设置所有的CMOS字段至它们的缺省值。如果AUTO_UPDATE特征未加载,BIOS在下一次引导显示CMOS校验求和错误信息并提示用户按F2键以执行Setup和手工重配置机器。
/CSCHECKSUM BIOS ROM-在BIOS ROM映象上计算校验求和。如果校验求和不为0,或如果可选的PLATFORM.DLL函数CheckSum失败,程序带有错误信息终止。
/HUSAGE-显示程序名,版本,版权和帮助屏。/?也可用于这个选项。
/IIMAGE SIZE VERIFICATION-只有ROM映象的文件大小与闪存部分大小相同时才运行。
/MODE=nOPERATION-为PHLASHNT选择一个运行模式。当前支持以下模式0只更新BIOS映象(正常运行模式)。在该模式下,PHLASHNT用新的映象代替当前BIOS映象。系统BIOS中的DMI信息被保持。这是缺省模式和如果没有/MODE命令行标记或如果没有指定运行模式,这是缺省模式。
1只更新DMI信息。在这个模式中,PHLASHNT将通过DMI命令行指定的字符串写入闪存。系统BIOS中的DMI信息被保持除非命令行中指定了新的DMI串。
2更新BIOS和DMI信息两者(保存系统DMI串)。在该模式下,PHLASHNT替换BIOS映象和将DMI命令行标志指定的串写入闪存。系统BIOS中的DMI信息被保持除非命令行中指定了新的DMI串。
3更新BIOS和DMI信息两者(复位系统DMI串)。在该模式下,PHLASHNT替换当前BIOS映象和将DMI命令行标志指定的串写入闪存。系统BIOS中的DMI信息被新的BIOSROM映象的DMI串和/或命令行指定的DMI串替换。
为了安全起见这些选项不由帮助选项(/H)显示。
/NNEW(不同)-只为BIOSROM的不同版本进行。如果BCPSYS的数据结构,包括BIOS版本和生成日期和时间,与BIOS.ROM文件中的相应的结构相同,则程序不闪(flashing)而终止。
/OOVERRIDE PLATFORM.DLL OPTIONS-禁止PLATFORM.DLL中设置的所有标志。没有这个开关,PLATFORM.DLL中设置的选项与命令行中指定的选项组合。当这个开关被使用,只使用命令行选项。
/PPRODUCTION-闪的最大速度。所有的用户反馈被减到最小(没有声音,屏幕更新)。这用于减少在生产环境中闪一个部分所需的时间。只报告最后的成功/失败。
/PNBIOS PART NUMBER CHECK-只有BIOS.ROM中的BIOS部件号与当前BIOS部件号相同时才进行。
/PF=“list of options”被传递到与平台有关模块PLATFORM.DLL的命令行选项。在一些平台中,它希望传递命令行选项至平台有关过程。这是通过CmdLine()函数实现。当CmdLine()地址是非零和这个命令行选项出现,紧接着等号的串被传递至PLATFORM.DLL(如果串中包含空格,包括双引号中的串)。
/RnRETRY-如果闪块失败,重试n次而不终止。
/Rn选项通过在PLATFORM.CPP中设置psiRetryCount为希望的重试次数而被用于紧急模式。
/SSILENT-无声运行而没有声音反馈。
/VVERIFY-每个块被编程后,闪部件地址空间中的数据与BIOS.ROM文件中的数据进行比较。任何差别被报告和程序被相同块重试编程或系统暂停(根据对提示的响应)。因为检查是在闪存被擦除后进行的,系统将非常不稳定和不可能正确提示用户和恢复。
/ZZERO BLOCKS-在擦除前零闪块。
filenameBIOS ROM映象文件名。前面没有反斜杠的任何命令行选项被解释为BIOSROM映象文件的文件名。只有当需要指定ROM BIOS映象和/或ROM BIOS映象文件不同于BIOS.ROM时才需要文件名。
@filename响应文件。上述任何命令行选项可以置于响应文件中。PHLASHNT将读取这个文件并作为输入的命令行进行处理。选项可以置于一行或不同行。
每行最多1024个字符。
以下命令行标志用于写信息至闪存以便其后通过凤凰桌面管理接口(DMI)取回。DMI命令行标志被忽略,如果目标BIOS映象不支持DMI接口(没有安装DMI BCP结构)或PHLASHNT运行模式只是BIOS(见以上)。
所有标志都有格式/DxxString,其中xx是识别指定DMI串的(见以下)一或两个字符。DMI命令行标志是可选的;即,如果一个给定的DMI命令行标志不被指定,相应的DMI串缓冲的以前的内容不被修改,除非在PLATFORM.DLL中指定了缺省串。这种情况下,PHLASHNT总是写入缺省串至相应的DMI串缓冲。如果DMI命令标志被指定而没有String字段,相应的DMI串缓冲被清空(置为空串)。String只能包含可打印ASCII字符。String如果含有空格,则必须包含在引号中。每个DMI串的最大长度是与平台有关的;PHLASHNT返回有关错误信息,如果传递的串长过相应的目标缓冲。当前支持以下的DMI字段。这些选项为了安全理由不能由帮助(/H)选项显示。
/DSSString指定系统序列号串/DMSString指定系统制造商名串/DPSString指定系统产品(模块)识别串/DVSString指定系统版本串/DSMString指定母板序列号串/DMMString指定母板制造商名串/DPMString指定母板产品(模块)识别串/DVMString指定母板版本串
/DSCString指定机箱序列号串/DMCString指定机箱制造商名串/DPCString指定机箱产品(模块)识别串/DVCString指定机箱版本串/DO1String指定OEM串1…/DOnString指定OEM串n系统和机箱开关只用于DMI版本2.0命令行的旧形式,见以下,原用于DMI1.2并保持兼容。它们分别相当于/DSM,/DPM和/DVM。
/DSString指定母板序列号串/DMString指定母板制造商名串/DPString指定母板产品(模块)识别串/DVString指定母板版本串接下来,闪存程序将加载PLATFORM.DLL文件和调用PLATFORM.DLL中的与平台有关函数EnableFlash()为闪准备平台。PLATFORM.DLL指示BIOSROM将在存储器中加载的存储器区域和指示哪个存储器区域被用于闪设备。存储器区域可以在传统存储器中或在扩展存储器中。在ROM映象被加载至存储器后,设备编程开始。
对于被编程的每个闪存ROM块1.BeginFlash()在PLATFORM.DLL中被调用2.PHLASHNT.EXE中的正确算法被执行。
3.EndFlash()在PLATFORM.DLL中被调用该过程在每个PLATFORM.DLL中指定的闪存块重复。这用于单个平台中的多个设备,一个设备中的多个块和每个块的块相关初始化/终止代码。
这还用于存储器区域的自动保存和恢复,例如引导块。
在闪期间,过程信息被显示给用户1.如果生产模式未被选择,一个适合的消息窗口被显示在屏幕上,其中包括时间,气体表形式的进度指示和状态行消息。
2.大约一秒一次短蜂鸣。
3.在每步的开始和结束,一个适合的代码被发送这跟踪端口。
视频至少被一秒更新一次。声音大约每秒生产一次。注意生产环境过程更新可以被禁止。
在闪完成之后,DisableFlash()被从PLATFORM.DLL文件中执行。两个不同的声音之一被生产以指示闪过程的成功或失败。如果有视频,适合的消息窗口被显示。在短暂的暂停后系统重引导。
2.3完成代码虽然程序通过许多步骤进行和能够报告给用户每个步骤的状态,只有三个主要阶段被声音和键盘LED代码识别。三个主要阶段是1.读和确认PLATFORM.DLL文件2.进行平台有关的初始化3.部件编程如果程序不能完成任何闪过程的三个主要阶段,程序将使用区别的声音序列和键盘LED以通知用户在哪个阶段失败。在程序的开始,键盘的CAPS_LOCK,NUM_LOCK和SCROLL_LOCK LED打开。三个阶段的每一个的失败指示如下声音 键盘LED开描述低蜂鸣+3短音 CAPS,NUM,SCROLL1.开始读platform.dll前低蜂鸣+2短音 CAPS,NUM, 2.初始平台前低蜂鸣+1短音 NUM 3.初始平台后一个长音 无 成功完成阶段1-失败发生在定位PLATFORM.DLL之前。最可能是因为PLATFORM.DLL文件格式错误。系统处于稳定模式,BIOS没有发生改变,不需要重引导。
阶段2-在平台有关初始时失败。。系统不稳定和需要重引导。BIOS未发生改变。
阶段3-在对闪存编程时发生失败。系统不稳定和BIOS闪存被破坏。系统必须用急救软盘重新开始。
该程序还在每个步骤进行错误检测。除非通过PRODUCTION选项明确禁止,在程序进行时,在屏幕和跟踪端口报告当前进行的步骤的步骤号,或错误代码。错误的代码号和程序在附件B2中被进一步定义。
当在对闪存部件作出任何改变之前检测到错误,程序将试图通知用户和带有正确的错误消息而退出PHLASHNT。一旦闪存被修改,错误将使程序停止。
2.4设备相关模块对于支持的每种闪存类型,将有一个部件指定模块进行以下1.识别部件和返回制造商ID和部件ID2.清零闪存范围(设置所有位为0)3.擦除闪存范围(设置所有位为1)4.编程闪存范围2.4.1自动检测这个模块是从闪存部件中读取制造商ID和部件ID所需的代码。如果不能确定这些ID,返回零。当在PLATFORM.DLL文件中提供AutoSense()函数;内置自动检测模块不被采用;而采用提供的AutoSense()函数。
2.4.2零有一些类型要求在被编程前闪存被置为零。这个模块中是设置存储器范围为零所需的代码。
2.4.3擦除大多数闪存部件要求在部件被编程前置为1。这些部件经常允许用一个写操作擦除闪存的整个块。在该模块中是将存储器范围置为1必须的代码。
当块描述符在PLATFORM.DLL文件中被定义时,必须建立描述符使闪存中每个“可擦除”块有至少一个描述符。例如在英特尔28F004闪存中,有一个16K字节BOOT块,两个8K字节PARAMETER块,一个96K字节MAI N块和三个128K字节EXTENDED块。七个块中的每一个能用一个写擦除和七个块的每一个必须有至少一个描述符。
2.4.4程序在这个模块中是从BIOS ROM映象中读取数据字节和将它们编程进闪存部件所需的代码。
2.5支持的设备由PHLASHNT.EXE支持的闪存设备的初始设置包括下表列出的部件。对于每个部件类型,列出了制造商和部件ID和部件描述。当有新的部件时,需要增加新的模块至PHLASHNT.EXE使得可以提供闪算法的新类型(新的AutoDetect(),Zero(),Erase(),Program()函数)。如果新的部件可能使用已有的算法而只是制造商和部件ID改变了,可以在PLATFORM.DLL文件中指出并不需要修改PHLASHNT.EXE(详情见PartTypes部分)。
类型 Mfg ID Part ID描述2 0x010xA1 AMD28F2562 0x010x25 AMD28F5121 0x010xA7 AMD28F0101 0x010xA2 AMD28F010A2 0x010x2A AMD28F0202 0x010x29 AMD28F020A2 0x010x20 AMD29F0102 0x010xA4 AMD29F0402 0x010x51 AMD29F200T1 00x00xB0 AMD29F002T1 00x00x34 AMD29F002B1 0x010xDC AMD29F002BXT1 0x010x5D AMD29F002BXB3 0x1F0xD5 ATMEL 29C0108 0x1F0xDA ATMEL 29C0203 0x1F0x35 ATMEL 29LV0101 0x1C0xD0 Mitsubishi 28F1011 0x890xB9 Intel 28F2561 0x890xB8 Intel 28F5121 0x890xB4 Intel 28F0101 0x890xBD Intel 28F0204 0x890x94 Intel 28F001 BX-T4 0x890x95 Intel 28F001 BX-B4 0x890x7C Intel 28F002 BX-T4 0x890x7D Intel 28F002 BX-B4 0x890x74 Intel 28F200 BX-T4 0x890x75 Intel 28F200 BX-B4 0x890x78 Intel 28F004 BX-T4 0x890x79 Intel 28F004 BX-B4 0x890x70 Intel 28F400 BX-T4 0x890x71 Intel 28F400 BX-B5 0xBF0x07 SST 29EE010/29LE01012 0xBF0x10 SST 29EE0205 0xBF0x5D SST 29EE5126 0xBF0x04 SST 28SF0401 0x200x07 ST M28F1017 0xC20x11 MX 28F100011 0xC2 0x2A MX 28F2000
3.0PLATFORM.DLL详情该模块包含所有与平台有关的代码和在特定平台上对闪存编程所需的参数。
3.1文件格式PLATFORM.DLL是视窗DLL,由PLATFORM.CPP编译生成(使用微软VisualC++ 4.2或其后版本)。它包含特定的平台数据和可执行代码。
PLATFORM.CPP文件的一个例子包含在附件B3中。
PLATFORM.DLL的文件版本将从版本“NT 1.00”开始。版本是由包含在PLATFORM.DLL中包含的szVersion变量指定。
3.2文件头部格式PLATFORM.DLL文件有以下描述的格式//----------------------------------------------//全局变量声明//---------------------------------------------DWORD dwFileSize//ROM映象文件大小BYTE bManufactID //闪存制造商BYTE bPartID //闪存设备部件IDDWORD dwFlags //选项标志DWORD dwImageBuf//映象文件的线性地址DWORD dwMfgIDAddr //制造商ID的线性地址DWORD dwPartIDAddr //部件ID的线性地址BYTE bRetryCount ///Rn选项计数(缺省=0)char szVersion[] //PLATFORM.DLL版本char szROMFileName[] //BIOS映象文件名DWORD dwDLLFuncDefine //指示哪个函数被定义BYTE BBLOCKtABLEsIZE //blockTable中块的个数BLOCK_DESCRIPTOR blockTable[]BYTE bpartTypesSize//增加的闪存部件数DEVICETABLE partTypes[]dwFileSizeBIOS.ROM文件中字节数bManufactID 制造商ID
bPartID部件IDdwFlags选项标志。必须是以下值的组合FLAG_AUTOSENSEOFF不从部件读取IDFLAG_BACKUP 备份系统BIOS ROMFLAG_NEWBIOSONLY 如果在F000:0的64K相同,则不闪FLAG_PRODUCTION 最大速度(声音和视频关)FLAG_SILENT 不产生任何声音FLAG_VERIFY 在闪后确认每个块FLAG_PLATFORMCMD PLATFORM选项串存在FLAG_BIOSPARTNUM 闪相同的BIOS部件号FLAG_CHECKSUM校验求和BIOS.ROMFLAG_CMOS清CMOS校验求和FLAG_IMAGESIZE 确认映象大小与闪存部件匹配DwImageBuf BIOS.ROM映象在扩展存储器中缓冲的地址。该字段确定映象被读入的缓冲区线性地址。
该区域还在SAVE线性被指定时使用。被存储的任何块将使用dwImageBuffer+dwFileSize开始的地址范围。
dwMfgIDAddrdwPartIDAddr这两个可选字段包含闪存ID字节的线性地址。当这些字段是零时,使用缺省地址E0000h和E0001h。
BRetryCount 如果闪失败重试的次数。
SzVersion PLATFORM.DLL的版本SzROMFileName 保留给串“BIOS.ROM”。该字段用于识别和确认PLATFORM.DLL文件的格式。
DwDLLFuncDefine 指出在PLATFORM.DLL中定义了哪些与平台有关的函数。
BblockTableSize 在blockTable中描述的块的个数。
DwBlockTable 闪存部件一次被编程一个连续块。被编程的每块必须有相应的描述符。
BpartTypesSize 增加的闪存部件个数DwPartTyes 支持的闪存部件的选项表。表的每项有以下格式
Typedef struct{BYTE CmFGid; //制造商IDBYTE cPartID;//部件IDWORD wFlashType //闪算法类型Char szPartName[28] //可选描述}DEVICETABLE;设备表由描述符终止,cMfgID,cPartID,wFlashType被置为0。许多平台允许多个不同的部件采用相同的BIOS.ROM映象。当有新的部件时,部件不在PHLASHNT.EXE当前支持的部件中时和该部件采用与支持的部件中的一个所用的闪算法相同时,采用该表。
ProcEnable 使能闪过程ProcDisable 禁止闪过程ProcBegin 闪过程开始ProcEnd 结束闪过程ProcGetBlock为备份过程取得下一个BIOS块ProcCmdLine 处理定制命令行选项过程ProcSense 定制autosense过程ProcIsflashable 定制OEM过程以确定是否可以进行ProcReboot 定制重引导过程ProcCheckSum如果BIOS ROM映象的校验求和不为零,定制采用的校验求和过程在附件B3中示出PLATFORM.DLL的示例性源代码。
3.3块表格式块表包含块描述符的列表。表中的每个块描述符由以下结构定义typedef struct{DWORD dwBlockSize; //块中的字节数DWORD dwFileOffset; //BIOS.ROM文件中的偏移DWORD dwLinearAddress; //闪存ROM的线性32位地址BYTE cMfgID //制造商ID或0
BYTE cPartID //部件ID或0WORD wBlockAttr//块属性}BLOCK_DESCRIPTOR;块表由描述符终止,所有入口置为0。
DwBlockSize 块的字节大小。块必须连续DwFileOffset BIOS.ROM文件中该块的偏移DwLinearAddress 该块在32位地址空间中的起始地址CmfgID 制造商ID或为0自动检测CpartID 部件ID或为0自动检测WBlockAttr 确定对该块进行的动作。必须是以下标志的组合ATTR_ZERO在被编程前块必须被置为0ATTR_ERASE 在被编程前块必须被擦除ATTR_SAVE在被编程前保存该块内容ATTR_PROG编程该块ATTR_RESTORE 在编程后恢复该块内容一次只能使用ATTR_SAVE,ATTR_PROG,ATTR_RESTORE中的一个。如果未指定属性,PHLASHNT.EXE不改变块。但是,即使所有这些被省略,还调用BeginFlash()和EndFlash()。BeginFlash()和EndFlash()当两块在不同的闪存设备上时使用,或引导块要求附加函数以使能块写入或在下一个编程前禁止它时使用。BeginFlash()还被用于条件块处理。如果BeginFlash()返回非零,当前块不处理。
每个ATTR_SAVE块在另一个ATTR_SAVE块被使用前,其后必须是ATTR_RESTORE块。
注意对于给定闪存存储器范围,可以有多个描述符。例如对于64K可擦除闪存中保留的16K闪存引导块,可以使用3个块描述符。第一个描述符保存16K引导块,第二个擦除和编程64K和第三个恢复引导块。
为减少闪所需的时间,推荐不使用ATTR_ZERO标志,因为这将避免清零步骤和减少一半闪时间。只有很少旧的闪存类型建议在重编程前进行部件清零。大多数部件不要求这个操作。
3.3.3多闪存块使用块表以支持多设备闪和每个设备多块。对于这种平台,ROM映象文件必须包含被编程的所有闪存部件的映象和块表必须包含被闪的数据的每个块的正确偏移和长度。
为了在每个闪存块之前和之后正确配置平台,PHLASHNT.EXE将调用函数BeginFlash(Block_Index)以允许PLATFORM.DLL进行任何这种设置。BeginFlash()和EndFlash()函数的任务是按照需要进行块间的任何初始化和终止。
3.3.4处理引导块和ESCD存储为了在一个闪存中编程一个存储器区域,可能对相同的存储器区域不得不有多个不同的块描述符。这可能需要保护在单个“擦写”存储器区域中的引导块或ESCD存储器许多闪存部件有少量的写操作作擦写,每个存储器块一个(例如英特尔28F400闪存有7个块(一个16K引导块,两个8K参数块,一个64K主块和3个128K扩展块)。这些部分只能用7个写操作擦除。)对于其他部件,擦除功能可以一次擦除64K闪存,不论该范围被分为引导和参数块。在这种情况下,重要的是存储器的每个64K块有3个块描述符。表中的第一个块描述符用于保存引导块,第二个块描述符擦除和编程参数块和第三个描述符在该范围恢复引导块。
一些部件要求在引导块被编程前进行附加的平台相关动作。例如英特尔部件要求VHH电压,及VPP电压被正确设置。在这种情况下,块描述符必须在BeginFlash()和EndFlash()过程中有这种函数(在每个块之前和之后调用)。
3.3.5块表实例以下是PLATFORM.CPP的“blockTable”部分中的代码。
擦除FC000处的4KB块DD4*1024 ;4KBDD0 ;文件偏移DD000FC000h ;该块的线性地址DB0 ;制造商ID(0=缺省)DB0 ;部件ID(0=缺省)DWATTR_ERASE ;动作标志清零,之后在指定部件在E000处编程128KB块DD128*1024;128KBDD0 ;文件偏移
DD000FC000h;该块的线性地址DB0;制造商ID(0=缺省)DB0;部件ID(0=缺省)DWATTR_ERASE ;动作标志3.4PLATFORM.DLL函数当前支持的函数是包含在PLATFORM.DLL中的以下函数被PHLASHNT.EXE访问以实现平台相关功能EnableFlashDisableFlashBeginFlashEndFlashGetBlockCmdLineAutoSenseIsFlashableRebootCheckSum以下函数允许PHLASHNT.EXE访问包含在PLATFORM.DLL中的全局变量和数据结构GetBIOSFileSizeGetManufactIDGetPartIDGetFlagsGetImageBufGetMfgIDAddrGetPartIDAddrGetRetryCountGetblockTableSizeGetpartTyupesSize
GetBlockTableGetpartTypesGetDLLVersionGetROMFileNameGetDLLFuncDefine3.4.1函数EnableFlash()入口无返回错误代码(或零)该函数必须出现在PLATFORM.DLL中。在任何试图访问闪存前调用它。这个函数进行的动作包括映射闪存至存储器禁止高速缓存,阴影和电源管理刷新高速缓存禁止PCI桥使能ROM以写(VPP开)大多数平台要求在部件被使能闪前改变一个跳接器。EnableFlash()过程必须确认这个跳接器已被去除并返回一个错误代码,如果它确定该跳接器设置错误。错误代码见附件B。
3.4.2函数DisableFlash()入口无返回错误代码(或0)该可选函数在最后一个块被编程(或检测到错误)后被调用。在PHLASHNT.EXE退出前被立即调用(一般作为重引导前的最后一个函数)。该函数一般进行的动作包括禁止ROM写入(VPP关)3.4.3函数BeginFlash(DWORD Block_Index)入口将被编程的块的索引(或如果不使用表为0)退出无返回错误代码(或0)这个可选函数被PHLASHNT.EXE在该闪存块被处理前立即被调用。它为(在块表中找到的)每个块调用。
该函数一般进行的动作包括在它被擦除前保存引导块从一个设备转换到另一个(在有多个设备的平台上)使能VHH使引导块重编程确定是否当前块被处理如果BeginFlash()返回非零,当前块不被处理。
3.4.4函数EndFlash(DWORD Block_Index)入口刚被编程的块的索引(如果不使用表为零)返回错误代码(或零)这个可选函数被PHLASHNT.EXE在该闪存块被处理后立即被调用。它为(在块表中找到的)每个块调用。
该函数一般进行的动作包括恢复由BeginFlash()函数保存的引导块在编程两个不同设备之间去除禁止VHH,如果引导块刚刚被编程3.4.5函数GetBlock(DWORD Index,DWORD Buffer_Address)入口被拷贝块的索引和64K缓冲区线性地址退出用现有的BIOS ROM映象的下一个块填写缓冲区返回负错误代码,零,或正块索引当/BACKUP标志被指定时,PHLASHNT.EXE调用可选函数。GetBlock()用于在闪存被改变之前保存闪存已有内容。因为许多的BIOS映象被解压缩至阴影RAM,PHLASHNT.EXE不是总可以访问所有的BIOSROM映象而没有平台相关相同设置。函数GetBlock()需要允许平台相关访问已有的BIOS ROM映象。BIOS ROM映象被PHLASHNT.EXE保存,使用以下步骤1.调用GetBlock(Index,Buffer)而Index置为0和64K缓冲区,由参数缓冲区指向,填入预定义方式。如果缓冲区的方式未被改变,程序带错误退出。如果方式被改变,方式被作为第一个64K块存入BIOS.BAK文件。之后程序进行到下一步。
2.调用GetBlock(Index,Buffer),Index置为前一个GetBlock()调用的返回值,保存64K缓冲区至BIOS.BAK和重复直至GetBlock()的返回值是非正数。
3.如果GetBlock()返回的最后一个值是零,则进行存储器闪。如果最后返回值是负错误代码,报告错误,删除BIOS.BAK并退出。
GetBlock()实现的任务是保证平台处于正确状态以允许GetBlock()拷贝BIOS ROM映象至缓冲区和在GetBlock()返回控制至PHLASHNT.EXE前平台恢复至原来模式。特别是,GetBlock()在调用EnableFlash()前被调用。传递给GetBlock()的缓冲区指针总是在64K以下的真实存储器范围,允许直接传递至磁盘。
3.4.6函数CmdLine(char *szOptions)入口有平台指定命令行选项的串指针返回错误代码(或0)该选项函数由PHLASHNT.EXE在PLATFORM.DLL被读入后立即调用。包含所有的平台指定命令行参数的字符串的地址被传入(在等号后被指定/PLATFORM=”命令行选项”)。如果有的话字符串包括包括前和后双引号。
3.4.7函数AutoSense()入口由PLATFORM。INI头部取回的制造商和设备ID返回从闪存部件取回的新的ID(或0)这个函数被PHLASHNT.EXE在在PLATFORM.DLL中的EnableFlash()函数被调用后立即被调用。当“非标准”存储器组织被用于闪存时,AutoSense()函数使能自动检测闪存部件。例如,当两个分开的部件被用于偶和奇BIOS地址(在这种情况下,传统自动检测将失败),该函数被用于获得和确认每个部件的ID。
ID是一字节长和被放入一个DWORD,制造商ID放入BYTE 0而设备ID放入BYTE 1。
3.4.8函数IsFlashable(char far *szErrorMsg)入口包含返回的错误信息字符串的指针退出szErrorMsg包含错误信息串返回错误代码(或0)该可选函数在EnableFlash()前调用确定是否可以进行处理前被调用。
如果函数返回非零错误代码,字符串szErrorMsg被显示并且程序终止。最多254加一个空终止符可以在szErrorMsg中返回。
如何使用它的一个例子是对于相同平台,OEM出售带或不带即插即用功能的系统。IsFlashable()函数能够确定系统当前是否是即插即用和在没有它的系统中不闪即插即用BIOS。
3.4.8函数Reboot()入口无返回无这个可选函数在编程结束后被调用以复位系统。如果被提供,它被调用而代替PHLASHNT自己的重引导代码。
3.4.10函数CheckSum()入口无返回错误代码(或0)在编程前调用这个可选函数确定BIOSROM允许的校验求和是否正确。一般,NuBIOS映象的BIOS ROM映象校验求和是零。当已知ROM映象校验求和将不是零时,这个例程可以用于提供另一种校验求和确认方法。如果这个函数返回非零,PHLASHNT将终止。
3.4.11函数GetBIOSFileSize()入口无返回BIOS映象的大小该函数从PLATFORM.DLL中返回全局变量dwFileSize的内容。
3.4.12函数GetManufactID()入口无返回制造商ID该函数从PLATFORM.DLL中返回全局变量bManufactID的内容。
3.4.13函数GetPartID()入口无返回部件ID该函数从PLATFORM.DLL中返回全局变量bPartID的内容。
3.4.14函数GetFlags()入口无返回选项标志该函数从PLATFORM.DLL中返回全局变量dwFlags的内容。
3.4.15函数GetImageBuf()入口无返回映象缓冲区的位置该函数从PLATFORM.DLL中返回全局变量dwImageBuf的内容。
3.4.16函数GetMfgIDAddr()入口无返回制造商ID的地址该函数从PLATFORM.DLL中返回全局变量dwMfgIDAddr的内容。
3.4.17函数GetPartIDAddr()入口无返回部件ID的地址该函数从PLATFORM.DLL中返回全局变量dwPartIDAddr的内容。
3.4.18函数GetRetryCount()入口无返回闪失败后重试的次数该函数从PLATFORM.DLL中返回全局变量bRetryCount的内容。
3.4.19函数GetblockTableSize()入口无返回blockTable中块的个数该函数从PLATFORM.DLL中返回全局变量bblockTableSize的内容。
3.4.20函数GetpartTypesSize()入口无返回PLATFORM.DLL将描述的附加闪存部件的个数该函数从PLATFORM.DLL中返回全局变量bpartTypesSize的内容。
3.4.21函数GetBlockTable()入口无返回blockTable的地址该函数从PLATFORM.DLL中返回全局结构blockTable的地址。
3.4.22函数Getpar tTypes()入口无返回partTypes的地址该函数从PLATFORM.DLL中返回全局结构partTypes的地址。
3.4.23函数GetDLLVersion()入口无返回PLATFORM.DLL的版本该函数从PLATFORM.DLL中返回全局变量szVersion的内容。
3.4.24函数GetROMFileName()入口无返回BIOS ROM文件名该函数从PLATFORM.DLL中返回全局变量szROMFileName的内容。
3.4.25函数GetDLLFuncDefine()入口无返回在PLATFORM.DLL中定义哪些平台有关的函数该函数从PLATFORM.DLL中返回全局变量dwDLLFuncDefine的内容。
4.0BIOS.ROM详情ROM映象文件大小必须足够大以容纳被编程的闪存设备中的所有块。任何BIOS映象所需的后处理,例如引导块交换或数据压缩,必须已包含在ROM映象文件中。
5.0一般实现指导使用微软Visual C++ V4.2和其后版本开发。
因为这个程序是新的设备可用和代码大小不是很重要,编码的风格应使代码可读和清晰的重要程度高于可执行代码的的小型化。
但是,因为程序也用于产品环境,它应当使部件闪操作的时间最短。特别是,它应当尽可能使非关键性用户界面提示可以被禁止;有可能的话,闪函数花费的时间用汇编语言优化。
附件B1-进一步增强带有键盘LED的完成代码如果程序不能完成闪过程的三个主要阶段的任一个,程序将使用键盘LED以通知用户程序的哪个阶段程序失败。在程序开始时键盘上的CAPS_LOCK,NUM_LOCK和SCROLL_LOCK LED打开。三个阶段的每个阶段的失败由以下指示键盘LED开 描述CAPS,NUM,SCROLL 在读platform.dll前CAPS,NUM 在platform初始前NUM 在platform初始后无成功完成附件B2-PHLASHNT.H完成和错误代码FFh BIOS.BAK缓冲区存储器分配失败FEh BIOS.BAK已存在(重命名或删除)FDh BIOS.BAK文件建立失败FCh BIOS.BAK文件写入失败FBh BIOS.BAK文件关闭失败FAh PLATFORM.DLL不支持BIOS备份F9h PLATFORM.DLL文件打开失败F8h PLATFORM.DLL文件读取失败F7h PLATFORM.DLL文件关闭失败F6h 不能在PLATFORM.DLL中定位字节位置F5h 不支持的PLATFORM.DLL文件版本F2h PLATFORM.DLL中的设备表有过多的项F1h PLATFORM.DLL中的设备表有不支持的闪存类型F0h 在PLATFORM.DLL中组合保存和恢复属性EFh 保存块而不匹配PLATFORM.DLL中的恢复块ECh 在支持的部件表中未找到部件IDEBh PLATFORM.DLL在命令行参数中找到错误Eah BIOS ROM映象分配错误E9h 打开BIOS ROM映象文件错误E8h 读取BIOS ROM映象文件错误E6h BIOS.ROM文件关闭错误E4h 试图读闪存ID失败E3h PLATFORM.DLL不能返回闪存IDE2h 在BIOS ROM文件映象中不能找到BCPSYS块E1h 文件不包含相同的BIOS部件号E0h 文件不包含BIOS ROM映象的不同版本DFh 写入闪存的数据与BIOSROM映象不匹配Deh 写入闪存失败DDh 擦除闪存块失败DCh VPP不在希望的范围DBh 擦除序列失败
Dah 新的DMI串过大D9h BIOS ROM文件可能不用于这个系统D8h 分配DMI OEM串失败D7h 在BIOS ROM中没有DMI OEM串的空间D6h DMI OEM串不支持(要求BCPDMI 0.1+)D5h 在BIOSROM文件映象中不能找到BCPDMI块D3h BIOS ROM文件可能被破坏(校验求和不为零)D2h BIOS ROM文件大小与闪存部件大小不匹配D1h DMI系统和机箱串要求BCPDMI 2.1+
附件B3-PLATFORM.DLL示例源代码PLATFORM.CPP/***题目PLATFORM.CPP-32位DLL用于PHLASHNT.EXE*的与平台相关函数*版权所有 凤凰技术公司 1997(C)*****************************************文件名PLATFORM.CPP*工程PLATFORM.EXE*功能块*注释变量dwDLLFuncDefine在PHLASHNT中用于确定*PLATFORM.DLL中确定了哪些与平台有关函数。
*以下列出的是dwDLLFuncDefine可能的值和它们在模块中定义*的函数* DLL_ENABLEFLASH EnableFlash* DLL_DISABLEFLASH DisableFlash* DLL_BEGINFLASHBeginFlash* DLL_ENDFLASH EndFlash* DLL_GETBLOCK GetBlock* DLL_CMDLINE CmdLine* DLL_AUTOSENSE AutoSense* DLL_ISFLASHABLE IsFlashable* DLL_REBOOTReboot* DLL_CHECKSUM ChectSum*内容*****************************************版本控制信息* $Logk/nb/archive/nuttols/phlash.nt/stage2/drivers/platform.cpv$
* Rev 1.0*最初再版****************************************#include ″stdfx.h″#include<afxdllx.h>
#include<stdio.h>
#include″d\nutools\phlash.nt\stage2\phlashnt.h″#define PLATFORM_CPP//------------------//全局变量声明//-----------------DWORD dwFileSize=0x00040000; //ROM映象文件大小BYTE bManufactID=0x89 //闪存设备制造商BYTE bPartID=0xBD //闪存设备部件IDDWORDdwFlags=FLAG_BIOSPARTNUM|FLAG_CHECKSUM|FLAG_IMAGESIZEDWORD dwImageBuf=0x00200000//映象缓冲区的线性地址DWORD dwMfgIDAddr=0xFFFE0000 //制造商ID的线性地址DWORD dwPartIDAddr=0xFFFE0001 //部件ID的线性地址BYTEbRetryCount=0 ///Rn选项的计数(缺省为零)CharszVersion[]=″NT 1.00″ //platform.d11版本CharszROMFileName[]=″BIOS.ROM″//BIOS映象文件名//指示PLATFORM.DLL中定义了哪些函数DWORD dwDLLFuncDefine=DLL_ENABLEFLASH |DLL_DISABLEFLASH |DLL_BEG INFLASH |DLL_ENDFLASH |DLL_GETBLOCK |DLL_CMDLINE |DLL_AUTOSENSE |DLL_ISFLASHABLE |
DLL_REBOOT |DLL_CHECKSUM//---------------------//定义blockTable//----------------------BYTE bblockTableSize=5 //blockTable中块的个数BLOCK_DESCRIPTOR blockTable[]={{128*1024,//128KB(低)0,//文件偏移0xFFFE0000,//闪存ROM的线性地址0,//MfgID(与缺省相同)0,//PartID(与缺省相同)ATTR_ZERO},{128*1024,//128KB(高)0x00020000,//文件偏移0xFFFE0000,//闪存ROM的线性地址0,//MfgID(与缺省相同)0,//PartID(与缺省相同)ATTR_ZERO},{128*1024,//128KB(低)0,//文件偏移0xFFFE0000,//闪存ROM的线性地址0,//MfgID(与缺省相同)0,//PartID(与缺省相同)ATTR_ERASE
},{128*1024,//128KB(低)0,//文件偏移0xFFFE0000,//闪存ROM的线性地址0,//MfgID(与缺省相同)0,//Part ID(与缺省相同)ATTR_PROG},{128*1024,//128KB(高)0x00020000,//文件偏移0xFFFE0000,//闪存ROM的线性地址0, //MfgID(与缺省相同)0, //PartID(与缺省相同)ATTR_PROG},{ //将块置为0以终止blockTable需要0,0,0,0,0,0},};//-------------------//定义partTypes//--------------------BYTE bpar tTypesSize=1 //平台中闪存部件的个数//如果不使用partTypes则置为0DEVICETABLE partTypes[]=
{{0x89, //闪存设备制造商ID0Xbd//闪存设备设备ID1, //闪操作算法类型0, //忽略wPartSizeIntel 28F0202″//闪存设备名},{ //将块置为0以终止parTypes需要0,0,0,0,″″},};HINSTANCEhKernel 32=0;//注意不要改变这行代码。
/**************************函数********************************/*********************************函数名DllMain**描述*参数*返回**注意不要修改这个函数**********************
extern″C″int APIENTRYDllMain(HINSTANCE hInstance,DWORD dwReason,LPVOID lpReserved){if(dwReason==DLL_PROCESS_ATTACH){TRACE0(″PLATFORM.DLL Begin|\n″);HKernel 32=LoadLibrary(″Kernel32.d11″);//取得Kernel 32.d11的句柄}else if(dwReason==DLL_PROCESS_DETACH){TRACE0(″PLATFORM.DLL Terminating|\n″);If(HKernel 32)FreeLibrary(hKernel 32);;}return 1;//ok}//DllMain()/****************************函数名EnableFlash**描述*参数*返回**注意**********************DLL_FUNC_TYPE void EnableFlash(){printf(″EnableFlash\n″); //(s tub)}
/****************************函数名DisableFlash**描述*参数*返回**注意**********************DLL_FUNC_TYPE void DisableFlash(){printf(″DisableFlash\n″);//(stub)}/****************************函数名BeginFlash**描述*参数*返回**注意**********************DLL_FUNC_TYPE short BeginFlash(USHORT blockNumber){return 0;//(stub)}/****************************函数名EndFlash*
*描述*参数*返回**注意**********************DLL_FUNC_TYPE short EndFlash(USHORT blockNumber){return 0;//(stub)}/****************************函数名GetBlock**描述*参数*返回**注意**********************DLL_FUNC_TYPE SHORT GetBlock(ULONG dwIndex,FULONG dwDst){printf(″GetBlock;dwIndex,dwDst passd in=%d,%d\n″,dwIndex,dwDst);//(stub)}/****************************函数名CmdLine**描述*参数*返回
**注意**********************DLL_FUNC_TYPE USHORT CmdLine(char *PlatformString){printf(″CmdLine\n″);//(stub)return(0);//(stub)}/****************************函数名AutoSense**描述*参数*返回**注意制造商ID在BYTE 0,设备ID在BYTE 1**********************DLL_FUNC_TYPE DWORD AutoSense(DWORD PartID){return (0x0000);//(stud)}/****************************函数名IsFlashable**描述*参数*返回**注意**********************
DLL_FUNC_TYPE USHORT IsFlashable(){printf(″IsFlashable\n″);//(stub)return 0;}/****************************函数名Reboot**描述*参数*返回**注意**********************DLL_FUNC_TYPE void Reboot(){printf(″Reboot\n″);//(stub)}/****************************函数名CheckSum**描述*参数*返回**注意**********************DLL_FUNC_TYPE void CheckSum(){printf(″CheckSum\n″);//(stub)
}//--------------------------//注意不要修改以下函数//----------------------------DLL_FUNC_TYPE DWORD GetBIOSFileSize(void){return(dwFileSize);}DLL_FUNC_TYPE BYTE GetManufactID(void){return(bManufactID);}DLL_FUNC_TYPE BYTE GetPartID(void){return(bPartID);}DLL_FUNC_TYPE DWORD GetFlags(void){return(dwFlags);}DLL_FUNC_TYPE DWORD GetImageBuf(void){return(dwImageBuf);}DLL_FUNC_TYPE DWORD GetMfgIDAddr(void){return(dwMfgIDAddr);}DLL_FUNC_TYPE DWORD GetPartIDAddr(void){return(dwPartIDAddr);}DLL_FUNC_TYPE BYTE GetRetryCount(void){return(bRetryCount);}DLL_FUNC_TYPE BYTE GetblockTableSize(void){return(bblockTableSize);}DLL_FUNC_TYPE BYTE GetpartTypesSize(void){return(bpartTable
);}DLL_FUNC_TYPE BLOCK_DESCRIPTOR *GetBlockTable(void){return(&blockTable[0”;}DLL_FUNC_TYPE DEVICETABLE*GetpartTable(void){return(&partTable
);}DLL_FUNC_TYPE char*GetDLLVersion(void){return(szVers ion);}DLL_FUNC_TYPE char*GetROMFileName(void){return(szROMFileName);}DLL_FUNC_TYPE DWORD GetDLLFuncDefine(void){return(dwDLLFuncDefine);}
附件C摘要本文件用于新的BIOS服务,称为BIOS32服务目录。新的服务将提供有关BIOS服务的信息,它们用于在32位代码段中运行的调用者。
(BIOS32服务目录自己是有关32位BIOS服务)该服务的客户是32位操作系统和32位设备驱动程序。该服务的提供者是实现一个或多个32位BIOS服务的BIOS供应商。
介绍BIOS32服务目录建议是在为外围部件互联(PCI)标准建立32位代码接口时出现的。要解决的主要问题是32位调用者如何确定32位BIOS服务的存在?功能接口的缺点(即,控制被转移至的入口点)在功能接口不存在的情况下是清楚的。可恢复方法似乎需要查找证明功能接口存在的签名。实际上,第一BIOS32位服务之一,EISA,使用0F000h处的固定位置的现有签名。但是,需要愈来愈多的BIOS服务和有愈来愈多的BIOS服务,显然给每个服务提供一个签名(以及任何相关信息,例如每个的入口点,段需求)对于紧张的存储器资源是一个消耗。因此,BIOS32服务目录后的思路是使用单一的签名标识一般32位服务,它返回所有指定32位服务的信息。
实现一般方案的进一步调整相对于继续逐个解决问题的优点是为工业提供标准。新的32位BIOS接口的代码重用性,模块化(“可插入”)实现等,通过调用环境需求标准,是可以想象到的优点。
BIOS32服务目录有两个部分头部和调用接口。头部是包含签名和位于已知存储器区域的静态数据结构。有效头部的存在表示调用接口的存在和实际上,描述它的入口点。调用接口是代码体和在由头部和任何特定32位BIOS服务分开的分立存储器空间中存在的数据。它提供了功能性接口,提供它调用者接收特定32位BIOS服务的信息。(部分0描述头部的假设存储器映象,调用接口,和32位BIOS服务的“XYZ”)。调用接口设计可以在二维扩展。第一,它是基于函数的接口,进一步更新服务可以加入新的功能,如果需要的话。第二,特定32位BIOS服务由4字节部件ID表示。这使OS调用者和BIOS32服务目录实现器两者相似从而在有新的32位BIOS服务时容易增加。
BIOS32服务目录接口,和示例综述2BIOS 32服务目录头部实现BIOS32服务目录的BIOS必须嵌入物理存储器范围0E0000h-0FFFFFh中某处特定的连续16字节方式。该方式必须分段对准(即,它必须从16字节边界开始)。该方式已知为在BIOS32服务目录头部中。
头部包括6个分立的字段。下表描述每个字段。

表1BIOS 32服务目录头部BIOS32服务目录的客户必须首先通过定位头部而确定它的存在。这是通过以段为增量扫描0E0000h至0FFF0h在每段的前4个字节查找签名匹配(“_32_”)而实现。当,和如果,检测到签名,客户应进行头部所有字节的校验求和。(段中头部长度在偏移9h中找到。)头部的所有字节相加到一起应为0h。如果校验求和有效,则32位入口点字段可以用作BIOS服务目录调用接口的地址。如果头部未找到,则BIOS32服务目录在平台中不存在。
3 BIOS 32服务目录调用接口如果已经确定BIOS32服务目录存在(通过以上的头部检测),则在头部中找到的32位物理地址作为调用接口的入口点。客户应CALL FAR至该地址。客户的调用环境有以下要求3.1代码段
CS代码段选择器必须设置为有以下值的段描述符*基地址必须小于或等于包含入口点的页的(4KB)页地址。例如,如果入口点是0FFF81234H,则基地址必须小于或等于0FFF81000h。
*该范围必须使基地址加该范围生成一个地址大于或等于包含入口点的页之后的页的最后地址。例如,如果入口点是0FFF81234H则基地址加范围必须大于或等于0FFF82FFFH。
*简而言之,基地址和范围必须“包围”包含入口点的页和随后页。
*段类型必须是100b(代码,只能可执行)或101b(代码,可执行/读)。
但是,服务目录的实现不能假设CS代码段的读访问。
*系统位必须是1(非系统段)。
*推荐描述符专用级(DPL)为0。(CS描述符DPL成为当前专用级,或CPL)。如果CPL是非0,则OS必须提供环0专用指令(例如访问CRx)的捕获和虚拟服务。还请注意该字段的依赖于EFLAGS中IOPL字段(见段0)。
*缺省大小位必须为1(32位)。
BIOS 32服务目录入口点和它相关的代码和数据可位于4GB物理地址空间的任何位置。但是,必须保证物理连续(即,它被送入ROM或闪存空间)和可以放入两页(即,它不跨越3页)。
3.2数据段DS数据段选择器必须设置有以下值的段描述符*基地址必须等于CS基地址。
*范围必须大于或等于CS范围。
*段类型必须是000b(数据,只读)或001(数据,读/写)。但是,服务目录的实现不能假设DS数据段的写访问。
*系统位必须为1(非系统段)。
*描述符专用级(DPL)必须大于或等于CPL(见段0 DPL字段)。
对于ES,FS和GS数据段选择器没有要求。
3.3堆栈段SS堆栈段选择器必须设置有以下值的段描述符*段类型必须是011b(数据,读/写,向下扩展)或001b数据,读/写,向上扩展)。
*系统位必须为1(非系统段)。
*描述符专用级(DPL)等于CPL(见段0 DPL字段)。
*缺省大小位必须是1(32位)。
*间隔位必须是1(4KB)。
注意以上设置保证堆栈大小至少4kb。保证至少有1kb未使用堆栈是调用者的责任。
3.4分页分页可以或不使能。如果paging使能,由CS和DS选择器描述的地址空间必须是线性连续。即,在ROM或FLASH中找到的调用接口的原始物理连续性必须保持。(调用接口代码和数据被与位置无关和EIP相关写入)。
3.5IOPL为使调用接口执行I/O指令,EFLAGS中的I/O专用级(IOPL)字段必须大于或等于CPL(见段0中DPL字段)。
BIOS32服务目录调用接口是基于函数的和所有参数在寄存器中被传递。如果寄存器未被指定作为函数的输出参数,则它被保留。所有的标志被保留。函数值在寄存器BL中作为输入参数被传递。返回状态被传递回寄存器AL。返回状态00h表示函数成功。返回状态80h表示不支持所要求的函数(在BL)。其它AL返回值有单个函数定义。当前定义了一个BIOS32服务目录函数。它在以下说明。
3.6部件存在函数(BL=0h)部件存在函数返回指定的32位BIOS范围存在的信息和,如果存在,占据了哪个存储器空间。
输入BL,0hEAX,部件ID部件ID是4字节ASCII串,唯一标识32位BIOS范围。特定的BIOS范围标准定义自己的部件ID。(这些标准定义部件ID是左至右或右至左打包是很重要的。)EBX,保留,置为0h输出如果被请求的32位服务不存在AL=81h
如果被请求的32位服务存在AL=0hEBX=32位BIOS服务基地址ECX=32位BIOS服务长度EDX=32位BIOS服务入口点偏移(从EBX)EBX,ECX和EDX寄存器的含义与特定的32位BIOS服务标准有关。即,它们表示建立段选择器的精确值,最小“包围”值等。
3.7将来的函数将来的BIOS服务目录函数可以在本文件以后的再版中定义。函数参数接口不限于寄存器传递和可以采用堆栈上的输入/输出参数。由于堆栈的静态定义,使它很灵活(见部分0)。
4总结本文件描述了BIOS32服务目录。它识别两个不同的存储器部件头部和调用接口。头部是一个签名数据段,位于存储器范围0E0000h-0FFFFFh。调用接口是4GB地址空间中任何位置的物理连续段的代码体,并且长度小于两页(8kb)。头部包含指向调用接口存储器区域的指针。BIOS32服务目录调用接口函数描述附加的存储器区域,包含特定32位BIOS范围的代码和数据。后面是假定头部的存储器映象,调用接口和“XYZ”32位BIOS范围。
- 4Gb3----------------------------------------------------------------------------------------33 BIOS32 Servies Directary 3ffffffff ·3Calling Interface 3 ·3Code/Data 3<fffff> ·3----------------------------------------------------------------------------------------3 ··33 ··.. ··.. ··.. ··33 ··33 ··33 1Mb ··33 ··3----------------------------------------------------------------------------------------3 ··3 BIOS32 Service Directory 3 fffff% ·3 Leader 3 ·3----------------------------------------------------------------------------------------3 ·33 ·3----------------------------------------------------------------------------------------3 ·3 ″XYZ″32-bit BIOS Service 3 ·3 Code/Data 3<ffffffff>%3----------------------------------------------------------------------------------------333 E0000h33..
..
..
33 0000h本文件提供了访问32位BIOS服务的标准方法。由于32位BIOS服务被认可和实现,可以方便地使用BIOS32服务目录调用接口来提高标准方法。
#ifdef TESTEXEC//测试bios执行函数printf(″phadtest-test bios execution breakpoint\n″) ;ioExec=(PIOC_EXEC1) systemBuffer;ioExec->biosFunction=biosShadowAreaBaseVA+biosServiceDirectoryVA;strncpy((PUCHAR)(&ioExec->regEAX),BIOS_PM_SIGNATURE,,4);ioExec->regEBX=OL;if(DeviceIoControl(hDriver,IOCTL_BIOS_EXEC,bufferPtr,256,bufferPtr,256,&actualXfr,NULL)) {printf(″IOCTL 2052-BIOS Execute(%s)-success\n″,BIOS_PM_SIGNATURE);printf(″#bytes returned%Ld\n″,actuaLXfr);printf(″Register contents\n″);printf(″AL=%X\n″,(ioExec->regEAX )&0xff);printf(″EBX=%LX\n″,ioExec->regEBX);printf(″ECX=%LX\n″,ioExec->regECX);printf(″EDX=%LX\n″,ioExec->regEDX);}else{ioCode=GetLastError();printf(″IOCTL 2050 failed on %LX\n″,ioCode);}#endif附件D1
//--------------------------------------------------------------------------case IOCTL_BIOS_EXEC#ifdef DEBUGMZMzIokdPrint(4);#endif//函数4=代码2052是′BIOS执行′//该函数执行阴影区中的代码ioExecbios=(PIOC_EXEC1)(Irp->AssceiscedIrp.SystemBuffer);if(foundBios32==FALSE)·(//如果bios32未在其中找到ioExecBios->runStat=FALSE; //不运行return (IoCtlFinish(Irp,STATUS_SUCCESS,sizeof(IOC_EXEC1)));}//check the range of the requested function.
actualXfrd=rangecheck(ioExecBios->biosFunction,//函数地址1L, //只在e.p.中查找MODI_SHADOW, //读/执行模式BIOSlenBiosRom //ROM空间的长度};//范围检查失败if(actualxfrd==0) (return(IoCtlFinish(Irp,STATUS_ACCESS_DENIED,sizeof(Ioc_EXECI)));}//现在执行函数if((ioExecBios->biosFunction)==((ULCNG)bios32ServiceEntryPoint+(ULONG)romMapPtr)connectBios(ioExecBios,ioExecBios->biosFunction);elseexecBios(ioExecBios,ioExecBios->biosFunction);ioExecBios->runStat=1;return(IoCtlFinish(Irp,STATUS_SUCCESS,sizeof(IOC_EXEC1)));//不要忘记返回执行结构//-------------------------------------------------------------------附件D2
//这个函数建立寄存器文本和调用入口点voidexecBios{PIOC_EXEC1 systembuffer,ULCNG entrypoint}{#ifdef BIOS_FAR_CALLvoid(far″address32)(PIOC_EXEC1);#elsevoid(″address32)(PIOC_EXEC1);#endif″address32=(void (*) (PIOC_EXEC1)) entrypoint;_asm{mov eax,(systembuffar)//systembuffer的指针pusheaxpushes //用FAR调用call(address32)//调用服务目录}//(″address32)(systembuffer),//这是服务接口}附件D权利要求
1.一种安全利用基本输入输出系统(BIOS)服务的系统,包括访问驱动程序,产生利用BIOS服务的服务请求,服务请求包括利用密钥对中的专用密钥建立的服务请求签名;以及接口,利用密钥对中共用密钥校验服务请求签名以保证服务请求完整性。
2.根据权利要求1的系统,其中访问驱动程序产生会话请求以与接口建立会话;以及会话请求包括利用密钥对中专用密钥建立的会话请求签名。
3.根据权利要求1的系统,其中访问驱动程序产生会话请求以结束与接口的会话;以及会话请求包括利用密钥对中专用密钥建立的会话请求签名。
4.根据权利要求1的系统,其中接口产生权限证书并在接收会话请求之后将权限证书发送到访问驱动程序;以及访问驱动程序利用包括在权限证书中的信息产生后续会话请求。
5.根据权利要求4的系统,其中权限证书包括新的共用密钥。
6.根据权利要求4的系统,其中权限证书包括新的专用密钥。
7.根据权利要求4的系统,其中权限证书包括证书签名。
8.根据权利要求1的系统,其中接口产生权限证书并在接收服务请求之后将权限证书发送到访问驱动程序;以及访问驱动程序利用权限证书中的信息产生后续服务请求。
9.一种安全调用基本输入输出系统(BIOS)服务的方法,包括产生调用BIOS服务的服务请求;利用密钥对中的专用密钥产生的服务请求签名签署服务请求;以及利用密钥对中共用密钥校验服务请求签名以保证服务请求完整性。
10.根据权利要求9的方法,还包括在处理服务请求之后产生包括新的专用密钥和新的共用密钥的权限证书;以利用新的专用密钥产生的服务请求签名签署后续服务请求;以及用新的共用密钥校验后续服务请求的服务请求签名。
11.根据权利要求9的方法,还包括执行由包含在服务请求中的服务操作码表示的BIOS服务程序。
12.根据权利要求9的方法,还包括产生会话请求以建立与ROM应用程序接口(RAPI)的会话;以利用密钥对中专用密钥产生的会话请求签名签署会话请求;以及用密钥对中的共用密钥校验会话请求签名以保证会话请求的完整性。
13.根据权利要求12的方法,还包括在处理会话请求之后产生包括新的专用密钥和新的共用密钥的权限证书;以利用新的专用密钥产生的会话请求签名签署后续会话请求;以及用新的共用密钥校验后续会话请求的会话请求签名。
14.根据权利要求9的方法,还包括产生会话请求以结束与ROM应用程序接口(RAPI)的会话;以利用密钥对中专用密钥产生的会话请求签名签署会话请求;以及用密钥对中的共用密钥校验会话请求签名以保证会话请求的完整性。
15.一种包含在计算机可读介质上以安全利用基本输入输出系统(BIOS)服务的计算机程序,包括访问驱动程序,产生利用BIOS服务的服务请求,服务请求包括利用密钥对中专用密钥建立的服务请求签名;以及接口,利用密钥对中共用密钥校验服务请求签名以保证服务请求完整性。
16.一种包含在数据流中的计算机数据信号,包括访问驱动程序,产生利用BIOS服务的服务请求,服务请求包括利用密钥对中专用密钥建立的服务请求签名;以及接口,利用密钥对中共用密钥校验服务请求签名以保证服务请求完整性。
全文摘要
本发明的系统包括存储器,存储处理基于处理器的系统的指令序列,存储器包括物理存储器和虚拟存储器。系统还包括执行所存储的指令序列的处理器。所存储的指令序列包括以下处理步骤使处理器将多个预定指令序列从物理存储器映射到虚拟存储器;在虚拟存储器中确定对所述多个预定指令序列其中之一的补偿;接收指令以执行所述多个预定指令序列其中之一;传送控制至所述多个指令序列其中之一传送控制;以及从虚拟存储器处理所述多个指令序列其中之一。
文档编号G06F12/14GK1690911SQ200510064880
公开日2005年11月2日 申请日期2000年6月18日 优先权日1999年6月18日
发明者L·J·加拉索, M·E·兹尔默, Q·范 申请人:凤凰技术有限公司
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1