linux 核心驅動工作原理

2021-10-01 06:35:06 字數 3082 閱讀 6024

重點: file_operations 結構體

(1) 裡面元素是函式指標, 用來指向實體函式位址

(2) 每個裝置驅動都需要乙個改結構體型別的變數

(3) 裝置驅動需要向核心註冊, 在註冊的時候, 是要提供此結構體的變數的

註冊字元驅動:

(1) 驅動是需要向核心註冊的, 不然核心不知道有這個驅動

(2) 註冊的函式主要是register_chrdev 函式去註冊

register_chrdev 函式

作用: 驅動向核心註冊自己的file_operations

註冊成功: 返回值 0 不成功 返回值 -1

static

inline

intregister_chrdev

(unsigned

int major,

const

char

*name,

const

struct file_operations *fops)

int__register_chrdev

(unsigned

int major,

unsigned

int baseminor,

unsigned

int count,

const

char

*name,

const

struct file_operations *fops)

inline 宣告的函式能夠減少函式排程的花銷, 但是帶來的***是可以把函式放到標頭檔案中去了.

(1) 核心中有乙個陣列用來儲存註冊的字元裝置驅動

(2) register_chrdev 內部將我們要註冊地的驅動資訊() 儲存在陣列中相應的位置

(3) cat /proc/devices 檢視核心中已經註冊過的字元裝置驅動(和塊裝置驅動)

/proc 虛擬檔案系統, 是將核心中的相關資料結構 通過檔案虛擬構建出來, 然後通過命令, 可以看到相關的資料變數的資訊

應用程式怎麼呼叫驅動程式

需要的就是裝置檔案, 裝置檔案關鍵的就是主次裝置號

使用mknod /dev/test c 250(主裝置號) 0 (次裝置號)

然後在應用程式中通過open close read writer 等函式操作裝置檔案

其實操作的就是open_operations 裡面的函式指標對應的函式

copy_from_user 用來將資料從使用者空間複製到核心空間

copy_to_user

然後其實就是在應用程式中得read 和 write函式中操作, 最終操作的是 copy_from_user 和copy_to_user函式,.

這樣就實現應用程式拷貝資料到驅動中了,

還有注意的是copy_from_user和copy_to_user函式的返回值是拷貝總數-拷貝成功數, 比如拷貝長度50 成功拷貝了40 則返回值就是

50-40=10

驅動中操作硬體,

操作的是虛擬位址, 不是實體地址,

虛擬位址對映分為靜態和動態對映

靜態有點像c語言中的全域性變數(通過硬編碼,然後編譯核心固定的), 而動態對映像malloc 動態申請記憶體一樣.

靜態對映好處就是執行效率高, 壞處就是時鐘占用虛擬位址, 動態對映的好處就是按需分配, 壞處就是每次都需要建立和銷毀對映.

尋找核心中的靜態對映表, 關鍵字 map va

pa 還有就是arch/arm裡面關於平台中額plat/include

驅動層**只負責操作硬體的**, 相關邏輯的判斷應該在應用層中處理完成

字元裝置新註冊介面

register_chrdev_regpion/alloc_chrdev_regpion+cdev

cdev 是乙個結構體裡面重點包含file_operations結構體

以及主次裝置號

相關的函式: cdev_alloc, cdev_init, cdev_addr, cdev_del

以及相關的巨集定義

mkdev, major, minor

register_chrdev_region + cdev_init+cdev_addr 進行驅動的註冊以及新增

然後使用cdev_del + unregister_chrdev_region 進行刪除和登出裝置驅動

自動建立裝置檔案

方法, udev(嵌入式中用的是mdev)

udev 是乙個應用程式

在busybox 中的指令, 然後在核心啟動過程中

已經執行了, 在rs.s中

mdev 使得核心驅動和應用層之間有一套資訊傳輸機制(netlink協議)

驅動註冊和登出時資訊會傳輸給udev。 因此udev可以在應用層中對裝置檔案進行建立和刪除

具體函式

class_create

device_create.

sys檔案系統和proc檔案系統一樣都是虛擬檔案系統,

有關靜態對映表的建立過程,

重點是machine_start 巨集的結構體中的

的map_io 函式裡面一直追溯到

iotable_init 函式引數中的乙個 struct map_desc 變數,

那個變數就是靜態對映表

是乙個結構體陣列

核心提供的讀寫暫存器的介面方式

writel 和 readl

還有就是iowrite32和 ioread32

我們在呼叫

class_register(&input_class); 函式的時候可以在 /sys/class/ 裡面看到相對應的類資料夾

但是裡面的裝置檔案是需要

device_register 函式進行註冊才能看得到

int device_register(struct device *dev)

注意, 其實device_register 裡面是兩個檔案, 有一些**是呼叫

device_register 裡面的device_initialize 和 device_add進行分開呼叫的,

因此看到device_initialize 和device_add出現的時候, 其實就是相當於device_register

跳槽驅動工作

收藏 還有乙個裁員名單被瘋狂 這些裁員訊息真假先放一邊,俗話說無風不起浪,至少行業裡面釋放的訊號是不太好的。不管你是主動跳槽,還是被動離職,每年的年初都是換工作高峰期。就算你所在的公司很穩定,或者你剛躲過了裁員名單,我覺得你也有必要早做準備。不然,你哪一天失業了還一臉懵圈。隨著工作經驗越長市場能匹配...

linux驅動工程師面試

首先,我要說的是,就業成功最關鍵的因素在於紮實的基礎,很寬的知識面,豐富的實踐經驗.這些都是,工作學習中我們需要自己積累的內容,這些真的很重要,如果大家現在不是立馬就要找到乙份工作,建議把以上我提到的三點務必達到一定的要求,這些才是根本.當然,我寫這篇文章並不是向大家介紹怎麼學習,我想與大家分享的是...

linux 核心 驅動

首先 1.建立裝置 分配cdev結構體 if globalmem major 手動分配 ret register chrdev region devno,1,globalmem else globalmem 提供給上層使用 2 建立核心裝置 struct globalmem dev globalme...