Linux内核模块-The__init and __exit宏(三)

1.先看程序的头文件(参考hello.c)
 # include <linux/module.h> /* Need by all modules */
# include <linux/kernel.h> /* Need for HERN_INFO */
# include <linux/init.h>   /* Need for the macros */

这三个头文件是编写内核模块程序必须的。
  • 由于内核编程和用户编程所用的库函数不一样,所以他的头文件也和我们在用户层编写程序时所用的头文件不 一样。
  • Linux中头文件存放位置:
a.内核头文件的位置:/usr/src/linux-2.6.x/include
b.用户层头文件位置:/usr/include

2.内核模块的(加/卸载)函数:
  • 加载函数:
 static int  hello_init(void) //不加void在调试时会出现警报
{
    printk(KERN_INFO "Hello world\n");
    /*
       A non 0 return means init
    */
    return 0;
}
  • 卸载函数(无返回值):
 static void  hello_exit(void)
{
    printk(KERN_INFO "Goodbye world\n");
}

3.对比hello.c中的(加/卸载)函数
# include <linux/init.h>   /* Need for the macros */

 static int __init hello_init(void)
{
    printk(KERN_INFO "Hello world\n");
    /*
       A non 0 return means init
    */
    return 0;
}

static void __exit hello_exit(void)
{
    printk(KERN_INFO "Goodbye world\n");
}

注解通过比较我们发现第二种函数在函数名称前加了__init和__exit前缀( init 和 exit 前面都是两个下划线)。
  • 那么第二种方法比第一种有什么好处呢?

_init 和 __exit 是 Linux 内核的一个宏定义,使系统在初始化完成后释放该函数,并释放其所占内存。因此它的优点是显而易见的。所以建议大家啊在编写入口函数和出口函数时采用第二中方法。

(1)  linux 内核中,所有标示为 __init 的函数在连接的时候都放在 .init.text 这个区段内,此外,所有的 __init 函数在区段 .initcall.init 中还保存了一份函数指针,在初始化时内核会通过这些函数指针调用这些 __init 函数,并在初始化完成后释放 init 区段(包括 .init.text,.initcall.init等)。

(2) 和 __init 一样, __exit 也可以使对应函数在运行完成后自动回收内存。


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值