vb中array函数中变量为_string字符串转为数组

vb中array函数中变量为_string字符串转为数组1 简介模块(Module)具有以下特点:模块本身不编译进内核映像内核加载之后,和其它内核中的部分完全一样。一个简单的示例:#include <linux/init.h>#include <linux/module.h>static int __ini

1 简介

模块(Module)具有以下特点:

  • 模块本身不编译进内核映像
  • 内核加载之后,和其它内核中的部分完全一样。

一个简单的示例:

#include <linux/init.h> #include <linux/module.h> static int __init hello_init(void) { printk(KERN_INFO "Hello world enter\n"); return 0; } module_init(hello_init); //内核加载函数 static void __exit hello_exit(void) { printk(KERN_INFO "Hello world exit\n"); } module_exit(hello_exit); //内核卸载函数 MODULE_AUTHOR("Test Hello"); MODULE_LICENSE("GPL v2"); MODULE_DESCRIPTION("A simple Hello World Module"); MODULE_ALIAS("A simple module");

Makefile:

KVERS = $(shell uname -r) # Kernel modules obj-m += hello.o # Specify flags for the module compilation. #EXTRA_CFLAGS=-g -O0 build: kernel_modules kernel_modules: make -C /lib/modules/$(KVERS)/build M=$(CURDIR) modules clean: make -C /lib/modules/$(KVERS)/build M=$(CURDIR) clean

编译,并且插入ko:

$ make $ sudo insmod hello.ko 

插入ko时,可能没有打印信息,可以使用dmesg命令查看:

可以通过lsmod命令查看当前系统插入了哪些ko,lsmod命令查看的结果对应/proc/modules文件,内核中已经加载模块信息也存在于/sys/module目录中:

$ lsmod | grep "hello" Module Size Used by hello 12425 0 $ cat /proc/modules | grep "hello" hello 12425 0 - Live 0xffffffffc06fc000 (OE) $ ls /sys/module/hello/ coresize initsize notes/ rhelversion srcversion uevent holders/ initstate refcnt sections/ taint

modinfo命令可以获得模块的信息,包括模块作者、模块的说明、模块所支持的参数以及vermagic:

$ modinfo hello.ko filename: /home/grace/driver_study/code/modules/hello.ko alias: A simple module description: A simple Hello World Module license: GPL author: Test Hello rhelversion: 7.4 srcversion: E4D5379B55084D8ED2D94E8 depends: vermagic: 3.10.0-693.el7.x86_64 SMP mod_unload modversions 

卸载模块命令rmmod:

$ rmmod hello

【文章福利】小编推荐自己的Linux内核技术交流群:整理了一些个人觉得比较好的学习书籍、视频资料共享在群文件里面,有需要的可以私信【内核】自行添加哦!!!(含视频教程、电子书、实战项目及代码)

vb中array函数中变量为_string字符串转为数组

2 模块程序结构

一个Linux内核模块主要由以下几个部分组成:

(1)模块加载函数

通过insmod或者modprobe命令加载模块时,模块的加载函数会自动被内核执行,完成模块的初始化工作。

(2)模块卸载函数

通过rmmod命令卸载模块时,模块的卸载函数会自动被内核执行,完成模块相关的卸载功能。

(3)模块许可证声明

许可证(LICENSE)声明描述了内核模块的许可权限,如果不申明LICENSE,模块加载时会收到内核被污染(Kernel Tainted)的警告。

[10688.] hello: module license 'unspecified' taints kernel.

在Linux内核模块中可接受的LICENSE包括:GPL、GPL v2等。大多数情况下,内核模块应遵循GPL兼容许可证。

(4)模块参数(可选)

模块参数是模块被加载时可以传递给它的值,它本身对应模块内部的全局变量。

(5)模块导出符号(可选)

内核模块可以导出的符号(symbol,对应于函数或变量),若导出,其它模块可以使用本模块的变量或函数。

(6)模块作者等信息声明(可选)

3 模块加载函数

Linux模块加载函数一般以__init标识声明,典型的模块加载函数的形式如下:

static int __init init_func(void) { /* 初始化代码 */ } module_init(init_func);

模块加载函数module_init(函数名)的方式指定,返回整型值,若初始化成功,返回0;初始化失败,返回错误编码。

Linux内核中,错误码是一个接近0的负值,定义在<lnux/errno.h>中。

Linux内核中,可以使用request_module(const char *fmt, …)函数加载内核模块,使用方式:

request_module(module_name);

初始化数据可以定义为__initdata,对于只在初始化阶段所需要的数据,内核在初始化完成之后会释放它们占用的内存。

static int hello_data __initdata = 1; static int __init hello_init(void) { printk(KERN_INFO "Hello world enter %d\n", hello_data); return 0; } module_init(hello_init); //内核加载函数

4 模块卸载函数

模块卸载函数一般以__exit标识声明,常见的用法如下:

static void __exit clean_func(void) { /* 释放代码 */ } module_exit(clean_func); //内核卸载函数

模块卸载函数在模块卸载的时候执行,不返回任何值,且必须以module_exit(函数名)的方式使用。

5 模块参数

可使用“module_param(参数名, 参数类型, 参数读/写权限)”为模块定义一个参数。

在加载模块时,用户可以向模块传递参数,形式为:

insmod 模块名 参数名=参数值

如果不传递,参数使用模块定义的缺省值。如果模块被内置无法insmod,在bootloader中可以通过bootargs设置”模块名.参数名=值”的形式给内核的模块传递参数。

参数的类型可以是:

byte short ushort int uint long ulong charp(字符指针) bool invbool(布尔的反)

在模块编译时会将module_param中的声明类型和变量定义的类型进行比较,判断是否一致。

模块也可以有参数数组,形式为:

module_param_array(数组名, 数组类型, 数组长, 参数读/写权限)

模块参数举例:

#include <linux/init.h> #include <linux/module.h> static char *book_name = "dissection Linux Device Driver"; module_param(book_name, charp, S_IRUGO); static int book_num = 400; module_param(book_num, int, S_IRUGO); static int __init hello_init(void) { printk(KERN_INFO "book name:%s\n", book_name); printk(KERN_INFO "book num:%d\n", book_num); return 0; } module_init(hello_init); //内核加载函数 static void __exit hello_exit(void) { printk(KERN_INFO "Hello world exit\n"); } module_exit(hello_exit); //内核卸载函数 MODULE_AUTHOR("Test Hello"); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("A simple Hello World Module"); MODULE_ALIAS("A simple module");

编译并且加载不带参数,可以看出输出的是默认的参数值:

$ make $ insmod para.ko $ dmesg [13186.] book name:dissection Linux Device Driver [13186.] book num:400

加载时带参数,打印的是输入的参数:

$ insmod para.ko book_name="LDD3" book_num=500 $ dmesg [13423.036831] book name:LDD3 [13423.036835] book num:500

在/sys/module/模块名/parameters目录下也可以看到模块的参数:

$ ls /sys/module/para/parameters/ book_name book_num $ cat /sys/module/para/parameters/book_num 500 $ cat /sys/module/para/parameters/book_name LDD3

6 导出符号

Linux下内核符号表在/proc/kallsyms下,它记录了符号以及符号所在的内存地址:

$ more /proc/kallsyms ffffffff8109f320 T sys_kill ffffffff8109f330 T SyS_tgkill

模块可以使用以下方式导出符号到符号表中,导出的符号可以被其它模块使用,使用前需要进行声明:

EXPORT_SYMBOL(符号名); EXPORT_SYMBOL_GPL(符号名); //只适用于包含GPL许可权的模块

测试用例:

#include <linux/init.h> #include <linux/module.h> int add_integer(int a, int b) { return a + b; } EXPORT_SYMBOL_GPL(add_integer); int sub_integer(int a, int b) { return a - b; } EXPORT_SYMBOL_GPL(sub_integer); MODULE_LICENSE("GPL v2");

加载并且查看相关信息:

$ insmod export_symb.ko ffffffffc0 t add_integer [export_symb] ffffffffc0 t sub_integer [export_symb]

7 模块声明与描述

Linux内核模块中,使用以下函数进行声明:

MODULE_AUTHOR //作者 MODULE_DESCRIPTION //描述 MODULE_VERSION //版本 MODULE_DEVICE_TABLE //设备表,对于USB、PCI驱动,表明该驱动模块所支持的设备 MODULE_ALIAS //别名

8 模块的使用计数

Linux2.6之后的模块计数管理接口为:try_module_get(&module)和module_put(&module)。模块的使用计数不用模块自己管理。

/* 用于增加模块使用计数;返回为0,表示调用失败,希望使用的模块没有加载或正在卸载 */ int try_module_get(struct module *module); /* 用于减少模块的使用计数 */ void module_put(struct module *module);

9 模块的编译

简单的Makefile:

KVERS = $(shell uname -r) # Kernel modules obj-m += hello.o # Specify flags for the module compilation. #EXTRA_CFLAGS=-g -O0 #是否使用调试信息 build: kernel_modules kernel_modules: make -C /lib/modules/$(KVERS)/build M=$(CURDIR) modules clean: make -C /lib/modules/$(KVERS)/build M=$(CURDIR) clean

该makefile和源码hello.c在同一个目录,运行make命令得到模块hello.ko。

如果需要包括多个.c文件,需要更改:

obj-m += modulename.o modulename-objs := file1.o file2.o

来源;https://www.cnblogs.com/mrlayfolk/p/15781248.html

2024最新激活全家桶教程,稳定运行到2099年,请移步至置顶文章:https://sigusoft.com/99576.html

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。 文章由激活谷谷主-小谷整理,转载请注明出处:https://sigusoft.com/15927.html

(0)
上一篇 2024年 9月 18日
下一篇 2024年 9月 18日

相关推荐

关注微信