日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

【Linux驱动】linux内核模块简介

發布時間:2024/4/21 linux 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【Linux驱动】linux内核模块简介 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一. 摘要

這篇文章主要介紹了Linux內核模塊的相關概念,以及簡單的模塊開發過程。主要從模塊開發中的常用指令、內核模塊程序的結構、模塊使用計數以及模塊的編譯等角度對內核模塊進行介紹。在Linux系統開發過程中,以模塊的形式開發其重要性不言自明,而在嵌入式設備驅動開發中將驅動程序以模塊的形式發布,更是極大地提高了設備使用的靈活性——用戶只需要拿到相關驅動模塊,再插入到用戶的內核中,即可靈活地使用你的設備。

二. 文章提綱

1. 摘要

2.?文章提綱

3. 概述

4. 模塊開發常用的指令

5. 內核模塊程序結構

6. 模塊使用計數

7. 模塊的編譯

8. 使用模塊繞開GPL

9. 總結

三.概述

Linux內核整體結構已經很龐大,包含了很多的組件,而對于我們工程師而言,有兩種方法將需要的功能包含進內核當中。

???????? 一:將所有的功能都編譯進Linux內核。

???????? 二:將需要的功能編譯成模塊,在需要的時候動態地添加。

上述兩種方式優缺點分析:

???????? 第一種:

?????????????????? 優點:不會有版本不兼容的問題,不需要進行嚴格的版本檢查

?????????????????? 缺點:生成的內核會很大;要在現有的內核中添加新的功能,則要編譯整個內核

???????? 第二種:

優點:模塊本身不編譯進內核,從而控制了內核的大小;模塊一旦被加載,將和其它的部分完全一樣。

缺點:可能會有內核與模塊版本不兼容的問題,導致內核崩潰;會造成內存的利用率比較低。

?

四.模塊開發常用的指令

在內核模塊開發的過程中常用的有以下指令。

1)? insmod: 將模塊插入內核中,使用方法:#insmod XXX.ko

2)? rmmod: 將模塊從內核中刪除,使用方法:#rmmod XXX.ko

3)? lsmod: 列表顯示所有的內核模塊,可以和grep指令結合使用。使用方法:#lsmod | grep XXX

4)? modprobe: modprobe可載入指定的個別模塊,或是載入一組相依賴的模塊。modprobe會根據depmod所產生的依賴關系,決定要載入哪些模塊。若在載入過程中發生錯誤,在modprobe會卸載整組的模塊。依賴關系是通過讀取 /lib/modules/2.6.xx/modules.dep得到的。而該文件是通過depmod 所建立。

5)? modinfo: 查看模塊信息。使用方法:#modinfo XXX.ko

6)? tree –a: 查看當前目錄的整個樹結構。使用方法:#tree -a

?

五.內核模塊程序結構

1)? 模塊加載函數(一般需要)

在用insmod或modprobe命令加載模塊時,該函數被執行。完成模塊的初始化工作。

Linux內核的模塊加載函數一般用__init標識聲明,模塊加載函數必須以module_init(函數名)的形式被指定。該函數返回整型值,如果執行成功,則返回0,初始化失敗時則返回錯誤編碼,Linux內核當中的錯誤編碼是負值,在<linux/errno.h>中定義。

在Linux中,標識__init的函數在連接時放在.init.text這個區段,而且在.initcall.init中保留一份函數指針,初始化的時候內核會根據這些指針調用初始化函數,初始化結束后釋放這些init區段(包括前兩者)。

代碼清單:

1 static int __init XXX_init(void) 2 3 { 4 5 return 0; 6 } 7 8 9 10 moudle_init(XXX_init);

?

2)? 模塊卸載函數(一般需要)

在用rmmod或modprobe命令卸載模塊時,該函數被執行。完成與加載相反的工作。

模塊的卸載函數和模塊加載函數實現相反的功能,主要包括

  • 若模塊加載函數注冊了XXX,則模塊卸載函數注銷XXX
  • 若模塊加載函數動態分配了內存,則模塊卸載函數釋放這些內存
  • 若模塊加載函數申請了硬件資源,則模塊卸載函數釋放這些硬件資源
  • 若模塊加載函數開啟了硬件資源,則模塊卸載函數一定要關閉這些資源
  • 代碼清單:

    1 static void __exit XXX_exit(void) 2 3 { 4 5 } 6 7 8 9 moudle_exit(XXX_exit);

    ?

    3)? 模塊許可證聲明(必須)

    如果不聲明,則在模塊加載時會收到內核被污染的警告,一般應遵循GPL協議。

    代碼清單:

    1 MODULE_LICENSE("GPL");

    ?

    4)? 模塊參數(可選)

    模塊在被加載時傳遞給模塊的值,本身應該是模塊內部的全局變量。

    示例程序book.c

    1 #include <linux/init.h> 2 3 #include <linux/module.h> 4 5 6 7 static char *bookName = "Good Book."; 8 9 static int bookNumber = 100; 10 11 12 13 static int __init book_init(void) 14 15 { 16 17 printk(KERN_INFO "Book name is %s\n", bookName); 18 19 printk(KERN_INFO "Book number is %d\n", bookNumber); 20 21 return 0; 22 23 } 24 25 26 27 static void __exit book_exit(void) 28 29 { 30 31 printk(KERN_INFO "Book module exit.\n"); 32 33 } 34 35 36 37 module_init(book_init); 38 39 module_exit(book_exit); 40 41 module_param(bookName, charp, S_IRUGO); 42 43 module_param(bookNumber, int, S_IRUGO); 44 45 46 47 MODULE_LICENSE("GPL");

    ?

    在向內核插入模塊的時候可以用以下方式,并且可以在內核日志中看到模塊加載以后變量已經有了值。

    ?

    ?

    5)? 模塊導出符號(可選)

    使用模塊導出符號,方便其它模塊依賴于該模塊,并使用模塊中的變量和函數等。

    在Linux2.6的內核中,/proc/kallsyms文件對應著符號表,它記錄了符號和符號對應的內存地址。對于模塊而言,使用下面的宏可以導出符號。

    1 EXPORT_SYMBOL(符號名);

    1 EXPORT_GPL_SYMBOL(符號名);

    ?

    6)? 模塊信息(可選)

    模塊信息則是指模塊的作者信息等。

    ?

    六.模塊使用計數

    Linux內核提供了MOD_INC_USE_COUNT和MOD_DEC_USE_COUNT宏來管理模塊使用計數。但是對于內核模塊而言,一般不會自己管理使用計數。

    ?

    七.模塊的編譯

    將下面的Makefile文件放在book.c同級的目錄下,然后使用#make命令或者#make all命令編譯即可生成book.ko模塊文件。

    對應的Makefile:

    1 ifneq ($(KERNELRELEASE),) 2 3 mymodule_objs := book.o 4 5 obj-m := book.o 6 7 else 8 9 PWD := $(shell pwd) 10 11 KVER ?= $(shell uname -r) 12 13 KDIR := /usr/src/linux-headers-2.6.38-8-generic 14 15 16 17 all: 18 19 $(MAKE) -C $(KDIR) M=$(PWD) 20 21 clean: 22 23 rm -rf *.mod.c *.mod.o *.ko *.o *.tmp_versions *.order *symvers 24 25 endif

    ?

    八.使用模塊繞開

    如果功能不編譯成模塊,則無法繞開GPL,編譯成模塊后公司發布產品則只需要發布模塊,而不需要發布源碼。為了Linux系統能夠支持模塊,需要做以下的工作:

  • 內核編譯時選擇“可以加載模塊”,嵌入式產品一般都不需要卸載模塊,則可以不選擇“可卸載模塊”
  • 將我們的ko文件放在文件系統中
  • Linux系統實現了insmod、rmmod等工具
  • 使用時可以用insmod手動加載模塊,也可以修改/etc/init.d/rcS文件,從而在系統啟動的時候就加載模塊。
  • ?

    九.總結

    本文主要介紹內核模塊的概念和基本編程方法,內核模塊主要由加載、卸載函數功能函數等一系列聲明組成。它可以被傳入參數,也可以導出符號,供其它的模塊使用。

    十.補充 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?

    ???學習內核,避免不了要和模塊打交道,而模塊的編譯一直都是用以前寫好的makefile文件,沒有研究過模塊是如何編譯的,后來在內核里面找到了一份文檔,才發現模塊的編譯的方式很“豐富”

    linux/Document/kbuild/module.txt文件中有詳細的講解。 ---------------------------------------------------------------------------------------
    一,一般的模塊的編譯。
    我喜歡用的一種格式如下:


  • obj-m?:=?find_mod.o
  • kernel_path=/home/linux/kernel/linux-3.5

  • all:
  • ???? make?-C $(kernel_path)?M=$(PWD)?modules
  • clean:
  • ???? make?-C $(kernel_path)?M=$(PWD)?clean
  • 只需要指定好三個參數:
    1,內核源代碼的絕對路徑,kernel_path。
    2,模塊所在的位置,一般都是當前目錄,PWD變量指定。
    3,產生的模塊的目標文件。這文件名要和模塊.c文件名一致。

    ------------------------------------------------------------------------------------------
    二,多個C文件的模塊編譯。
    在用戶態編程時,很多時候都是多個文件編譯,這么多文件組成一個項目。
    這么多文件可以由makefile組織到一起,同樣模塊中也可以編譯多個文件。
    而且實現起來也特別簡單。

  • obj-m?:=?hello.o
  • hello-y?:=?hello1.o hello2.o?
  • kernel_path=/home/linux/kernel/linux-3.5

  • all:
  • ???? make?-C $(kernel_path)?M=$(PWD)?modules
  • clean:
  • ???? make?-C $(kernel_path)?M=$(PWD)?clean
  • 假如有兩個C文件,hello1.c hello2.c將這兩個文件編譯的方式 見上面的Makefile文件。
    -----------------------------------------------------------------------------------------
    三,多個模塊同時編譯。
    C文件:hello.c find_mod.c 目標模塊:hello.ko ?find_mod.ko
  • obj-m?:=?find_mod.o
  • obj-m?+=?hello.o
  • kernel_path?=?/home/linux/kernel/linux-3.5
  • all:
  • ??????make?-C $(kernel_path)?M=$(PWD)?modules
  • clean:
  • ???? make?-C $(kernel_path)?M=$(PWD)?clean
  • ----------------------------------------------------------------------------------------
    四,其他。
    還有很多其他的編譯方式,比如說要在包含指定目錄的.h文件,該如何
    包含,加入這個模塊中有多個目錄,又該怎么編寫Makefile,等等,這些在module.txt中就有介紹。
    ---------------------------------------------------------------------------------------

    參考網址:http://www.cnblogs.com/tianyou/p/3448573.html

    總結

    以上是生活随笔為你收集整理的【Linux驱动】linux内核模块简介的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。