Linux驱动入门篇(一):Hello, world,入门篇hello


  学习Linux驱动有半年的时间了,但是临近毕业,由于各种事务的耽误,很多东西遗忘,现在写此博客以记录重新学习的历程。

 

  首先,自然是从最简单的内核模块,Hello, world开始啦。

 1 #include <linux/init.h>
 2 #include <linux/module.h>
 3  
 4 static int __init hello_init(void)
 5 {
 6     printk(KERN_NOTICE "Hello, world.");
 7     return 0;
 8 }
 9 
10 static void __exit hello_exit(void)
11 {
12     printk(KERN_NOTICE "Goodbye, world.");
13 }
14 
15 MODULE_LICENSE("GPL");
16 module_init(hello_init);
17 module_exit(hello_exit);

预备知识

  为了能理解这个内核模块,首先需要一些准备。

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

  所有的的内核模块代码中都要包含这两个头文件,它们是专门用于内核模块的。

  包含init.h文件,可以指定初始化函数和清除函数;而module.h文件内含有可装载的模块需要的符号和函数定义。

初始化和清除

static int __init hello_init(void)
{
    语句;
}

  初始化函数不会被其他文件引用,因此被声明为static。但这不是强制的,因为一个模块函数要对内核其他部分可见,必须被显式地导出。

  __init标记表示该函数只在初始化时使用。在模块加载以后,模块装载器会释放初始化函数占用的内存。

 

module_init(hello_init);

  此宏是强制使用的,用来说明初始化函数的位置。

 

static void __exit hello_exit(void)
{
    语句;
}

  清除函数和初始化函数一致,在模块移除的时候被调用,用来注销接口和向系统返回所有资源。

  若模块内嵌到内核,或内核不允许卸载此模块,被标记为 __exit 的函数将被丢弃。

 

module_exit(hello_exit);

  此宏是强制使用的,用来说明清除函数的位置。

 许可证

MODULE_LICENSE("GPL");

  指定该模块代码使用的许可证。内核能识别"GPL"、"GPL v2"、"GPL and additional rights"、"Dual BSD/GPL"、 "Dual MPL/GPL"和"Proprietary"。若没有指定,则内核假定它是"Proprietary"(专有)。

内核函数

 printk(KERN_NOTICE "Hello, world.");

  内核是不能依赖标准C库的,自然内核相关的编程中也就不能使用 printf 函数。这时需要使用内核版本的打印函数 printk 。当模块连接到内核时,就可以访问公共符号。

  KERN_NOTICE定义了这条内核消息的优先级。

相关内容