## 12.2.?回顧: ISA
設計上 ISA 總線非常老了, 并且是非常地低能, 但是它仍然持有一塊挺大的控制設備的市場. 如果速度不重要并且你想支持老式主板, 一個 ISA 實現要優于 PCI. 這個老標準的另外一個好處是如果你是一個電子愛好者, 你可輕易建立你自己的 ISA 設備, 顯然對 PCI 是不可能的.
另一方面, ISA 的許多缺點是它緊密綁定在 PC 體系上; 這個接口總線有所有的 80286 處理器的限制并且給系統程序員帶來無窮的痛苦. ISA 設計(從原始的 IBM PC 繼承下來的)的另一個大問題是地理式尋址的缺乏, 它已導致許多問題和長時間的拔下-重置跳線-插上-測試 循環來添加新設備. 有趣的是要注意甚至是最老的 Aplle II 計算機都已經采用了地理式尋址, 并且它們特有無跳線擴展板.
不管它的大的缺點, ISA 仍然在幾個意想不到的地方使用. 例如, 用在幾個掌上電腦的 VR41xx 系列的 MIPS 處理器特有一個 ISA 兼容的擴展總線, 就象它看起來那么奇怪. 在 ISA 的這些意想不到的用法之后的理由是一些老式設備的相當低的成本, 例如基于 8390 的以太網卡, 因此一個帶有 ISA 電路信號的 CPU 可輕易采用這個糟糕的, 但是便宜的 PC 設備.
### 12.2.1.?硬件資源
一個 ISA 設備可配備有 I/O 端口, 內存區, 和中斷線.
盡管 x86 處理器支持 64 KB I/O 端口內存(即, 處理器有 16 條地址線), 一些老 PC 硬件僅解碼最低的 10 位地址線. 這限制可用的地址空間為 1024 個端口, 因為任何在 1 KB 到64 KB 范圍內的地址都被只解碼低地址的任何設備錯當成一個低地址. 一些外設解決這個限制通過映射一個端口到低 KB 并且使用高地址線來選擇不同的設備寄存器. 例如, 一個映射在 0x340 的設備可安全地使用端口 0x740, 0x840, 等等.
如果 I/O 端口的可用性被限制, 內存存取更加麻煩. 一個 ISA 設備可只使用 640KB 到1 MB 之間的內存范圍和 15 MB 和 16MB 之間的范圍給 I/O 寄存器和設備控制. 640-KB 到 1-MB 范圍被 PC BIOS , VAG-兼容的視頻卡, 和各種其他設備使用, 給新設備留下了很少空間. 另一方面, 在 15MB 的內存, 不被 Linux 直接支持, 并且改造內核來支持它是浪費時間.
對 ISA 設備板第 3 個可用資源是中斷線. 一個有限數目的中斷線被連接到 ISA 總線, 并且它們由所有接口板共享. 結果是, 如果設備不被正確配置, 它們可能發現它們自己在使用同一個中斷線.
盡管原始的 ISA 規范不允許在設備間共享, 大部分設備板允許這樣. [[44](#)]在軟件層次的共享在"中斷共享"一節中描述, 在第 10 章.
### 12.2.2.?ISA 編程
對于編程, 內核中沒有特別的幫助來易于存取 ISA 設備(象對 PCI 那樣有, 例如). 你可使用的唯一工具是 I/O 端口和 IRQ 線的注冊, 在 10 章的"安裝一個中斷處理"一節.
在本書第一部分所展示的編程技術適用于 ISA 設備; 驅動可探測 I/O 端口, 并且中斷線必須被自動探測, 使用在 10 章的"自動探測 IRQ 號"一節的一個技術.
幫忙函數 isa_readb 和 它的朋友已經在"使用 I/O 內存" 9 章中簡單介紹了, 并且對它們沒有更多要說的.
### 12.2.3.?即插即用規范
一些新 ISA 設備板遵循特殊的設計規范并且需要一個特別的初始化順序, 對增加接口板的簡單安裝和配置的擴展. 這些板的設計規范稱為即插即用, 由一個麻煩的規則集組成, 來建立和配置無跳線的 ISA 設備. PnP 設備實現可重分配的 I/O 區; PC 的 BIOS 負責重新分配 -- 回想 PCI
簡短來說, PnP 的目標是獲得同樣的靈活性, 在 PCI 設備中有的, 而不必關閉底層的電路接口(ISA 總線). 為此, 這個規范定義了一套設備獨立的配置寄存器和一個地理式尋址接口板的方法, 盡管物理總線沒有每塊板子相連(地理上)--每個 ISA 信號線連接到每個可用的槽位.
地理式尋址通過分配一個小的整數, 稱為卡選擇號(CSN), 給計算機中的每個 PnP 外設. 每個 PnP 設備特有一個唯一的系列標識符, 64-位寬, 這硬連線到外設板. CSN 分配使用唯一的序列號來標識 PnP 設備. 但是 CSN 可被分配只在啟動時, 它要求 BISO 是知道 PnP 的. 由于這個理由, 老式計算機要求用戶來獲得并插入一個特別的配置磁盤, 即便這個設備是 PnP 的.
遵循 PnP 的接口板在硬件級別上是復雜的. 它們比 PCI 板更加精細并且需要復雜的軟件. 安裝這些設備有困難是常有的, 并且即便安裝順利, 你仍然面對性能限制和 ISA 總線的受限的 I/O 空間. 最好在任何可能時安裝 PCI 設備, 并且享受新技術.
如果你對 PnP 配置軟件感興趣, 你可瀏覽 drivers/net/3c509.c, 它的探測函數處理 PnP 設備. 2.6 內核有許多工作在 PnP 設備支持領域, 因此許多靈活的接口和之前的內核發行相比被清理了.
[[44](#)] 中斷共享的問題是一個電子工程的問題: 如果一個設備驅動信號線非激活 -- 通過給一個低阻電平 -- 中斷無法被共享. 如果, 另一方面, 設備使用一個上拉電阻來去激活邏輯電平, 共享是可能的. 現在這是正常的. 但是, 仍然有潛在的丟失中斷事件的危險, 因為 ISA 中斷是沿觸發的而不是電平觸發的. 沿觸發中斷易于在硬件中實現, 但是沒有使它們可安全共享.
- Linux設備驅動第三版
- 第 1 章 設備驅動簡介
- 1.1. 驅動程序的角色
- 1.2. 劃分內核
- 1.3. 設備和模塊的分類
- 1.4. 安全問題
- 1.5. 版本編號
- 1.6. 版權條款
- 1.7. 加入內核開發社團
- 1.8. 本書的內容
- 第 2 章 建立和運行模塊
- 2.1. 設置你的測試系統
- 2.2. Hello World 模塊
- 2.3. 內核模塊相比于應用程序
- 2.4. 編譯和加載
- 2.5. 內核符號表
- 2.6. 預備知識
- 2.7. 初始化和關停
- 2.8. 模塊參數
- 2.9. 在用戶空間做
- 2.10. 快速參考
- 第 3 章 字符驅動
- 3.1. scull 的設計
- 3.2. 主次編號
- 3.3. 一些重要數據結構
- 3.4. 字符設備注冊
- 3.5. open 和 release
- 3.6. scull 的內存使用
- 3.7. 讀和寫
- 3.8. 使用新設備
- 3.9. 快速參考
- 第 4 章 調試技術
- 4.1. 內核中的調試支持
- 4.2. 用打印調試
- 4.3. 用查詢來調試
- 4.4. 使用觀察來調試
- 4.5. 調試系統故障
- 4.6. 調試器和相關工具
- 第 5 章 并發和競爭情況
- 5.1. scull 中的缺陷
- 5.2. 并發和它的管理
- 5.3. 旗標和互斥體
- 5.4. Completions 機制
- 5.5. 自旋鎖
- 5.6. 鎖陷阱
- 5.7. 加鎖的各種選擇
- 5.8. 快速參考
- 第 6 章 高級字符驅動操作
- 6.1. ioctl 接口
- 6.2. 阻塞 I/O
- 6.3. poll 和 select
- 6.4. 異步通知
- 6.5. 移位一個設備
- 6.6. 在一個設備文件上的存取控制
- 6.7. 快速參考
- 第 7 章 時間, 延時, 和延后工作
- 7.1. 測量時間流失
- 7.2. 獲知當前時間
- 7.3. 延后執行
- 7.4. 內核定時器
- 7.5. Tasklets 機制
- 7.6. 工作隊列
- 7.7. 快速參考
- 第 8 章 分配內存
- 8.1. kmalloc 的真實故事
- 8.2. 后備緩存
- 8.3. get_free_page 和其友
- 8.4. 每-CPU 的變量
- 8.5. 獲得大量緩沖
- 8.6. 快速參考
- 第 9 章 與硬件通訊
- 9.1. I/O 端口和 I/O 內存
- 9.2. 使用 I/O 端口
- 9.3. 一個 I/O 端口例子
- 9.4. 使用 I/O 內存
- 9.5. 快速參考
- 第 10 章 中斷處理
- 10.1. 準備并口
- 10.2. 安裝一個中斷處理
- 10.3. 前和后半部
- 10.4. 中斷共享
- 10.5. 中斷驅動 I/O
- 10.6. 快速參考
- 第 11 章 內核中的數據類型
- 11.1. 標準 C 類型的使用
- 11.2. 安排一個明確大小給數據項
- 11.3. 接口特定的類型
- 11.4. 其他移植性問題
- 11.5. 鏈表
- 11.6. 快速參考
- 第 12 章 PCI 驅動
- 12.1. PCI 接口
- 12.2. 回顧: ISA
- 12.3. PC/104 和 PC/104+
- 12.4. 其他的 PC 總線
- 12.5. SBus
- 12.6. NuBus 總線
- 12.7. 外部總線
- 12.8. 快速參考
- 第 13 章 USB 驅動
- 13.1. USB 設備基礎知識
- 13.2. USB 和 sysfs
- 13.3. USB 的 Urbs
- 13.4. 編寫一個 USB 驅動
- 13.5. 無 urb 的 USB 傳送
- 13.6. 快速參考
- 第 14 章 Linux 設備模型
- 14.1. Kobjects, Ksets 和 Subsystems
- 14.2. 低級 sysfs 操作
- 14.3. 熱插拔事件產生
- 14.4. 總線, 設備, 和驅動
- 14.5. 類
- 14.6. 集成起來
- 14.7. 熱插拔
- 14.8. 處理固件
- 14.9. 快速參考
- 第 15 章 內存映射和 DMA
- 15.1. Linux 中的內存管理
- 15.2. mmap 設備操作
- 15.3. 進行直接 I/O
- 15.4. 直接內存存取
- 15.5. 快速參考
- 第 16 章 塊驅動
- 16.1. 注冊
- 16.2. 塊設備操作
- 16.3. 請求處理
- 16.4. 一些其他的細節
- 16.5. 快速參考
- 第 17 章 網絡驅動
- 17.1. snull 是如何設計的
- 17.2. 連接到內核
- 17.3. net_device 結構的詳情
- 17.4. 打開與關閉
- 17.5. 報文傳送
- 17.6. 報文接收
- 17.7. 中斷處理
- 17.8. 接收中斷緩解
- 17.9. 連接狀態的改變
- 17.10. Socket 緩存
- 17.11. MAC 地址解析
- 17.12. 定制 ioctl 命令
- 17.13. 統計信息
- 17.14. 多播
- 17.15. 幾個其他細節
- 17.16. 快速參考
- 第 18 章 TTY 驅動
- 18.1. 一個小 TTY 驅動
- 18.2. tty_driver 函數指針
- 18.3. TTY 線路設置
- 18.4. ioctls 函數
- 18.5. TTY 設備的 proc 和 sysfs 處理
- 18.6. tty_driver 結構的細節
- 18.7. tty_operaions 結構的細節
- 18.8. tty_struct 結構的細節
- 18.9. 快速參考