嵌入式-Linux内核模块开发入门示例

内核模块开发

What?

Linux内核的整体结构非常庞大,其包含的组件也非常多,如何使用需要的组件呢?① 把所有组件都编译进内核文件,即:zlmage或bzlmage,但这样会导致两个问题:一是生成的内核文件过大;二是如果要添加或删除某个组件,需要重新编译整个内核。

模块功能:

有没有一种机制能让内核文件(zlmage或bzlmage)本身并不包含某组件,而是在该组件需要被使用的时候,动态地添加正在运行的内核中?答:有一种机制可以实现,Linux提供了一种叫做“内核模块”的机制,就可以实现以上效果。

内核模块特点:

模块本身并不被编译进内核文件(zlmage或bzlmage)。

可以根据需求,在内核运行期间动态的安装或卸载。

程序结构:

  •  安装模块时被系统自动调用的函数,通过module_init宏来指定,在示例HelloWorld模块中,模块加载函数为Hello_init。
  • 卸载模块时被系统自动调用的函数,通过module_exit宏来指定,在示例HelloWorld模块中,卸载函数为Hello_exit

示例 ①:

内核模块由单个源文件构成:

代码:

Hello.c

#include<linux/init.h>
#include<linux/module.h>

static int hello_init(void)
{
        printk(KERN_WARNING"Hello,world!\n");
        return 0;
}
static void hello_exit(void)
{
        printk(KERN_INFO"Goodbye,world\n");
}

module_init(hello_init);
module_exit(hello_exit);

Makefile

ifneq ($(KERNELRELEASE),)

obj-m :=Hello.o

else

KDIR :=/lib/modules/3.13.0-32-generic/build
all:
        make -C $(KDIR) M=$(PWD) modules
clean:
        rm -f *.ko *.o *.mod.c *.symvers
endif

显示结果:

示例 ②:

内核模块由多个源文件构成:

代码:

main.c

#include<linux/module.h>
#include<linux/init.h>
//#include<linux/kernel.h>
MODULE_LICENSE("GPL"); //许可证申明
MODULE_AUTHOR("hello_worldmy"); //作者申明
MODULE_DESCRIPTION("Hello World Module"); //模块描述
MODULE_ALIAS("a simplest module"); //模块别名

extern int add(int a,int b);
static int hello_init(void)
{
        printk("Hello World!\n");
        add(1,2);
        return 0;
}

static void hello_exit(void)
{
        printk("<7> hello <0> exit\n");
}

module_init(hello_init);
module_exit(hello_exit);

add.c

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

Makefile

ifneq ($(KERNELRELEASE),)

obj-m :=MyModule.o
MyModule-objs :=main.o add.o

else

KDIR := /lib/modules/3.13.0-32-generic/build
all:
        make -C $(KDIR) M=$(PWD) modules
clean:
        rm -f *.ko *.o *.mod.o *.mod.c *.symvers

endif

显示结果:


在Makefile文件中MyModule为模块名,必须与下面的MyModule-objs中的MyModule保持一致。

MyModule-objs后添加的是源代码文件:main.o add.o;如果在操作中,超过两个的文件只需向后一直添加即可,文件与文件之间以空格间隔。

在该内核模块开发中,内核模块由单个源文件构成或内核模块由多个源文件构成生成的模块是以 .ko结尾的文件。在该示例中,示例一的模块为Hello.ko;示例二的模块为MyModule.ko。

模块安装与卸载:

加载insmod (insmod hello.ko)

卸载 rmmod (rmmod hello)

查看 lsmod

加载 modprobe (modprobe hello)

Modprobe如同insmod,也是加载一个模块到内核。它的不同之处在于它会根据文件

来查看要加载的模块,看它是否还依赖于其他模块,如果是,modprobe会首先找到这些模块,把它们先加载到内核。

示例一:

 

 

示例二:

 



模块可选信息:

1、许可证申明:宏MODULE_LICENSE用来告知内核,该模块带有一个许可证,没有这样的说明,加载内核模块时内核会抱怨。有效的许可证有“GPL”、“GPLv2”、“GPL and additional rights”、“Dual BSD/GPL”、“Dual MPL/GPL”和“Proprietary”

2、作者申明(可选)

MODULE_AUTHOR(“Sir”);

3、模块描述(可选)

MODULE_DESCRIPTION(“Hello World Module”);

4、模块版本(可选)

MODULE_VERSION(“V1.0”);

5、模块别名(可选)

MODULE_ALIAS(“a simple module”);

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值