【Linux】【Kernel】一個簡單的內核模塊例子

来源:https://www.cnblogs.com/k030941503/archive/2018/07/31/9397219.html
-Advertisement-
Play Games

1.本地主機的參數 zhangjun@zhangjun-virtual-machine:~$ uname -a Linux zhangjun-virtual-machine 4.4.0-31-generic #50~14.04.1-Ubuntu SMP Wed Jul 13 01:07:32 UTC ...


 

1.本地主機的參數

zhangjun@zhangjun-virtual-machine:~$ uname -a

Linux zhangjun-virtual-machine 4.4.0-31-generic #50~14.04.1-Ubuntu SMP Wed Jul 13 01:07:32 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux

zhangjun@zhangjun-virtual-machine:~$ ls /usr/src/linux-headers-4.4.0-31-generic/arch    Documentation  include  Kconfig   mm              scripts   tools   zfs

block   drivers        init     kernel    Module.symvers  security  ubuntu

certs   firmware       ipc      lib       net             sound     usr

crypto  fs             Kbuild   Makefile  samples         spl       virt

 

2.編寫內核模塊文件

編寫自己的內核模塊文件myModule.c,內容如下:

#include  <linux/kernel.h>

#include <linux/module.h>

#include <linux/types.h>

static int __init myModule_init(void)

{

    printk(KERN_INFO"myModule init.\r\n");

        return 0;

}

 

static void __exit myModule_exit(void)

{

    printk(KERN_INFO"myModule exit.\r\n");

}

module_init(myModule_init);

module_exit(myModule_exit);

MODULE_LICENSE("GPL");

 

3.編寫Makefile

#kernel代碼的路徑

KERN_DIR = /usr/src/linux-headers-4.4.0-31-generic/   

all:

         make -C $(KERN_DIR) M=`pwd` modules   

clean:   

         make -C $(KERN_DIR) M=`pwd` modules clean   

obj-m += myModule.o

4.編譯

root@zhangjun-virtual-machine:/home/zhangjun/zj_driver/myModule# make

make -C /usr/src/linux-headers-4.4.0-31-generic/     M=`pwd` modules   

make[1]: 正在進入目錄 `/usr/src/linux-headers-4.4.0-31-generic'

  CC [M]  /home/zhangjun/zj_driver/myModule/myModule.o

  Building modules, stage 2.

  MODPOST 1 modules

  CC      /home/zhangjun/zj_driver/myModule/myModule.mod.o

  LD [M]  /home/zhangjun/zj_driver/myModule/myModule.ko

make[1]:正在離開目錄 `/usr/src/linux-headers-4.4.0-31-generic'

 

5.安裝驅動

root@zhangjun-virtual-machine:/home/zhangjun/zj_driver/myModule# insmod myModule.ko

root@zhangjun-virtual-machine:/home/zhangjun/zj_driver/myModule# cat /proc/modules

myModule 16384 0 - Live 0xffffffffc03d4000 (OE)

nls_utf8 16384 1 - Live 0xffffffffc016f000

isofs 40960 1 - Live 0xffffffffc03f4000

vmw_vsock_vmci_transport 28672 1 - Live 0xffffffffc03cc000

vsock 36864 2 vmw_vsock_vmci_transport, Live 0xffffffffc0165000

bnep 20480 2 - Live 0xffffffffc0178000

rfcomm 69632 8 - Live 0xffffffffc050b000

nfsd 315392 13 - Live 0xffffffffc05e4000

auth_rpcgss 57344 1 nfsd, Live 0xffffffffc0542000

nfs_acl 16384 1 nfsd, Live 0xffffffffc038b000

nfs 249856 0 - Live 0xffffffffc05a6000

binfmt_misc 20480 1 - Live 0xffffffffc0393000

lockd 90112 2 nfsd,nfs, Live 0xffffffffc052b000

grace 16384 2 nfsd,lockd, Live 0xffffffffc0386000

sunrpc 331776 19 nfsd,auth_rpcgss,nfs_acl,nfs,lockd, Live 0xffffffffc04b9000

fscache 61440 1 nfs, Live 0xffffffffc04a9000

coretemp 16384 0 - Live 0xffffffffc03c7000

kvm_intel 167936 0 - Live 0xffffffffc057c000

kvm 532480 1 kvm_intel, Live 0xffffffffc0426000

snd_ens1371 28672 2 - Live 0xffffffffc0365000

snd_ac97_codec 131072 1 snd_ens1371, Live 0xffffffffc0405000

irqbypass 16384 1 kvm, Live 0xffffffffc0381000

crct10dif_pclmul 16384 0 - Live 0xffffffffc037c000

gameport 16384 1 snd_ens1371, Live 0xffffffffc0373000

crc32_pclmul 16384 0 - Live 0xffffffffc034b000

ac97_bus 16384 1 snd_ac97_codec, Live 0xffffffffc0400000

snd_pcm 106496 2 snd_ens1371,snd_ac97_codec, Live 0xffffffffc03d9000

aesni_intel 167936 0 - Live 0xffffffffc039d000

vmw_balloon 20480 0 - Live 0xffffffffc036d000

snd_seq_midi 16384 0 - Live 0xffffffffc0360000

snd_seq_midi_event 16384 1 snd_seq_midi, Live 0xffffffffc035b000

aes_x86_64 20480 1 aesni_intel, Live 0xffffffffc0355000

lrw 16384 1 aesni_intel, Live 0xffffffffc0321000

gf128mul 16384 1 lrw, Live 0xffffffffc0350000

snd_rawmidi 32768 2 snd_ens1371,snd_seq_midi, Live 0xffffffffc0342000

glue_helper 16384 1 aesni_intel, Live 0xffffffffc033d000

ablk_helper 16384 1 aesni_intel, Live 0xffffffffc0277000

cryptd 20480 2 aesni_intel,ablk_helper, Live 0xffffffffc031b000

joydev 20480 0 - Live 0xffffffffc0315000

input_leds 16384 0 - Live 0xffffffffc0307000

serio_raw 16384 0 - Live 0xffffffffc0233000

snd_seq 69632 2 snd_seq_midi,snd_seq_midi_event, Live 0xffffffffc032b000

snd_seq_device 16384 3 snd_seq_midi,snd_rawmidi,snd_seq, Live 0xffffffffc0326000

snd_timer 32768 2 snd_pcm,snd_seq, Live 0xffffffffc030c000

btusb 45056 0 - Live 0xffffffffc02fb000

btrtl 16384 1 btusb, Live 0xffffffffc0272000

btbcm 16384 1 btusb, Live 0xffffffffc0160000

btintel 16384 1 btusb, Live 0xffffffffc0145000

bluetooth 516096 25 bnep,rfcomm,btusb,btrtl,btbcm,btintel, Live 0xffffffffc027c000

snd 81920 11 snd_ens1371,snd_ac97_codec,snd_pcm,snd_rawmidi,snd_seq,snd_seq_device,snd_timer, Live 0xffffffffc021e000

soundcore 16384 1 snd, Live 0xffffffffc006b000

nfit 32768 0 - Live 0xffffffffc01f0000

vmwgfx 229376 3 - Live 0xffffffffc0239000

ttm 94208 1 vmwgfx, Live 0xffffffffc01d8000

drm_kms_helper 143360 1 vmwgfx, Live 0xffffffffc01fa000

drm 360448 6 vmwgfx,ttm,drm_kms_helper, Live 0xffffffffc017f000

shpchp 36864 0 - Live 0xffffffffc0156000

fb_sys_fops 16384 1 drm_kms_helper, Live 0xffffffffc0151000

syscopyarea 16384 1 drm_kms_helper, Live 0xffffffffc014c000

vmw_vmci 65536 2 vmw_vsock_vmci_transport,vmw_balloon, Live 0xffffffffc0134000

sysfillrect 16384 1 drm_kms_helper, Live 0xffffffffc00fc000

sysimgblt 16384 1 drm_kms_helper, Live 0xffffffffc00b8000

i2c_piix4 24576 0 - Live 0xffffffffc0120000

8250_fintek 16384 0 - Live 0xffffffffc00f7000

parport_pc 36864 0 - Live 0xffffffffc00ae000

ppdev 20480 0 - Live 0xffffffffc0065000

mac_hid 16384 0 - Live 0xffffffffc003d000

lp 20480 0 - Live 0xffffffffc0043000

parport 49152 3 parport_pc,ppdev,lp, Live 0xffffffffc0030000

hid_generic 16384 0 - Live 0xffffffffc004d000

usbhid 49152 0 - Live 0xffffffffc0127000

hid 118784 2 hid_generic,usbhid, Live 0xffffffffc0102000

psmouse 122880 0 - Live 0xffffffffc00d8000

mptspi 24576 2 - Live 0xffffffffc00cd000

mptscsih 40960 1 mptspi, Live 0xffffffffc00be000

mptbase 102400 2 mptspi,mptscsih, Live 0xffffffffc0072000

e1000 135168 0 - Live 0xffffffffc008c000

scsi_transport_spi 32768 1 mptspi, Live 0xffffffffc0052000

ahci 36864 1 - Live 0xffffffffc005b000

libahci 32768 1 ahci, Live 0xffffffffc0027000

pata_acpi 16384 0 - Live 0xffffffffc000f000

fjes 28672 0 - Live 0xffffffffc001f000

vmw_pvscsi 24576 0 - Live 0xffffffffc0014000

vmxnet3 57344 0 - Live 0xffffffffc0000000

安裝驅動應該會調用myModule_init函數,那麼應該有列印輸出,但是實際上沒有;

 

6.卸載驅動

root@zhangjun-virtual-machine:/home/zhangjun/zj_driver/myModule# rmmod myModule.ko

 

7.模塊安裝時的列印

步驟5在安裝myModule.ko的時候終端上並沒有列印出信息,但是實際上列印的信息寫入文件/var/log/kern.log,可以通過tail命令查看該文件最後的條目。

root@zhangjun-virtual-machine:/home/zhangjun/zj_driver/myModule# tail -f /var/log/kern.log

Jan 15 11:17:16 zhangjun-virtual-machine kernel: [ 5755.442589] myModule: module verification failed: signature and/or required key missing - tainting kernel

Jan 15 11:17:16 zhangjun-virtual-machine kernel: [ 5755.448875] myModule init.

Jan 15 11:21:12 zhangjun-virtual-machine kernel: [ 5991.177018] myModule exit.

 

8.關於printk函數

Linux 內核中通過printk輸出信息,信息的類型在文件/usr/src/ linux-headers-4.4.0-31-generic /include/linux/printk.h中(有些源碼在文件include\linux\kernel.h中)定義。

/*

 * These can be used to print at the various log levels.

 * All of these will print unconditionally, although note that pr_debug()

 * and other debug macros are compiled out unless either DEBUG is defined

 * or CONFIG_DYNAMIC_DEBUG is set.

 */

#define pr_emerg(fmt, ...) \

         printk(KERN_EMERG pr_fmt(fmt), ##__VA_ARGS__)

#define pr_alert(fmt, ...) \

         printk(KERN_ALERT pr_fmt(fmt), ##__VA_ARGS__)

#define pr_crit(fmt, ...) \

         printk(KERN_CRIT pr_fmt(fmt), ##__VA_ARGS__)

#define pr_err(fmt, ...) \

         printk(KERN_ERR pr_fmt(fmt), ##__VA_ARGS__)

#define pr_warning(fmt, ...) \

         printk(KERN_WARNING pr_fmt(fmt), ##__VA_ARGS__)

#define pr_warn pr_warning

#define pr_notice(fmt, ...) \

         printk(KERN_NOTICE pr_fmt(fmt), ##__VA_ARGS__)

#define pr_info(fmt, ...) \

         printk(KERN_INFO pr_fmt(fmt), ##__VA_ARGS__)

如果不指定,預設是 DEFAULT_MESSAGE_LOGLEVE,和KERN_WARNING一樣。 
root@vickytong:/usr/src/ linux-headers-4.4.0-31-generic# find . -name “*.h” | xargs grep “DEFAULT_MESSAGE_LOGLEVE”

./include/generated/autoconf.h: #define CONFIG_MESSAGE_LOGLEVEL_DEFAULT 4

 

9.交叉編譯

有時候我們需要將模塊移植到其他晶元方案的主機(或開發板)上運行,那麼需要交叉編譯。交叉編譯需要修改Makefile,主要是修改kernel代碼的路徑和編譯工具。kernel代碼的路徑要修改為目的主機系統的源代碼路徑,編譯工具gcc要修改為目的主機晶元架構對應的編譯工具。 設置編譯器,與編譯內核用的編譯器要一致。下麵為編譯驅動時,在terminal終端設置環境變數如下:

root@zhangjun-virtual-machine:/home/zhangjun/zj_driver/myModule# source /opt/Xilinx/SDK/2015.4/settings64.sh

 

root@zhangjun-virtual-machine:/home/zhangjun/zj_driver/myModule# export ARCH=arm

 

root@zhangjun-virtual-machine:/home/zhangjun/zj_driver/myModule#  export CROSS_COMPILE=arm-xilinx-linux-gnueabi-

 

說明:在目前ZedBoard上跑的linux系統,使用該編譯器似乎也能編譯驅動插入到內核中去(後面做gpio驅動時仔細驗證):

root@zhangjun-virtual-machine:/home/zhangjun/zj_driver/myModule# export ARCH=arm

 

root@zhangjun-virtual-machine:/home/zhangjun/zj_driver/myModule#  export CROSS_COMPILE= arm-linux-gnueabihf-

 


makefile文件修改如下:

#kernel代碼的路徑

KERN_DIR = /home/zhangjun/linux 

obj-m := myModule.o

all:

     make -C $(KERN_DIR) ARCH=arm M=`pwd` modules 

clean:     

     rm -rf .*.cmd *.o *.mod.c *.ko .tmp_versions

 

 

10.下載、安裝和卸載

         在Zedboard上的linux掛在nfs,在Terminal上做如下操作:

analog@analog:~$ sudo mount -t nfs 192.168.0.25:/home/zhangjun /mnt/

mount.nfs: /mnt is busy or already mounted

analog@analog:~$ cd /mnt

analog@analog:/mnt$ cd zj_driver

analog@analog:/mnt/zj_driver$ ls

driver_demo  myModule

analog@analog:/mnt/zj_driver$ cd myModule

analog@analog:/mnt/zj_driver/myModule$ ls

Makefile   Module.symvers  myModule.c   myModule.ko     myModule.mod.o

Makefile~  modules.order   myModule.c~  myModule.mod.c  myModule.o

analog@analog:/mnt/zj_driver/myModule$ insmod myModule.ko

insmod: ERROR: could not insert module myModule.ko: Operation not permitted

analog@analog:/mnt/zj_driver/myModule$ sudo su

root@analog:/mnt/zj_driver/myModule# insmod myModule.ko

root@analog:/mnt/zj_driver/myModule# cat /proc/modules

myModule 737 0 - Live 0xbf000000 (O)

root@analog:/mnt/zj_driver/myModule# rmmod myModule.ko

 

11.添加模塊參數

有時候需要從用戶態傳參數給內核模塊,這時候在內核模塊中需要通過巨集module_param聲明參數。本例增加兩個參數,一個是字元串參數cString,一個是int型參數iInt,修改後代碼如下:

#include <linux/kernel.h>

#include <linux/module.h>

#include <linux/types.h>

 

static char* cString = NULL;

static int iInt = 0;

module_param(cString, charp, 0644);

module_param(iInt, int, 0644);

 

static int __init myModule_init(void)

{

    printk(KERN_INFO"myModule init, cString = %s, iInt = %d\r\n", cString, iInt);

    return 0;

}

 

static void __exit myModule_exit(void)

{

    printk(KERN_INFO"myModule exit.\r\n");

}

module_init(myModule_init);

module_exit(myModule_exit);

MODULE_LICENSE("GPL");

 

交叉編譯後,下載,安裝命令如下:

/tmp # insmod myModule.ko cString=helloworld iInt=100 
myModule init, cString = helloworld, iInt = 100

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • Dictionary<string, string>是一個泛型,什麼是泛型?使用泛型下麵是用泛型來重寫上面的棧,用一個通用的數據類型T來作為一個占位符,等待在實例化時用一個實際的類型來代替。讓我們來看看泛型的威力: public class Stack<T> { private T[] m_item ...
  • 1. 概念: WFI(Wait for interrupt)和WFE(Wait for event)是兩個讓ARM核進入low power standby模式的指令,由ARM architecture定義,由ARM core實現。 2. WFI和WFE 2.1 相同點 WFI和WFE的功能非常類似, ...
  • 字元串是shell編程中最常用最有用的數據類型(除了數字和字元串,也沒啥其它類型好用了),字元串可以用單引號,也可以用雙引號,也可以不用引號。 但是單引號和雙引號是有區別的: 單引號: 單引號里的任何字元都會原樣輸出,單引號字元串中的變數是無效的; 單引號字串中不能出現單獨一個的單引號(對單引號使用 ...
  • 1.ansible的安裝 1)使用源碼安裝Python3.5 安裝支持包 yum -y install lrzsz vim net-tools gcc gcc-c++ ncurses ncurses-devel unzip zlib-devel zlib openssl-devel openssl ...
  • 在Shell里存在的一些特殊變數:$!、$@、$#、$$、$*、$0、$n、$_、$? [root@shell ~]# sh shell.sh aaa bbb ccc$0 獲取當前執行的shell腳本的文件名:shell.sh$n 獲取當前執行的shell腳本的第n個參數值,n=1..9:$1=aa ...
  • [TOC] 1. 前期預備知識 1.1 串口通訊電路圖 ![image_1bqjjhr9leo112efe02df51fp.png 25kB][1] 從上圖可見,CC2530晶元通過P0埠的P0.1和P0.2引腳進行串口通訊。這個實驗當中對於埠的操作也主要就是P0埠。 1.2 實驗相關寄存器 ...
  • [TOC] 1.前期預備知識 1.1 新大陸ZigBee模塊LED燈電路 ![image_1bq999vhb104s1v6249bq031jjg9.png 32.1kB][1] 從上兩的兩個電路可知 1.LED1連接在LED LINK上,而LED LINK是從CC2530晶元的P1.0埠引出,同樣 ...
  • Zookeeper+Kafka的單節點standalone配置 環境描述:Ubuntu16.04 server系統,在系統上搭建Java環境,jdk的版本為1.8或更高,我的伺服器IP地址為192.168.0.106。 1.使用命令mkdir /opt/data在opt目錄下創建data目錄。 2. ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...