章節概覽#
本章介紹 Linux kernel 提供的裝置基礎設施 (device infrastructure)。內容涵蓋傳統的裝置檔案系統 (device files)、kernel 如何透過 sysfs 提供裝置設定資訊、dd 工具的使用、常見裝置命名慣例、udev 系統的運作方式,以及 SCSI 子系統在 Linux kernel 中的角色。
目標是讓讀者能夠從系統中提取裝置資訊,並理解基本的裝置操作原理。
3.1 Device Files(裝置檔案)#
Linux kernel 將大部分裝置的 I/O 介面以檔案的形式呈現給 user-space processes,這些檔案稱為 device files(也叫 device nodes)。裝置檔案位於 /dev 目錄下。
例如,將輸出導向 /dev/null 時,kernel 會繞過一般的檔案操作,改用 device driver 處理資料:
$ echo blah blah > /dev/null裝置類型#
使用 ls -l 可以辨識裝置,檔案模式的第一個字元代表裝置類型:
- Block device (b):以固定大小的區塊存取資料,例如磁碟 (
sda1)。因為大小固定,process 可以隨機存取任意區塊。 - Character device (c):以資料串流方式運作,只能讀寫字元,沒有固定大小。例如
/dev/null、印表機。kernel 無法回溯已傳送的資料。 - Pipe device (p):類似 character device,但另一端連接的是另一個 process,而非 kernel driver。也稱為 named pipe。
- Socket device (s):用於行程間通訊 (interprocess communication) 的特殊介面,常見於
/dev目錄之外。
在 ls -l 的輸出中,block 和 character device 日期前的數字是 major 和 minor 設備號碼,kernel 用來識別裝置。相同 major number 的裝置通常屬於同一類(例如 sda3 和 sdb1 都是硬碟分割區)。
並非所有裝置都有 device files。例如,network interface 沒有 device files,因為 block/character I/O 介面不適用於網路裝置。
3.2 The sysfs Device Path#
傳統的 /dev 目錄是一個簡化的命名方案,名稱本身提供的資訊有限,且裝置名稱可能在重新開機後改變。為了提供基於實際硬體屬性的統一檢視,Linux kernel 提供了 sysfs 介面。
- sysfs 是一套檔案與目錄系統,掛載在
/sys/devices - 例如
/dev/sda對應的 sysfs 路徑可能是:
/sys/devices/pci0000:00/0000:00:17.0/ata3/host0/target0:0:0/0:0:0:0/block/sda/dev 與 /sys 的差異#
| 路徑 | 用途 |
|---|---|
/dev | 讓 user process 使用裝置 |
/sys/devices | 讓程式檢視與管理裝置資訊 |
常用捷徑與工具#
/sys/block包含所有 block device 的 symbolic link- 使用
udevadm查詢裝置的 sysfs 路徑:
$ udevadm info --query=all --name=/dev/sda3.3 dd and Devices#
dd 是處理 block 和 character device 時非常實用的工具。它從 input file/stream 讀取資料,寫入 output file/stream,可進行編碼轉換。
dd非常強大,操作不慎容易損壞檔案和裝置上的資料。如果不確定效果,建議先將 output 導向新檔案。
基本用法#
$ dd if=/dev/zero of=new_file bs=1024 count=1重要參數#
if=file:輸入檔案,預設為 standard inputof=file:輸出檔案,預設為 standard outputbs=size:每次讀寫的 block size(可用b表示 512、k表示 1024)ibs=size, obs=size:分別設定輸入和輸出的 block sizecount=num:要複製的 block 數量skip=num:跳過輸入檔案開頭的 block 數
dd的選項格式源自 IBM Job Control Language (JCL),使用=而非-來設定參數值。
3.4 Device Name Summary(裝置名稱總覽)#
查找裝置名稱的方法:
- 使用
udevadm查詢 udev - 查看
/sys目錄 - 使用
journalctl -k查看 kernel messages - 使用
mount指令查看已掛載的磁碟裝置 - 查看
/proc/devices了解系統目前有哪些 driver
3.4.1 Hard Disks: /dev/sd*#
- 大部分硬碟使用 sd 前綴(代表 SCSI disk)
- 整顆磁碟:
/dev/sda、/dev/sdb - 分割區:
/dev/sda1、/dev/sda2 - 使用
lsscsi列出 SCSI 裝置:
$ lsscsi
[0:0:0:0] disk ATA WDC WD3200AAJS-2 01.0 /dev/sda
[2:0:0:0] disk FLASH Drive UT_USB20 0.00 /dev/sdb- Linux 按照 driver 偵測順序分配裝置名稱,重新開機後名稱可能改變
- 為解決此問題,現代系統使用 UUID (Universally Unique Identifier) 或 LVM 穩定映射
3.4.2 Virtual Disks: /dev/xvd*, /dev/vd*#
用於虛擬機器(如 AWS、VirtualBox),Xen 使用 /dev/xvd 前綴。
3.4.3 Non-Volatile Memory Devices: /dev/nvme*#
NVMe (Non-Volatile Memory Express) 介面用於 SSD,使用 nvme list 查看。
3.4.4 Device Mapper: /dev/dm-*, /dev/mapper/*#
LVM (Logical Volume Manager) 使用的 kernel 系統,稱為 device mapper。
3.4.5 CD and DVD Drives: /dev/sr*#
光碟機顯示為 SCSI 裝置 /dev/sr0、/dev/sr1,為唯讀。寫入需使用 generic SCSI device(如 /dev/sg0)。
3.4.6 PATA Hard Disks: /dev/hd*#
較舊的 PATA (Parallel ATA) 裝置使用 /dev/hda、/dev/hdb 等,基於介面固定分配。
3.4.7 Terminals: /dev/tty*, /dev/pts/*, /dev/tty#
- Terminal 是在 user process 與 I/O 裝置之間傳遞字元的裝置
- 大部分 terminal 是 pseudoterminal(模擬終端機),kernel 將 I/O 介面呈現給軟體而非硬體
- 常見裝置:
/dev/tty1(第一個 virtual console)、/dev/pts/0(第一個 pseudoterminal) /dev/tty是目前 process 的 controlling terminal 的同義詞
Virtual Consoles:Linux 支援以 ALT+Function Key 在多個虛擬控制台間切換。在圖形模式下需使用 CTRL+ALT+Function Key。
3.4.8 Serial Ports: /dev/ttyS*, /dev/ttyUSB*, /dev/ttyACM*#
- RS-232 序列埠:
/dev/ttyS0(COM1)、/dev/ttyS1(COM2) - USB 轉序列埠:
/dev/ttyUSB0、/dev/ttyACM0 - 可用於連接 microcontroller 開發板(如 CircuitPython)
3.4.9 Parallel Ports: /dev/lp0 and /dev/lp1#
單向平行埠 /dev/lp0、/dev/lp1(對應 Windows 的 LPT1、LPT2),雙向為 /dev/parport0、/dev/parport1。
3.4.10 Audio Devices: /dev/snd/*, /dev/dsp, /dev/audio#
- ALSA (Advanced Linux Sound Architecture) 裝置位於
/dev/snd - 較舊的 OSS (Open Sound System) 裝置為
/dev/dsp、/dev/audio
Linux 音效涉及多層架構。kernel 層級之上通常有 user-space 音效伺服器(如 PulseAudio)作為中介。
3.4.11 Device File Creation#
在現代系統中,device files 由 devtmpfs 和 udev 自動建立。手動建立裝置使用 mknod:
# mknod /dev/sda1 b 8 1其中 b 8 1 表示 block device、major number 8、minor number 1。Character 和 pipe device 使用 c 或 p。
3.5 udev#
udev 系統負責在 user space 中管理裝置檔案。kernel 偵測到新裝置時,會發送通知給 user-space process udevd,由其建立 device file 並執行裝置初始化。
3.5.1 devtmpfs#
devtmpfs 解決了開機時裝置可用性的問題:
- kernel 在開機時建立必要的 device files
- 當新裝置出現時,通知 udevd
- udevd 不建立 device files,而是負責:
- 設定權限
- 通知其他 process
- 在
/dev/disk/by-id等目錄建立 symbolic links 以便識別
$ ls -l /dev/disk/by-iddevtmpfs 中的 “tmp” 表示檔案系統存在於主記憶體中,具有 read/write 能力,讓 udevd 能建立 symbolic links。
3.5.2 udevd Operation and Configuration#
udevd daemon 的運作流程:
- kernel 透過內部網路連結發送 uevent 通知給 udevd
- udevd 載入 uevent 中的所有屬性
- udevd 根據 rules 解析、過濾並更新 uevent,執行對應動作
Rules 檔案位於:
/lib/udev/rules.d/— 預設規則/etc/udev/rules.d/— 自訂覆蓋規則
udev rules 語法重點#
- 條件式 (conditional):使用
==(等於)或!=(不等於) - 指令 (directive):使用
=(設定)、+=(新增)、:=(強制設定) - Rules 從頭到尾逐行讀取,可使用
GOTO跳過不相關的區段 IMPORT{program}可執行外部程式匯入變數SYMLINK+=為裝置建立 symbolic link
3.5.3 udevadm#
udevadm 是 udev 的管理工具,主要功能:
- 查詢裝置資訊:
$ udevadm info --query=all --name=/dev/sda輸出中的前綴含義:
| 前綴 | 意義 |
|---|---|
P: | sysfs device path |
N: | device node 名稱(/dev 中的名稱) |
S: | udev 根據 rules 建立的 symbolic link |
E: | 從 udev rules 取得的額外裝置資訊 |
3.5.4 Device Monitoring#
使用 udevadm monitor 即時監控 uevent:
$ udevadm monitor- 預設同時顯示 kernel 和 udevd 的訊息
--kernel:只顯示 kernel 事件--udev:只顯示 udevd 處理事件--property:顯示完整 uevent 屬性--subsystem-match=scsi:過濾特定子系統
3.6 In-Depth: SCSI and the Linux Kernel#
本節深入探討 SCSI (Small Computer System Interface) 在 Linux kernel 中的支援。此為進階內容,非使用磁碟所必需。
SCSI 基本架構#
- 傳統 SCSI 硬體:host adapter 透過 SCSI bus 連接一串裝置
- 每個裝置有一個 SCSI ID,每條 bus 可有 8 或 16 個 ID
- 裝置間可透過 SCSI command 以 peer-to-peer 方式通訊
- 現代系統中,USB storage 和 ATAPI(CD/DVD)裝置也使用 SCSI 指令集
- SATA 磁碟透過 libata 轉譯層接入 SCSI 子系統

Figure 3-1: SCSI bus with host adapter and devices
使用 lsscsi 查看裝置,輸出中的四個數字分別代表:SCSI host adapter number、SCSI bus number、device SCSI ID、LUN (Logical Unit Number)。
SCSI 子系統的三層架構#
Linux kernel 的 SCSI 子系統分為三層 driver:
- 上層 (Top layer):處理裝置類別的操作。例如
sddriver 將 block device 請求轉譯為 SCSI disk 指令。 - 中層 (Middle layer):協調與路由上下層之間的 SCSI 訊息,追蹤所有 SCSI bus 與裝置。
- 下層 (Bottom layer):處理硬體特定的動作,將 SCSI 協定訊息發送到特定的 host adapter 或硬體。

Figure 3-2: Linux SCSI subsystem schematic
對於任何一個 device file,kernel 幾乎總是使用一個上層 driver 和一個下層 driver。例如
/dev/sda使用sd上層 driver 和 ATA bridge 下層 driver。
3.6.1 USB Storage and SCSI#
- Linux kernel 的 USB 子系統與 SCSI 子系統結構類似(三層架構)
- USB storage driver 作為轉譯器:一端說 SCSI,另一端說 USB
- 因為 USB 訊息內就包含 SCSI 指令,轉譯工作相對簡單
- 最終由一個 SCSI bridge driver 連接兩個子系統
3.6.2 SCSI and ATA#
- SATA 硬碟和光碟機共用相同的 SATA 介面
- 光碟機使用 ATAPI(ATA 協定中編碼的 SCSI 指令版本),轉譯較簡單
- 硬碟不使用 ATAPI,也不編碼任何 SCSI 指令,需要 libata 進行完整轉譯
- libata 負責將 ATA/SATA 介面和裝置連接到 SCSI 子系統
3.6.3 Generic SCSI Devices#
- 一般情況下,user process 透過 block device layer 和 SCSI device class driver(如
sd、sr)與裝置互動 - Generic SCSI device(
/dev/sg*)允許 user process 繞過 device class driver,直接向裝置發送 SCSI 指令

Figure 3-3: Optical device driver schematic
- 使用
lsscsi -g可查看每個裝置對應的 generic device
$ lsscsi -g
[0:0:0:0] disk ATA WDC WD3200AAJS-2 01.0 /dev/sda /dev/sg0
[1:0:0:0] cd/dvd Slimtype DVD A DS8A5SH XA15 /dev/sr0 /dev/sg1Generic SCSI device 的典型使用場景是 CD/DVD 寫入。讀取光碟由專用 kernel driver 處理,但寫入因為複雜度高且非系統關鍵操作,改由 user-space 程式透過
/dev/sg*進行,減少 kernel 的複雜度。