Linux对I/O端口资源的管理〔1〕
博主按:下文原作者在linux2.4.0基礎上分析的,我現在的內核是2.6.32。在有區別的地方我會用紅色文字標出,作為對原文的一些補充吧。
本文主要從內核實現的角度分析linux 2.4.0內核IO子系統中對IO端口資源的管理的實現原理。本文是為那些想要深入分析Linux的IO子系統的讀者和設備驅動程序開發人員而寫的。
Copyright ?0? 2002 by 詹榮開
E-mail:zhanrk@sohu.com
linux-2.4.0
Version 1.0.0,2002-10-1
關鍵詞:設備管理、驅動程序、I/O端口、資源
申明:這份文檔是按照自由軟件開放源代碼的精神發布的,任何人可以免費獲得、使用和重新發布,但是你沒有限制別人重新發布你發布內容的權利。發布本文的目的是希望它能對讀者有用,但沒有任何擔保,甚至沒有適合特定目的的隱含的擔保。更詳細的情況請參閱GNU通用公共許可證(GPL),以及GNU自由文檔協議(GFDL)。
幾乎每一種外設都是通過讀寫設備上的寄存器來進行的。外設寄存器也稱為“I/O端口”,通常包括:控制寄存器、狀態寄存器和數據寄存器三大類,而且一 個外設的寄存器通常被連續地編址。CPU對外設IO端口物理地址的編址方式有兩種:一種是I/O映射方式(I/O-mapped),另一種是內存映射方式 (Memory-mapped)。而具體采用哪一種則取決于CPU的體系結構。
有些體系結構的CPU(如,PowerPC、m68k等)通常只實現一個物理地址空間(RAM)。在這種情況下,外設I/O端口的物理地址就被映射到 CPU的單一物理地址空間中,而成為內存的一部分。此時,CPU可以象訪問一個內存單元那樣訪問外設I/O端口,而不需要設立專門的外設I/O指令。這就 是所謂的“內存映射方式”(Memory-mapped)。
而另外一些體系結構的CPU(典型地如X86)則為外設專門實現了一個單獨地地址空間,稱為“I/O地址空間”或者“I/O端口空間”。這是一個與 CPU地RAM物理地址空間不同的地址空間,所有外設的I/O端口均在這一空間中進行編址。CPU通過設立專門的I/O指令(如X86的IN和OUT指 令)來訪問這一空間中的地址單元(也即I/O端口)。這就是所謂的“I/O映射方式”(I/O-mapped)。與RAM物理地址空間相比,I/O地址空 間通常都比較小,如x86 CPU的I/O空間就只有64KB(0-0xffff)。這是“I/O映射方式”的一個主要缺點。
linux將基于I/O映射方式的或內存映射方式的I/O端口通稱為“I/O區域”(I/O region)。在討論對I/O區域的管理之前,我們首先來分析一下Linux是如何實現“I/O資源”這一抽象概念的。
3.1 linux對I/O資源的描述
linux設計了一個通用的數據結構resource來描述各種I/O資源(如:I/O端口、外設內存、DMA和IRQ等)。該結構定義在include/linux/ioport.h頭文件中:
struct resource {
??? const char *name;
??? unsigned long start, end;
??? unsigned long flags;
??? struct resource *parent, *sibling, *child;
};
2.6.32中start和end的類型是resource_size_t,在64位系統下是u64,32位系統下是u32
各成員的含義如下:
1. name指針:指向此資源的名稱。
2. start和end:表示資源的起始物理地址和終止物理地址。它們確定了資源的范圍,也即是一個閉區間[start,end]。
3. flags:描述此資源屬性的標志(見下面)。
4. 指針parent、sibling和child:分別為指向父親、兄弟和子資源的指針。
屬性flags是一個unsigned long類型的32位標志值,用以描述資源的屬性。比如:資源的類型、是否只讀、是否可緩存,以及是否已被占用等。下面是一部分常用屬性標志位的定義(ioport.h):
/*
* IO resources have these defined flags.
*/
#define IORESOURCE_BITS 0x000000ff /* Bus-specific bits */
#define IORESOURCE_IO 0x00000100 /* Resource type */
#define IORESOURCE_MEM 0x00000200
#define IORESOURCE_IRQ 0x00000400
#define IORESOURCE_DMA 0x00000800
#define IORESOURCE_PREFETCH 0x00001000 /* No side effects */
#define IORESOURCE_READONLY 0x00002000
#define IORESOURCE_CACHEABLE 0x00004000
#define IORESOURCE_RANGELENGTH 0x00008000
#define IORESOURCE_SHADOWABLE 0x00010000
#define IORESOURCE_BUS_HAS_VGA 0x00080000
#define IORESOURCE_UNSET 0x20000000
#define IORESOURCE_AUTO 0x40000000
#define IORESOURCE_BUSY 0x80000000
/* Driver has marked this resource busy */
指針parent、sibling和child的設置是為了以一種樹的形式來管理各種I/O資源。
轉載于:https://www.cnblogs.com/java-time/archive/2011/01/20/tt43.html
《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀總結
以上是生活随笔為你收集整理的Linux对I/O端口资源的管理〔1〕的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Aspx页面中直接编写javascrip
- 下一篇: Linux服务器网页显示乱码