紀(jì)向尚 莊克良 王大慶
(海軍704廠 青島 266109)
小型計(jì)算機(jī)系統(tǒng)接口(Small Computer System Interface),簡(jiǎn)稱SCSI,主要應(yīng)用于計(jì)算機(jī)外圍設(shè)備,如硬盤、軟驅(qū)、光驅(qū)、打印機(jī)等。SCSI標(biāo)準(zhǔn)定義了命令、通訊協(xié)議以及實(shí)體的電氣特性,其主要軟件接口是SCSI命令。
SCSI的原始版本是SCSI-1,SCSI-1具有8位總線,數(shù)據(jù)傳輸率為4Mbps。目前SCSI-1已經(jīng)很少使用。作為對(duì)SCSI-1的改進(jìn),SCSI-2使用了兩項(xiàng)新技術(shù)Fast SCSI和 Wide SCSI。
Fast SCSI將傳輸速率提高到10MB/Sec,而Wide SCSI突破SCSI-1的單字節(jié)傳輸限制,將數(shù)據(jù)總線的帶寬提高到16位或者32位。當(dāng)使用Fast-Wide SCSI時(shí),其理論傳輸速率為20MB/s或者40MB/s,SCSI-2增加了新的設(shè)備命令集,對(duì)光驅(qū)的支持也出現(xiàn)在SCSI-2標(biāo)準(zhǔn)文檔中。
UEFI則定義了操作系統(tǒng)與系統(tǒng)硬件平臺(tái)固件之間的開放接口。該規(guī)范定義的接口包括平臺(tái)相關(guān)信息、啟動(dòng)服務(wù)例程以及操作系統(tǒng)運(yùn)行時(shí)服務(wù)例程。操作系統(tǒng)裝載器與操作系統(tǒng)可通過接口調(diào)用這些服務(wù)例程。UEFI規(guī)范是一個(gè)公開的純接口定義,它不依賴于某個(gè)特定的BIOS制造商或某個(gè)特定的BIOS的實(shí)現(xiàn),它僅僅定義了平臺(tái)固件必須實(shí)現(xiàn)的接口,以及操作系統(tǒng)可能使用的一系列接口與數(shù)據(jù)結(jié)構(gòu),其實(shí)現(xiàn)的方式與細(xì)節(jié)均取決于該規(guī)范的實(shí)現(xiàn)者。UEFI規(guī)范還定義了固件驅(qū)動(dòng)程序模型,使得所有遵循此模型開發(fā)的固件驅(qū)動(dòng)程序能夠互相協(xié)作。
目前UEFI BIOS下還沒有相應(yīng)的虛擬光驅(qū)方面的應(yīng)用程序,本文研究的就是在UEFI接口規(guī)范下基本SCSI虛擬光驅(qū)技術(shù)的設(shè)計(jì)和實(shí)現(xiàn)。
UEFI的所有驅(qū)動(dòng)依靠協(xié)議堆疊形成協(xié)議棧,并以此組織系統(tǒng)中的驅(qū)動(dòng)模塊。SCSI作為總線控制器,要求提供控制器本身的控制協(xié)議即SCSI Pass Thru Protocol或者其擴(kuò)展版本Ext Scsi Pass Thru Protocol。該協(xié)議可以驅(qū)動(dòng)SCSI總線控制器,向總線控制器發(fā)出輸入輸出或其它控制命令。SCSI設(shè)備驅(qū)動(dòng)則依賴該協(xié)議提供具體的設(shè)備輸入輸出控制接口。
在UEFI中,這種總線結(jié)構(gòu)依賴于三個(gè)驅(qū)動(dòng)實(shí)現(xiàn):總線控制器驅(qū)動(dòng)、總線驅(qū)動(dòng)、子設(shè)備驅(qū)動(dòng)??偩€控制器作為一種設(shè)備,其驅(qū)動(dòng)提供控制接口??偩€驅(qū)動(dòng)則利用這種接口查詢并枚舉總線控制器上的所有子設(shè)備,并為每一個(gè)子設(shè)備創(chuàng)建新的設(shè)備句柄,安裝Device Path Protocol以及向子設(shè)備發(fā)送命令的總線IO協(xié)議??偩€驅(qū)動(dòng)不關(guān)心子設(shè)備類型,子設(shè)備上的總線IO只可向設(shè)備發(fā)送IO及控制信號(hào)。不同設(shè)備的驅(qū)動(dòng)為了提供設(shè)備本身特有的接口,將該總線IO封裝,提供工業(yè)標(biāo)準(zhǔn)中的設(shè)備控制接口。
如圖1所示,SCSI總線控制器句柄SCSI Bus Controller Handle由系統(tǒng)或其父節(jié)點(diǎn)的總線驅(qū)動(dòng)負(fù)責(zé)創(chuàng)建。SCSI總線控制器的控制接口協(xié)議Ext SCSI Pass Thru Protocol由總線控制器驅(qū)動(dòng)實(shí)現(xiàn)并安裝在該控制器句柄上。
圖1 SCSI總線及設(shè)備協(xié)議棧
SCSI總線驅(qū)動(dòng)使用Ext SCSI Pass Thru Protocol查詢并枚舉總線上的每個(gè)子設(shè)備,創(chuàng)建新的句柄,為這些子設(shè)備句柄安裝Device Path Protocol和SCSI IO Protocol。其中,SCSI IO Protocol提供了統(tǒng)一的設(shè)備輸入輸出及控制接口。圖1中Scsi Device 1Handle和SCSI Device 2Handle即為總線子設(shè)備句柄,由總線驅(qū)動(dòng)創(chuàng)建。
由于SCSI設(shè)備的多樣性,不同的設(shè)備需要特定的協(xié)議作為接口。圖1中的SCSI設(shè)備為CD-Drive、磁盤等塊設(shè)備。UEFI標(biāo)準(zhǔn)規(guī)定這些塊設(shè)備應(yīng)當(dāng)提供Block IO Protocol,因此,EDK II中給出了SCSI塊設(shè)備的驅(qū)動(dòng)。該驅(qū)動(dòng)檢測(cè)通過SCSI IO Protocol檢查每個(gè)設(shè)備的類型,并負(fù)責(zé)為光驅(qū)和磁盤創(chuàng)建塊輸入輸出協(xié)議Block IO Protocol。
到此,SCSI總線結(jié)構(gòu)的協(xié)議棧已經(jīng)建立。EDK II提供Disk IO Protocol,其接口與Block IO Protocol有所不同,但一部分上層驅(qū)動(dòng)同時(shí)使用這兩個(gè)協(xié)議。Simple File System Protocol由文件系統(tǒng)相關(guān)的驅(qū)動(dòng)模塊負(fù)責(zé)。簡(jiǎn)單文件系統(tǒng)協(xié)議向Shell以及所有使用文件系統(tǒng)的驅(qū)動(dòng)提供了文件訪問接口。
根據(jù)以上分析,可以得出這樣的結(jié)論:有效驅(qū)動(dòng)SCSI光驅(qū)或者磁盤需要三個(gè)驅(qū)動(dòng)模塊完成,總線控制器驅(qū)動(dòng),總線驅(qū)動(dòng)和子設(shè)備驅(qū)動(dòng)。這三個(gè)驅(qū)動(dòng)彼此獨(dú)立地負(fù)責(zé)三個(gè)協(xié)議的安裝,即 Ext Scsi Pass Thru Protocol,Scsi IO Protocol和Block IO Protocol。其中,Block IO Protocol抽象了塊設(shè)備讀寫,與具體設(shè)備無關(guān)。
圖2 SCSI虛擬光驅(qū)頂層結(jié)構(gòu)
SCSI虛擬光驅(qū)系統(tǒng)由兩個(gè)模塊組成,虛擬光驅(qū)驅(qū)動(dòng)和Shell接口。模塊間通過固件卷(Firmware Volume)實(shí)現(xiàn)配置信息的傳遞。圖2給出了系統(tǒng)的頂層結(jié)構(gòu)圖。
Shell接口通過命令行獲得配置信息,并將配置信息存入到固件卷中,比如虛擬光驅(qū)的數(shù)目,每個(gè)光驅(qū)對(duì)應(yīng)的ISO鏡像文件等。驅(qū)動(dòng)的內(nèi)核通過讀取這些信息,動(dòng)態(tài)創(chuàng)建出相應(yīng)的數(shù)據(jù)結(jié)構(gòu)來提供虛擬光驅(qū)服務(wù),比如向用戶提供一個(gè)或多個(gè)虛擬光驅(qū)等。
從前面的論述中知道,虛擬光驅(qū)驅(qū)動(dòng)在實(shí)質(zhì)上虛擬SCSI總線控制器,提供Ext SCSI Pass Thru Protocol接口。雖然該驅(qū)動(dòng)是總線控制器驅(qū)動(dòng),但仍然是一個(gè)設(shè)備驅(qū)動(dòng),驅(qū)動(dòng)接口被總線驅(qū)動(dòng)(即SCSI Bus驅(qū)動(dòng))所使用。而在總線控制器內(nèi)部維持著一些數(shù)據(jù)結(jié)構(gòu),向上層總線驅(qū)動(dòng)提供虛擬信息,基于這個(gè)選擇,可以得到如圖3所示的驅(qū)動(dòng)內(nèi)核結(jié)構(gòu)。
圖3 遵循UEFI驅(qū)動(dòng)模型的虛擬光驅(qū)驅(qū)動(dòng)內(nèi)核
虛擬光驅(qū)系統(tǒng)具有如下要求功能:
1)列出所有虛擬光驅(qū),及其對(duì)應(yīng)的ISO文件信息;
2)設(shè)置虛擬光驅(qū)數(shù)量;
3)為指定編號(hào)的虛擬光驅(qū)進(jìn)行ISO鏡像裝載;
4)為指定編號(hào)的虛擬光驅(qū)進(jìn)行ISO鏡像卸載。
根據(jù)預(yù)期的四個(gè)功能,設(shè)計(jì)出如下格式的Shell命令:
其中,vscsi為Shell接口的程序名,-l選項(xiàng)以列表形式所有的虛擬光驅(qū)信息,-n用來設(shè)置虛擬光驅(qū)的數(shù)量,-m用來設(shè)置Num對(duì)應(yīng)虛擬光驅(qū)的鏡像文件,-u用來對(duì)Num指定虛擬光驅(qū)進(jìn)行卸載。
虛擬光驅(qū)的Shell接口程序?qū)⒆裱瓨?biāo)準(zhǔn)的程序結(jié)構(gòu),利用Shell相關(guān)的庫和協(xié)議獲得命令行參數(shù)并將其存放入固件卷中。Shell接口程序的框架如上圖所示。Shell接受用戶命令并分析后,將調(diào)用EFI Runtime Services向固件卷中寫入配置信息。需要說明的是,命令行指定的文件路徑中的盤符信息不能被設(shè)備驅(qū)動(dòng)識(shí)別。比如,在f8:\sample\example1.iso這樣的文件路徑中,f8:\不能被設(shè)備識(shí)別。因此,在Shell接口應(yīng)當(dāng)將盤符信息轉(zhuǎn)化為設(shè)備驅(qū)動(dòng)可以識(shí)別的信息,然后存儲(chǔ)。
分析上述可知,驅(qū)動(dòng)內(nèi)核將使用一些數(shù)據(jù)結(jié)構(gòu)來表示配置信息,并提供虛擬光驅(qū)服務(wù)。驅(qū)動(dòng)應(yīng)當(dāng)首先創(chuàng)建虛擬的SCSI控制器建立對(duì)應(yīng)數(shù)據(jù)結(jié)構(gòu),并根據(jù)配置信息在UEFI系統(tǒng)堆內(nèi)存中動(dòng)態(tài)地創(chuàng)建表示子設(shè)備的數(shù)據(jù)結(jié)構(gòu)。
虛擬SCSI控制器對(duì)應(yīng)的數(shù)據(jù)結(jié)構(gòu)將采用C面向?qū)ο蟮姆椒ǎ瑪U(kuò)展Ext Scsi Pass Thru Protocol結(jié)構(gòu),將需要的數(shù)據(jù)結(jié)構(gòu)作為該協(xié)議私有的數(shù)據(jù),如圖4所示。
其中,擴(kuò)展后的Ext Scsi Pass Thru Protocol定義如圖5。
以這個(gè)結(jié)構(gòu)體作為虛擬的SCSI總線控制器的核心數(shù)據(jù)結(jié)構(gòu)。
圖4 虛擬SCSI控制器結(jié)構(gòu)
圖5 虛擬SCSI總線控制器結(jié)構(gòu)體定義
前四個(gè)字節(jié)為signature。因?yàn)樵摻Y(jié)構(gòu)體在內(nèi)存中動(dòng)態(tài)創(chuàng)建,協(xié)議中的函數(shù)可以利用這四個(gè)字節(jié)檢查數(shù)據(jù)結(jié)構(gòu)的正確性,這個(gè)特性類似于信息安全領(lǐng)域的數(shù)字簽名。
簽名結(jié)束后是協(xié)議接口,在向系統(tǒng)注冊(cè)協(xié)議時(shí)將這個(gè)地址傳入U(xiǎn)EFI系統(tǒng)。并且,虛擬SCSI總線控制器結(jié)構(gòu)體中,只有該域?qū)ν忾_放。在向虛擬設(shè)備裝載協(xié)議時(shí),ExtScsiPassThruInterface域的地址將被傳入系統(tǒng),保證了內(nèi)部數(shù)據(jù)結(jié)構(gòu)的封裝。因此,其它驅(qū)動(dòng)或者用戶在向系統(tǒng)請(qǐng)求該協(xié)議接口時(shí),得到的不是整個(gè) VIRTUAL_SCSI_CONTROLLER結(jié)構(gòu)體地址,而是其中ExtScsiPassThruInterface的地址。
VIRTUAL_SCSI_CONTROLLER的最后部分由一個(gè)類型匿名的Private域構(gòu)成。該域僅包含兩項(xiàng),虛擬光驅(qū)數(shù)量以及指向虛擬光驅(qū)結(jié)構(gòu)體數(shù)組的指針。對(duì)該域的數(shù)據(jù)類型進(jìn)行匿名,可以保證該域的封裝性。
對(duì)于每個(gè)虛擬光驅(qū),其數(shù)據(jù)結(jié)構(gòu)定義如圖6所示。
圖6 虛擬光驅(qū)設(shè)備結(jié)構(gòu)體定義
CDRomMounted用以表示該CD Drive中是否裝載了CD-Rom,F(xiàn)ileDevicePath指向文件類型的Device Path。它主要用來保存從CMOS中獲得的虛擬光驅(qū)配置信息,不負(fù)責(zé)文件的相關(guān)操作。根據(jù)FileDevicePath被打開的文件由FileHandle指向,文件的訪問操作也將通過FileHandle來進(jìn)行。TargetID和Lun是SCSI規(guī)范中定義的兩種類型的數(shù)據(jù),TargetID用來表示SCSI目標(biāo)器的編號(hào),Lun用來表示邏輯單元號(hào)(Logical Unit Number)。需要指出的是,在本虛擬光驅(qū)系統(tǒng)中對(duì)于任何一個(gè)TargetID,Lun均只為0,不使用其它值。
圖7 SCSI虛擬光驅(qū)驅(qū)動(dòng)模塊詳細(xì)設(shè)計(jì)
綜合UEFI驅(qū)動(dòng)模型、SCSI虛擬控制器結(jié)構(gòu)及虛擬光驅(qū)設(shè)備結(jié)構(gòu)得出如圖7的SCSI虛擬光驅(qū)驅(qū)動(dòng)模塊詳細(xì)設(shè)計(jì)。其中鏡像文件(Image File)部分是驅(qū)動(dòng)的二進(jìn)制可加載鏡像,由代碼編譯得到。堆空間(Heap Memory)中的所有數(shù)據(jù)結(jié)構(gòu)由驅(qū)動(dòng)的Driver Binding Protocol負(fù)責(zé)構(gòu)造和析構(gòu)。
圖2系統(tǒng)的頂層結(jié)構(gòu)圖中,Shell接口和驅(qū)動(dòng)內(nèi)核通過固件卷進(jìn)行配置信息的傳遞。在進(jìn)行這種配置傳遞時(shí)需要解決兩個(gè)問題。
第一,由于UEFI規(guī)范不使用時(shí)鐘中斷外的所有中斷,因此UEFI系統(tǒng)應(yīng)當(dāng)處于單一的運(yùn)行環(huán)境,即單指令流。因此,不可能同時(shí)存在驅(qū)動(dòng)進(jìn)程和Shell接口進(jìn)程,也不可能實(shí)時(shí)傳遞配置參數(shù)。由于EFI的加載速度很快,重啟EFI并不會(huì)耗費(fèi)時(shí)間,所以無論是在傳統(tǒng)BIOS,還是在EFI中,一些配置往往都要求重啟。本設(shè)計(jì)選擇回避該問題,配置信息設(shè)置保存后應(yīng)當(dāng)重新啟動(dòng)UEFI系統(tǒng),以便驅(qū)動(dòng)內(nèi)核讀取配置信息。
第二,EDK II的Shell中表示的盤符(如f8:\)屬于Shell內(nèi)部表示,只有在Shell環(huán)境下可見。但驅(qū)動(dòng)不在Shell環(huán)境下運(yùn)行,也不能利用Shell庫讀取文件。如果簡(jiǎn)單地向固件卷中寫入路徑f8:\sample\example1.iso,那么即使路徑信息能夠被設(shè)備驅(qū)動(dòng)所獲取,驅(qū)動(dòng)程序也不能從f8:\訪問任何設(shè)備。
本文主要研究了符合UEFI接口規(guī)范的SCSI虛擬光驅(qū)技術(shù),并設(shè)計(jì)實(shí)現(xiàn)了該SCSI虛擬光驅(qū)系統(tǒng)。該系統(tǒng)可以向其它驅(qū)動(dòng)或者用戶提供一個(gè)虛擬的SCSI總線控制器以及連接在總線控制器上的一個(gè)或多個(gè)虛擬光驅(qū)設(shè)備,用戶可以通過Shell接口配置光驅(qū)數(shù)量以及各光驅(qū)中加載的ISO 9660結(jié)構(gòu)的文件鏡像。該方法的實(shí)現(xiàn),對(duì)于擴(kuò)展基于UEFI BIOS計(jì)算機(jī)系統(tǒng)的多光驅(qū)應(yīng)用以及擴(kuò)展外部設(shè)備接口,具有非?,F(xiàn)實(shí)的積極意義。
[1]UEFI Forum.February 2010.UEFI Specification.Version 2.3.http://www.uefi.org/specs/
[2]UEFI Forum.February 2010.UEFI Platform Initialization Specification.Version 1.2.http://www.uefi.org/specs/
[3]Vincent Zimmer.2006.Beyond BIOS.Intel corporation.17-32,143-146.
[4]Framework Open Source Community.March 2008.Pre_EFI Initialization Core Interface http://www.uefi.org/specs/.
[5]EFI技術(shù)解析.March 2010.http://www.gz-benet.com.cn/.
[6]Basic Instruction for Using EFI.January 2,2008.http://www.intel.com/.
[7]Enterprise64BIOS.March 2010.http://ami.com/.