文獻(xiàn)標(biāo)識(shí)碼: A
文章編號(hào): 0258-7998(2014)03-0025-04
快速啟動(dòng)能力是衡量產(chǎn)品性能的一個(gè)重要指標(biāo)。無(wú)論是消費(fèi)類電子產(chǎn)品(例如手機(jī)、電腦、電視機(jī)),還是專業(yè)的通信電子設(shè)備(例如示波器、網(wǎng)關(guān)、服務(wù)器),啟動(dòng)速度快無(wú)疑能給用戶留下美好的第一印象。雖然電子設(shè)備的“心臟”越來(lái)越多地選用了多核處理器,但是目前大部分啟動(dòng)代碼還停留在單內(nèi)核處理器的思維框架中,沒(méi)有能夠充分利用多內(nèi)核處理器的長(zhǎng)處,而越來(lái)越多的外部器件卻在另一方面悄悄地延長(zhǎng)了啟動(dòng)時(shí)間。
為了彌補(bǔ)這一不足,突破傳統(tǒng)單核啟動(dòng)的思維框架,本文以一個(gè)典型的嵌入式系統(tǒng)為例,對(duì)加快系統(tǒng)啟動(dòng)速度進(jìn)行了研究。
1 典型的系統(tǒng)架構(gòu)和啟動(dòng)過(guò)程
1.1 系統(tǒng)架構(gòu)
智能通信電子產(chǎn)品的典型架構(gòu)是以CPU(中央處理器)為核心,根據(jù)產(chǎn)品需求輔以內(nèi)存、硬盤、網(wǎng)卡、USB、串口等各種外設(shè),如圖1所示。
系統(tǒng)的核心是飛思卡爾(FreeScale)公司開(kāi)發(fā)的32位PowerPC架構(gòu)處理器MPC8572E[1],主頻最高可達(dá)1.333 GHz。芯片集成了2個(gè)完全相同的高性能e500內(nèi)核,每個(gè)內(nèi)核各包含32 KB一級(jí)指令緩存和32 KB一級(jí)數(shù)據(jù)緩存。芯片還集成了豐多彩富的內(nèi)部功能模塊和外設(shè)接口,包括:2個(gè)內(nèi)核共享的1 MB容量的二級(jí)緩存、2個(gè)64位DDR2/DDR3內(nèi)存控制器、1個(gè)可編程的中斷控制器、1個(gè)安全引擎、2個(gè)I2C總線控制器、2個(gè)異步串口控制器、1個(gè)增強(qiáng)型本地總線控制器、4個(gè)支持10/100/1 000 MB/s的以太網(wǎng)接口、3個(gè)符合PCIe 1.0a標(biāo)準(zhǔn)的PCIe接口等。
CPU、內(nèi)存、閃存、串口和網(wǎng)口組成了一個(gè)常見(jiàn)的最小系統(tǒng),其他模塊則是錦上添花。處理器通過(guò)PCIe接口連接SATA/SAS控制器(例如LSI公司的SAS2008芯片),再外接SATA/SAS硬盤。實(shí)時(shí)時(shí)鐘芯片(RTC)和溫度感應(yīng)器通過(guò)I2C總線與處理器相連。FPGA用于輔助CPU工作。這個(gè)系統(tǒng)具有強(qiáng)大的處理能力和靈活的可擴(kuò)展性,適合于路由器、網(wǎng)關(guān)等多種應(yīng)用場(chǎng)合。其他智能電子設(shè)備的控制系統(tǒng)的架構(gòu)也大致如此,只是CPU可能替換成ARM、MIPS或x86等體現(xiàn)結(jié)構(gòu)的處理器,外圍器件有所增減,但是總體框架和啟動(dòng)過(guò)程大同小異。
1.2 啟動(dòng)過(guò)程
該系統(tǒng)由業(yè)界常用的U-BOOT[2]引導(dǎo)啟動(dòng)。圖2顯示了多內(nèi)核處理器系統(tǒng)中啟動(dòng)代碼的工作流程。上電或重啟后,內(nèi)核0根據(jù)配置引腳的設(shè)定,選擇從閃存中讀取啟動(dòng)代碼。其他內(nèi)核保持Reset狀態(tài)。內(nèi)核0依次初始化了e500內(nèi)核、第一個(gè)串口、一級(jí)數(shù)據(jù)緩存和指令緩存、二級(jí)緩存、I2C總線設(shè)備、內(nèi)存。因?yàn)槌跏蓟瘍?nèi)存時(shí)CPU需要訪問(wèn)內(nèi)存條上的SPD(SPD是存儲(chǔ)內(nèi)存條規(guī)格參數(shù)的EEPROM芯片),所以I2C總線的初始化必須在內(nèi)存初始化之前完成。之所以較早地初始化串口,是為了盡早建立人機(jī)交互的環(huán)境,以方便用戶判斷系統(tǒng)啟動(dòng)到各個(gè)階段的狀態(tài)。然后,內(nèi)核從閃存中讀取FPGA配置文件并且下載到FPGA芯片中,再初始化PCIe設(shè)備、網(wǎng)口、SAS/SATA控制器、硬盤和文件系統(tǒng)。接著,內(nèi)核0釋放其他內(nèi)核的Reset信號(hào)。
其他內(nèi)核也從閃存中讀取啟動(dòng)代碼,依次初始化e500內(nèi)核、一級(jí)數(shù)據(jù)緩存和指令緩存,然后通過(guò)共享內(nèi)存的方式(也可以通過(guò)內(nèi)部寄存器或者內(nèi)核間中斷等方式)通知內(nèi)核0“我準(zhǔn)備就緒了。”一旦內(nèi)核0發(fā)現(xiàn)其他內(nèi)核準(zhǔn)備就緒后,就從硬盤中讀取操作系統(tǒng)的鏡像文件,校驗(yàn)正確后加載執(zhí)行。如果內(nèi)核0發(fā)現(xiàn)其他內(nèi)核啟動(dòng)失敗,則重新發(fā)出Reset信號(hào),要求其他內(nèi)核重復(fù)初始化的過(guò)程。
經(jīng)過(guò)測(cè)試,整個(gè)系統(tǒng)的啟動(dòng)時(shí)間約9 s。表1列舉了耗時(shí)超過(guò)0.1 s的模塊,其他模塊的耗時(shí)微乎其微,可以忽略不計(jì)。從啟動(dòng)過(guò)程可以看出,所有的初始化任務(wù)基本上都由內(nèi)核0承擔(dān),總的啟動(dòng)時(shí)間是各模塊初始化時(shí)間的總和。顯然,這種傳統(tǒng)的多核啟動(dòng)方式?jīng)]有利用多內(nèi)核的優(yōu)勢(shì),還停留在單核啟動(dòng)的框架中。
2 啟動(dòng)過(guò)程的改進(jìn)
在多核系統(tǒng)中,為了高效地利用多個(gè)核的并行工作,啟動(dòng)代碼的設(shè)計(jì)需要從傳統(tǒng)意義上的任務(wù)串行機(jī)制轉(zhuǎn)換到任務(wù)并行機(jī)制,并且要注重多內(nèi)核間的協(xié)作。改進(jìn)后的啟動(dòng)方案不僅充分利用了多內(nèi)核的優(yōu)勢(shì),將一些模塊的初始化任務(wù)分配給了其他內(nèi)核,而且優(yōu)化了一些模塊的初始化方法,建立了內(nèi)核間有效的通信機(jī)制。
如何將模塊分配給其他內(nèi)核初始化,分配原則之一是獨(dú)立性。如果該模塊和其他模塊沒(méi)有相互依賴關(guān)系,則可以將該模塊分配給其他內(nèi)核加載。原則之二是耗時(shí)的模塊盡量分配給不同的內(nèi)核加載,即每個(gè)核承擔(dān)模塊的總耗時(shí)盡量平均,盡可能減少等待時(shí)間。據(jù)此優(yōu)化為圖3所示的啟動(dòng)流程。
啟動(dòng)過(guò)程中,內(nèi)核0仍然扮演主力隊(duì)員的角色,首先初始化e500、串口、一級(jí)緩存和二級(jí)緩存,然后只初始化一部分內(nèi)存,而不是全部?jī)?nèi)存。這一部分內(nèi)存姑且稱為基本內(nèi)存,即啟動(dòng)代碼所要用到的內(nèi)存,本系統(tǒng)中是32 MB。因?yàn)閮?nèi)存的初始化比較費(fèi)時(shí),主要時(shí)耗不在內(nèi)存控制器的初始化上,而在于將所有的4 GB內(nèi)存清零,所以把內(nèi)存劃分為一大一小兩部分初始化,將容量大的那部分內(nèi)存分配給其他內(nèi)核初始化,有利于提升整體的啟動(dòng)速度。
完成內(nèi)核、串口1和基本內(nèi)存的初始化之后,內(nèi)核0先把啟動(dòng)代碼從閃存復(fù)制到內(nèi)存中,再釋放其他內(nèi)核的Reset信號(hào)。其他內(nèi)核立刻初始化e500內(nèi)核和內(nèi)嵌的一級(jí)緩存,然后通知內(nèi)核0“我已經(jīng)準(zhǔn)備好了。”內(nèi)核0得知其他內(nèi)核準(zhǔn)備就緒了,就開(kāi)始分配其余的初始化任務(wù)。其他內(nèi)核依次初始化剩余的大部分內(nèi)存,下載FPGA的配置文件,初始化網(wǎng)口,最后等待操作系統(tǒng)。與此同時(shí),內(nèi)核0初始化PCIe設(shè)備、SAS/SATA控制器及磁盤,加載文件系統(tǒng),最后從磁盤中讀入操作系統(tǒng)文件,計(jì)算校驗(yàn)和,引導(dǎo)操作系統(tǒng)的啟動(dòng)。
除了改進(jìn)啟動(dòng)流程之外,充分利用硬件特性,優(yōu)化一些模塊的初始化方法和工作機(jī)制,設(shè)計(jì)高效的內(nèi)核間通信機(jī)制,也可以提升啟動(dòng)速度。
(1)內(nèi)存初始化。內(nèi)存初始化的主要耗時(shí)動(dòng)作是清零。目前主流的處理器都集成了DMA(直接存儲(chǔ)器訪問(wèn))引擎,DMA引擎就是為了降低CPU負(fù)載而設(shè)計(jì)的。測(cè)試發(fā)現(xiàn),與處理器直接清零內(nèi)存操作比較,采用DMA方式,速度可以提升一倍。并且,在DMA引擎清零的同時(shí),CPU還可以承擔(dān)其他工作,例如下載FPGA配置文件。此外,如果內(nèi)存設(shè)置為交織模式,其吞吐量可以翻番,從而減少耗時(shí),進(jìn)一步提升啟動(dòng)速度。
(2)PCIe初始化。PCIe[3]總線在軟件上兼容PCI、PCI-x總線,PCI或者PCI-x器件可以通過(guò)PCIe橋設(shè)備連接到PCIe的總線拓?fù)渲小CIe總線的拓?fù)浣Y(jié)構(gòu)像一顆樹,最多允許擁有256條總線,每條總線上最多允許32個(gè)設(shè)備,每個(gè)設(shè)備上最多可集成8個(gè)功能模塊。一般采用深度遞歸算法,從根節(jié)點(diǎn)出發(fā),遍歷整棵樹,找到存在的有效設(shè)備并初始化。初始化的操作就是分配總線號(hào)、設(shè)備號(hào)、中斷號(hào)和地址空間等。其中,PCIe拓?fù)浣Y(jié)構(gòu)的遍歷過(guò)程是比較耗時(shí)的一個(gè)操作。
實(shí)際上,對(duì)于電子產(chǎn)品而言,一旦電路板裝配好了,除了PCIe插槽上的設(shè)備未定之外,其他PCIe設(shè)備都固定了,是已知數(shù),所以對(duì)于已知設(shè)備可以省略掃描這個(gè)步驟。它的相關(guān)信息可以存儲(chǔ)在閃存的指定區(qū)域,啟動(dòng)代碼直接從這個(gè)區(qū)域讀取。如果電路板上沒(méi)有PCIe插槽,則整個(gè)PCIe拓?fù)浣Y(jié)構(gòu)的信息都可以保存在閃存中,徹底省略了遍歷過(guò)程,耗時(shí)微乎其微。對(duì)于插槽上的未定設(shè)備,深度遍歷的出發(fā)點(diǎn)可以從根節(jié)點(diǎn)出發(fā)改為從各個(gè)PCIe插槽出發(fā),大幅縮小遍歷范圍,從而節(jié)省了大量時(shí)間。
(3)簡(jiǎn)單高效的基于共享內(nèi)存的內(nèi)核間通信機(jī)制。內(nèi)核之間為了緊密配合,相互間需要傳遞一些命令和數(shù)據(jù),雖然有些處理器擁有特別的內(nèi)核間的通信方式,例如博通公司XLR系統(tǒng)處理器的消息環(huán)機(jī)制[4](Message Ring),但是共享內(nèi)存是一個(gè)比較通用的方法,不僅適合于內(nèi)核之間,也適合于處理器之間以及處理器與外設(shè)之間的通信,可移植性較強(qiáng)。基于共享內(nèi)存,設(shè)計(jì)一個(gè)簡(jiǎn)單高效的通信機(jī)制,有助于內(nèi)核0與其他內(nèi)核之間命令的上行下達(dá)。
因?yàn)閱?dòng)過(guò)程中內(nèi)核0起主導(dǎo)作用,所以在內(nèi)核0和其他每個(gè)內(nèi)核之間都創(chuàng)建了一條通信通道,組成一個(gè)星形結(jié)構(gòu):內(nèi)核0在中間,其他內(nèi)核在四周,如圖4所示。每條通道由收、發(fā)2個(gè)隊(duì)列組成:內(nèi)核0只能寫發(fā)送隊(duì)列,其他內(nèi)核只能讀發(fā)送隊(duì)列;接收隊(duì)列的操作相反,內(nèi)核0只能讀接收隊(duì)列,其他內(nèi)核只能寫接收隊(duì)列。
讀寫隊(duì)列的基本單位是數(shù)據(jù)塊,即每次從隊(duì)列中讀取一個(gè)或多個(gè)數(shù)據(jù)塊,或者往隊(duì)列中寫入一個(gè)或多個(gè)數(shù)據(jù)塊。數(shù)據(jù)塊由序列號(hào)、命令、數(shù)據(jù)長(zhǎng)度、數(shù)據(jù)等域組成。發(fā)送隊(duì)列數(shù)據(jù)塊中的序列號(hào)是偶數(shù),而接收隊(duì)列數(shù)據(jù)塊的序列號(hào)是奇數(shù),每一個(gè)發(fā)送數(shù)據(jù)塊都對(duì)應(yīng)一個(gè)響應(yīng)的接收數(shù)據(jù)塊,它們的序列號(hào)相差1。發(fā)送隊(duì)列數(shù)據(jù)塊中的數(shù)據(jù)域是與命令相關(guān)的參數(shù),接收隊(duì)列數(shù)據(jù)塊中的數(shù)據(jù)域是命令的執(zhí)行結(jié)果。
借助這個(gè)收發(fā)隊(duì)列通信機(jī)制,內(nèi)核0可以便捷地把初始化等任務(wù)分派給其他內(nèi)核并得到反饋,有利于系統(tǒng)的可擴(kuò)展性。例如系統(tǒng)中增加了一個(gè)新器件,內(nèi)核0可以把新器件的初始化工作分配給一個(gè)比較空閑的內(nèi)核,從而最大限度地減少對(duì)整個(gè)啟動(dòng)時(shí)間的影響。
經(jīng)過(guò)啟動(dòng)流程的改進(jìn)、模塊加載和初始化方式的優(yōu)化、內(nèi)核間高效通信機(jī)制的設(shè)計(jì)等工作,系統(tǒng)的啟動(dòng)時(shí)間大約縮短了50%,達(dá)到了比較滿意的結(jié)果。目前多處理器的發(fā)展和應(yīng)用如火如荼,希望本文所介紹的經(jīng)驗(yàn)對(duì)各種體系結(jié)構(gòu)的多內(nèi)核處理器的啟動(dòng)代碼設(shè)計(jì)都有所幫助。
參考文獻(xiàn)
[1] FreeScale Semiconductor.MPC8572E PowerQUICC III integrated processor hardware specifications,Rev.5[Z].2011.
[2] DENK W.The universal boot loader[EB/OL].[2013-07]. http://www.denx.de/wiki/DULG/WebHome.
[3] PCISIG.PCI Express base specification,revision 3.0[Z]. 2008.
[4] Broadcom Inc..XLR processor family data sheet,revision 2.00[Z].2008.