1. 1. 架構
    1. device driver類型
      1. charcacter
      2. block
      3. network
    2. driver 分兩種層面
      1. Virtual Device Driver
        1. 往上層支援 Linux kernel 所提供的 Virtual File System 層,並藉此實作 system calls
        2. Virtual device driver 的目的在於善用 Linux 的 APIs 來設計機制 (mechanism) 與行為 (behavior) 良好的驅動程式
      2. Physical Device Driver
        1. 往下層使用 Linux kernel 所提供的 device interface 來存取並控制實體硬體裝置。
        2. Physical device driver 則是討論「如何透過 I/O port 或 I/O memory」來控制裝置,也就是與晶片組的溝通 。這個部份需要實作晶片組的 data sheet
  2. 2. System Call
    1. 是 user application 與 Linux device driver 的溝通介面。
    2. 每個 system call 都會對應到 driver 內的一個 task,此 task 即是 file_operation 函數指標所指的函數。
    3. example
      1. example中的open()與ioctl() function會call到/dev/debug驅動程式的對應函數
      2. "call" 驅動程式函數的動作涉及user space與kernel space的切換,此動作 藉由system call介面來完成
  3. 3. Device File
    1. 在 UNIX 系統底下我們把外部的周邊裝置均視為一個檔案,並透過此檔案與實體硬體溝通
    2. 檔案屬性的第一個位元(i.e., 使用ls -l /dev)
      1. 若為 “c” 表示這是一個字元型裝置的device file
      2. 若為 “b” 表示這是一個區塊型裝置的device file
    3. Number
      1. major
        1. 代表一個特定的裝置,例如 major number 為 1 為 null 虛擬裝置
      2. minor
        1. 代表裝置上的子裝置,例如同一個硬碟上的分割區就用不同的 minor number 來代表,但其 major number 相同
    4. 與驅動程式的關係
      1. 在設計 device driver 時,會先透過一個 “註冊” (register) 的動作將自己 註冊到 kernel 裡,註冊時,我們會指定一個 major number 參數,以指 定此驅動程式所要實作的週邊裝置
      2. 當 user 開啟 device file 時,kernel 便會根據 device file 的major number 找到對應的驅動程式來回應使用者。
      3. file_operations 是學習 device driver 最重要的一個資料結構,file_operations內的成員 為函數指標,指向 “system call 的實作函數”
      4. file_operations 即是Linux的 VFS 層。換句話說, Linux驅動程式是透過file_operations來建構VFS層的支援。 而file_operation裡的函數指標,即是指向每一個system call的實作函數。
  4. 4. 一般化設計流程
    1. Linux 驅動程式的設計雖然沒有一定的標準流程,但是由「觀念」層面可以歸納出一個一般化的流程。
    2. struct file_operations
      1. kernel 提供的一個重要資料結構
      2. Linux 驅動程式建構在 file_operations 之上。
    3. linux driver implementation
      1. Virtual Device Driver
        1. introduction
          1. kernel 會在需要時回呼 (callback) 我們所註冊的driver method。 因此,當 driver 裡的 method 被呼叫時,kernel便將傳遞parameters給 driver method,driver method可由 kernel 所傳遞進來的參數取得驅動程式資訊。
        2. 分為3階段的觀念實作:
          1. 定義 file_operations
          2. 驅動程式呼叫 register_chrdev() 將fops註冊到 kernel 裡後, fops 便成為該 device driver 所實作的system call進入點。
          3. 實作 system calls
          4. 實作system call的函數便是透過file_operations結構來定義, 我們稱實作system call的函數為driver method。
          5. 註冊 driver (VFS)
          6. 註冊driver的動作呼叫register_chrdev()函數完成,此函數接受3個參數如下:
          7. major:要註冊的裝置 major number
          8. name:device 名稱
          9. fops:driver 的 file operation
      2. Physical Device Driver
        1. introduction
          1. 目的在於實作控制硬體的程式碼
          2. 設計控制硬體周邊的驅動程式時,需要了解硬體使用的晶片組,晶片組則需要參 考IC設計廠商所提供的「datasheet」才能了解晶片組的暫存器名稱與用途,通 常不同的暫存器會對應到一個「相對」的偏移位址(offset)。
        2. implement
          1. 首先會將晶片的 datasheet 寫成C語言的標頭檔,通常這個檔案都可以從 vendor 取得
          2. 再定義一組操作暫存器的I/O函數,我們稱這組函數為I/O wrapper function
          3. I/O wrapper functions通常是重新定義Linux kernel所提供的readb()、writeb()或inb()、outb()系列函數所寫成的
          4. Chipset control functions是由實作system calls的函數(driver method)所呼叫
        3. 理論上,可將晶片的暫存器分成3大類:
          1. data registers
          2. 晶片裡用來存放資料的暫存器
          3. control registers
          4. 用來控制晶片行為的暫存器
          5. status registers
          6. 用來保存目前晶片的狀態