日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

(2021) 23 [持久化] I/O设备与驱动

發(fā)布時間:2025/3/8 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 (2021) 23 [持久化] I/O设备与驱动 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

(2021) 23 [持久化] I/O設備與驅動

南京大學操作系統(tǒng)課蔣炎巖老師網絡課程筆記。

視頻:https://www.bilibili.com/video/BV1HN41197Ko?p=23
講義:http://jyywiki.cn/OS/2021/slides/13.slides#/

背景

很多人 (你們的同學們、家長們) 都有一個認識,“計算機系就是裝 (修) 電腦的”,因為大家對電腦的印象只有 I/O 設備。但上了計算機系發(fā)現(xiàn)根本不是這么回事啊,根本沒有直接教怎么 “修電腦”。

但不應該是這樣的!

  • 學 “計算機” 的人不僅會修電腦,還會造電腦!

只要我們有一個設備的手冊或者文檔等充足的信息,就可以結合自己在操作系統(tǒng)等課程上的知識,來查找并修復問題。

本次課的內容和目標

理解 “I/O 設備是什么”

  • 鍵盤
  • 磁盤
  • 中斷控制器
  • 總線
  • DMA
  • GPU

學習 I/O 設備在操作系統(tǒng)中的抽象

  • 設備 = 可以讀、寫、控制的對象
  • “設備驅動程序”

常見 I/O 設備

孤獨的CPU

CPU 只是 “無情的指令執(zhí)行機器”,不斷地從內存上進行取指令、譯碼、執(zhí)行

我們是通過各種各樣IO設備實現(xiàn)與CPU的交互的。

CPU眼中的IO設備

I/O 設備是一個能與 CPU 交換數(shù)據(jù)的接口

通俗來講:

  • 就是 “幾組線”
    • 每一組線有約定的功能 (RTFM)
    • CPU 通過握手信號從線上讀出/寫入數(shù)據(jù)
  • 每一組線有自己的地址
    • CPU 可以直接使用指令 (in/out/MMIO) 和設備交換數(shù)據(jù)

在CPU看來,與常見的IO設備的交互,就是按照特定的規(guī)則(RTFM)來讀寫一組寄存器。比如下面介紹的鍵盤控制器和磁盤控制器。

鍵盤控制器

IBM PC/AT 8042 PS/2 (Keyboard) Controller

  • “硬編碼” 到兩個 I/O port: 0x60 (data), 0x64 (status/command)
Command ByteUse說明
0xEDLED 燈控ScrollLock/NumLock/CapsLock
0xF3設置重復速度30Hz - 2Hz; Delay: 250 - 1000ms
0xF4/0xF5打開/關閉N/A
0xFE重新發(fā)送N/A
0xFFRESETN/A

參考 AbstractMachine 的鍵盤部分實現(xiàn)

磁盤控制器

ATA (Advanced Technology Attachment)

  • IDE (Integrated Drive Electronics) 接口磁盤
    • primary: 0x1f0 - 0x1f7; secondary: 0x170 - 0x177
void readsect(void *dst, int sect) {waitdisk();out_byte(0x1f2, 1); // sector count (1)out_byte(0x1f3, sect); // sectorout_byte(0x1f4, sect >> 8); // cylinder (low)out_byte(0x1f5, sect >> 16); // cylinder (high)out_byte(0x1f6, (sect >> 24) | 0xe0); // driveout_byte(0x1f7, 0x20); // command (write)waitdisk();for (int i = 0; i < SECTSIZE / 4; i ++)((uint32_t *)dst)[i] = in_long(0x1f0); // data }

總之,以上這些IO設備,在CPU看來,就是按照特定的規(guī)則(RTFM)來讀寫一組寄存器。

特殊的IO設備

中斷控制器

我們的設備中通常有許多IO設備,那我們只想在這些IO設備有有意義的數(shù)據(jù)/信號時,CPU才回去處理這些數(shù)據(jù),而在平時IO設備沒有數(shù)據(jù)時,不要打擾CPU的其他正常工作。這就要通過中斷來實現(xiàn)。

CPU有一個中斷引腳收到某個特定的電信號會觸發(fā)中斷

  • 保存 5 個寄存器 (cs, rip, rflags, ss, rsp)
  • 跳轉到中斷向量表對應項執(zhí)行

CPU有且只有一個中斷引腳(如圖中6502的4號引腳 IRQˉ\bar{IRQ}IRQˉ?)。那CPU是怎樣管理各種不同的中斷,以及不同中斷到來時的處理優(yōu)先級的呢?這就要用到一個特殊的IO設備:中斷控制器

系統(tǒng)中的其他設備可以向中斷控制器連線。從而實現(xiàn)上面提到的中斷優(yōu)先級的判斷、中斷屏蔽等功能。

  • Intel 8259 PIC(programmable interrupt controller),(微機原理中也介紹過,配合8086),可以設置中斷屏蔽、中斷觸發(fā)等……
  • APIC (Advanced PIC)(現(xiàn)代CPU中使用的中斷控制器)
    • local APIC(每個CPU內部的中斷管理): 中斷向量表, IPI, 時鐘, ……
    • I/O APIC(外部IO的中斷管理): 其他 I/O 設備

總線

想法

如果你只造 “一臺計算機”,隨便給每個設備定一個端口/地址,用 mux 連接到 CPU 就行。

但如果你希望給未來留點空間?

  • 想賣大價錢的 “大型機”
    • IBM, DEC, …
  • 車庫里造出來的 “微型機”
    • 名垂青史的夢想家
  • 都希望接入更多 I/O 設備
    • 甚至是未知的設備,即可擴展性

在多個IO設備時,每個IO設備中的每個寄存器都有一個自己的地址,那肯定不能將這些寄存器全部直連到CPU上。

總線介紹

總線提供地址到設備的轉發(fā)。把從CPU傳來的地址(總線地址)和數(shù)據(jù)轉發(fā)到相應的設備上(按照上面說的每個設備中的每個寄存器的地址)。例如: port I/O 的端口就是總線上的地址,IBM PC 的 CPU 其實只看到這一個 I/O 設備。

這樣 CPU 只需要直連一個總線 (例如今天的 PCI總線 (Peripheral Component Interconnect) 就行了

  • 總線可以負責IO設備寄存器的地址編址
  • 總線可以橋接其他總線 (例如 PCI → USB)
  • lspci -tv 和 lsusb -tv: 查看系統(tǒng)中總線上的設備
  • 概念簡單,實際非常復雜
    • 電氣特性、burst 傳輸、中斷……

例子:PCI Device Probe

DMA(Direct Memory Access)

想法

假設程序希望寫入 1 GB 的數(shù)據(jù)到磁盤

  • 即便磁盤已經準備好,依然需要非常浪費緩慢的循環(huán)
  • out 指令寫入的是設備緩沖區(qū),需要去總線上繞一圈
    • cache disable; store 其實很慢的
for (int i = 0; i < 1 GB / 4; i++) {outl(PORT, ((u32 *)buf)[i]); }

能否把 CPU 從執(zhí)行循環(huán)中解放出來?

  • 比如,在系統(tǒng)里加一個 CPU,專門復制數(shù)據(jù)?
  • 好像 memcpy_to_port(ATA0, buf, length);

DMA介紹

  • DMA可以理解為一個只能執(zhí)行memcpy這一條指令的迷你處理器,它只負責直接將內存上的內容搬運的磁盤。而不需要真正的CPU的參與,不需要占用真正的CPU時間。實際實現(xiàn):直接把 DMA 控制器連接在總線和內存。

  • 由于DMA處理器只進行memcpy這樣一條指令,因此它的實現(xiàn)比通用的真正的CPU簡單得多。

  • DMA不僅可以完成內存和設備之間的內容搬運,而也可以是內存和內存之間。即可以有:

    • memory → memory
    • memory → device (register)
    • device (register) → memory
  • PCI 總線支持 DMA,即PCI中自帶DMA,這就是為什么 CPU 會有 PCIe lanes。

  • GPU

    在CPU眼中,顯卡(GPU)也是一種IO設備,通過讀寫某些寄存器來交互。

    一切皆可計算

    for (int i = 1; i <= H; i++) {for (int j = 1; j <= W; j++)putchar(j <= i ? '*' : ' ');putchar('\n'); }

    難辦的是性能

    • NES: 6502 @ 1.79Mhz; IPC = 0.43
      • 屏幕共有 256 x 240 = 61K 像素 (256 色)
      • 60FPS → 每一幀必須在 ~10K 條指令內完成
        • 如何在有限的 CPU 運算力下實現(xiàn) 60Hz?

    既然能做一個只專注于 memcpy 的硬件DMA,為什么不能做一個畫圖的硬件?在輸出圖形時,可以認為對每個像素點做的是相同的計算指令,不同的數(shù)據(jù)的計算,因此,可以認為是一種并行計算。因此,我們也可以用一個專注于處理并行計算的非通用功能的處理器:GPU,只用來處理圖形相關的這類并行計算

    現(xiàn)代GPU:一個通用計算設備

    一個完整的眾核多處理器系統(tǒng)

    • 注重大量并行相似的任務
      • 程序使用例如 OpenGL, CUDA, OpenCL, … 書寫
    • 程序保存在內存 (顯存) 中
      • nvcc: 把 main 編譯/鏈接成 ELF; kernel 編譯成 GPU 指令
    • 數(shù)據(jù)也保存在內存 (顯存) 中
      • 可以輸出到視頻接口 (DP, HDMI, …)
      • 也可以通過 DMA 傳回系統(tǒng)內存

    gpgpu:通用圖形處理器

    通過對處理圖形顯示這類并行計算任務的推廣,出現(xiàn)了通用圖形處理器。它們不再只關注圖形處理,而是可以針對更廣范圍的并行計算,比如神經網絡的計算、矩陣計算。

    通用圖形處理器(General-purpose computing on graphics processing units,簡稱GPGPU),是一種利用處理圖形任務的圖形處理器來計算原本由中央處理器處理的通用計算任務。這些通用計算常常與圖形處理沒有任何關系。由于現(xiàn)代圖形處理器強大的并行處理能力和可編程流水線,令流處理器可以處理非圖形數(shù)據(jù)。特別在面對單指令流多數(shù)據(jù)流(SIMD),且數(shù)據(jù)處理的運算量遠大于數(shù)據(jù)調度和傳輸?shù)男枰獣r,通用圖形處理器在性能上大大超越了傳統(tǒng)的中央處理器應用程序。

    I/O設備的抽象

    I/O設備是操作系統(tǒng)中的對象(文件)

    無論何種 I/O 設備,都是可以讀 (read) 寫 (write) 的字節(jié)序列 (流或數(shù)組)。

    I/O設備應該是操作系統(tǒng)中怎樣的對象?操作系統(tǒng)最簡單,或者說最不負責任的做法,當然是可以直接將IO設備的寄存器,或者PCI總線的控制寄存器,暴露給應用程序。微內核的操作系統(tǒng)就是這么做的,微內核的系統(tǒng)只做最少、最必要的部分。

    但如果操作系統(tǒng)再負責一點,將我們的每個IO設備(比如鍵盤、磁盤等)都抽象成操作系統(tǒng)中的一個對象。

    操作系統(tǒng):設備 = 支持以下三種操作的對象 (文件)

    • read: 從設備某個指定的位置讀出數(shù)據(jù)
    • write: 向設備某個指定位置寫入數(shù)據(jù)
    • ioctl: 讀取/設置設備的狀態(tài)

    而以上這三種操作,恰恰就是文件系統(tǒng)中,一個文件應該支持的操作。 Everything is a file !

    設備驅動程序:實現(xiàn)抽象

    設備驅動程序把對設備的 read/write/ioctl 系統(tǒng)調用 “翻譯” 成設備的寄存器命令序列。

    以 “面向對象” 的方式訪問 I/O 設備,設備 = 支持 read, write, ioctl, … 功能的對象。

    例子:/dev 中的對象

    • /dev/pts/[x] - pseudo terminal
    • /dev/zero - “零” 設備
    • /dev/null - “null” 設備,一般不想要的輸出可以直接重定位到這個設備。
    • /dev/random,/dev/urandom- 隨機數(shù)生成器

    未必一定要有物理設備

    設備驅動程序:將設備抽象為一個對象和操作,未必一定要有物理設備,比如/dev/null, /dev/urandom。就是操作系統(tǒng)中不需要物理設備的一種設備/文件/對象的抽象。

    試一試

  • 試一試執(zhí)行命令:head -c 512 [device] | xxd,并觀察它們的strace來查看訪問設備的系統(tǒng)調用。

  • tty查看當前終端,輸出/dev/pts/3,即當前終端是3號終端。

    如果我們再打開一個終端并向之前的3號終端輸出,是可以直接出現(xiàn)在3號終端上的:echo Hello > /dev/pts/3。

    也就是說,每個打開的終端也被看做是在設備目錄/dev下的一個設備。

  • 存儲設備的抽象

    磁盤 (存儲設備) 的訪問特性與其他的設備的讀寫略有不同,是以塊為單位的。

  • 以數(shù)據(jù)塊 (block) 為單位訪問,傳輸有 “最小單元”,塊內不支持任意隨機訪問
  • 大吞吐量,使用 DMA 傳送數(shù)據(jù)。
  • 應用程序不直接訪問
    • 訪問者通常是文件系統(tǒng) (維護磁盤上的數(shù)據(jù)結構)
    • 大量并發(fā)的訪問 (操作系統(tǒng)中的進程都要訪問文件系統(tǒng))
  • 對比一下終端和 GPU,的確是很不一樣的設備

    • 終端:小數(shù)據(jù)量、直接流式傳輸
    • GPU:大數(shù)據(jù)量、DMA 傳輸

    總結

    本次課內容與目標

    • 理解 “什么是 I/O 設備
      • 終端、鍵盤、鼠標、總線、DMA、GPU……
    • 理解 “I/O 設備在操作系統(tǒng)中的抽象
      • 可以讀/寫/控制的對象

    Takeaway messages

    • 如果你 “自己造一臺計算機”,你會發(fā)現(xiàn)這一切都是自然的
      • “不容易理解” 的部分是隨時間積累的復雜性

    總結

    以上是生活随笔為你收集整理的(2021) 23 [持久化] I/O设备与驱动的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。