linux驱动

模块编程


模块init&exit 宏

  • module_init 在初始化或模块insert时调用, 定义模块入口函数
/**
 * module_init() - driver initialization entry point
 * @x: function to be run at kernel boot time or module insertion
 *
 * module_init() will either be called during do_initcalls() (if
 * builtin) or at module insertion time (if a module).  There can only
 * be one per module.
 */
#define module_init(x)  __initcall(x);
  • module_exit模块退出时调用, 定义模块退出时的清理函数
/**
 * module_exit() - driver exit entry point
 * @x: function to be run when driver is removed
 *
 * module_exit() will wrap the driver clean-up code
 * with cleanup_module() when used with rmmod when
 * the driver is a module.  If the driver is statically
 * compiled into the kernel, module_exit() has no effect.
 * There can only be one per module.
 */
#define module_exit(x)  __exitcall(x);

Licensing and Module Documentation

  • MODULE_LICENSE 通过license可以提醒用户模块是否开源
/*
 * The following license idents are currently accepted as indicating free
 * software modules
 *
 *  "GPL"               [GNU Public License v2 or later]
 *  "GPL v2"            [GNU Public License v2]
 *  "GPL and additional rights" [GNU Public License v2 rights and more]
 *  "Dual BSD/GPL"          [GNU Public License v2
 *                   or BSD license choice]
 *  "Dual MIT/GPL"          [GNU Public License v2
 *                   or MIT license choice]
 *  "Dual MPL/GPL"          [GNU Public License v2
 *                   or Mozilla license choice]
 *
 * The following other idents are available
 *
 *  "Proprietary"           [Non free products]
 *
 * There are dual licensed components, but when running with Linux it is the
 * GPL that is relevant so this is a non issue. Similarly LGPL linked with GPL
 * is a GPL combined work.
 *
 * This exists for several reasons
 * 1.   So modinfo can show license info for users wanting to vet their setup
 *  is free
 * 2.   So the community can ignore bug reports including proprietary modules
 * 3.   So vendors can do likewise based on their own policies
 */
#define MODULE_LICENSE(_license) MODULE_INFO(license, _license)
  • MODULE_AUTHOR 模块作者,不被内核使用,只用于查看
  • MODULE_DESCRIPTION 模块描述,不被内核使用,只用于查看
  • MODULE_SUPPORTED_DEVICE 支持的设备,不被内核使用,只用于查看

模块代码

#include <linux/module.h>   /* Needed by all modules */
#include <linux/kernel.h>   /* Needed for KERN_INFO */
#include <linux/init.h>     /* Needed for the macros */
#include <linux/moduleparam.h> /* Needed for the params */

/*
 * int
 */
static int cnt = 0;
module_param(cnt, int, 0);
MODULE_PARM_DESC(cnt, " is int param");

/*
 * string
 */
static char *str = "lxhuster";
module_param(str, charp, 0);
MODULE_PARM_DESC(str, " is str param");

/*
 * buf
 */
static char name[100] = {0};
module_param_string(myname, name, 100, 0);
MODULE_PARM_DESC(name, " is str param");

/*
 * int array
 */
static int arry[2] = {0};
static unsigned int num = 2;
module_param_array(arry, int, &num, 0);
MODULE_PARM_DESC(arry, " is arry param");

/*
 * 模块入口函数
 */
static int __init hello_init(void)
{
    printk(KERN_ALERT "hello world!\r\n");
    printk(KERN_ALERT "cnt is %d \r\n", cnt);
    printk(KERN_ALERT "str is %s \r\n", str);
    printk(KERN_ALERT "name is %s \r\n", name);
    printk(KERN_ALERT "arry[0] is %d  arry[1] is %d\r\n", arry[0], arry[1]);
    return 0;
}

/*
 * 模块清理函数
 */
static void __exit hello_cleanup(void)
{
    printk(KERN_ALERT "good to go world\r\n");
}

module_init(hello_init);
module_exit(hello_cleanup);

MODULE_LICENSE("GPL");

/*
 * 不被内核使用
 */
MODULE_AUTHOR("lxhuster"); // 模块作者
MODULE_DESCRIPTION("module hello"); // 模块描述
MODULE_SUPPORTED_DEVICE("x86"); // 支持的设备

编译模块

# KERNELRELEASE被定义表明被内核构造系统调用
ifneq ($(KERNELRELEASE), )
    obj-m := hello.o

# else表明从命令行调用
else
    KERNELDIR ?= /lib/modules/$(shell uname -r)/build
    PWD := $(shell pwd)

all:
    $(MAKE) -C $(KERNELDIR) M=$(PWD) modules

clean:
    rm -rf *.cmd *.o *.ko *.mod.c

endif
  • 模块装卸命令
sudo insmod hello.ko cnt=10 str="dash" myname="Thestars,mydestination" arry=5,6

sudo rmmod hello.ko

这里写图片描述

  • printk打印
dmesg

这里写图片描述

  • 模块信息
sudo modinfo hello.ko

这里写图片描述

  • 查看内核导出的符号
cat /proc/kallsyms

内核导出的符号

参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值