内核模块HelloWorld

linux内核编程(1)—内核模块helloworld  

 

1.代码helloworld.c
#include <linux/init.h>
#include <linux/kernel.h>  
#include <linux/module.h>

static int hello_init(void)

    printk("Hello! This is the helloworld module!\n");
    return 0;


static void hello_exit(void)
{
    printk("Module exit! Bye Bye!\n");
    return;
}

module_init(hello_init);
module_exit(hello_exit);
MODULE_LICENSE("GPL");

1.1这几段代码就是一个模块函数代码了,其中有几个需要注意:

    a)        static是为了防止函数命名污染。

    b)        在内核中的打印函数是printk,其中<0>表示该信息的等级,数字越小,级别越高。

    c)        用module_init和module_exit宏来指定入口函数。

当在命令行安装该模块时,会自动调用hello_init这个函数,当卸载该函数时,对自动调用hello_exit函数。

1.2

2、  模块可选信息

模块有一些用来表示相关信息的宏:

           MODULE_LICENSE                     用来告诉内核遵循什么协议   GPL GPLv2等

           MODULE_AUTHOR                     作者

           MODULE_DESCRIPTION           描述

           MODULE_VERSION                     版本

           MODULE_ALIAS                           别名



2、两种Makefile(2.6的内核)
第一种Makefile(推荐):
obj-m := helloworld.o
KERNELBUILD := /lib/modules/`uname -r`/build
all:
         make -C $(KERNELBUILD) M=$(shell pwd) modules
clean:
         rm -rf *.o  *.ko  *.mod.c .tmp_versions modules* Module*

第二种Makefile:
obj-m := helloworld.o
clean:
         rm -rf *.o  *.ko  *.mod.c .tmp_versions modules* Module* 

#make –C /lib/modules/`uname -r`/build M=$(shell pwd) modules
Linux内核学习(1)—内核模块helloworld - cjhust - 我一直在努力 
备注:2.6内核的kbuild子系统与2.4相比有本质的改变

2.1

其中:

    a)        KERNELRELEASE是在内核源码的顶层Makefile中定义的一个变量。

                ifneq($(KERNELRELEASE),)  判断该变量是否为空。

                在第一次读取执行此Makefile时,KERNELRELEASE没有被定义,
                所以make将读取执行else之后的内容。

 

   b)        KDIR := /lib/modules/2.6.35.6-45.fc14.i686/build  是给KDIR这个变量赋值,值为当前linux运行的内核源码。红色标记的只是我的Linux下的,可以直接

               KDIR := /lib/modules/ $(shell  uname  -r) /build 这样写。

 

   c)        当make的目标为all时,-C $(KDIR) 指明跳转到内核源码目录下读取那里的Makefile;M=$(PWD)表明然后返回到当前目录继续读入、执行当前的Makefile。当从内核源码目录返回时,KERNELRELEASE已被被定义,kbuild也被启动去解析kbuild语法的语句,make将继续读取else之前的内容。

   d)        我们可以把上述的Makefile文件作为一个模板,只需要改动obj-m := hello.o这条语句就可以了:obj-m=XXX.o。



3、编译
#make
Linux内核学习(1)—内核模块helloworld - cjhust - 我一直在努力
Linux内核学习(1)—内核模块helloworld - cjhust - 我一直在努力

#insmod  hello.ko
Linux内核学习(1)—内核模块helloworld - cjhust - 我一直在努力
备注:屏幕上没有输出,是由console的日志记录级别和printk指定的级别决定的。可以用dmesg命令,看到输出。

#dmesg|tail
Linux内核学习(1)—内核模块helloworld - cjhust - 我一直在努力


4、知识拓展(1)
        C程序员都知道,要使用某个外部的函数,应当#include某个头文件,这个头文件包含了那个函数的原型。内核的头文件在/usr/src/linux/include/下,其中/usr/src/linux/include/asm是个符号链接,指向所用内核的具体体系结构目录,比方说我的系统是i386的,那么include/asm就指向include/asm-i386 。
Linux内核学习(1)—内核模块helloworld - cjhust - 我一直在努力

 

内核编程不能链接libc库,即不能使用libc库中的函数,所以很麻烦。一些重要的函数如strcpy/strcmp/snprintf等,kernel为我们实现并导出(export)了,而我们需要#include相关的头文件,在/usr/src/linux/include/linux和/usr/src/linux/include/asm中,你需要自己寻找你所要使用的函数在哪个头文件中声明,并将其#include进来。Linux内核学习(1)—内核模块helloworld - cjhust - 我一直在努力


5、知识拓展(2)

printk可以当作printf函数来使用。其中一个不同点是,printk允许你按照相关的记录级或优先级将消息严格分类。通常你需要一个宏来指定记录等级。记录级宏的作用是扩展为一个字符串,这个字符串会在编译期间与相应的消息文本相连接,因此宏和字符串之间不需要逗号连接。如:printk(KERN_CRIT "I'm trashed; giving up on %p\n", ptr); 在头文件<linux/kernel.h>中共定义了八个可用的记录级,按其严重性倒序排列为:
       1)KERN_EMERG:Used for emergency messages, usually those that precede a crash.
        用于突发性事件的消息,通常在系统崩溃之前报告此类消息。

2)KERN_ALERT:A situation requiring immediate action.
        在需要立即操作的情况下使用此消息。  

3)KERN_CRIT:Critical conditions, often related to serious hardware or software .
        用于临界条件下,通常遇到严重的硬软件错误时使用此消息。

4)KERN_ERR:Used to report error conditions; device drivers often use KERN_ERR to report hardware difficulties.
        用于报告错误条件,设备驱动经常使用KERN_ERR报告硬件难题。  

5)KERN_WARNING:Warnings about problematic situations that do not, in themselves, create serious problems with the system.
        是关于问题状况的警告,一般这些状况不会引起系统的严重问题。  

6)KERN_NOTICE :Situations that are normal, but still worthy of note. A number of security-related conditions are reported at this level.
       该级别较为普通,但仍然值得注意,许多与安全性相关的情况会在这个级别被报告。  

7)KERN_INFO:Informational messages. Many drivers print information about the hardware they find at startup time at this level.
        信息消息,许多驱动程序在启动时刻用它来输出获得的硬件信息。  

8)KERN_DEBUG :Used for debugging messages
        用于调试。

转载于:https://www.cnblogs.com/bo1989/articles/2759474.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值