开始写一个内核模块

建立和运行模块

从hello world开始,一个完整的内核模块helloword.c如下:

#include<linux/init.h> //module_init 和 module_exit 的头文件
#include<linux/module.h> //这个头文件包含了许多符号与函数的定义,这些符号与函数多与加载模块有关

MODULE_LICENSE("Dual BSD/GPL"); //和开源软件带的license文件差不多,是个使用许可证,在module.h里有可定义的license。

static int hello_init(void) //尽量使用static,防止重名产生的编译错误
{
    printk(KERN_ALERT"hello world !");//KERN_ALERT这个玩意是最高优先级,暂时当它是log里面的
                                      //info级,避免某些地方打印不出来。
    return 0;
}

static int hello_exit(void)
{
    printk(KERN_ALERT"goodbye world !");//printk内核的打印函数,在 insmod 加载了它之后,
                                        //模块被连接到内核并且可存取内核的公用符号,所以可用
}

module_init(hello_init);//加载到内核时调用
module_exit(hello_exit);//去除内核时调用 

编译该文件之后会生成内核模,.ko文件,这个就是载入内核时的代码段,hello.ko。

依据你的系统用来递交消息行的机制, 你的输出可能不同. 特别地, 前面的屏幕输出是来自一个字符控制台; 如果你从一个终端模拟器或者在窗口系统中运行 insmod 和 rmmod, 你不会在你的屏幕上看到任何东西. 消息进入了其中一个系统日志文件中, 例如 /var/log/messages

使用insmod hello.ko可以加载该模块到内核,rmmod卸载该模块,卸载时会执行module_exit,相当于告诉内核我下班了,表给我打电话。

内核模块运行在内核空间,而不是应用程序一样运行在用户空间,意味着内核模块有着更高的特权级别,也意味着他们有着各自的地址空间。应用程序存在虚拟内存中,有一个很大的堆栈区。内核的堆栈很小,可能只有一个4096字节的页,而且还要与这个内核空间调用链共享这个堆栈。

模块的角色是扩展内核功能,模块化的代码在内核空间运行,驱动会进行两种任务,模块的里的一部分来作为系统调用,一部分用来负责中断处理。当一个应用冲虚发出一个系统调用或者硬件中断挂起时,执行系统调用的内核代码对进程来说是异步的,不和任何特别的进程有关。

内核编程要注意并发问题,因为在同一个时间不止一个程序能够调用同一个驱动,大部分设备能够终端处理器;中断处理异步运行,并且可能在你的驱动试图做其他事情的同一时间被调用,也可能字多个cpu上并发运行。所以内核代码,包括驱动代码,必须是可以重入的。这里必须要注意的是,内核模块在退出之前必须小心的释放所有的资源,否则会一直运行直到系统重启。

当你查看内核 API 时, 你会遇到以双下划线(__)开始的函数名. 这样标志的函数名通常是一个低层的接口组件, 应当小心使用. 本质上讲, 双下划线告诉程序员:" 如果你调用这个函数, 确信你知道你在做什么."

内核代码不支持浮点运算。 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值