〖想觀看更多課程筆記,至[課程筆記]課程筆記系列總覽可以看到目前已發布的所有文章!〗
Course 1 - Linux驅動開發
驅動開發思維
為何需要Linux driver?
- 直接在Linux下操作register不現實,太複雜也不安全
- Linux具有各種驅動框架(driver framework),使得各種設置能夠依照一訂的規範進行開發
Linux下一切皆文件,而所有的driver都放置在/dev/xxx下,可以透過fops(file operation)來操作(打開、關閉、讀寫)
新版的Linux下supoort device tree,是一個.dts,記錄devices information,kernel會去分析.dts文件了解有哪些設備
驅動開發分類
linux 驅動分成三大類
- char device driver: 字符設備驅動,按照字符依序存取,大部分的驅動都是這種,e.g. i2c
- block device driver: 能以固定大小長度傳送和轉移,可以不需要按照順序操作,e.g. SD card
- network device driver: 網路設備驅動,e.g. wifi
一個設備可以同時是不同類型的驅動,例如USB WIFI, SDIO WIFI是network device driver但同時也是char device driver
Course 2 - 字符設備驅動開發基礎實驗
應用程序和驅動的交互原理
驅動就是用來和device溝通的程式。Linux驅動編譯除了要編寫一個driver外,還要編寫一個測試應用程式(application)
- 單晶片機下驅動和應用是放在一個文件內
- Linux下驅動和應用是完全分開的,所以此時就牽扯到user space & kernel space
以下部分內容引用自linux内存管理—用户空间和内核空间
关于虚拟内存有三点需要注意:
- 4G的进程地址空间被人为的分为两个部分—用户空间与内核空间。用户空间从0到3G(0xc0000000),内核空间占据3G到4G。用户进程通常情况下只能访问用户空间的虚拟地址,不能访问内核空间的虚拟地址。例外情况只有用户进程进行系统调用(代表用户进程在内核态执行)等时刻可以访问到内核空间。
- 用户空间对应进程,所以每当进程切换,用户空间就会跟着变化;而内核空间是由内核负责映射,它并不会跟着进程变化,是固定的。内核空间地址有自己对应的页表,用户进程各自有不同的页表。
- 每个进程的用户空间都是完全独立、互不相干的。
user space & kernel space: 為了安全性而做的區隔
- linux kernel & driver在kernel space執行
- application跑在user space
因此當app要access kernel resource時有三種方式
- system call: 可以透過API來間接調用system call,例如POSIX & C Lib
- interrupt
- trap: software interrupt
每個system call會有一個id,例如在/arch/arm64/include/asm/unistd32.h中可以看到system call和對應的id
0 | /* /arch/arm64/include/asm/unistd32.h */ |
要使用system call,必須要先透過trap觸發軟體中斷進入kernel mode,然後還需要指定system call id,然後整個流程大致如下圖:
字符設備驅動開發流程
Linux下一切皆文件(/dev/xxx),application可以透過open()
來打開設備,並透過read()
, write()
來存取設備, 並透過close()
來關閉
因此在設計驅動的時候,需要撰寫對應的open()
, close()
, write()
… function,這些被記錄在file_operations的struct內向外提供