1個(gè)系統(tǒng)要能正確工作,必須要有數(shù)據(jù)通道(data paths)的機(jī)制,軟件和硬件系統(tǒng)都概莫能外。對(duì)計(jì)算機(jī)系統(tǒng)而言,必須要有data paths的機(jī)制來確保CPU, RAM和I/O裝備之間的信息數(shù)據(jù)能正確的活動(dòng)。這些data paths,通常被稱為總線,是計(jì)算機(jī)內(nèi)部主要的通訊通道。
計(jì)算機(jī)內(nèi)部1般有系統(tǒng)總線來連接內(nèi)部所有的硬件裝備。1個(gè)典型的系統(tǒng)總線是PCI((Peripheral Component Interconnect)總線。其他類型的用得較多的總線還有ISA,EISA, MCA, SCSI, 和USB。1個(gè)計(jì)算機(jī)有多個(gè)不同類型的總線,這些總線由橋(bridge)鏈接起來。有以下兩種高速總線處理到達(dá)或出自內(nèi)存芯片的數(shù)據(jù)傳輸:
(1)前端總線:連接CPU和RAM控制器;
(2)后端總線:連接CPU和外部硬件裝備CACHE.
主機(jī)橋(HostBridge)連接系統(tǒng)總線和前端總線。
連接I/O裝備和CPU的數(shù)據(jù)通道可統(tǒng)稱為I/O總線。外設(shè)是為了用來適配1個(gè)外設(shè)總線而存在的, 并且大部份流行的 I/O 總線成型在個(gè)人計(jì)算機(jī)上。可見,總線的類型影響到I/O裝備的內(nèi)部設(shè)計(jì)同時(shí)影響到Linux內(nèi)核對(duì)它的處理方式。
PC的通用I/O架構(gòu)以下所示:
接下來,我將依照從上而下的順序(即I/O controller--> I/O Interface--->I/O Port)對(duì)該圖進(jìn)行點(diǎn)評(píng)。
裝備控制器( I/O Controller)的作用有以下兩個(gè):
(1)解析從I/O Interface接收到的高層次命令,并通過發(fā)送時(shí)序正確的電信號(hào)給I/O裝備,I/O裝備則根據(jù)這些信號(hào)去履行相應(yīng)的動(dòng)作。
(2)正確的解析和翻譯來自I/O裝備的電信號(hào)并通過I/O Interface修改相應(yīng)的I/O 狀態(tài)寄存器值。(I/O狀態(tài)寄存器是I/O PORT的1種。)
I/O Interface是1種硬件電路,插入在I/O Port和相應(yīng)的裝備控制器之間。它充當(dāng)1個(gè)解釋器的功能,把I/O Port里的值解析為對(duì)應(yīng)裝備的命令或數(shù)據(jù)。相應(yīng)的,它也會(huì)讀取裝備的狀態(tài)值,并更新I/O port里的值。
有兩種類型的interface:
(1)定制化接口。經(jīng)常使用的有鍵盤接口,圖形接口,磁盤接口,總線鼠標(biāo)接口,網(wǎng)絡(luò)接口等。
(2)通用接口。常見的有串口,并口,PCMCIA(如硬盤、網(wǎng)卡等)接口,SCSI接口,USB接口等。
為了統(tǒng)1起見,裝備的I/O Port也被結(jié)構(gòu)化為1系列專用寄存器:
(1)控制寄存器;
(2)狀態(tài)寄存器;
(3)輸入寄存器;
(4)輸出寄存器。
示意圖以下:
對(duì)CPU而言,如果它要發(fā)數(shù)據(jù)到某個(gè)裝備,實(shí)際上是發(fā)到對(duì)應(yīng)的接口(I/O Interface),接口電路里有多個(gè)寄存器(也稱為端口,即“I/O PORT”),訪問裝備實(shí)際上是讀寫這些寄存器,所有的信息會(huì)由接口轉(zhuǎn)給它的裝備。1般來講,CPU會(huì)根據(jù)需要向裝備控制寄存器寫入需要履行的命令,并會(huì)從裝備狀態(tài)寄存器讀取裝備的內(nèi)部狀態(tài)。CPU也會(huì)從輸入寄存器獲得(Featch or pull)字節(jié)數(shù)據(jù),或向輸出寄存器以推送的方式寫入(Push)字節(jié)數(shù)據(jù)。
1個(gè)外部裝備要想接入系統(tǒng),就用自己的接口和總線上的某個(gè)匹配接口對(duì)接。通常會(huì)有多個(gè)外設(shè),每一個(gè)外設(shè)的接口電路中,又會(huì)有多個(gè)端口,每一個(gè)端口都需要1個(gè)地址,為他們標(biāo)識(shí)1個(gè)具體的地址值,是系統(tǒng)必須解決的事,與此同時(shí),你還有個(gè)內(nèi)存條,多是512M或1G或更大的金士頓、現(xiàn)代DDR2之類,他們的每個(gè)地址也都需要分配1個(gè)標(biāo)識(shí)值,另外,很多外設(shè)有自己的內(nèi)存、緩沖區(qū),就像你的內(nèi)存條1樣,你一樣需要為它們分配內(nèi)存……你的CPU可能需要和它們的每個(gè)字節(jié)都打交道,所以:別期望偷懶,它們的每寸土地都要計(jì)劃好!
為了計(jì)劃好I/O端口,有兩種編址方式:獨(dú)立編址和統(tǒng)1編址。
(1)統(tǒng)1編址:
外設(shè)接口中的IO寄存器(即IO端口)與主存單元1樣看待,每一個(gè)端口占用1個(gè)存儲(chǔ)單元的地址,將主存的1部份劃出來用作IO地址空間,如,在 PDP⑴1中,把最高的4K主存作為IO裝備寄存器地址。端口占用了存儲(chǔ)器的地址空間,使存儲(chǔ)量容量減小。統(tǒng)1編址也稱為“I/O內(nèi)存”方式,外設(shè)寄存器位于“內(nèi)存空間”(很多外設(shè)有自己的內(nèi)存、緩沖區(qū),外設(shè)的寄存器和內(nèi)存統(tǒng)稱“I/O空間”)。
(2)獨(dú)立編址(單獨(dú)編址):
IO地址與存儲(chǔ)地址分開獨(dú)立編址,I/0端口地址不占用存儲(chǔ)空間的地址范圍,這樣,在系統(tǒng)中就存在了另外一種與存儲(chǔ)地址無關(guān)的IO地址,CPU也必須具有專用與輸入輸出操作的IO指令(IN、OUT等)和控制邏輯。獨(dú)立編址下,地址總線上過來1個(gè)地址,裝備不知道是給IO端口的、還是給存儲(chǔ)器的,因而處理器通過MEMR/MEMW和IOR/IOW兩組控制信號(hào)來實(shí)現(xiàn)對(duì)I/O端口和存儲(chǔ)器的不同尋址。如,intel 80x86就采取單獨(dú)編址,CPU內(nèi)存和I/O是1起編址的,就是說內(nèi)存1部份的地址和I/O地址是堆疊的。獨(dú)立編址也稱為“I/O端口”方式,外設(shè)寄存器位于“I/O(地址)空間”。
本文力求通俗易懂,主要參考書籍: Understanding the Linux Kernel