萬盛學電腦網

 萬盛學電腦網 >> Linux教程 >> 高手進階:Linux系統下驅動程序框架概述

高手進階:Linux系統下驅動程序框架概述

class="21187"> ; 一、linux的設備驅動程序與外界的接口可以分為三個部分: 1.驅動程序與操作系統內核的接口。通過file_operations(include/linux/fs.h)數據結構來完成的。 2.驅動程序與系統引導的接口。這部分利用驅動程序對設備進行初始化。 3.驅動程序與設備的接口。這部分描述了驅動程序如何與設備進行交互,與具體的設備密切相關。 二、根據功能劃分,設備驅動程序的代碼有以下幾部分: 1.驅動程序的注冊和注銷。 2.設備的打開和釋放。 3.設備的讀寫操作。 4.設備的控制操作。 5.設備的中斷和輪詢處理。 三、驅動程序的注冊和注銷: 設備驅動程序可以在系統啟動的時候初始化,也可以在需要的時候動態加載。字符設備的初始化由chr_dev_init()完成,包括對內存(devfs_register_chrdev(MEM_MAJOR,"mem",&memory_fops)),終端(tty_init()),打印機(lp_init()),鼠標(misc_init())等字符設備的初始化。 塊設備初始化由blk_dev_init()完成,這包括對IDE硬盤(ide_init()),軟盤(floppy_init()),光驅等塊設備的初始化。 每個字符設備或是塊設備的初始化都是通過devfs_register_chrdev()或是devfs_register_blkdev()向內核注冊。在關閉字符設備或是塊設備時,還需要通過devfs_unregister_chrdev()或是devfs_unregister_blkdev()從內核中注銷設備。 四、設備的打開和釋放: 打開設備是由open()來完成的。例如,打印機是用lp_open()打開的,而硬盤是用hd_open()打開的。在大部分設備驅動程序中,open完成如下工作: 1.增加設備的是用計數。 2.檢查設備的相關錯誤,如設備尚未准備好或是類似硬件的問題。 3.檢查是首次打開,則初始化設備。 4.識別次設備號,如有必要則更新f_op指針。 5.如果需要,分配且設置要放在filp->private_data裡的數據結構。 釋放設備由release()來完成,例如釋放打印機是用lp_release(),而釋放終端設備是用tty_release()。釋放設備的一般步驟包括: 1.釋放在filp->private_data中的open分配的內存。 2.如果是最後一次釋放,則關閉設備。 3.遞減設別的使用計數。 五、設備的讀寫操作: 字符設備使用各自的read()和write()來進行數據讀寫。例如,對虛擬終端的讀寫是通過vcs_read()和vcs_write()來進行數據讀寫的。 塊設備使用通用的generic_file_read()和generic_file_write()來進行數據讀寫。這兩個通用函數向請求表添加讀寫請求,內核可以通過ll_rw_block()優化請求順序。由於是對內存緩沖區而不是設備進行操作的,因而可以加快讀寫請求。如果內存緩沖區內沒有要讀入的數據或是要將寫請求寫入設備,那麼就要真正的執行數據傳輸。這是通過數據結構request_queue和request_fn()來完成(include/linux/blkdev.h)。 六、設備的控制操作: 除了讀寫操作,有時還要控制設備。這可以通過設備驅動程序中的ioctl()來完成。例如IDE硬盤的控制可以通過hd_ioctl(),對光驅的控制可以通過cdrom_ioctl()。 與讀寫操作不同,ioctl()的用法與具體設備密切相關。以軟驅的floppy_ioctl()為例(drivers/block/floppy.c): static int fd_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long param); 其中,cmd的取值及含義都是與軟驅有關的,比如,FDEJECT表示彈出軟盤。 除了ioctl(),設備驅動程序還可能有其他控制函數,比如llseek()等。 七、設備的輪詢和中斷處理: 對於不支持中斷的設備,讀寫時需要輪詢設備狀態,以及是否需要繼續進行數據傳輸。例如,打印機。如果設備支持中斷,則可按照中斷方式進行。

copyright © 萬盛學電腦網 all rights reserved