Hello world模块

本文介绍如何向内核中添加一个hello模块。该模块的功能是在模块加载时,向系统日志输出“hello world\n” 在模块卸载时输出“Good bye,cruel world!".

一个模块源代码一般有含有一个init函数(加载时调用)和一个exit函数(卸载时调用)。这两个函数由分别由宏module_init和module_exit调用。因而一个简单的Hello world模块源代码如下:


关于MODULE_XXX宏做一个简单介绍:


编译、Makefile

前面我们已经写好了一个简单的hello模块,接下来要对模块进行编译。我们使用Makefile文件

# If KERNELRELEASE is defined, we've been invoked from the                                                               
# kernel build system and can use its language. 
ifneq ($(KERNELRELEASE),) 
    obj-m := hello.o 
# Otherwise we were called directly from the command 
# line; invoke the kernel build system. 
else 
    KERNELDIR ?= /lib/modules/$(shell uname -r)/build  #KERNELDIR赋值,指代内核源代码目录

    PWD := $(shell pwd)  #当前目录
default: 
    $(MAKE) -C $(KERNELDIR) M=$(PWD) modules 
endif 

这是一个很有意思的Makefile脚本,当你在当前目录make的时候,它会执行两次。第一次执行的时候KERNELRELEASE未定义,因而会执行else分支的default目标的命令,即$(MAKE) -C $(KERNELDIR) M=$(PWD) modules .这条命令会进入内核源代码目录,执行内核源代码根目录下的Makefile,根目录下的Makefile会定义KERNELRELEASE,并切换到当前目录,再执行一遍当前目录的Makefile。此时KERNELRELEASE已被定义,因而会执行obj-m := hello.o 这条命令。从而整个依赖关系才完整,生成目标文件hello.ko。

ifeq ($(KERNELRELEASE),)目前,并无用处,它的由来是指在Linux源码根目录下的Makefile编译内核时,KERNELRELEASE宏会被定义,那么如果是从源码根目录开始的make则会将myhello.o模块编译进内核。

$(MAKE) -C $(KERNELDIR) M=$(PWD) modules 是Makefile的规则:这里的$(MAKE)就相当于make,-C 选项的作用是指将当前工作目录转移到你所指定的位置。“M=”选项的作用是,当用户需要以某个内核为基础编译一个外部模块的话,需要在make modules 命令中加入“M=dir”,程序会自动到你所指定的dir目录中查找模块源码,将其编译,生成ko文件。


模块加载:

编译好的模块hello.ko需要加载如内核才能使用。

 而我们的prink输出会写入系统日志,可以通过dmesg查看。

因此我们的测试过程如下:

windeal@ubuntu:driver$ lsmod | grep hello   #确认当前没有加载hello模块
windeal@ubuntu:driver$ sudo insmod hello.ko #加载hello.ko模块
windeal@ubuntu:driver$ dmesg<span style="white-space:pre">			</span>#查看系统日志
[190444.174802] Hello world!
windeal@ubuntu:driver$ lsmod | grep hello<span style="white-space:pre">	</span>#查看是否加载了hello模块
hello                  12449  0 
windeal@ubuntu:driver$ sudo rmmod hello<span style="white-space:pre">		</span>#卸载hello模块
windeal@ubuntu:driver$ dmesg<span style="white-space:pre">			</span>#查看系统日志
[190444.174802] Hello world!
[190487.913667] Good bye, cruel world!
windeal@ubuntu:driver$ lsmod | grep hello<span style="white-space:pre">	</span>#查看模块是否被卸载了
windeal@ubuntu:driver$ 

图:

Linux驱动入门——构建和运行模块














 
 

 

相关文章:

  • 2021-04-12
  • 2021-08-29
  • 2021-08-27
  • 2022-02-06
  • 2021-08-30
  • 2022-02-03
  • 2021-11-13
猜你喜欢
  • 2022-12-23
  • 2021-09-24
  • 2021-10-08
  • 2021-06-01
  • 2022-02-20
  • 2022-12-23
  • 2021-08-21
相关资源
相似解决方案