實(shí)驗(yàn)四-linux驅(qū)動(dòng)程序的編寫(共7頁(yè))_第1頁(yè)
實(shí)驗(yàn)四-linux驅(qū)動(dòng)程序的編寫(共7頁(yè))_第2頁(yè)
實(shí)驗(yàn)四-linux驅(qū)動(dòng)程序的編寫(共7頁(yè))_第3頁(yè)
實(shí)驗(yàn)四-linux驅(qū)動(dòng)程序的編寫(共7頁(yè))_第4頁(yè)
實(shí)驗(yàn)四-linux驅(qū)動(dòng)程序的編寫(共7頁(yè))_第5頁(yè)
已閱讀5頁(yè),還剩3頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、中國(guó)石油大學(xué)(北京)計(jì)算機(jī)科學(xué)與技術(shù)系實(shí) 驗(yàn) 報(bào) 告評(píng)定成績(jī)指導(dǎo)教師實(shí)驗(yàn)課程: 軟件系統(tǒng)設(shè)計(jì)與開(kāi)發(fā)實(shí)踐 實(shí)驗(yàn)名稱: linux驅(qū)動(dòng)程序的編寫 學(xué)號(hào): 2017215538 姓名: 于寧 班級(jí): 信息研17-4班 完成日期: 2018 年 4 月 16 日 一、實(shí)驗(yàn)?zāi)康?. 掌握l(shuí)inux驅(qū)動(dòng)程序的編寫方法;2. 掌握驅(qū)動(dòng)程序動(dòng)態(tài)模塊的調(diào)試方法;3. 掌握驅(qū)動(dòng)程序填加到內(nèi)核的方法。二、實(shí)驗(yàn)內(nèi)容1. 學(xué)習(xí)linux驅(qū)動(dòng)程序的編寫流程;2. 學(xué)習(xí)驅(qū)動(dòng)程序動(dòng)態(tài)模塊的調(diào)試方法;3. 學(xué)習(xí)驅(qū)動(dòng)程序填加到內(nèi)核的流程。三、實(shí)驗(yàn)設(shè)備1. PentiumII以上的PC機(jī),LINUX操作系統(tǒng),EL-ARM830實(shí)驗(yàn)

2、箱。四、linux的驅(qū)動(dòng)程序的編寫嵌入式應(yīng)用對(duì)成本和實(shí)時(shí)性比較敏感,而對(duì)linux的應(yīng)用主要體現(xiàn)在對(duì)硬件的驅(qū)動(dòng)程序的編寫和上層應(yīng)用程序的開(kāi)發(fā)上。嵌入式linux驅(qū)動(dòng)程序的基本結(jié)構(gòu)和標(biāo)準(zhǔn)Linux的結(jié)構(gòu)基本一致,也支持模塊化模式,所以,大部分驅(qū)動(dòng)程序編成模塊化形式,而且,要求可以在不同的體系結(jié)構(gòu)上安裝。linux是可以支持模塊化模式的,但由于嵌入式應(yīng)用是針對(duì)具體的應(yīng)用,所以,一般不采用該模式,而是把驅(qū)動(dòng)程序直接編譯進(jìn)內(nèi)核之中。但是這種模式是調(diào)試驅(qū)動(dòng)模塊的極佳方法。設(shè)備驅(qū)動(dòng)程序是操作系統(tǒng)內(nèi)核和機(jī)器硬件之間的接口。設(shè)備驅(qū)動(dòng)程序?yàn)閼?yīng)用程序屏蔽了硬件的細(xì)節(jié),這樣在應(yīng)用程序看來(lái),硬件設(shè)備只是一個(gè)設(shè)備文件,

3、應(yīng)用程序可以像操作普通文件一樣對(duì)硬件設(shè)備進(jìn)行操作。同時(shí),設(shè)備驅(qū)動(dòng)程序是內(nèi)核的一部分,它完成以下的功能:對(duì)設(shè)備初始化和釋放;把數(shù)據(jù)從內(nèi)核傳送到硬件和從硬件讀取數(shù)據(jù);讀取應(yīng)用程序傳送給設(shè)備文件的數(shù)據(jù)和回送應(yīng)用程序請(qǐng)求的數(shù)據(jù);檢測(cè)和處理設(shè)備出現(xiàn)的錯(cuò)誤。在linux操作系統(tǒng)下有字符設(shè)備和塊設(shè)備兩類主要的設(shè)備文件類型。字符設(shè)備和塊設(shè)備的主要區(qū)別是:在對(duì)字符設(shè)備發(fā)出讀寫請(qǐng)求時(shí),實(shí)際的硬件I/O一般就緊接著發(fā)生了;塊設(shè)備利用一塊系統(tǒng)內(nèi)存作為緩沖區(qū),當(dāng)用戶進(jìn)程對(duì)設(shè)備請(qǐng)求滿足用戶要求時(shí),就返回請(qǐng)求的數(shù)據(jù)。塊設(shè)備是主要針對(duì)磁盤等慢速設(shè)備設(shè)計(jì)的,以免耗費(fèi)過(guò)多的CPU時(shí)間來(lái)等待。4.1 設(shè)備驅(qū)動(dòng)程序的 file_op

4、erations 結(jié)構(gòu)通常,一個(gè)設(shè)備驅(qū)動(dòng)程序包括兩個(gè)基本的任務(wù):驅(qū)動(dòng)設(shè)備的某些函數(shù)作為系統(tǒng)調(diào)用執(zhí)行;而某些函數(shù)則負(fù)責(zé)處理中斷(即中斷處理函數(shù))。而file_operations 結(jié)構(gòu)的每一個(gè)成員的名稱都對(duì)應(yīng)著一個(gè)系統(tǒng)調(diào)用。用戶程序利用系統(tǒng)調(diào)用,比如在對(duì)一個(gè)設(shè)備文件進(jìn)行諸如read操作時(shí),這時(shí)對(duì)應(yīng)于該設(shè)備文件的驅(qū)動(dòng)程序就會(huì)執(zhí)行相關(guān)的ssize_t (*read) (struct file *, char *, size_t, loff_t *);函數(shù)。在操作系統(tǒng)內(nèi)部,外部設(shè)備的存取是通過(guò)一組固定入口點(diǎn)進(jìn)行的,這些入口點(diǎn)由每個(gè)外設(shè)的驅(qū)動(dòng)程序提供,由file_operations結(jié)構(gòu)向系統(tǒng)進(jìn)行說(shuō)明,

5、因此,編寫設(shè)備驅(qū)動(dòng)程序的主要工作就是編寫子函數(shù),并填充file_operations的各個(gè)域。file_operations結(jié)構(gòu)在kernel/include/linux/fs.h中可以找到。struct file_operations struct module *owner;loff_t (*llseek) (struct file *, loff_t, int);ssize_t (*read) (struct file *, char *, size_t, loff_t *);ssize_t (*write) (struct file *, const char *, size_t, l

6、off_t *);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 (

7、*flush) (struct file *);int (*release) (struct inode *, struct file *);int (*fsync) (struct file *, struct dentry *, int datasync);int (*fasync) (int, struct file *, int);int (*lock) (struct file *, int, struct file_lock *);ssize_t (*readv) (struct file *, const struct iovec *, unsigned long, loff_t

8、 *);ssize_t (*writev) (struct file *, const struct iovec *, unsigned long, loff_t *);ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int);unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);#ifdef MAGIC_ROM_PTRint (*

9、romptr) (struct file *, struct vm_area_struct *);#endif /* MAGIC_ROM_PTR */;其中主要的函數(shù)說(shuō)明如下:1. open 是驅(qū)動(dòng)程序用來(lái)完成設(shè)備初始化操作的, open還會(huì)增加設(shè)備計(jì)數(shù),以防止文件在關(guān)閉前模塊被卸載出內(nèi)核。open主要完成以下操作:檢查設(shè)備錯(cuò)誤(諸如設(shè)備未就緒或相似的硬件問(wèn)題);如果是首次打開(kāi),初始化設(shè)備;標(biāo)別次設(shè)備號(hào);分配和填寫要放在fileprivate_data內(nèi)的數(shù)據(jù)結(jié)構(gòu);增加使用計(jì)數(shù)。2. read 用來(lái)從外部設(shè)備中讀取數(shù)據(jù)。當(dāng)其為指針時(shí),將引起read系統(tǒng)調(diào)用返回-EINVAL(“非法參數(shù)”)。函

10、數(shù)返回一個(gè)非負(fù)值表示成功地讀取了多少字節(jié)。3. write 向外部設(shè)備發(fā)送數(shù)據(jù)。如果沒(méi)有這個(gè)函數(shù),write 系統(tǒng)調(diào)用向調(diào)用程序返回一個(gè)-EINVAL。如果返回值非負(fù),就表示成功地寫入的字節(jié)數(shù)。4. release是當(dāng)設(shè)備被關(guān)閉時(shí)調(diào)用這個(gè)操作。release的作用正好與open相反。這個(gè)設(shè)備方法有時(shí)也稱為close。它應(yīng)該完成以下操作:使用計(jì)數(shù)減1;釋放open分配在fileprivate_data中的內(nèi)存,在最后一次關(guān)閉操作時(shí)關(guān)閉設(shè)備。5. llseek 是改變當(dāng)前的讀寫指針。6. readdir 一般用于文件系統(tǒng)的操作。7. poll 一般用于查詢?cè)O(shè)備是否可讀可寫或處于特殊的狀態(tài)。8. i

11、octl 執(zhí)行設(shè)備專有的命令。9. mmap 將設(shè)備內(nèi)存映射到應(yīng)用程序的進(jìn)程地址空間。4.2 設(shè)備驅(qū)動(dòng)程序編寫的具體內(nèi)容通過(guò)了解驅(qū)動(dòng)程序的file_operations 結(jié)構(gòu),用戶就可以編寫出相關(guān)外部設(shè)備的驅(qū)動(dòng)程序。首先,用戶在自己的驅(qū)動(dòng)程序源文件中定義file_operations結(jié)構(gòu),并編寫出設(shè)備需要的各操作函數(shù),對(duì)于設(shè)備不需要的操作函數(shù)用NULL初始化,這些操作函數(shù)將被注冊(cè)到內(nèi)核,當(dāng)應(yīng)用程序?qū)υO(shè)備相應(yīng)的設(shè)備文件進(jìn)行文件操作時(shí),內(nèi)核會(huì)找到相應(yīng)的操作函數(shù),并進(jìn)行調(diào)用。如果操作函數(shù)使用NULL,操作系統(tǒng)就進(jìn)行默認(rèn)的處理。定義并編寫完file_operations結(jié)構(gòu)的操作函數(shù)后,要定義一個(gè)初始

12、化函數(shù),比如函數(shù)名可device_init(),在linux初始化的時(shí)候要調(diào)用該函數(shù),因此,該函數(shù)應(yīng)包含以下幾項(xiàng)工作:a. 對(duì)該驅(qū)動(dòng)所使用到的硬件寄存器進(jìn)行初始化。包括中斷寄存器。b. 初始化設(shè)備相關(guān)的參數(shù)。一般來(lái)說(shuō)每個(gè)設(shè)備要定義一個(gè)設(shè)備變量,用來(lái)保存設(shè)備相關(guān)的參數(shù)。c. 注冊(cè)設(shè)備。Linux內(nèi)核通過(guò)主設(shè)備號(hào)將設(shè)備驅(qū)動(dòng)程序同設(shè)備文件相連。每個(gè)設(shè)備有且僅有一個(gè)主設(shè)備號(hào)。通過(guò)查看linux系統(tǒng)中/proc下的devices文件,該文件記錄已經(jīng)使用的主設(shè)備號(hào)和設(shè)備名,選擇一個(gè)沒(méi)有使用的主設(shè)備號(hào),調(diào)用下面的函數(shù)來(lái)注冊(cè)設(shè)備。int register_chrdev(unsigned int,const c

13、har*,struct file_operations*),其中的三個(gè)參數(shù)代表主設(shè)備號(hào),設(shè)備名,file_operations的結(jié)構(gòu)地址。d. 注冊(cè)設(shè)備使用的中斷。注冊(cè)中斷使用的函數(shù)。int request_irq(unsigned irq,void(*handler)(int,void*,struct pt_regs*),unsigned long flags, const char* device, void* dev_id);其中,irq是中斷向量。硬件系統(tǒng)將IRQn映射成中斷向量。handler-中斷處理函數(shù)。flags-中斷處理中的一些選項(xiàng)的掩碼。device-設(shè)備的名稱dev_id

14、-在中斷共享時(shí)使用的id。e. 其他的一些初始化工作,比如給設(shè)備分配I/O,申請(qǐng)DMA通道等。當(dāng)設(shè)備的驅(qū)動(dòng)程序使用了如下的函數(shù)方式,則設(shè)備驅(qū)動(dòng)可以動(dòng)態(tài)的加載和卸載int _init device_init (void)void _exit device_exit(void)module_init(device _init);module_exit(device _exit);當(dāng)然,也可以編譯進(jìn)內(nèi)核中。4.3 將設(shè)備驅(qū)動(dòng)加到linux內(nèi)核中設(shè)備驅(qū)動(dòng)程序?qū)懲旰?,就可以加到linux的內(nèi)核中了,這需要修改linux的源碼,然后重新編譯linux內(nèi)核。1. 將設(shè)備驅(qū)動(dòng)文件(比如device_drive

15、r.c)復(fù)制到kernel/drivers/char目錄下,該目錄保存了linux的字符型設(shè)備的設(shè)備驅(qū)動(dòng)程序。該驅(qū)動(dòng)程序中,使用 int _int device_init(void)方式編寫。2. 在 kernel/drivers/char目錄下的Makefile文件中填加如下代碼:ifeq($(CONFIG_DEVICE_DRIVER),y)L_OBJS+= DEVICE_DRIVER.oendif或obj-$(CONFIG_DEVICE_DRIVER) += DEVICE_DRIVER.o如果在配置linux內(nèi)核的時(shí)候,選擇了支持我們定義的設(shè)備,則在編譯內(nèi)核的時(shí)候,會(huì)編譯DEVICE_DR

16、IVER.c,生成DEVICE_DRIVER.o文件。3. 在kernel/drivers/char目錄下修改config.in文件。在comment 'Character devices'下面填加:bool support for DEVICE_DRIVER CONFIG_DEVICE_DRIVER這樣在編譯內(nèi)核時(shí),運(yùn)行make menuconfig時(shí),在配置字符設(shè)備時(shí)就會(huì)出現(xiàn)support for DEVICE_DRIVER的字樣。當(dāng)選中它時(shí),編譯通過(guò),則驅(qū)動(dòng)程序就加到內(nèi)核中去了。在文件系統(tǒng)cramfs中加上設(shè)備驅(qū)動(dòng)程序?qū)?yīng)的設(shè)備文件。掛在操作系統(tǒng)中的設(shè)備都使用了設(shè)備驅(qū)動(dòng)程

17、序,要使一個(gè)設(shè)備成為應(yīng)用程序可以訪問(wèn)的設(shè)備,必須在文件系統(tǒng)中有一個(gè)代表此設(shè)備的設(shè)備文件,通過(guò)使用設(shè)備文件,就可以對(duì)外部設(shè)備進(jìn)行具體操作。設(shè)備文件都包含在/dev目錄下,linux使用的根文件系統(tǒng)是cramfs文件系統(tǒng)。這個(gè)系統(tǒng)是一個(gè)只讀壓縮文件系統(tǒng),要在制作cramfs文件系統(tǒng)之前,在root_tech目錄結(jié)構(gòu)中的/usr/etc/rc.local文件下,添加相應(yīng)的設(shè)備文件。用mknod命令來(lái)創(chuàng)建一個(gè)設(shè)備文件:mknod device_driver c 120 0, device_driver為設(shè)備文件名,指的是字符設(shè)備,120是主設(shè)備號(hào),0為次設(shè)備號(hào)。device_driver這個(gè)名字與注冊(cè)

18、函數(shù)中使用的字符串要一致! 4.4 將設(shè)備驅(qū)動(dòng)編譯成驅(qū)動(dòng)模塊 使用同一個(gè)驅(qū)動(dòng)程序的源代碼,當(dāng)然一定要如下定義某些函數(shù) int _init device_init (void);void _exit device_exit(void);module_init(device _init);module_exit(device_exit);利用相應(yīng)的交叉編譯器,以及編譯命令,就能把device_driver.c編譯成device_driver.o這樣的動(dòng)態(tài)驅(qū)動(dòng)模塊。當(dāng)編譯通過(guò)后,利用nfs網(wǎng)絡(luò)文件系統(tǒng),mount到根文件系統(tǒng)下,在存有驅(qū)動(dòng)模塊的文件系統(tǒng)下,在linux系統(tǒng)的終端中,鍵入加載驅(qū)動(dòng)模塊命令 insmod device_driver.o,則系統(tǒng)安裝上驅(qū)動(dòng)模塊,如果在/dev目錄下沒(méi)有相應(yīng)的設(shè)備文件,就可以使用 mknod device_name c 主設(shè)備號(hào) 從設(shè)備號(hào) 來(lái)創(chuàng)建一個(gè)設(shè)備文件。從而正確使用驅(qū)動(dòng)模塊。當(dāng)卸載驅(qū)動(dòng)模塊時(shí),使用 rmmod device_driver即可。刪除設(shè)備文件則使用 r

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論