教你寫第一個Linux設備驅動程序

首先說明:寫這個第一個Linux設備驅動程序的目的是熟悉Linux驅動的框架以及編程流程,所以是通過打印的信息來觀察程序運行的情況,並不是真正的實現了某一個具體設備的驅動,可以類比於C語言編程中的“Hello World”。

Linux下的設備驅動架構如下圖所示:

教你寫第一個Linux設備驅動程序


在本篇文章中以first_device_driver為例進行介紹

一般來說,寫出完整的設備驅動程序需要如下幾個步驟:

  1. 寫出first_drv_open、first_drv_write、first_drv_read和first_drv_ioctl等函數;
  2. 定義file_operations結構體並填充其成員函數first_drv_open、first_drv_write、first_drv_read和first_drv_ioctl等;
  3. 模塊加載函數,通過register_chrdev將字符設備註冊到內核中;
  4. 寫驅動的入口函數;
  5. 寫驅動的出口函數;
  6. 通過module_init()來修飾驅動入口函數;
  7. 通過module_exit()來修飾驅動出口函數;
  8. 聲明模塊許可證;


下面進行詳細講解

步驟一:在新創建的.c文件中編寫如圖例中的代碼


教你寫第一個Linux設備驅動程序


教你寫第一個Linux設備驅動程序


步驟二:編寫Makefile腳本


教你寫第一個Linux設備驅動程序


值得提出的一點是,編寫Makefile是Linux驅動工程師必備的基礎,但是要明白我們並不需要完全的掌握Makefile的語法及編程,我們只需要能模仿著其他工程的Makefile文件寫出我們自己想要的Makefile文件即可。


步驟三:在對應目錄中執行make命令,生成.ko模塊文件

這一步驟較為簡單,只是在相應目錄輸入make命令即可。


步驟四:通過U盤或者nfs網絡文件系統將該.ko文件加載到內核中

我們在加載驅動模塊之前可以先通過命令:cat /proc/devices來查看字符主設備號是否已經被佔用。proc文件系統是Linux在運行時存在於內存中的文件系統,它記錄著系統運行的實時信息,當關閉系統時,proc文件系統也隨之釋放。

然後可通過命令:insmod first_drv.ko將模塊掛載到內核, 通過命令:cat /proc/devices可以觀察first_drv設備是否已經掛載成功;另外也可以通過modprobe來加載驅動模塊,這兩者的區別在於modprobe可以解決加載模塊時的依賴關係,它是通過/lib/modules/#uname -r/modules.dep(.bb)文件來查找依賴關係的,而insmod不能解決模塊間的依賴問題。


步驟五:創建dev/first_driver設備節點

通過命令:mknod /dev/first_driver 100 0 來創建設備節點。


步驟六:編寫應用程序進行測試

測試的應用程序如下:


教你寫第一個Linux設備驅動程序

在這裡我們可以發現測試程序裡的open()函數實際就是調用了驅動中的first_drv_open()函數,而write()函數實際調用了驅動中的first_drv_write()函數。本質上是這樣的一個執行過程:用戶空間的open()函數->文件系統的sys_open()函數->驅動的first_drv_open()函數。


另外很重要的一點,上文中圖例中的程序是需要手動創建設備節點,從而提供給用戶程序訪問的,如此一來當驅動模塊較多的時候就很麻煩,所以Linux也提供自動創建設備節點的接口,建議使用自動創建設備節點的機制。如下是自動創建設備節點的方法:

1、首先創建一個class設備類,然後在class類下,創建一個class_device,即在類下面創建類的設備;

2、在驅動入口函數中添加步驟:firstdrv_class= class_create(THIS_MODULE,"first_drv");irstdrv_class_devs=class_device_create(firstdrv_class,NULL,MKDEV(major,0),NULL,"first_drv");

3、在驅動出口函數中添加:class_device_unregister(firstdrv_class_devs);class_destroy(firstdrv_class);

這個自動創建設備節點的功能是基於Linux支持的熱拔插功能,Linux內核中每當設備出現變動時,都會處理對應的信息,使用戶程序對/dev目錄下的設備進行操作。


最後,此驅動程序運行的實際效果就是打印信息,這個Linux設備驅動例程可以類比於C語言中的“Hello World”例程,希望可以幫助大家初步認識Linux的設備驅動程序。


分享到:


相關文章: