王 威
(中船重工七二三研究所,江蘇 揚(yáng)州 225009)
隨著大規(guī)模集成化電路的出現(xiàn),嵌入式單板計(jì)算機(jī)在各個(gè)領(lǐng)域中應(yīng)用廣泛。因此,通過(guò)硬件測(cè)試來(lái)提高單板計(jì)算機(jī)的質(zhì)量成為一個(gè)值得研究的課題。國(guó)內(nèi)各大嵌入式單板計(jì)算機(jī)廠商的產(chǎn)品,整體系統(tǒng)架構(gòu)具有多樣性和緊湊性。一種既具有通用性可以兼容多個(gè)硬件平臺(tái),又具備一定性能的系統(tǒng)軟件成為測(cè)試軟件必備之選。Linux系統(tǒng)[1]由于其具有很強(qiáng)的跨平臺(tái)性與可裁剪性,因此被本測(cè)試軟件使用。Linux 是一套可供免費(fèi)使用和自由傳播的類Unix 操作系統(tǒng),是一個(gè)基于POSIX 和UNIX 的多用戶、多任務(wù)、支持多線程和多CPU 的操作系統(tǒng)。它能運(yùn)行主要的UNIX 工具軟件、應(yīng)用程序和網(wǎng)絡(luò)協(xié)議。它支持32 位和64位硬件。Linux 繼承了Unix 以網(wǎng)絡(luò)為核心的設(shè)計(jì)思想,是一個(gè)性能穩(wěn)定的多用戶網(wǎng)絡(luò)操作系統(tǒng)。Linux 存在著許多不同的版本,但都使用Linux 內(nèi)核。
x86 平臺(tái)的CPU 具有32 根地址線,根據(jù)編制原理232=4G 內(nèi)存空間。
圖1 x86 內(nèi)存映射模型
可以從x86 內(nèi)存映射模型(見(jiàn)圖1)上看出[2],0 到1M 內(nèi)存空間用來(lái)保留與DOS 系統(tǒng)的兼容,1M向上一直到RAM 頂端TOLUD 為RAM 存儲(chǔ)空間,PCI 設(shè)備則在RAM 頂端到APIC 之間,APIC 向上為中斷控制程序與BIOS 的FLASH 映射。
PCI 空間中對(duì)系統(tǒng)的PCI 設(shè)備進(jìn)行編址并映射設(shè)備其中的內(nèi)存空間,因此對(duì)系統(tǒng)中的PCI 設(shè)備進(jìn)行訪問(wèn),即是對(duì)PCI 空間進(jìn)行訪問(wèn)。
PCI 設(shè)備包含配置空間、IO 空間和內(nèi)存空間。在x86 系統(tǒng)中,所有可以訪問(wèn)的內(nèi)存以及IO空間都被映射到了統(tǒng)一的4G 的x86 內(nèi)存空間中,并且系統(tǒng)使用PCI 配置空間來(lái)管理所有的PCI 設(shè)備空間。而PCI 配置空間本身又可以通過(guò)x86 IO空間設(shè)置的PCI 配置空間地址和數(shù)據(jù)端口訪問(wèn)。此時(shí)訪問(wèn)地址是由PCI 總線號(hào),功能號(hào)以及PCI類型等數(shù)據(jù)編址而成。
當(dāng)從配置空間中得到PCI 設(shè)備的基地址的時(shí)候,就可以根據(jù)設(shè)備中自身的地址映射使用相同的偏移量結(jié)合基地址對(duì)設(shè)備內(nèi)容進(jìn)行訪問(wèn)。
本嵌入式單板計(jì)算機(jī)選用了以下的硬件架構(gòu)(見(jiàn)圖2):Intel ATOM E620T (x86 architecture)其中集成了北橋、USB 鍵盤、PCI 設(shè)備(Ethernet等)、南橋設(shè)備(USB,SATA)和256MB DDRAM Memory。
表1 PCI 配置空間
圖2 實(shí)驗(yàn)單板計(jì)算機(jī)硬件框架
通過(guò)對(duì)此實(shí)驗(yàn)單板計(jì)算機(jī)架構(gòu)分析所得,絕大多數(shù)芯片由PCI 總線連接至CPU,由CPU 對(duì)其進(jìn)行控制和訪問(wèn)。其中由于CPU 芯片集成了北橋,因此,對(duì)于RAM 芯片的訪問(wèn)功能集成至CPU中。對(duì)此平臺(tái)的測(cè)試主要是對(duì)PCI 空間上的一些設(shè)備以及端口,由于端口的實(shí)現(xiàn)方式為存儲(chǔ)器映射方式,因此,對(duì)端口的訪問(wèn)實(shí)際上是對(duì)PCI 芯片設(shè)備的存儲(chǔ)空間進(jìn)行訪問(wèn)。
由于制作自定制Linux 系統(tǒng)必須對(duì)其內(nèi)核程序進(jìn)行重新編譯,因此,需要額外的Linux 系統(tǒng)計(jì)算機(jī)輔助開(kāi)發(fā)。開(kāi)發(fā)環(huán)境包括一臺(tái)帶有Linux 操作系統(tǒng)的PC。安裝并使用GCC 編譯器來(lái)輔助編譯kernel 和root 文件系統(tǒng)。同時(shí)安裝busybox 和syslinux。
由于大多數(shù)嵌入式系統(tǒng)都具有CF 卡槽,或者M(jìn)SD 卡槽,因此,本系統(tǒng)選擇使用CF 卡作為測(cè)試軟件系統(tǒng)的載體。Linux 系統(tǒng)啟動(dòng)的簡(jiǎn)略步驟:CPU 上電后,BIOS 進(jìn)行工作,BIOS 將讀取硬盤的MBR 區(qū)數(shù)據(jù);在MBR 區(qū)啟動(dòng)boot loader(LILO,GRUB,SYSLINUX 等),進(jìn)行boot 程序的加載。在boot loader 啟動(dòng)過(guò)程中,boot 程序?qū)⒊跏蓟O(shè)備驅(qū)動(dòng),并且使有些設(shè)備可以通過(guò)boot 程序啟動(dòng)。在boot loader 程序完成后,操作系統(tǒng)接管CPU 的控制,系統(tǒng)成功啟動(dòng)。
基于上文中的硬件環(huán)境建立Linux kernel。從www.linux.org 下載最新的Linux kernel;解壓縮下載下來(lái)的內(nèi)核代碼,安裝GCC 編譯器;根據(jù)待測(cè)硬件配置源碼包,制作bzImage 內(nèi)核鏡像??蓮木W(wǎng)上下載linux - 2.6.38.3. tar. bz2,運(yùn)行“make menuconfig”在配置項(xiàng)中選擇“Enable Eg20T south bridge I2c support”.
從www.busybox.net 下載busybox 源代碼,并且使用“make menuconfig”來(lái)配置busybox 的編譯。在編譯的過(guò)程中,[* ]ash 的選項(xiàng)必須選中。
因?yàn)閍sh 功能是linux 系統(tǒng)的基本功能,所以此選項(xiàng)必須被選中。其他的選項(xiàng)可以根據(jù)軟件需求進(jìn)行修改。完成“make menuconfig”的配置以后,運(yùn)行“make”命令,則根文件系統(tǒng)將在“-install/. folder”下創(chuàng)建出來(lái),并且shell 工具可以運(yùn)行在目標(biāo)Linux 平臺(tái)上。
通過(guò)syslinux 工具可以制作一張用來(lái)啟動(dòng)系統(tǒng)的CF 卡。在命令行輸入“. /extlinux —i/dev/sdc1”(這里默認(rèn)CF 卡占據(jù)設(shè)備的SDC1),通過(guò)這個(gè)命令使CF 卡能用來(lái)啟動(dòng)系統(tǒng)。并將CF 卡格式化為ext2 或ext3 的文件系統(tǒng)。
將根文件系統(tǒng)拷貝到CF 卡上,即將打包好的內(nèi)核鏡像“bzImage”拷貝到CF 卡上。并且根據(jù)以下配置來(lái)編輯配置文件“extlinux. conf”來(lái)設(shè)置Linux 系統(tǒng)環(huán)境:
Linux 操作系統(tǒng)給編程人員提供了PCI 驅(qū)動(dòng)的接口,因此可以通過(guò)此接口直接操作PCI 設(shè)備。本軟件系統(tǒng)使用Linux 系統(tǒng)函數(shù)pci-get-domain-bus-and-slot()來(lái)枚舉硬件系統(tǒng)中所有的PCI 設(shè)備。通過(guò)pci-scan()函數(shù)來(lái)對(duì)具體的PCI設(shè)備進(jìn)行查詢,這種查詢是通過(guò)對(duì)PCI 總線號(hào),設(shè)備號(hào)以及功能號(hào)的設(shè)置來(lái)實(shí)現(xiàn)的,在使用查詢功能之前可以通過(guò)閱讀硬件手冊(cè)來(lái)獲得被訪問(wèn)設(shè)備的PCI 硬件信息。如果查詢成功的話,函數(shù)將返回PCI 設(shè)備配置字描述結(jié)構(gòu)指針。通過(guò)對(duì)此指針的操作,可以實(shí)現(xiàn)對(duì)PCI 設(shè)備配置內(nèi)容的操作。
取得PCI 設(shè)備配置內(nèi)容后,可以根據(jù)基地址存儲(chǔ)單元即BAR(Base Address Register)中提供的內(nèi)容結(jié)合PCI 設(shè)備中的偏移量來(lái)生成相應(yīng)的地址,然后可以用iomap()函數(shù)將要訪問(wèn)的物理內(nèi)存映射至測(cè)試程序的邏輯地址中執(zhí)行。在對(duì)PCI設(shè)備地址中的IO 地址進(jìn)行操作時(shí)也可以按照此方法,可以調(diào)用pci-iomap()函數(shù)來(lái)將IO 端口映射至內(nèi)存空間進(jìn)行訪問(wèn),映射結(jié)果為獲得一個(gè)指向此地址的指針,因此,可以通過(guò)對(duì)指針進(jìn)行操作來(lái)訪問(wèn)硬件資源[3]。
根據(jù)嵌入式硬件和軟件的結(jié)構(gòu)(見(jiàn)圖3)。整個(gè)測(cè)試系統(tǒng)被分為三層,最底層為硬件層,此層包含了x86 平臺(tái)的硬件,其中有芯片、端口、總線等部件。中間層為L(zhǎng)inux 內(nèi)核層,在此層Linux 系統(tǒng)自動(dòng)將對(duì)底層硬件的訪問(wèn)封裝在驅(qū)動(dòng)程序內(nèi),其中有IO 空間訪問(wèn),內(nèi)存空間訪問(wèn)等,甚至包括一些特殊協(xié)議包括I2C 協(xié)議等等,都將其封裝在內(nèi)核層。而本軟件系統(tǒng)的PCI 測(cè)試驅(qū)動(dòng)也是存在于此層。最頂層是應(yīng)用層,在這一層應(yīng)用函數(shù)通過(guò)sys-call()的系統(tǒng)調(diào)用來(lái)訪問(wèn)內(nèi)核層的驅(qū)動(dòng),從而實(shí)現(xiàn)對(duì)硬件底層的訪問(wèn)。
圖3 硬件測(cè)試驅(qū)動(dòng)程序框架
由于Linux 系統(tǒng)的保護(hù)機(jī)制,應(yīng)用程序無(wú)法直接對(duì)物理內(nèi)存進(jìn)行訪問(wèn),只有在內(nèi)核級(jí)的編程模式下,才可以對(duì)硬件地址進(jìn)行訪問(wèn)。因此要實(shí)現(xiàn)對(duì)硬件的測(cè)試程序,只有將其置于內(nèi)核級(jí)的編程模式下。而普通的內(nèi)核級(jí)編程由于必須對(duì)內(nèi)核進(jìn)行打包并且每次調(diào)試都需要重新編譯,導(dǎo)致調(diào)試非常不方便。為了解決這個(gè)問(wèn)題,本系統(tǒng)采用了測(cè)試驅(qū)動(dòng)模塊的方式,將對(duì)硬件的測(cè)試功能添加入驅(qū)動(dòng)程序中,并且在調(diào)試過(guò)程中使用了insmod 命令來(lái)實(shí)時(shí)插入和卸載測(cè)試驅(qū)動(dòng)模塊,從而實(shí)現(xiàn)調(diào)試的實(shí)時(shí)性,并且可以在調(diào)試完之后卸載模塊,不影響整個(gè)系統(tǒng)的運(yùn)行。
同時(shí)為了滿足測(cè)試程序的多重調(diào)用,可將被測(cè)芯片所有的測(cè)試函數(shù)封裝至驅(qū)動(dòng)框架內(nèi),并且通過(guò)ioctl()函數(shù)向驅(qū)動(dòng)程序傳遞調(diào)用何種測(cè)試函數(shù)的命令,從而實(shí)現(xiàn)了測(cè)試程序的多重調(diào)用功能。具體程序?qū)崿F(xiàn)如下:
示例代碼中,對(duì)單板計(jì)算機(jī)中常用的FPGA芯片的各個(gè)功能模塊建立了測(cè)試函數(shù),例如fpga-ram(),并且通過(guò)對(duì)各測(cè)試函數(shù)設(shè)定其ioctl 調(diào)用命令,從而實(shí)現(xiàn)芯片整體測(cè)試的集成,并形成一個(gè)通用性的硬件測(cè)試驅(qū)動(dòng)程序框架。
當(dāng)測(cè)試驅(qū)動(dòng)模塊趨于調(diào)試穩(wěn)定時(shí),本系統(tǒng)將驅(qū)動(dòng)程序生成的* .ko 文件打包置內(nèi)核的啟動(dòng)批處理* . sh 文件中,從而實(shí)現(xiàn)了測(cè)試程序的自動(dòng)調(diào)用與測(cè)試。
本文討論了一種基于自定制Linux 硬件測(cè)試軟件的開(kāi)發(fā)方式,研究了Linux 環(huán)境下PCI 總線及PCI 設(shè)備的訪問(wèn)方式,同時(shí)根據(jù)Linux 驅(qū)動(dòng)程序的框架對(duì)于硬件測(cè)試程序進(jìn)行了探討,實(shí)現(xiàn)了硬件自動(dòng)化測(cè)試。
[1] 林納斯·托瓦茲.Linux 系統(tǒng)[EB/OL].(1991 -10-5)[2014 - 01 - 11]. http://baike. baidu. com/view/1634.htm?fr=aladdin.
[3] 科波特.LINUX 設(shè)備驅(qū)動(dòng)程序[M].3 版.北京:中國(guó)電力出版社,2006.