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

【Linux】【Kernel】一个简单的内核模块例子的更多相关文章

  1. 一个简单的CORBA例子

    因为对CORBA分析的需要,这里写一个简单的CORBA例子.从JDK1.2开始,JDK中集成了ORB的实现,本例子使用了JDK1.7,对于JDK1.2+应该都没有问题.这个例子实现一个简单的加减乘除的 ...

  2. Linux下一个简单的日志系统的设计及其C代码实现

    1.概述 在大型软件系统中,为了监测软件运行状况及排查软件故障,一般都会要求软件程序在运行的过程中产生日志文件.在日志文件中存放程序流程中的一些重要信息, 包括:变量名称及其值.消息结构定义.函数返回 ...

  3. 轻松创建nodejs服务器(1):一个简单nodejs服务器例子

    这篇文章主要介绍了一个简单nodejs服务器例子,本文实现了一个简单的hello world例子,并展示如何运行这个服务器,需要的朋友可以参考下   我们先来实现一个简单的例子,hello world ...

  4. 使用Multiplayer Networking做一个简单的多人游戏例子-3/3(Unity3D开发之二十七)

    使用Multiplayer Networking做一个简单的多人游戏例子-1/3 使用Multiplayer Networking做一个简单的多人游戏例子-2/3 使用Multiplayer Netw ...

  5. 使用Multiplayer Networking做一个简单的多人游戏例子-2/3(Unity3D开发之二十六)

    猴子原创,欢迎转载.转载请注明: 转载自Cocos2Der-CSDN,谢谢! 原文地址: http://blog.csdn.net/cocos2der/article/details/51007512 ...

  6. 使用Multiplayer Networking做一个简单的多人游戏例子-1/3(Unity3D开发之二十五)

    猴子原创,欢迎转载.转载请注明: 转载自Cocos2Der-CSDN,谢谢! 原文地址: http://blog.csdn.net/cocos2der/article/details/51006463 ...

  7. 一个简单的cmake例子

    一个简单的cmake例子CMakeLists.txt,生成动态库文件,可以指定发布目录. 尚不支持: 1.交叉编译环境配置 2.添加依赖库   #在当前目录新建一个build目录,然后cd build ...

  8. [转帖] Linux 创建一个简单的私有CA、发证、吊销证书

    原创帖子地址:   https://blog.csdn.net/mr_rsq/article/details/71001810 Linux 创建一个简单的私有CA.发证.吊销证书 2017年04月30 ...

  9. Linux C 一个简单的线程池程序设计

    最近在学习linux下的编程,刚开始接触感觉有点复杂,今天把线程里比较重要的线程池程序重新理解梳理一下. 实现功能:创建一个线程池,该线程池包含若干个线程,以及一个任务队列,当有新的任务出现时,如果任 ...

随机推荐

  1. 2018-2019-2 网络对抗技术 20165303 Exp6 信息搜集与漏洞扫描

    实践内容 (1)各种搜索技巧的应用 (2)DNS IP注册信息的查询 (3)基本的扫描技术:主机发现.端口扫描.OS及服务版本探测.具体服务的查点(以自己主机为目标) (4)漏洞扫描:会扫,会看报告, ...

  2. SQLserver提示事务日志已满无法重建索引,前台提示日志已满处理方案

    1.数据库--属性--选项--恢复模式:简单. 2.数据库--任务--文件类型:日志                            在释放未使用的空间潜重新组织页:1M 3.数据库--属性-- ...

  3. pycharm配置QtDesigner

    QtDesigner C:\Qt\Qt5.12.2\5.12.2\mingw73_64\bin\designer.exe $ProjectFileDir$ Pyuic C:\Anaconda3\pyt ...

  4. python 编码 自动加双斜杠问题

    小编最近在进行utf-8转码的时候,遇到一个问题: 当其他编码中含有斜杆,如: 当取出该字符串时,会自动把斜杆转换成双斜杠 导致转码报错: 这时候可以在转码的时候加上,即可转换成功了 .decode( ...

  5. .net core 获取本地ip及request请求端口

    1.获取ip和端口 string str = (Request.HttpContext.Connection.LocalIpAddress.MapToIPv4().ToString() + " ...

  6. [LeetCode] 80. Remove Duplicates from Sorted Array II ☆☆☆(从有序数组中删除重复项之二)

    https://leetcode.com/problems/remove-duplicates-from-sorted-array-ii/discuss/27976/3-6-easy-lines-C% ...

  7. ssh-keygen公钥进行免登

    A服务器地址:192.168.1.200,下面简称A B服务器地址:192.168.1.201,下面简称B 1.在A生成密钥对ssh-keygen -t rsa -P ""1执行上 ...

  8. android studio 编辑markdown文件

    作为开发人员,对markdown应该比较熟悉,我们在Android开始中,可以使用studio引入Markdown Navigator插件,进行编辑. 搜索 Markdown Navigator 安装 ...

  9. ThinkPHP部署在lnmp环境中碰到的问题

    先说一下问题: 因为tp5的入口文件在public目录下,而Application和public同级, 我用的lnmp1.5默认做了防跨站目录设置,所以导致入口文件无法进入application目录, ...

  10. Jeecg

    姓名:黄于霞          班级:软件151 1.第一步将Jeecg引包到javaEE中,如图下图所示: 2.第二步改jeecg_config.properties中的用户名和密码改成和数据库中一 ...