在讀者學習本章之前,最好擁有部分裸機程式基礎(如點亮led、arm-linux-gcc、中斷等),初學者可以檢視:arm裸機加強版
linux將儲存器和外設分為3個基礎大類:
1. 字元裝置:如led、按鍵
2. 塊裝置:如磁碟
3. 網路裝置
對於使用者而言,它們都需要使用檔案系統的操作介面open()、read()、write()和close()進行訪問
對於驅動而言,我們需要完成的是操作介面函式對應的函式
那麼這兩個的對應和呼叫關係是什麼樣的呢?
首先,介面函式會通過swi實現從使用者模式變換到管理模式
swi指令格式如下:
cond:執行指令的條件
immed_24:24位整數,
用於區分使用者的不同操作,從而執行不同核心函式
讀者到這裡可能會有乙個疑問,為什麼要通過swi進入管理模式呢?
模擬於windows,有的時候我們會使用管理員身份執行程式,這樣的程式就會有更高的權利
作業系統之所以這麼做,是為應用程式的執行建立良好的環境,保障每個程式都可以最大化利用硬體資源,防止非法程式破壞其它應用程式執行環境
為達目的,作業系統會將硬體的操作許可權交給核心程式來管理,使用者程式不能隨意使用硬體,使用硬體(對硬體暫存器進行讀寫)時要先向作業系統發出請求,作業系統核心幫助使用者程式實現其操作,作業系統通過一組稱為系統呼叫的(system call)的介面呈現給使用者,系統呼叫把應用程式的請求傳給核心,呼叫相應的核心函式完成所需的處理,將處理結果返回給應用程式
核心中的系統呼叫定義在arch/arm/kernel/calls.s
/*其中call的定義如下,為**段的偏移位址,可以看到sys_open()的偏移是50 */
call(sys_restart_syscall)
call(sys_exit)
call(sys_read)
call(sys_write)
/*5
*/call(sys_open)
call(sys_close)
.../*
375
*/call(sys_setns)
call(sys_process_vm_readv)
call(sys_process_vm_writev)
#define call(x) .long x那麼核心是怎麼知道呼叫哪個函式呢?
在eabi模式下,系統呼叫通過傳入的暫存器r7的值來判斷呼叫哪個函式
mov r7, #num @ num對應系統呼叫的某個函式原來的系統呼叫方式是這樣:swi
0x0 @ 設定多少號軟中斷
swi (#num | 0x900000) @ 0x900000是個magic值這兩個選擇是由巨集config_oabi_compat(原來的呼叫方式)和config_aeabi(eabi)控制的
對於原來的呼叫方式,核心給出的處理是給它建立乙個單獨的system call table,叫sys_oabi_call_table,這樣,相容方式下就會有兩個system call table,以原來的呼叫方式的系統呼叫會執行old_syscall_table表中的函式指標,eabi方式的系統呼叫會用sys_call_table中的函式指標
總結起來就是,通過swi指令和暫存器傳入引數,以查表方式找到對應的系統呼叫函式
下圖為核心中裝置驅動的層次關係:
之後,如果我們想要控制led的亮滅,由於led屬於字元驅裝置驅動,因此程式就會依次通過應用程式open() -> swi -> 系統呼叫sys_open() -> vfs -> 驅動程式open() -> 硬體操作
下一章 2、點亮led
1 裝置驅動基礎
一.驅動程式程式設計概念 1.驅動學習知識結構 1.linux驅動設計模式,框架.40 2.核心相關的知識.30 2.驅動程式的分類 1.字元裝置驅動 能以位元組來訪問。通過字元裝置檔案訪問塊驅動程式。2.網路介面 乙個網路負責傳送和接受資料報文。通過套接字訪問塊驅動程式,不是通過檔案。3.塊裝置 ...
Linux驅動基礎開發1
目前,linux軟體工程師大致可分為兩個層次 主要利用c庫函式和linux api進行應用軟體的編寫 從事這方面的開發工作,主要需要學習 符合linux posix標準的api函式及系統呼叫,linux的多工程式設計技巧 多程序 多執行緒 程序間通訊 多工之間的同步互斥等,嵌入式資料庫的學習,ui程...
驅動開發(1)基礎知識
驅動程式是作業系統和硬體通訊的橋梁,同時,驅動程式可以實現很多特殊功能,比如,虛擬光碟機 虛擬裝置 核心級hook,檔案系統透明加密 過濾驅動 修改windows核心等等 並非所有驅動程式都必須由裝置的設計方編寫。如果裝置根據已發布的硬體標準來設計。這時驅動程式可以由 microsoft 編寫,裝置...