Linux 简单的Hello World 驱动模块与Makefile编写

我们首先从hello world 开始编写一个驱动模块
既然说模快,肯定有非模块,非模块就是直接编译进内核。
模块具有这样的特点:

  • 模块不会被编译进内核,从而减少了内核image的大小

  • 内核加载后,与内核中其他部分一样

废话不多说,先上代码
hello_world.c

#include 
#include 

MODULE_LICENSE("GPL v2"); //模块许可证声明,如果不声明,加载模块时,会出现内核被污染(kernel tainted)的警告
MODULE_AUTHOR("xl");  //声明模块的作者
MODULE_DESCRIPTION("a simple hello world module");//模块的描述

static char *name = "hello world";  
module_param(name,charp,S_IRUGO); //加载模块时输入的参数


static int __init hello_init(void)
{
        printk("module init\n");
        printk("parameter name is :  %s\n",name);
        return 0;
}

module_init(hello_init);

static void __exit hello_exit(void)
{
        printk("module exit\n");
}

module_exit(hello_exit);

int add(int a, int b)
{
  return a+b;
}
EXPORT_SYMBOL(add);

Makefile

obj-m:=hello_world.o
KDIR:= /lib/modules/4.4.0-171-generic/build  //内核目录
all:
        make -C $(KDIR) M=$(PWD) modules
clean:
        rm -f *.ko *.o *.mod.o *.mod.c *.symvers *.order

当前目录下的文件如下:

root@xl-virtual-machine:/home/xl/linux_codes# ls
hello_world.c  Makefile 

输入make命令进行编译,生成文件如下所示

root@xl-virtual-machine:/home/xl/linux_codes# make
make -C /lib/modules/4.4.0-171-generic/build M=/home/xl/linux_codes modules
make[1]: Entering directory '/usr/src/linux-headers-4.4.0-171-generic'
  CC [M]  /home/xl/linux_codes/hello_world.o
  Building modules, stage 2.
  MODPOST 1 modules
  CC      /home/xl/linux_codes/hello_world.mod.o
  LD [M]  /home/xl/linux_codes/hello_world.ko
make[1]: Leaving directory '/usr/src/linux-headers-4.4.0-171-generic'
root@xl-virtual-machine:/home/xl/linux_codes# ls
hello_world.c   hello_world.mod.c  hello_world.o  modules.order   
hello_world.ko  hello_world.mod.o  Makefile       Module.symvers 
root@xl-virtual-machine:/home/xl/linux_codes# 

hello_world.ko 为生成的驱动文件,使用insmod hello_world.ko命令加载驱动,使用dmesg -c查看输出

root@xl-virtual-machine:/home/xl/linux_codes# insmod hello_world.ko 
root@xl-virtual-machine:/home/xl/linux_codes# dmesg -c
[28411.480284] module init
[28411.480293] parameter name is :  hello world
root@xl-virtual-machine:/home/xl/linux_codes# 

卸载驱动:rmmod hello_world

root@xl-virtual-machine:/home/xl/linux_codes# rmmod hello_world
root@xl-virtual-machine:/home/xl/linux_codes# dmesg -c
[31809.006710] module exit

扩展:
__init和__exit的作用是告诉编译器将这些函数或者数据放入相应的代码段。

使用了__init和__exit,则代码使用的内存会在使用后被释放掉,以节省系统开销。

使用modinfo hello_world.ko查看模块信息,包括作者、说明等

root@xl-virtual-machine:/home/xl/linux_codes# modinfo hello_world.ko 
filename:       /home/xl/linux_codes/hello_world.ko
description:    a simple hello world module
author:         xl
license:        GPL v2
srcversion:     3327DF89233436F0B2F297F
depends:        
retpoline:      Y
vermagic:       4.4.0-171-generic SMP mod_unload modversions 
parm:           name:charp

加载模块时输入参数:insmod hello_world.ko name=xl
如下所示参数name的值变为xl.

root@xl-virtual-machine:/home/xl/linux_codes# insmod hello_world.ko name=xl
root@xl-virtual-machine:/home/xl/linux_codes# dmesg -c
[32640.753793] module init
[32640.753806] parameter name is :  xl

导出符号
EXPORT_SYMBOL()导出符号到内核符号表,导出的符号可以被其它模块使用,其它模块使用时只需要声明一下即可。
在/proc/kallsyms中记录了符号以及符号所在的内存地址。

root@xl-virtual-machine:/home/xl/linux_codes# grep hello_add /proc/kallsyms 
ffffffffc0427087 r __kstrtab_hello_add	[hello_world]
ffffffffc0427040 r __kcrctab_hello_add	[hello_world]
ffffffffc0427030 r __ksymtab_hello_add	[hello_world]
ffffffffc0426000 T hello_add	[hello_world]

你可能感兴趣的:(Linux 简单的Hello World 驱动模块与Makefile编写)