国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

Linux驅動實踐:帶你一步一步編譯內核驅動程序

系統 Linux
今天給大家分享一些筆記本里的一些存貨: Linux 系統中的驅動和中斷相關。在這部分,會以 GPIO 為例子,重點描述其中的關鍵節點。

[[434709]]

別人的經驗,我們的階梯!

大家好,我是道哥。今天給大家分享一些筆記本里的一些存貨: Linux 系統中的驅動和中斷相關。

大概會用 6~7 篇的文章,由淺入深的為大家介紹Linux 中驅動程序的編寫方法。

文章的順序,也是我之前自己學習時的順序。

以前的學習記錄比較零散,現在只是把它們按照一定的順序重新梳理一下。

這幾篇文章,理論知識會少一些,更注重實際的操作。

我會把操作用引導的代碼,全部上傳到網盤上,在文末有下載說明。

只要根據文中介紹的步驟進行操作,就一定可以操作成功。

學習的困惑

記得以前我在開始學習驅動開發的時候,找來很多文章、資料來學習,但是總是覺得缺少了點全局視角。

就好像:我想看清一座山的全貌,但總是被困在一個、又一個山谷中一樣。

主要的困惑有 3 點:

  1. 每一篇文章的介紹都是正確的,但是如果把很多文章放在一起看,就會發現怎么說的都不一樣啊?
  2. 有些文章注重函數的介紹,但是缺乏一個全局的視角,從整體上來觀察驅動程序的結構;
  3. 對于一個新手來說,能夠邊學習、邊實踐,這是最好的學習方式,但是很多文章不會注意這方面。雖然文章內容很漂亮,但是不知道怎么去實踐、驗證。

因此,這幾篇文章我們就從最簡單的驅動模塊編譯開始,然后介紹字符設備驅動程序。

在這部分,會以 GPIO 為例子,重點描述其中的關鍵節點。

最后再介紹在中斷處理程序中,如何利用信號量、小任務、工作隊列,把內核事件傳遞到應用層來處理。

作為第一個開篇文章,從最簡單的內核編譯開始。

實際操作一下:如何把一個最簡單的驅動程序(hello),按照 2 種方式進行編譯:

  1. 編譯進內核;
  2. 編譯為一個獨立的驅動模塊;

實踐環境

為了便于測試,以下操作都是在 Ubuntu16.04 操作系統里完成的。

編譯Linux驅動程序,肯定需要內核源碼,這里選擇的是 linux-4.15 版本,可以在官網下載。

文末有下載方式。

下載之后,把linux-4.15.tar.gz解壓到Ubuntu中任意目錄即可,例如:解壓到~/tmp/目錄下:

  1. $ tar -zxvf linux-4.15.tar.gz -C ~/tmp/ 

編譯進內核

創建驅動程序目錄

linux 中的驅動,一般都放在 linux-4.15/drivers/ 目錄下,因此在這個目錄中創建一個hello文件夾。

  1. $ mkdir linux-4.15/drivers/hello 

對于一個驅動來說,最重要的就是3個文件:

  1. 源代碼
  2. Kconfig
  3. Makefile

只要按照固定的格式來編寫這3個文件,linux內核的編譯腳本就可以確保把我們的驅動程序編譯進去。

創建源文件

首先是源碼,在hello文件夾中創建源文件 hello.c:

  1. $ cd linux-4.15/drivers/hello 
  2. $ touch hello.c 

源文件hello.c的內容是:

  1. #include <linux/module.h> 
  2. #include <linux/init.h> 
  3.  
  4. // 當驅動被加載的時候,執行此函數 
  5. static int __init hello_init(void) 
  6.     printk(KERN_ALERT "welcome, hello"\n"); 
  7.     return 0; 
  8.  
  9. // 當驅動被卸載的時候,執行此函數 
  10. static void __exit hello_exit(void) 
  11.     printk(KERN_ALERT "bye, hello\n"); 
  12.  
  13. // 版權聲明 
  14. MODULE_LICENSE("GPL"); 
  15.  
  16. // 以下兩個函數屬于 Linux 的驅動框架,只要把驅動兩個函數地址注冊進去即可。 
  17. module_init(hello_init); 
  18. module_exit(hello_exit); 

有兩個小地方注意一下:

  1. 在內核中,打印函數是 printk,而不是 printf;
  2. 打印信息的級別有好幾個,從 DEBUG 到 EMERG,這里使用的是 KERN_ALERT,方便查看打印信息。

創建 Kconfig 文件

這個文件是用來對內核進行配置的,當執行 make menuconfig 指令的時候,這個文件就被解析。

先創建文件:

  1. $ cd linux-4.15/drivers/hello 
  2. $ touch Kconfig 

添加如下內容:

  1. config HELLO 
  2. tristate "hello driver" 
  3. help 
  4.   just a simplest driver. 
  5. default y 

第一行內容 config HELLO ,在執行配置的時候,將會生成一個變量 CONFIG_HELLO ,而這個變量,將會在編譯的時候,被 Makefile 引用。

最后一行的 default y ,就表示把 CONFIG_HELLO 的值設置成 y,從而讓這個驅動被編譯到內核中。

現在,hello驅動中的KConfig配置文件已經準備好了,但是還需要這個配置文件登記到 Linux 內核的整體配置文件中。

也就是把它登記在 linux-4.15/drivers/Kconfig 文件的末尾:

  1. source "drivers/hello/Kconfig" 
  2.  
  3. endmenu   // 加在這一句的上面 

現在,可以來執行下面指令,看一下具體的配置界面:

  1. $ cd linux-4.15/ 
  2. $ make distclean 
  3. $ make ARCH=x86_64 defconfig 
  4. $ make ARCH=x86_64 menuconfig 

第2條指令,是用來把默認的配置保存到當前目錄下的 .config 配置文件,也就是把一個默認的配置文件復制過來,作為我們自己的配置文件。

以后再修改配置參數時,修改的內容就會存儲在 .config 文件中,

第3條指令,是用來配置內核的,可以進入 Device Drivers 菜單,然后在最底層看到我們的 hello driver 被標記成星號, 這表示被編譯進內核。

按向下方向鍵,把高亮定位到 Device Drivers ---> ,然后敲回車鍵,進入到 Device Drivers 的配置界面。

按向下方向鍵,一直到最后一個條目,就可以看到我們的 hello 驅動了,如下:

可以看到 hello driver 前面顯示的是型號 *,這表示:該驅動將會編譯進內核。

我們可以按下空格鍵試一下,會在三種標記中切換:型號,M,空值。M 標記意思是編譯成驅動模塊。

我們這里選擇星號(編譯進內核),然后按下右方向鍵,最下方的幾個按鍵的焦點移動到按鈕上:

按下回車鍵,就會彈出保存對話框,選擇默認保存文件 .config 即可,然后在按鈕高亮的時候,按下回車鍵即可保存。

此時,在彈出的確認窗口中,選擇 ,按下回車鍵即可:

此時,返回到 Device Drivers 的配置界面,在最下面的按鈕中,選擇讓 高亮,然后一路退出即可。

創建 Makefile 文件

Makefile 文件是make工具的腳本,首先創建它:

  1. $ cd linux-4.15/drivers/hello 
  2. $ touch Makefile 

其中的內容只有一行:

  1. obj-$(CONFIG_HELLO) += hello.o 
  1. CONFIG_HELLO 可以看做一個變量,在編譯的時候,這個變量的值可能是:y, n 或者 m。
  2. 在剛才的 Kconfig 參數配置中,CONFIG_HELLO 被設置為 y,于是這句話就被翻譯成:obj-y += hello,表示把 hello 驅動編譯進內核。

現在,hello驅動程序的Makefile已經創建好了,我們還要讓linux內核的編譯框架知道這個文件才行。

在文件 linux-4.15/drivers/Makefile 中的末尾,添加如下內容:

  1. obj-$(CONFIG_HELLO)    += hello/ 

編譯

萬事俱備,只欠編譯!依次執行如下指令:

  1. $ cd linux-4.15/ 
  2. $ make -j4 

make指令執行結束之后,編譯得到的內核中(vmlinux)就包含了我們的hello驅動。

編譯為驅動模塊

編譯為驅動模塊,也有兩種 操作方式:

編譯所有的驅動模塊

  1. 在執行 make ARCH=x86_64 menuconfig 指令的時候,把 hello 配置成 M;
  2. 然后在 linux-4.15 中執行編譯模塊指令:make -j4 modules。

編譯成功之后,就可以得到文件: linux-4.15/drivers/hello/hello.ko。

這樣的編譯指令,是把所有的模塊都編譯了一次(在輸出信息中,可以看到編譯了很多模塊)。

只編譯 hello 這一個驅動模塊

另外一種編譯驅動模塊的方式是:進入hello目錄,只編譯這一個驅動模塊。

這種編譯方法,就需要修改hello目錄下的Makefile文件了,內容如下:

可以把 hello 目錄下的所有文件刪除,只保留源文件 hello.c,然后新建 Makefile 文件。

  1. ifneq ($(KERNELRELEASE),) 
  2.         obj-m := hello.o 
  3. else 
  4.         KERNELDIR ?= /lib/modules/$(shell uname -r)/build 
  5.         PWD := $(shell pwd) 
  6. default
  7.         $(MAKE) -C $(KERNELDIR) M=$(PWD) modules 
  8. clean: 
  9.         $(MAKE) -C $(KERNEL_PATH) M=$(PWD) clean 
  10. endif 

然后,在hello文件夾中執行make指令,即可得到驅動模塊 hello.ko 。

驗證一下

加載驅動:

  1. $ cd linux-4.15/drivers/hello 
  2. $ sudo insmod ./hello.ko 

此時終端窗口是沒有任何輸出的,需要輸入指令 dmesg | tail ,可以看到 hello_init 函數的輸出內容:

卸載驅動:

  1. $ sudo rmmod hello 

再次輸入 dmesg | tail ,可以看到 hello_exit 函數的輸出內容:

本文轉載自微信公眾號「IOT物聯網小鎮」

 

責任編輯:姜華 來源: IOT物聯網小鎮
相關推薦

2021-11-22 08:14:23

Linux Linux驅動Linux 系統

2018-12-24 10:04:06

Docker存儲驅動

2019-03-05 14:09:27

Docker存儲容器

2019-07-09 15:23:22

Docker存儲驅動

2019-11-04 10:06:19

MySQL索引

2009-07-06 19:29:37

云計算私有云服務器虛擬化

2022-08-29 15:19:09

CSS煙花動畫

2010-07-12 17:10:23

Android應用程序

2019-09-18 07:20:34

深度學習人臉識別人工智能

2017-09-13 09:05:29

iOS11iOS蘋果

2015-05-25 09:51:55

Azure混合云平臺VPN技術

2018-03-07 15:24:41

PythonMySQL

2013-03-18 16:09:27

JavaEEOpenfire

2011-06-07 16:03:48

匿名SQL Server

2013-11-11 13:24:21

cocos2dx 2.Android編譯

2017-09-28 09:40:36

圖像分類準確率

2022-09-30 15:37:19

Web網站服務器

2012-03-22 10:33:33

思杰XenDesktop

2009-12-18 16:27:43

Cisco路由器配置

2017-11-29 11:14:52

離線緩存URL協議緩存
點贊
收藏

51CTO技術棧公眾號

国产精品情趣视频| 中文一区二区在线观看| 日韩一区视频在线| 亚洲成人福利| 不卡的电视剧免费网站有什么| 99中文字幕| 啪啪亚洲精品| 一区二区在线视频| 欧美草逼视频| 欧美一区二区三区影视| 日日噜噜噜夜夜爽爽狠狠| 日本午夜一区二区| 国产一区二中文字幕在线看| 久久精品福利| 欧美二区乱c黑人| 欧美尤物美女在线| 欧美性猛交99久久久久99按摩| 最新地址在线观看| 欧美激情中文字幕一区二区| 中文字幕の友人北条麻妃| 亚洲日本国产| 99九九视频| 人人狠狠综合久久亚洲| 日韩.欧美.亚洲| 日本欧美加勒比视频| 亚洲免费不卡| 成人国产精品免费观看动漫| 日韩最新中文字幕| 亚洲一区中文| 欧美伦理一区二区| 欧美aaa在线| 97超碰人人看人人| 理论电影国产精品| 免费毛片小视频| 91美女福利视频| 99riav视频| 欧美日韩中文字幕在线| 欧美激情图区| 欧美视频在线观看一区二区| 黄av在线播放| 亚洲人免费视频| 久久综合社区| 国产精品专区h在线观看| 一区二区三区午夜视频| 国产区一区二区| www.欧美日韩国产在线| 性欧美xxx69hd高清| 久久久av亚洲男天堂| 久久久一本精品99久久精品66 | 黄色网址在线免费| 亚洲欧美一区二区三区久久 | 国产成人精品综合在线观看| 日本va中文字幕| 一本色道久久综合精品竹菊| 免费福利在线视频| 一本一本久久a久久精品综合小说| 精品久久97| 久久这里只有精品18| 一个色在线综合| 中文字幕中文字幕在线中高清免费版| 精品国偷自产在线| 亚洲五月婷婷| 免费在线观看毛片网站| 在线电影欧美成精品| 青青一区二区| 国产91视频一区| 精品福利在线看| 偷拍精品精品一区二区三区| 国产精品久久久久久婷婷天堂 | 国产在线视频2019最新视频| 亚洲自拍偷拍麻豆| 国产精品影片在线观看| av爱爱亚洲一区| xvideos.蜜桃一区二区| 久久久精品国产一区二区三区| 亚洲一区二区三区在线播放| 2022成人影院| 国产精品igao激情视频| 欧美日韩你懂得| 在线日韩av| 北岛玲一区二区三区| 久久成人资源| 精品日本一线二线三线不卡| 欧美a级片网站| 最新中文字幕在线观看| 国产999在线| 狠狠狠综合7777久夜色撩人| 亚洲美女自拍视频| av福利精品导航| 日本午夜大片a在线观看| 久久久久久亚洲精品不卡4k岛国| 日韩一区二区三区av| 99riav1国产精品视频| 天堂资源中文在线| 国产欧美日韩精品在线观看| 亚洲精品免费在线播放| 欧洲亚洲精品| 亚洲欧美激情网| 国产成人a亚洲精品| 亚洲综合另类小说| 亚洲先锋成人| 成人看片在线观看| 国产美女极品在线| 久久综合亚洲精品| 91亚洲国产成人精品性色| 欧美二区三区91| 久久综合国产精品| 日本强好片久久久久久aaa| 精品国产一区二区三区噜噜噜 | 成人av综合一区| 欧美国产偷国产精品三区| 欧美性孕妇孕交| 黄色99视频| 国产精品视频久久| 成人信息集中地欧美| 91亚洲精华国产精华| 国产精品无av码在线观看| 91精品国产自产91精品| 98精品国产高清在线xxxx天堂| 欧美亚洲国产成人精品| 国产深夜精品福利| 国产精品亚发布| 91黑丝高跟在线| 国产aaa精品| 国产精品丝袜高跟| 国产精品国产一区二区| 国产精品一区二区你懂得| 91国内揄拍国内精品对白| 91chinesevideo永久地址| 国产中文字幕亚洲| 日本不卡一区二区三区在线观看| 久久亚裔精品欧美| 天堂资源在线亚洲资源| 黑人巨大精品欧美一区二区小视频| 国产成人自拍视频在线观看| 57pao国产成人免费| 国产精品久久久久一区二区| 精品一卡二卡三卡四卡日本乱码| 不卡中文字幕在线| 国产野外作爱视频播放| 日本三级视频在线观看| 国产a亚洲精品| 一二三区精品| 夜夜嗨av一区二区三区| 中文字幕亚洲一区在线观看| 91国产在线播放| www.99re.av| 成人一级视频| 777午夜精品电影免费看| 最近中文字幕在线中文视频| 首播影院在线观看免费观看电视| 国产无遮挡又黄又爽免费网站| 国产小视频精品| 超碰在线人人爱| 播放灌醉水嫩大学生国内精品| 亚洲看片网站| 亚洲女人被黑人巨大进入| 伦伦影院午夜日韩欧美限制| 国产精品普通话| 久久久久欧美| 蜜臀久久99精品久久久酒店新书| 成人福利影院| 成人动漫在线播放| 97欧美成人| 国产精品亚洲人成在99www| 国产精品二区不卡| 另类的小说在线视频另类成人小视频在线 | www.日本在线播放| 婷婷丁香六月天| 欧美人与禽性xxxxx杂性| 96sao在线精品免费视频| 中文无码久久精品| 国产99精品在线观看| 香蕉加勒比综合久久| 精品视频—区二区三区免费| 国产精品视频久久久久| 亚洲精品一区二区三区樱花| 欧美成人三级在线播放| 免费在线观看av| 亚洲综合福利| 韩国av一区二区三区在线观看| 午夜久久久久久电影| 日韩在线激情视频| 91国产在线免费观看| 中文字幕在线观看第三页| eeuss鲁一区二区三区| 精品日本12videosex| 成人毛片在线观看| 欧美日韩国产欧美日美国产精品| 久久久久免费精品国产| www.激情网| 亚洲欧美在线成人| 久久电影国产免费久久电影| 在线免费不卡电影| 92看片淫黄大片看国产片| 日本福利片免费看| 欧美变态网站| 亚洲日本中文字幕区| 日本久久精品视频| 中国动漫在线观看完整版免费|