新聞中心

EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > linux 基礎(chǔ)復(fù)習(xí)(9)設(shè)備驅(qū)動(dòng)入門

linux 基礎(chǔ)復(fù)習(xí)(9)設(shè)備驅(qū)動(dòng)入門

作者: 時(shí)間:2016-10-08 來源:網(wǎng)絡(luò) 收藏

Linux 內(nèi)核中采用可加載的模塊化設(shè)計(jì)(LKMs,Loadable Kernel Modules),一般情況下編譯的Linux 內(nèi)核是支持可插入式模塊的,也就是將最基本的核心代碼編譯在內(nèi)核中,其他的代碼可以選擇在內(nèi)核中,或者編譯為內(nèi)核的模塊文件。常見的驅(qū)動(dòng)程序也是作為內(nèi)核模塊動(dòng)態(tài)加載的。

本文引用地址:http://2s4d.com/article/201610/305814.htm

模塊相關(guān)命令

lsmod 列出當(dāng)前系統(tǒng)加載的模塊

rmmod 將當(dāng)前模塊卸載

insmod、modprobe 用于加載當(dāng)前模塊。但insmod不會(huì)自動(dòng)解決依存關(guān)系,而modprobe可以根據(jù)模塊間的依存關(guān)系以及 /etc/modules.conf 文件中的內(nèi)容自動(dòng)插入模塊

mknod 創(chuàng)建相關(guān)模塊

Linux 系統(tǒng)的設(shè)備文件分為三類:塊設(shè)備文件、字符設(shè)備文件和網(wǎng)絡(luò)設(shè)備文件。

· 塊設(shè)備文件通常指一些需要以塊(如512 字節(jié))的方式寫入的設(shè)備,如IDE 硬盤、SCSI硬盤、光驅(qū)等。

· 字符型設(shè)備文件通常指可以直接讀寫,沒有緩沖區(qū)的設(shè)備,如并口、虛擬控制臺(tái)等。

· 網(wǎng)絡(luò)設(shè)備文件通常是指網(wǎng)絡(luò)設(shè)備訪問的BSD socket接口,如網(wǎng)卡等。

設(shè)備號(hào)設(shè)備號(hào)是一個(gè)數(shù)字,它是設(shè)備的標(biāo)志。就如前面所述,一個(gè)設(shè)備文件(也就是設(shè)備節(jié)點(diǎn))可以通過mknod命令來創(chuàng)建,其中指定了主設(shè)備號(hào)和次設(shè)備號(hào)。主設(shè)備號(hào)表明某一類設(shè)備,

一般對(duì)應(yīng)著確定的驅(qū)動(dòng)程序;次設(shè)備號(hào)一般是用于區(qū)分標(biāo)明不同屬性,例如不同的使用方法,不同的位置,不同的操作等,它標(biāo)志著某個(gè)具體的物理設(shè)備。高字節(jié)為主設(shè)備號(hào)和底字節(jié)為次設(shè)備號(hào)。例如,在系統(tǒng)中的塊設(shè)備IDE 硬盤的主設(shè)備號(hào)是3,而多個(gè)IDE 硬盤及其各個(gè)分區(qū)分別賦予次設(shè)備號(hào)1、2、3……

Linux 設(shè)備驅(qū)動(dòng)程序包含中斷處理程序和設(shè)備服務(wù)子程序兩部分

設(shè)備服務(wù)子程序包含了所有與設(shè)備操作相關(guān)的處理代碼。它從面向用戶進(jìn)程的設(shè)備文件系統(tǒng)中接受用戶命令,并對(duì)設(shè)備控制器執(zhí)行操作。這樣,設(shè)備驅(qū)動(dòng)程序屏蔽了設(shè)備的特殊性,使用戶可以像對(duì)待文件一樣操作設(shè)備。

設(shè)備控制器需要獲得系統(tǒng)服務(wù)時(shí)有兩種方式:查詢和中斷。因?yàn)長inux 下的設(shè)備驅(qū)動(dòng)程序是內(nèi)核的一部分,在設(shè)備查詢期間系統(tǒng)不能運(yùn)行其他代碼,查詢方式的工作效率比較低,所以只有少數(shù)設(shè)備如軟盤驅(qū)動(dòng)程序采取這種方式,大多設(shè)備以中斷方式向設(shè)備驅(qū)動(dòng)程序發(fā)出輸入/輸出請(qǐng)求。

screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new windownCTRL+Mouse wheel to zoom in/out';} onclick=if(!this.resized) {return true;} else {window.open(this.src);} alt= src=http://blogimg.chinaunix.net/blog/upfile2/080413193842.jpg onload=if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new windownCTRL+Mouse wheel to zoom in/out';} border=0>

Linux 中的設(shè)備驅(qū)動(dòng)程序有如下特點(diǎn)。

(1)內(nèi)核代碼:設(shè)備驅(qū)動(dòng)程序是內(nèi)核的一部分,如果驅(qū)動(dòng)程序出錯(cuò),則可能導(dǎo)致系統(tǒng)崩潰。

(2)內(nèi)核接口:設(shè)備驅(qū)動(dòng)程序必須為內(nèi)核或者其子系統(tǒng)提供一個(gè)標(biāo)準(zhǔn)接口。比如,一個(gè)終端驅(qū)動(dòng)程序必須為內(nèi)核提供一個(gè)文件I/O 接口;一個(gè)SCSI設(shè)備驅(qū)動(dòng)程序應(yīng)該為SCSI子系統(tǒng)提供一個(gè)SCSI設(shè)備接口,同時(shí)SCSI子系統(tǒng)也必須為內(nèi)核提供文件的I/O 接口及緩沖區(qū)。

(3)內(nèi)核機(jī)制和服務(wù):設(shè)備驅(qū)動(dòng)程序使用一些標(biāo)準(zhǔn)的內(nèi)核服務(wù),如內(nèi)存分配等。

(4)可裝載:大多數(shù)的Linux 操作系統(tǒng)設(shè)備驅(qū)動(dòng)程序都可以在需要時(shí)裝載進(jìn)內(nèi)核,在不需要時(shí)從內(nèi)核中卸載。

(5)可設(shè)置:Linux 操作系統(tǒng)設(shè)備驅(qū)動(dòng)程序可以集成為內(nèi)核的一部分,并可以根據(jù)需要把其中的某一部分集成到內(nèi)核中,這只需要在系統(tǒng)編譯時(shí)進(jìn)行相應(yīng)的設(shè)置即可。

(6)動(dòng)態(tài)性:在系統(tǒng)啟動(dòng)且各個(gè)設(shè)備驅(qū)動(dòng)程序初始化后,驅(qū)動(dòng)程序?qū)⒕S護(hù)其控制的設(shè)備。

如果該設(shè)備驅(qū)動(dòng)程序控制的設(shè)備不存在也不影響系統(tǒng)的運(yùn)行,那么此時(shí)的設(shè)備驅(qū)動(dòng)程序只是多占用了一點(diǎn)系統(tǒng)內(nèi)存罷了。

驅(qū)動(dòng)開發(fā)時(shí)卻沒有main 函數(shù),模塊在調(diào)用insmod命令時(shí)被加載,此時(shí)的入口點(diǎn)是init_module函數(shù),通常在該函數(shù)中完成設(shè)備的注冊(cè)。同樣,模塊在調(diào)rmmod

函數(shù)時(shí)被卸載,此時(shí)的入口點(diǎn)是cleanup_module函數(shù),在該函數(shù)中完成設(shè)備的卸載。在設(shè)備完成注冊(cè)加載之后,用戶的應(yīng)用程序就可以對(duì)該設(shè)備進(jìn)行一定的操作,如read、write等,而驅(qū)動(dòng)程序就是用于實(shí)現(xiàn)這些操作,在用戶應(yīng)用程序調(diào)用相應(yīng)入口函數(shù)時(shí)執(zhí)行相關(guān)的操作,init_module入口點(diǎn)函數(shù)則不需要完成其他如read、write之類功能。

設(shè)備驅(qū)動(dòng)程序的入口點(diǎn),它是一個(gè)在中定義的struct file結(jié)構(gòu),這是一個(gè)內(nèi)核結(jié)構(gòu),不會(huì)出現(xiàn)在用戶空間的程序中,它定義了常見文件I/O 函數(shù)的入口。

struct file_operations {

loff_t (*llseek) (struct file *, loff_t, int);

ssize_t (*read) (struct file *filp, char *buff, size_t count, loff_t *offp);

ssize_t (*write) (struct file *filp, const char *buff, size_t count, loff_t *offp);

int (*readdir) (struct file *, void *, filldir_t);

unsigned int (*poll) (struct file *, struct poll_table_struct *);

int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned

long);

int (*mmap) (struct file *, struct vm_area_struct *);

int (*open) (struct inode *, struct file *);

int (*flush) (struct file *);

int (*release) (struct inode *, struct file *);

int (*fsync) (struct file *, struct dentry *);

int (*fasync) (int, struct file *, int);

int (*check_media_change) (kdev_t dev);

int (*revalidate) (kdev_t dev);

int (*lock) (struct file *, int, struct file_lock *);

};

每個(gè)設(shè)備的驅(qū)動(dòng)程序不一定要實(shí)現(xiàn)其中所有的函數(shù)操作,若不需要定義實(shí)現(xiàn)時(shí),則只需將其設(shè)為NULL即可。


上一頁 1 2 3 下一頁

關(guān)鍵詞:

評(píng)論


相關(guān)推薦

技術(shù)專區(qū)

關(guān)閉