最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網 會員登陸 & 注冊

一篇徹底理解Linux I/O體系結構!

2022-08-15 17:55 作者:補給站Linux內核  | 我要投稿

為了確保計算機能夠正常工作,必須提供數(shù)據(jù)通路,讓信息在連接到個人計算機的CPU、RAM和I/O設備之間流動。這些數(shù)據(jù)通路總稱為總線,擔當計算機內部主通信通道的作用。

所有計算機都擁有一條系統(tǒng)總線,它連接大部分內部硬件設備。一種典型的系統(tǒng)總線是PCI(Peripheral Component Interconnect)總線。目前使用其他類型的總線也很多,如ISA、EISA、MCA、SCSI和USB。

典型的情況是,一臺計算機包括幾種不同類型的總線,它們通過被稱作“橋”的硬件設備連接在一起。兩條高速總線用于在內存芯片上來回傳送數(shù)據(jù):前端總線將CPU連接到RAM控制器上,而后端總線將CPU直接連接到外部硬件的高速緩存上。主機上的橋將系統(tǒng)總線和前端總線連接在一起。

任何I/O設備有且僅能連接一條總線??偩€的類型影響I/O設備的內部設計,也影響著內核如何處理設備。我們這篇博文將討論所有PC體系結構共有的功能性特點,而不具體介紹特定總線類型的技術細節(jié)。

CPU和I/O設備之間的數(shù)據(jù)通路通常稱為I/O總線。80x86微處理器使用16位的地址總線對I/O設備進行尋址,使用8位、16位或32位的數(shù)據(jù)總線傳輸數(shù)據(jù)。每個I/O設備依次連接到I/O總線上,這種連接使用了包含3個元素的硬件組織層次:I/O端口、接口和設備控制器。下圖顯示了I/O體系結構的這些成分:


【文章福利】小編推薦自己的Linux內核技術交流群:【891587639】整理了一些個人覺得比較好的學習書籍、視頻資料共享在群文件里面,有需要的可以自行添加哦?。。。ê曨l教程、電子書、實戰(zhàn)項目及代碼)? ??

1 I/O端口

每個連接到I/O總線上的設備都有自己的I/O地址集,通常稱為I/O端口(I/O port)。在IBM PC體系結構中,I/O地址空間一共提供了65536個8位的I/O端口??梢园褍蓚€連續(xù)的8位端口看成一個16位端口,但是這必須從偶數(shù)地址開始。同理,也可以把兩個連續(xù)的16位端口看成一個32位端口,但是這必須是從4的整數(shù)倍地址開始。有四條專用的匯編語言指令可以允許CPU對I/O端口進行讀寫,它們是in、ins、out和outs。在執(zhí)行其中的一條指令時,CPU使用地址總線選擇所請求的I/O端口,使用數(shù)據(jù)總線在CPU寄存器和端口之間傳送數(shù)據(jù)。 I/O端口還可以被映射到物理地址空間。因此,處理器和I/O設備之間的通信就可以使用對內存直接進行操作的匯編語言指令(例如,mov、and、or等等)?,F(xiàn)代的硬件設備更傾向于映射的I/O,因為這樣處理的速度較快,并可以和DMA結合起來。

系統(tǒng)設計者的主要目的是對I/O編程提供統(tǒng)一的方法,但又不犧牲性能。為了達到這個目的,每個設備的I/O端口都被組織成如下圖所示的一組專用寄存器。CPU把要發(fā)送給設備的命令寫入設備控制寄存器(device control register),并從設備狀態(tài)寄存器(device status register)中讀出表示設備內部狀態(tài)的值。CPU還可以通過讀取設備輸入寄存器(device input register)的內容從設備取得數(shù)據(jù),也可以通過向設備輸出寄存器(device output register)中寫入字節(jié)而把數(shù)據(jù)輸出到設備。



為了降低成本,通常把同一I/O端口用于不同目的。例如,某些位描述設備的狀態(tài),而其他位指定向設備發(fā)出的命令。同理,也可以把同一I/O端口用作輸入寄存器或輸出寄存器。

in、out、ins和outs匯編語言指令都可以訪問I/O端口。內核中包含了以下輔助函數(shù)來簡化這種訪問: inb(),inw(),inl()

分別從I/O端口讀取1、2或4個連續(xù)字節(jié)。后綴“b”、“w”、“l(fā)”,分別代表一個字節(jié)(8位)、一個字(16位)以及一個長整型(32位)。

inb_p(),inw_p(),inl_p()

分別從I/O端口讀取1、2或4個連續(xù)字節(jié),然后執(zhí)行一條“啞元(dummy,即空指令)”指令使CPU暫停。

outb(),outw(),outl()

分別向一個I/O端口寫入1、2或4個連續(xù)字節(jié)。

outb_p(),outw_p(),outl_p()

分別向一個I/O端口寫入1、2或4個連續(xù)字節(jié),然后執(zhí)行一條“啞元”指令使CPU暫停。

insb(),insw(),insl()

分別從I/O端口讀取以1、2或4個字節(jié)為一組的連續(xù)字節(jié)序列。字節(jié)序列的長度由該函數(shù)的參數(shù)給出。

outsb(),outsw(),outsl()

分別向I/O端口寫入以1、2或4個字節(jié)為一組的連續(xù)字節(jié)序列。

80x86沒有使用以上這些輔助函數(shù),因為對于直接使用in、out、ins和outs這些匯編語言是再好不過了,如果你要分析arm、mpis等其他體系結構,可以看看他們。我們主要分析x86體系,所以就不去管他們了。

雖然訪問I/O端口非常簡單,但是檢測哪些I/O端口已經分配給I/O設備可能就不這么簡單了。通常,I/O設備驅動程序為了探測硬件設備,需要盲目地向某一I/O端口寫入數(shù)據(jù);但是,如果其他硬件設備已經使用了這個端口,那么系統(tǒng)就會崩潰。為了防止這種情況的發(fā)生,內核必須使用“資源”來記錄分配給每個硬件設備的I/O端口。

資源(resource)表示某個實體的一部分,這部分被互斥地分配給設備驅動程序。在我們的情況中,一個資源表示I/O端口地址的一個范圍。每個資源對應的信息存放在resource數(shù)據(jù)結構中。所有的同種資源都插入到一個樹型數(shù)據(jù)結構中;例如,表示I/O端口地址范圍的所有資源都包含在一個根節(jié)點為ioport_resource的樹中: struct resource { resource_size_t start; /* 資源范圍的開始 /resource_size_t end; / 資源范圍的結束 */ const char name; / 資源擁有者的描述 /unsigned long flags; / 各種標志 // 指向資源樹中父親、兄弟和第一個孩子的指針 */


#define IO_SPACE_LIMIT 0xffff /* x86體系是16位總線端口地址 */

注意,第一個I/O端口資源賦給了PCI接口。節(jié)點的孩子被收集在一個鏈表中,其第一個元素由child指向。sibling字段指向鏈表中的下一個節(jié)點。

那么,為什么要使用樹,而不是其他諸如鏈表等形式呢?例如,考慮一下SCSI磁盤接口所使用的I/O端口地址 —— 比如說從0xf000到0xf00f。然后,start字段為0xf000且end字段為0xf00f的這樣一個資源包含在樹中,控制器的常規(guī)名字存放在name字段中。但是,SCSI設備驅動程序需要記住另外的信息,也就是SCSI鏈(SCSI chain)的主盤(master disk)使用0xf0000xf007的子范圍,從盤(slave disk)使用0xf0080xf00f的子范圍。為了做到這點,設備驅動程序把兩個子范圍對應的孩子插入到0xf00O0xf00f的整個范圍對應的資源下。一般來說,樹中的每個節(jié)點肯定相當于父節(jié)點對應范圍的一個子范圍。I/O端口資源樹(ioport_resource)的根節(jié)點跨越了整個I/O地址空間(從端口065535)。一個典型的PC I/O端口資源分配如下:

0000~000F:DMA控制器1 0020~0021:主中斷控制器 0040~0043:系統(tǒng)時鐘 0060:鍵盤控制器控制狀態(tài)口 0061:系統(tǒng)揚聲器 0064:鍵盤控制器數(shù)據(jù)口 0070~0071:系統(tǒng)CMOS/實時鐘 0080~0083:DMA控制器1 0087~0088:DMA控制器1 0089~008B:DMA控制器1 00A0~00A1:從中斷控制器 00C0~00DF:DMA控制器2 00F0~00FF:數(shù)值協(xié)處理器 0170~0117:標準IDE/ESDI硬盤控制器 01F0~01FF:標準IDE/ESDI硬盤控制器 0200~0207:游戲口 0274~0277:ISA即插即用計數(shù)器 0278~027F:并行打印機口 02F8~02FF:串行通信口2(COM2) 0376:第二個IDE硬盤控制器 0378~037F:并行打印口1 03B0~03BB:VGA顯示適配器 03C0~03DF:VGA顯示適配器 03D0~03DF:彩色顯示器適配器 03F2~03F5:軟磁盤控制器 03F6:第一個硬盤控制器 03F8~03FF:串行通信口1(COM1)

0400~FFFF沒有指明端口,供用戶擴展使用

任何設備驅動程序都可以使用下面三個函數(shù),傳遞給它們的參數(shù)為資源樹的根節(jié)點和要插入的新資源數(shù)據(jù)結構的地址:


allocate_resource() —— 在資源樹中尋找一個給定大小和排列方式的可用范圍;若存在,就將這個范圍分配給一個I/O設備(主要由PCI設備驅動程序使用,這種驅動程序可以配置成使用任意的端口號和主板上的內存地址對其進行配置)。


release_resource() —— 釋放以前分配給I/O設備的給定范圍。


內核也為以上應用于I/O端口的函數(shù)定義了一些快捷函數(shù):request_region()分配I/O端口的給定范圍,release_region()釋放以前分配給I/O端口的范圍。當前分配給I/O設備的所有I/O地址的樹都可以從/proc/ioports文件中獲得。下面給大家展示一下本人的系統(tǒng)環(huán)境的I/O端口的最終分配情況:

[root@localhost proc]# cat ioports 0000-001f : dma1 0020-0021 : pic1 0040-0043 : timer0 0050-0053 : timer1 0060-0060 : keyboard 0064-0064 : keyboard 0070-0077 : rtc 0080-008f : dma page reg 00a0-00a1 : pic2 00c0-00df : dma2 00f0-00ff : fpu 02f8-02ff : serial 03c0-03df : vga+ 03f8-03ff : serial 0400-041f : 0000:00:1f.3 0400-041f : i801_smbus 0800-0803 : ACPI PM1a_EVT_BLK 0804-0805 : ACPI PM1a_CNT_BLK 0808-080b : ACPI PM_TMR 0810-0815 : ACPI CPU throttle 0820-082f : ACPI GPE0_BLK 0850-0850 : ACPI PM2_CNT_BLK 0a00-0a0f : pnp 00:08 0ca2-0ca3 : pnp 00:0c 0ca2-0ca2 : ipmi_si 0ca3-0ca3 : ipmi_si a400-a41f : 0000:00:1d.0 a400-a41f : uhci_hcd a480-a49f : 0000:00:1d.1 a480-a49f : uhci_hcd a800-a81f : 0000:00:1d.2 a800-a81f : uhci_hcd a880-a89f : 0000:00:1a.0 a880-a89f : uhci_hcd ac00-ac1f : 0000:00:1a.1 ac00-ac1f : uhci_hcd b000-b01f : 0000:00:1a.2 b000-b01f : uhci_hcd b400-b407 : 0000:00:1f.2 b480-b49f : 0000:00:1f.2 b800-b803 : 0000:00:1f.2 b880-b887 : 0000:00:1f.2 bc00-bc03 : 0000:00:1f.2 c000-cfff : PCI Bus #01 cc00-cc1f : 0000:01:00.0 d000-dfff : PCI Bus #02 dc00-dc1f : 0000:02:00.0 e000-efff : PCI Bus #05 e400-e4ff : 0000:05:00.0 e800-e8ff : 0000:05:00.1

注意咯,其實這個樹的最大深度也就是2。因為主從關系最多也就從到2。

2 I/O接口

I/O接口(I/O interface)是處于一組I/O端口和對應的設備控制器之間的一種硬件電路。它起翻譯器的作用,即把I/O端口中的值轉換成設備所需要的命令和數(shù)據(jù)。在相反的方向上,它檢測設備狀態(tài)的變化,并對起狀態(tài)寄存器作用的I/O端口進行相應的更新。還可以通過一條IRQ線把這種電路連接到可編程中斷控制器上,以使它代表相應的設備發(fā)出中斷請求。

有兩種類型的接口:

2.1 專用I/O接口

專門用于一個特定的硬件設備。在一些情況下,設備控制器與這種I/O接口處于同一塊卡中(每塊卡都要擂入PC的一個可用空閑總線插槽中。如果一塊卡通過一條外部電纜連接到一個外部設備上,那么在PC后面的面板中就有一個對應的連接器。)。連接到專用I/O接口上的設備可以是內部設備(位于PC機箱內部的設備),也可以是外部設備(位于PC機箱外部的設備)。

專用I/O接口的種類很多,因此目前已裝在PC上設備的種類也很多,我們無法一一列出,在此只列出一些最通用的接口:

鍵盤接口: 連接到一個鍵盤控制器上,這個控制器包含一個專用微處理器。這個微處理器對按下的組合鍵進行譯碼,產生一個中斷并把相應的鍵盤掃描碼寫人輸入寄存器。

圖形接口: 和圖形卡中對應的控制器封裝在一起,圖形卡有自己的幀緩沖區(qū),還有一個專用處理器以及存放在只讀存儲器(ROM)芯片中的一些代碼。幀緩沖區(qū)是顯卡上固化的存儲器,其中存放的是當前屏幕內容的圖形描述。

磁盤接口: 由一條電纜連接到磁盤控制器,通常磁盤控制器與磁盤放在一起。例如,IDE接口由一條40線的帶形電纜連接到智能磁盤控制器上,在磁盤本身就可以找到這個控制器。

總線鼠標接口: 由一條電纜把接口和控制器連接在一起,控制器就包含在鼠標中。

網絡接口: 與網卡中的相應控制器封裝在一起,用以接收或發(fā)送網絡報文。雖然廣泛采用的網絡標準很多,但還是以太網(IEEE 802.3)最為通用。

2.2 通用I/O接口

用來連接多個不同的硬件設備。連接到通用I/O接口上的設備通常都是外部設備。現(xiàn)代PC都包含連接很多外部設備的幾個通用I/O接口。最常用的接口有:

并口: 傳統(tǒng)上用于連接打印機,它還可以用來連接可移動磁盤、掃描儀、備份設備、其他計算機等等。數(shù)據(jù)的傳送以每次1字節(jié)(8位)為單位進行。

串口: 與并口類似,但數(shù)據(jù)的傳送是逐位進行的。串口包括一個通用異步收發(fā)器(UART)芯片,它可以把要發(fā)送的字節(jié)信息拆分成位序列,也可以把接收到的位流重新組裝成字節(jié)信息。由于串口本質上速度低于并口,因此主要用于連接那些不需要高速操作的外部設備,如調制解調器、鼠標以及打印機。

PCMCIA接口: 大多數(shù)便攜式計算機都包含這種接口。在不重新啟動系統(tǒng)的情況下,這種形狀類似于信用卡的外部設備可以被插入插槽或從插槽中拔走。最常用的PCMCIA設備是硬盤、調制解調器、網卡和擴展RAM。

SCSI(小型計算機系統(tǒng)接口)接口: 是把PC主總線連接到次總線(稱為SCSI總線)的電路。SCSI-2總線允許一共8個PC和外部設備(硬盤、掃描儀、CR-ROM刻錄機等等)連接在一起。如果有附加接口,寬帶SCSI-2和新的SCSI-3接口可以允許你連接多達16個以上的設備。SCSI標準是通過SCSI總線連接設備的通信協(xié)議。

通用串行總線(USB): 高速運轉的通用I/O接口,可用于連接外部設備,代替?zhèn)鹘y(tǒng)的并口、串口以及SCSI接口。

3 設備控制器

復雜的設備可能需要一個設備控制器(device controller)來驅動。從本質上說,控制器起兩個重要作用: (1)對從I/O接口接收到的高級命令進行解釋,并通過向設備發(fā)送適當?shù)碾娦盘栃蛄袕娭圃O備執(zhí)行特定的操作。 (2)對從設備接收到的電信號進行轉換和適當?shù)亟忉?,并修改(通過I/O接口)狀態(tài)寄存器的值。

典型的設備控制器是磁盤控制器,它從微處理器(通過I/O接口)接收諸如“寫這個數(shù)據(jù)塊”之類的高級命令,并將其轉換成諸如“把磁頭定位在正確的磁道上”和“把數(shù)據(jù)寫入這個磁道”之類的低級磁盤操作?,F(xiàn)代的磁盤控制器相當復雜,因為它們可以把磁盤數(shù)據(jù)快速保存到內存的高速緩存中,還可以根據(jù)實際磁盤的幾何結構重新安排CPU的高級請求,使其最優(yōu)化。

比較簡單的設備沒有設備控制器,可編程中斷控制器和可編程間隔定時器就是這樣的設備。

很多硬件設備都有自己的存儲器,通常稱之為I/O共享存儲器。例如,所有比較新的圖形卡在幀緩沖區(qū)中都有幾MB的RAM,用它來存放要在屏幕上顯示的屏幕映像。


一篇徹底理解Linux I/O體系結構!的評論 (共 條)

分享到微博請遵守國家法律
广东省| 临西县| 格尔木市| 浦北县| 湟源县| 郑州市| 海丰县| 盐亭县| 阿拉尔市| 阿城市| 尚义县| 塔河县| 中超| 石屏县| 澳门| 朝阳县| 承德县| 盈江县| 新源县| 和田县| 白沙| 维西| 岐山县| 元阳县| 芷江| 静宁县| 遵义市| 佛教| 西华县| 高雄市| 健康| 工布江达县| 攀枝花市| 兴义市| 郸城县| 澄迈县| 张家川| 武乡县| 都江堰市| 临桂县| 工布江达县|