searchusermenu
  • 发布文章
  • 消息中心
点赞
收藏
评论
分享
原创

Legacy PXE从入门到精通

2024-06-11 16:55:09
201
0

PXE

简介

PXE全称是Pre-boot Execution Environment,由 Intel 公司开发的网络引导技术,工作在 Client/Server 模式,允许客户机通过网络从远程服务器下载引导镜像,并加载安装整个操作系统。PXE 严格来说是一种引导的方式。协议分为 client 和 server 端,PXE client 在网卡的 ROM 中,当计算机引导时,BIOS 把 PXE client 调入内存执行,由 PXE client 将放置在远端的boot文件通过网络下载到本地运行。PXE client先通过DHCP协议获取IP地址以及TFTP服务器地址,然后通过TFTP从服务器下载boot文件,并加载允许boot文件。所以,PXE client都集成了DHCP client和TFTP client的功能。有了PXE,就可以大规模地、自动化地实现操作系统的安装。

如前所述,PXE client的加载和执行由BIOS来负责,BIOS分Legacy和UEFI两种,Legacy是早期的接口规范,有诸多限制,UEFI则是新一代的接口规范。实现上,网卡作为一种PCIe设备,而PCIe提供PCI Expansion ROM功能,所以,通常将PXE client制作成PCI Expansion ROM烧进网卡,BIOS通过访问PCI设备空间的方式来获取PXE client。习惯上,PCI Expansion ROM也叫PCI Option ROM。

 

Legacy

Legacy BIOS是上世纪80年代开发的基于16位的系统固件接口标准,只支持Intel CPU,磁盘采用MBR分区,最多支持4个主分区,硬盘容量也限制在2T,启动时间较慢。

Legacy启动流程如下:

1.电脑开机后,开始启动BIOS,开始BIOS自检;

2.通过自检后,bios找到硬盘上的主引导记录MBR;

3.MBR开始读取硬盘分区表DPT,找到活动分区中的分区引导记录PBR,并且把控制权交给PBR;

4.PBR搜索活动区中的启动管理器bootmgr,找到后,PBR把控制权交给bootmgr(相当于xp里的ntldr文件);

5.Bootmgr寻找活动分区中的boot文件夹中的BCD文件(启动配置数据,相当于xp里的boot.ini文件);

6.找到BCD后,Bootmgr首先从BCD 中读取启动管理器bootmgr菜单的语言版本信息,没多系统直接加载系统,有多系统会显示多操作系统选择画面。

 

UEFI

UEFI全称是Unified Extensible Firmware Interface,是基于六十四位的系统固件接口标准。UEFI 是Legacy BIOS 的继承者,旨在解决其技术限制。UEFI的前身是Intel在1998年开始开发的Intel Boot Initiative,后来被重命名为可扩展固件接口(Extensible Firmware Interface,缩写EFI)。Intel在2005年将其交由统一可扩展固件接口论坛(Unified EFI Forum)来推广与发展,为了凸显这一点,EFI也更名为UEFI(Unified EFI)。UEFI论坛的创始者是11家知名电脑公司,包括Intel、IBM等硬件厂商,软件厂商Microsoft,及BIOS厂商AMI、Insyde及Phoenix。

UEFI使用GPT的分区引导方案,支持更大的硬盘。由于省去了BIOS自检的过程,所以启动速度更快。

UEFI启动流程如下:

1.电脑开机后,上电自检,UEFI固件被载,并由它初始化启动要用的硬件;

2.UEFI固件寻找EFI分区中的启动文件(\efi\Microsoft\boot\bootmgfw.efi)启动管理器;

3.启动管理器读取硬盘EFI分区中BCD文件(efi\Microsoft\BCD)系统菜单;

4.最后根据配置内容加载引导程序winload.efi(\Windows\system32\winload.efi)加载系统。

总之,UEFI是取代Legacy的新一代的BIOS,功能更加强大,而且它是以图形图像模式显示,让用户更便捷的直观操作。

Legacy与UEFI的区别

UEFI提供了更好的用户界面;

legacy使用MBR分区方案,UEFI使用GPT分区方案;

legacy最多支持4个分区,硬盘容量2TB,UEFI支持最多128个分区,硬盘容量9zB;

legacy有POST自检,启动速度慢,UEFI没有POST自检,启动速度快;

legacy仅在16位模式下运行,UEFI支持32位和六十四位模式;

legacy仅支持键盘,UEFI支持鼠标、触摸板;

legacy不支持安全启动,UEFI支持安全启动;

legacy流程复杂,UEFI流程简单。

在系统上电的时候,可以进入bios配置界面,选择Legacy还是UEFI。

Option ROM

简介

为了将操作系统加载到内存中,系统需要三类设备:

存储设备:用于保存操作系统;

显示设备:用于显示当前的启动进度;

输入设备:用于接收用户输入信息;

在这个阶段,操作系统还没有被加载到内存执行,也就意味着操作系统中对应的设备驱动程序也没有被加载,因此,就需要在Expansion ROM里面存放一份启动阶段使用的设备驱动程序。简单来说就是,BIOS阶段要使用一个PCIe设备,但是BIOS不包含这个设备的驱动程序,这个时候就从这个PCIe设备Expansion ROM里获取设备驱动程序代码,并加载到内存中执行。

PCI Expansion ROM又叫PCI Option ROM,用于设备初始化和系统启动的code。有的PCI Option ROM被存放在板卡上,而有的则保存在BIOS的binary里面。PCI Option ROM有固定的格式,BIOS通过读取PCI的配置空间来确定是否当前网卡支持Option ROM。如果支持,且配置了从网络引导,那么BIOS会负责将Option ROM中的PXE client载入内存,并执行PXE client。

 

配置空间

在PCI 配置空间的0X30处有这么一个寄存器,叫Expansion ROM Base Address。

 

关于“Expansion ROM Base Address”寄存器的具体定义细节如下:

bit11-bit31表示Expansion ROM映射到内存空间的高位地址,BIOS先全写1再回读就能获取到Option ROM的size,bit0用于控制对Expansion ROM的访问,1为使能Expansion ROM,启动地址解码。BIOS把“Expansion ROM Base Address”寄存器的基地址配置成内存空间地址并使能Expansion ROM以后,BIOS就可以对设备的Expansion ROM进行读访问了。具体过程如下:

1、 BIOS向Expansion ROM Base Address Register的高21位写入全1;

2、 BIOS读取Expansion ROM Base Address Register,如果值是0,那就表示不存在Expansion ROM;否则高21位就表示Expansion ROM所需的地址空间,所有无关的位都将返回0;

3、 BIOS给PCIe Expansion ROM映射内存空间,并把内存地址写入Expansion ROM Base Address Register的高21bit;

4、 BIOS将Expansion ROM Base Address Register bit 0置为1,使能address decode;

5、 后续BIOS访问这个内存地址即可实现对Expansion ROM的访问。

 

Shadow RAM

Shadow RAM也称为“影子”内存。它是为了提高系统效率而采用的一种专门技术。 Shadow RAM所使用的物理芯片仍然是CMOS DRAM(动态随机存取存储器)芯片。Shadow RAM 占据了系统主存的一部分地址空间。其编址范围为C0000~FFFFF,即为1MB主存中的 768KB~1024KB区域。这个区域通常也称为内存保留区,用户程序不能直接访问。 Shadow RAM的功能是用来存放各种ROM BIOS的内容。或者说Shadow RAM中的内容是ROM BIOS的拷贝。因此也把它称为ROM Shadow(即Shadow RAM的内容是ROM BIOS的“影 子”)。 在机器上电时,将自动地把系统BIOS、显示BIOS及其它适配器的BIOS装载到Shadow RAM 的指定区域中。由于Shadow RAM的物理编址与对应的ROM相同,所以当需要访问BIOS时, 只需访问Shadow RAM即可,而不必再访问ROM。 通常访问ROM的时间在200ns左右,而访问DRAM的时间小于100ns(最新的DRAM芯片访问时 间为60ns左右或者更小)。在系统运行的过程中,读取BIOS中的数据或调用BIOS中的程序 模块是相当频繁的。显然,采用了Shadow技术后,将大大提高系统的工作效率。 按下按键你可以看到该地址空间分配图,在如图所示的1MB主存地址空间中,640KB以下的 区域是常规内存。640KB~768KB区域保留为显示缓冲区。768KB~1024KB区域即为Shadow RAM区。在系统设置中,又把这个区域按16KB大小的尺寸分为块,由用户设定是否允许使 用。 C0000~C7FFF这两个16KB块(共32KB)通常用作显示卡的ROM BIOS的Shadow区。 C8000~EFFFF这10个16KB块可作为其它适配器的ROM BIOS的Shadow区。F0000~FFFFF 共64KB规定由系统ROM BIOS使用。 应该说明的是,只有当系统配置有640KB以上的内存时才有可能使用Shadow RAM。在系统 内存大于640KB时,用户可在CMOS设置中按照ROM Shadow分块提示,把超过640KB以上的 内存分别设置为“允许”(Enabled)即可。

格式

Option ROM为了方便BIOS解析,需要有一定的格式。每个ROM都有一个Option ROM Header和PCI Data Structure以及Image,对于UEFI Image可以是不同的CPU平台,比如Intel、AMD、ARM等;Option ROM Header和PCI Data Structure都有一定的结构,由标准定义。Other Header是用于自定义的一些头,不同的实现可以不一样;如果同时支持Leagacy PXE和UEFI PXE,那么Legacy PXE ROM必须排第一。

Option ROM Header

Option ROM Header结构定义如下:

每个ROM都必须以0x55AA开始,BIOS会对此进行校验,以表示是否是一个有效的Option ROM。

EFI ROM Header

EFI ROM Header存在一些差异。

PCI Data Structure

PCI Data Structure必须以”PCIR”开始,否则会认为是无效的;

Revision Level of Code/Data:Option ROM按版本分有2.1的Option ROM和3.0的Option ROM;

Device List Pointer:指向该ROM支持的设备id列表,值为相当于该PCI Data Structure的偏移,如果Code Type值为3,该字段必须为0;

Image Length:镜像的大小,单位512字节;

Code Type:取值范围0-3,如下:

0:Intel x86,PC-AT compatible

1:Open Firmware standard for PCI

2:Hewlett-Packard PA RISC

3:UEFI

对于Leagcy PXE来说,Code Type为0,对于UEFI PXE来说,Code Type是3;

Indicator:是否最后一个PCI Data Structure。

Expansion Header

每个Expansion Header都必须以“$PnP”开始。

PXE协议

1、 通过4次DHCP报文交互,获取分配的IP地址、TFTP server的地址和boot file name;

a)pxe client广播一个dhcp discovery广播报文;

b)dhcp server回复一个dhcp offer单播报文;

c)pxe client广播一个dhcp request广播报文;

d)dhcp server回复一个dhcp ack单播报文,dhcp ack的Next Server IP Address会提供TFTP server的IP地址,Boot file name会提供引导文件的名字;

2、 通过TFTP从TFTP Server下载boot file:

3、 执行boot file,将控制权交给boot file,boot file会继续下载OS镜像相关的文件,然后加载OS。

BIOS

中断

BIOS和Option ROM之间是通过中断来访问的,BIOS上电会注册中断服务,Option ROM在运行过程中可以重新进行注册。BIOS中断比较多,以下只列举了Option ROM常用的几个中断:

1、 INT 18h:引导失败触发该中断通知BIOS恢复,将控制权还给BIOS;

2、 INT 19h:启动引导,Option ROM注册并调用该中断就可以控制整个引导过程,BIOS默认会内置INI 19h服务,用于启动软盘、CD-ROM、硬盘等驱动器;

3、 INT 13h:访问磁盘服务,例如:读写扇区、初始化驱动器参数、读取驱动器参数、硬盘复位等;

 

POST流程

1、 上电初始化:所有设备上电,BIOS会完成所有Option ROM的内存映射;

2、 PnP Option ROM初始化:调用ROM header的初始化入口完成初始化并返回BIOS,该阶段不会注册与引导有关的中断;

3、 BIOS更新IPL 表和BCV表,每一个表项都存放了BCV或BEV,表项顺序代表了启动优先级;

4、 BIOS遍历BCV表,安装每一个BCV设备:调用BCV,注册INT 13h,将驱动器添加到系统中,第一个添加的驱动器获得80h编号,将作为引导设备;

5、 Legacy Option ROM初始化:调用ROM header的初始化入口;

6、 按热键,弹出启动菜单,选中的设备将优先引导;

7、 BIOS执行INT 19h处理:

a)到这一阶段,所有设备都已安装,从IPL表中的第一个设备开始尝试启动;

b)如果是软盘等不带Option ROM的设备,则调用BIOS内置的引导程序,如果是BEV设备,则调用表项中存放的BEV指针;

c)如果成功,程序永远不返回;

d)如果引导失败,则触发INT 18h中断做恢复处理,将控制权返回BIOS,BIOS则尝试下一个设备。

 

iPXE

简介

iPXE是一个PXE开源项目,除了DHCP/TFTP外还支持多种网络协议,如:HTTP、Iscsi、wireless、Infiniband等,集成了很多种友商网卡驱动,可以制作多种Option ROM,包括Legacy、UEFI、USB等;

代码架构

iPXE架构设计比较通用合理,从上往下分为:应用层、dhcp/tftp client、socket接口层、协议栈、驱动适配层、网卡驱动层。

dhcp/tftp client:主要实现了client功能,例如:dhcp client、tftp client、iSCSI INI等;

socket层:为上层提供统一的send/receive接口;

协议栈:提供类似Linux协议栈的功能,包括TCP/IP协议栈、Infiniband协议栈等;

驱动层适配层:向上为协议栈提供统一的接口,向下要提供框架,适配各种类型的网卡驱动;

网卡驱动层:真正的网卡驱动,负责将上层传递下来的报文递交给网卡传输出去,将网卡上送的报文递交给上层处理,驱动适配层通过UNDI API接口来访问网卡驱动层提供的服务。

目录结构

代码在src目录下

src/arch目录下主要个各种cpu平台的代码,跟体系结构相关,如:x86、arm等;

src/bin是编译rom输出的存放目录;

src/net目录是各种协议栈的实现,如TCP/IP、802.11、Infiniband等;

src/driver目录下是各种驱动,以太网卡位于driver/net目录下,driver下面又按照驱动类别划分了子目录

各种Header的定义

对于Legacy PXE来说,Option ROM Header、PCI Data Structure、Expansion Header都定义在src/arch/x86/prefix/romprefix.S文件中。除此之外,还定义了几个私有的Header:iPXE Header、UNDI Header、PXENV+ Header、!PXE Header,其中PXENV+ Header用于保护模式,!PXE Header用于实模式。因为PXE client访问服务都是通过API CALL的形式来进行的,所以增加了PXENV+ Header和!PXE Header。

 

pxe_api_call机制

pxe_api_call已经设计为一种通用机制,上层代码都通过该机制来访问下层提供的服务,通过opcode查找下层注册的回调函数,然后执行回调函数。

tftp pxe_api_call

应用层要启动tftp 传输,就会调用pxe_api_call来访问tftp协议层提供的服务.

 

udp pxe_api_call

tftp是通过udp来传输的,因此tftp层又会通过pxe_api_call来访问udp层提供的服务.

网卡的加载/卸载

上层服务通过pxe_api_call来启动网口的加载和卸载.

上层服务通过pxenv_start_undi来实现网卡的probe,通过pxenv_stop_undi来实现网口的remove。

 

访问网卡服务

设备的打开、关闭,报文的接收和传输,也是通过pxe_api_call机制来访问网卡驱动的:

上层服务通过pxenv_start_undi来实现网卡的probe,通过pxenv_stop_undi来实现网口的remove。

 

访问网卡服务

设备的打开、关闭,报文的接收和传输,也是通过pxe_api_call机制来访问网卡驱动的:

pxenv_undi_open会调用到netdev_open,pxenv_undi_close会调用到netdev_close,通过pxenv_undi_transmit来发送报文,通过pxenv_undi_isr来实现poll,注意:一张网卡可能会注册多个netdev,但当前active的只能有一个,从netdev_open和netdev_close的代码可以看出。

而pxe_netdev的设置是通过pxe_set_netdev函数实现的,pxe_set_netdev函数最终会被pxenv_start_undi调用,因此,在probe的时候就确定了当前active的netdev。因此,iPXE会从第一个网口probe开始,一直到引导成功,只有引导失败才会尝试下一个网口。

 

iPXE驱动框架

struct pci_driver

网卡是一种PCIe设备,因此驱动适配层提供了接口来完成PCIe设备的接入。只要对完成对struct pci_driver类型变量的定义和初始化即可完成驱动代码的接入。

0条评论
0 / 1000
c****6
14文章数
3粉丝数
c****6
14 文章 | 3 粉丝
c****6
14文章数
3粉丝数
c****6
14 文章 | 3 粉丝
原创

Legacy PXE从入门到精通

2024-06-11 16:55:09
201
0

PXE

简介

PXE全称是Pre-boot Execution Environment,由 Intel 公司开发的网络引导技术,工作在 Client/Server 模式,允许客户机通过网络从远程服务器下载引导镜像,并加载安装整个操作系统。PXE 严格来说是一种引导的方式。协议分为 client 和 server 端,PXE client 在网卡的 ROM 中,当计算机引导时,BIOS 把 PXE client 调入内存执行,由 PXE client 将放置在远端的boot文件通过网络下载到本地运行。PXE client先通过DHCP协议获取IP地址以及TFTP服务器地址,然后通过TFTP从服务器下载boot文件,并加载允许boot文件。所以,PXE client都集成了DHCP client和TFTP client的功能。有了PXE,就可以大规模地、自动化地实现操作系统的安装。

如前所述,PXE client的加载和执行由BIOS来负责,BIOS分Legacy和UEFI两种,Legacy是早期的接口规范,有诸多限制,UEFI则是新一代的接口规范。实现上,网卡作为一种PCIe设备,而PCIe提供PCI Expansion ROM功能,所以,通常将PXE client制作成PCI Expansion ROM烧进网卡,BIOS通过访问PCI设备空间的方式来获取PXE client。习惯上,PCI Expansion ROM也叫PCI Option ROM。

 

Legacy

Legacy BIOS是上世纪80年代开发的基于16位的系统固件接口标准,只支持Intel CPU,磁盘采用MBR分区,最多支持4个主分区,硬盘容量也限制在2T,启动时间较慢。

Legacy启动流程如下:

1.电脑开机后,开始启动BIOS,开始BIOS自检;

2.通过自检后,bios找到硬盘上的主引导记录MBR;

3.MBR开始读取硬盘分区表DPT,找到活动分区中的分区引导记录PBR,并且把控制权交给PBR;

4.PBR搜索活动区中的启动管理器bootmgr,找到后,PBR把控制权交给bootmgr(相当于xp里的ntldr文件);

5.Bootmgr寻找活动分区中的boot文件夹中的BCD文件(启动配置数据,相当于xp里的boot.ini文件);

6.找到BCD后,Bootmgr首先从BCD 中读取启动管理器bootmgr菜单的语言版本信息,没多系统直接加载系统,有多系统会显示多操作系统选择画面。

 

UEFI

UEFI全称是Unified Extensible Firmware Interface,是基于六十四位的系统固件接口标准。UEFI 是Legacy BIOS 的继承者,旨在解决其技术限制。UEFI的前身是Intel在1998年开始开发的Intel Boot Initiative,后来被重命名为可扩展固件接口(Extensible Firmware Interface,缩写EFI)。Intel在2005年将其交由统一可扩展固件接口论坛(Unified EFI Forum)来推广与发展,为了凸显这一点,EFI也更名为UEFI(Unified EFI)。UEFI论坛的创始者是11家知名电脑公司,包括Intel、IBM等硬件厂商,软件厂商Microsoft,及BIOS厂商AMI、Insyde及Phoenix。

UEFI使用GPT的分区引导方案,支持更大的硬盘。由于省去了BIOS自检的过程,所以启动速度更快。

UEFI启动流程如下:

1.电脑开机后,上电自检,UEFI固件被载,并由它初始化启动要用的硬件;

2.UEFI固件寻找EFI分区中的启动文件(\efi\Microsoft\boot\bootmgfw.efi)启动管理器;

3.启动管理器读取硬盘EFI分区中BCD文件(efi\Microsoft\BCD)系统菜单;

4.最后根据配置内容加载引导程序winload.efi(\Windows\system32\winload.efi)加载系统。

总之,UEFI是取代Legacy的新一代的BIOS,功能更加强大,而且它是以图形图像模式显示,让用户更便捷的直观操作。

Legacy与UEFI的区别

UEFI提供了更好的用户界面;

legacy使用MBR分区方案,UEFI使用GPT分区方案;

legacy最多支持4个分区,硬盘容量2TB,UEFI支持最多128个分区,硬盘容量9zB;

legacy有POST自检,启动速度慢,UEFI没有POST自检,启动速度快;

legacy仅在16位模式下运行,UEFI支持32位和六十四位模式;

legacy仅支持键盘,UEFI支持鼠标、触摸板;

legacy不支持安全启动,UEFI支持安全启动;

legacy流程复杂,UEFI流程简单。

在系统上电的时候,可以进入bios配置界面,选择Legacy还是UEFI。

Option ROM

简介

为了将操作系统加载到内存中,系统需要三类设备:

存储设备:用于保存操作系统;

显示设备:用于显示当前的启动进度;

输入设备:用于接收用户输入信息;

在这个阶段,操作系统还没有被加载到内存执行,也就意味着操作系统中对应的设备驱动程序也没有被加载,因此,就需要在Expansion ROM里面存放一份启动阶段使用的设备驱动程序。简单来说就是,BIOS阶段要使用一个PCIe设备,但是BIOS不包含这个设备的驱动程序,这个时候就从这个PCIe设备Expansion ROM里获取设备驱动程序代码,并加载到内存中执行。

PCI Expansion ROM又叫PCI Option ROM,用于设备初始化和系统启动的code。有的PCI Option ROM被存放在板卡上,而有的则保存在BIOS的binary里面。PCI Option ROM有固定的格式,BIOS通过读取PCI的配置空间来确定是否当前网卡支持Option ROM。如果支持,且配置了从网络引导,那么BIOS会负责将Option ROM中的PXE client载入内存,并执行PXE client。

 

配置空间

在PCI 配置空间的0X30处有这么一个寄存器,叫Expansion ROM Base Address。

 

关于“Expansion ROM Base Address”寄存器的具体定义细节如下:

bit11-bit31表示Expansion ROM映射到内存空间的高位地址,BIOS先全写1再回读就能获取到Option ROM的size,bit0用于控制对Expansion ROM的访问,1为使能Expansion ROM,启动地址解码。BIOS把“Expansion ROM Base Address”寄存器的基地址配置成内存空间地址并使能Expansion ROM以后,BIOS就可以对设备的Expansion ROM进行读访问了。具体过程如下:

1、 BIOS向Expansion ROM Base Address Register的高21位写入全1;

2、 BIOS读取Expansion ROM Base Address Register,如果值是0,那就表示不存在Expansion ROM;否则高21位就表示Expansion ROM所需的地址空间,所有无关的位都将返回0;

3、 BIOS给PCIe Expansion ROM映射内存空间,并把内存地址写入Expansion ROM Base Address Register的高21bit;

4、 BIOS将Expansion ROM Base Address Register bit 0置为1,使能address decode;

5、 后续BIOS访问这个内存地址即可实现对Expansion ROM的访问。

 

Shadow RAM

Shadow RAM也称为“影子”内存。它是为了提高系统效率而采用的一种专门技术。 Shadow RAM所使用的物理芯片仍然是CMOS DRAM(动态随机存取存储器)芯片。Shadow RAM 占据了系统主存的一部分地址空间。其编址范围为C0000~FFFFF,即为1MB主存中的 768KB~1024KB区域。这个区域通常也称为内存保留区,用户程序不能直接访问。 Shadow RAM的功能是用来存放各种ROM BIOS的内容。或者说Shadow RAM中的内容是ROM BIOS的拷贝。因此也把它称为ROM Shadow(即Shadow RAM的内容是ROM BIOS的“影 子”)。 在机器上电时,将自动地把系统BIOS、显示BIOS及其它适配器的BIOS装载到Shadow RAM 的指定区域中。由于Shadow RAM的物理编址与对应的ROM相同,所以当需要访问BIOS时, 只需访问Shadow RAM即可,而不必再访问ROM。 通常访问ROM的时间在200ns左右,而访问DRAM的时间小于100ns(最新的DRAM芯片访问时 间为60ns左右或者更小)。在系统运行的过程中,读取BIOS中的数据或调用BIOS中的程序 模块是相当频繁的。显然,采用了Shadow技术后,将大大提高系统的工作效率。 按下按键你可以看到该地址空间分配图,在如图所示的1MB主存地址空间中,640KB以下的 区域是常规内存。640KB~768KB区域保留为显示缓冲区。768KB~1024KB区域即为Shadow RAM区。在系统设置中,又把这个区域按16KB大小的尺寸分为块,由用户设定是否允许使 用。 C0000~C7FFF这两个16KB块(共32KB)通常用作显示卡的ROM BIOS的Shadow区。 C8000~EFFFF这10个16KB块可作为其它适配器的ROM BIOS的Shadow区。F0000~FFFFF 共64KB规定由系统ROM BIOS使用。 应该说明的是,只有当系统配置有640KB以上的内存时才有可能使用Shadow RAM。在系统 内存大于640KB时,用户可在CMOS设置中按照ROM Shadow分块提示,把超过640KB以上的 内存分别设置为“允许”(Enabled)即可。

格式

Option ROM为了方便BIOS解析,需要有一定的格式。每个ROM都有一个Option ROM Header和PCI Data Structure以及Image,对于UEFI Image可以是不同的CPU平台,比如Intel、AMD、ARM等;Option ROM Header和PCI Data Structure都有一定的结构,由标准定义。Other Header是用于自定义的一些头,不同的实现可以不一样;如果同时支持Leagacy PXE和UEFI PXE,那么Legacy PXE ROM必须排第一。

Option ROM Header

Option ROM Header结构定义如下:

每个ROM都必须以0x55AA开始,BIOS会对此进行校验,以表示是否是一个有效的Option ROM。

EFI ROM Header

EFI ROM Header存在一些差异。

PCI Data Structure

PCI Data Structure必须以”PCIR”开始,否则会认为是无效的;

Revision Level of Code/Data:Option ROM按版本分有2.1的Option ROM和3.0的Option ROM;

Device List Pointer:指向该ROM支持的设备id列表,值为相当于该PCI Data Structure的偏移,如果Code Type值为3,该字段必须为0;

Image Length:镜像的大小,单位512字节;

Code Type:取值范围0-3,如下:

0:Intel x86,PC-AT compatible

1:Open Firmware standard for PCI

2:Hewlett-Packard PA RISC

3:UEFI

对于Leagcy PXE来说,Code Type为0,对于UEFI PXE来说,Code Type是3;

Indicator:是否最后一个PCI Data Structure。

Expansion Header

每个Expansion Header都必须以“$PnP”开始。

PXE协议

1、 通过4次DHCP报文交互,获取分配的IP地址、TFTP server的地址和boot file name;

a)pxe client广播一个dhcp discovery广播报文;

b)dhcp server回复一个dhcp offer单播报文;

c)pxe client广播一个dhcp request广播报文;

d)dhcp server回复一个dhcp ack单播报文,dhcp ack的Next Server IP Address会提供TFTP server的IP地址,Boot file name会提供引导文件的名字;

2、 通过TFTP从TFTP Server下载boot file:

3、 执行boot file,将控制权交给boot file,boot file会继续下载OS镜像相关的文件,然后加载OS。

BIOS

中断

BIOS和Option ROM之间是通过中断来访问的,BIOS上电会注册中断服务,Option ROM在运行过程中可以重新进行注册。BIOS中断比较多,以下只列举了Option ROM常用的几个中断:

1、 INT 18h:引导失败触发该中断通知BIOS恢复,将控制权还给BIOS;

2、 INT 19h:启动引导,Option ROM注册并调用该中断就可以控制整个引导过程,BIOS默认会内置INI 19h服务,用于启动软盘、CD-ROM、硬盘等驱动器;

3、 INT 13h:访问磁盘服务,例如:读写扇区、初始化驱动器参数、读取驱动器参数、硬盘复位等;

 

POST流程

1、 上电初始化:所有设备上电,BIOS会完成所有Option ROM的内存映射;

2、 PnP Option ROM初始化:调用ROM header的初始化入口完成初始化并返回BIOS,该阶段不会注册与引导有关的中断;

3、 BIOS更新IPL 表和BCV表,每一个表项都存放了BCV或BEV,表项顺序代表了启动优先级;

4、 BIOS遍历BCV表,安装每一个BCV设备:调用BCV,注册INT 13h,将驱动器添加到系统中,第一个添加的驱动器获得80h编号,将作为引导设备;

5、 Legacy Option ROM初始化:调用ROM header的初始化入口;

6、 按热键,弹出启动菜单,选中的设备将优先引导;

7、 BIOS执行INT 19h处理:

a)到这一阶段,所有设备都已安装,从IPL表中的第一个设备开始尝试启动;

b)如果是软盘等不带Option ROM的设备,则调用BIOS内置的引导程序,如果是BEV设备,则调用表项中存放的BEV指针;

c)如果成功,程序永远不返回;

d)如果引导失败,则触发INT 18h中断做恢复处理,将控制权返回BIOS,BIOS则尝试下一个设备。

 

iPXE

简介

iPXE是一个PXE开源项目,除了DHCP/TFTP外还支持多种网络协议,如:HTTP、Iscsi、wireless、Infiniband等,集成了很多种友商网卡驱动,可以制作多种Option ROM,包括Legacy、UEFI、USB等;

代码架构

iPXE架构设计比较通用合理,从上往下分为:应用层、dhcp/tftp client、socket接口层、协议栈、驱动适配层、网卡驱动层。

dhcp/tftp client:主要实现了client功能,例如:dhcp client、tftp client、iSCSI INI等;

socket层:为上层提供统一的send/receive接口;

协议栈:提供类似Linux协议栈的功能,包括TCP/IP协议栈、Infiniband协议栈等;

驱动层适配层:向上为协议栈提供统一的接口,向下要提供框架,适配各种类型的网卡驱动;

网卡驱动层:真正的网卡驱动,负责将上层传递下来的报文递交给网卡传输出去,将网卡上送的报文递交给上层处理,驱动适配层通过UNDI API接口来访问网卡驱动层提供的服务。

目录结构

代码在src目录下

src/arch目录下主要个各种cpu平台的代码,跟体系结构相关,如:x86、arm等;

src/bin是编译rom输出的存放目录;

src/net目录是各种协议栈的实现,如TCP/IP、802.11、Infiniband等;

src/driver目录下是各种驱动,以太网卡位于driver/net目录下,driver下面又按照驱动类别划分了子目录

各种Header的定义

对于Legacy PXE来说,Option ROM Header、PCI Data Structure、Expansion Header都定义在src/arch/x86/prefix/romprefix.S文件中。除此之外,还定义了几个私有的Header:iPXE Header、UNDI Header、PXENV+ Header、!PXE Header,其中PXENV+ Header用于保护模式,!PXE Header用于实模式。因为PXE client访问服务都是通过API CALL的形式来进行的,所以增加了PXENV+ Header和!PXE Header。

 

pxe_api_call机制

pxe_api_call已经设计为一种通用机制,上层代码都通过该机制来访问下层提供的服务,通过opcode查找下层注册的回调函数,然后执行回调函数。

tftp pxe_api_call

应用层要启动tftp 传输,就会调用pxe_api_call来访问tftp协议层提供的服务.

 

udp pxe_api_call

tftp是通过udp来传输的,因此tftp层又会通过pxe_api_call来访问udp层提供的服务.

网卡的加载/卸载

上层服务通过pxe_api_call来启动网口的加载和卸载.

上层服务通过pxenv_start_undi来实现网卡的probe,通过pxenv_stop_undi来实现网口的remove。

 

访问网卡服务

设备的打开、关闭,报文的接收和传输,也是通过pxe_api_call机制来访问网卡驱动的:

上层服务通过pxenv_start_undi来实现网卡的probe,通过pxenv_stop_undi来实现网口的remove。

 

访问网卡服务

设备的打开、关闭,报文的接收和传输,也是通过pxe_api_call机制来访问网卡驱动的:

pxenv_undi_open会调用到netdev_open,pxenv_undi_close会调用到netdev_close,通过pxenv_undi_transmit来发送报文,通过pxenv_undi_isr来实现poll,注意:一张网卡可能会注册多个netdev,但当前active的只能有一个,从netdev_open和netdev_close的代码可以看出。

而pxe_netdev的设置是通过pxe_set_netdev函数实现的,pxe_set_netdev函数最终会被pxenv_start_undi调用,因此,在probe的时候就确定了当前active的netdev。因此,iPXE会从第一个网口probe开始,一直到引导成功,只有引导失败才会尝试下一个网口。

 

iPXE驱动框架

struct pci_driver

网卡是一种PCIe设备,因此驱动适配层提供了接口来完成PCIe设备的接入。只要对完成对struct pci_driver类型变量的定义和初始化即可完成驱动代码的接入。

文章来自个人专栏
文章 | 订阅
0条评论
0 / 1000
请输入你的评论
0
0