L哪些是内核模块

(1)内核模块是具有独立功能的程序,它可以被单独的编译,而且不能独立的运行,他必须联接到内核作为内核的一部份在内核空间中运行。

(2)模块编程与内核版本密切相关,因为不同的内核版本中个别函数的函数名会有变化。因而模块编程也可叫做内核的编程。

(3)特性:模块本身不被编译进内核映像,进而控制了内核的大小;模块一旦被加载就和内核中的其他部份完全一样。

用户层编程与内核模块编程的区别:

在这里插入图片描述

编撰内核模块

testm.c文件:

#include 
#include 
MODULE_LICENSE("GPL");
MODULE_AUTHOR("weipeng jing");

linux内核编程_内核编程强制删除文件_内核编程和普通编程

MODULE_DESCRIPTION("Hello World Module"); MODULE_ALIAS("a simplest module"); static int __init hello_init() { printk(KERN_EMERG"Hello World!n"); return 0; } static void __exit hello_exit() { printk("hello exitn"); printk(KERN_EMERG"good bye!n"); } module_init(hello_init); module_exit(hello_exit);

#include

#include

编撰内模块程序的必须的头文件

因为内核编程与用户编程所用的库函数不同,所以头文件也不同。

内核头文件的位置:/usr/src/linux2.6.29/include/

用户头文件的位置:/usr/include/

加载函数staticinthello_init(void);//不加 void 在调试时会出现报案

卸载函数staticvoidhello_exit(void);// 不加 void 会出现报案 , 若改为 static int 也会报错 , 由于出口函数是不能返会值的

内核编程和普通编程_内核编程强制删除文件_linux内核编程

在模块编程中必需要有前面这两个函数;

注册函数和卸载函数还有一种写法二者的区别与联系:

1> 模块加载函数

staticint_initinit_fun(void)

printk(“helloworld/n”);

return0;

2> 卸载函数 无返回值

static void __exit exit(void){

printk(“byebye!/n”);

通过比较我们可以发觉第二个函数区别在于一个有_init

和_exit前缀,_init与_exit都是Linux内核的一个宏定义,使系统在初始化完成后释放该函数,并释放其所占的显存。因而它的优点是显而易见的,所以通常都建议使用第二种写法。

(1)在Linux内核中,所有标识_init的函数在联接时都置于.init.text这个区段内,再者。所有的_init函数在区段.initcall.init中还保存了一份函数的表针linux rar,在初始化时内核会通过这种表针调用那些_init函数,并在初始化完成后释放_init区段。

(2)和_init一样linux内核编程,_exit也可以使对应的函数在运行完成后手动的回收显存。

printk()函数

printk是内核态的信息

复印函数,功能和标准的printf类似,而且printk有信息复印级别。

intprintk(constchar*fmt,…)

消息的复印级别:

fmt–消息级别:

#defineKERN_EMERG“”/紧急风波消息,系统崩溃之前的提示,表示系统不可以用。

#defineKERN_ALERT””/报告消息,表示必须立刻采取举措。

#defineKERN_CRIT””/临界条件linux内核编程,一般涉及严重的硬件或软件操作失败。

#defineKERN_ERR””/错误条件,驱动程序常用KERN_ERR来报告错误。

#defineKERN_WARNING””/警告条件,对可能出现的问题情况进行警告。

#defineKERN_NOTICE””/正常但又重要的条件,用于提醒。经常用于安全相关的信息。

内核编程强制删除文件_内核编程和普通编程_linux内核编程

#defineKERN_INFO””/提示信息linux查看硬件信息,如驱动程序启动时,复印硬件信息。

#defineKERN_DEBUG””/调试级别信息。

不同的级别用不同的字符串表示,数字越小级别越高。

在内核态使用printk()而在用户态使用printf()是由于,printk()函数是直接的使用了向终端写函数tty_write(),而printf()函数时调用write()系统调用函数向标准输出设备写,所以在用户态不能直接的使用printk()函数,而在内核态因为它已是特权级,所以无需系统调用来

改变特权级,因此能直接使用printk()函数。printk()是内核态的输出,在终端是看不见的,可以使用cat/var/log/messages,或则是dmesg命令来查看输出信息。

加载模块与卸载模块

modules_init(hello_init)告诉内核你编撰的模块程序从那里开始执行。

modules_exit(hello_exit)告诉内核你编撰的模块程序从那里离开。

参数就是卸载函数与注册函数的函数名

许可权限,

MOUDLES_LICENSE(“DUALBSD/GPL);

在linux2.6中可接受的LICENSE包括“GPL”,“GPLV2”,“GPLandadditionalrights”,“DualMPL/GPL”,“Proprietary”。

Tagged:
Author

这篇优质的内容由TA贡献而来

刘遄

《Linux就该这么学》书籍作者,RHCA认证架构师,教育学(计算机专业硕士)。

发表回复