Linux driver 基础之 hello world

本系列以实用及累积基础为目标,不必要不会深入代码


文章目录

  • 前言
  • 一、内核模块从哪里开始?
  • 二、hello world 实例
  • 总结


前言

额,这个内容应该已经烂大街了,不过我还是得写一份自己的,嘻嘻嘻,后续会有新的内容的。

此文内核版本:4.4.143


一、内核模块从哪里开始?

module_init(); 驱动模块都是从这个宏开始的,向宏里传入一个 static int __init 类型的函数作为该模块的入口,内核在启动时就会调用这个函数啦,当然前提是要已经加入编译链接。
此宏就不展开分析了,要说说的是,内核还用此宏封装了大量的宏来方便大家编程,如下:

#define module_driver(__driver, __register, __unregister, ...) \
static int __init __driver##_init(void) \
{ \
	return __register(&(__driver) , ##__VA_ARGS__); \
} \
module_init(__driver##_init); \
static void __exit __driver##_exit(void) \
{ \
	__unregister(&(__driver) , ##__VA_ARGS__); \
} \
module_exit(__driver##_exit);

直接用上述宏就直接新增了模块,并注册了驱动;还有如下

/* module_platform_driver() - Helper macro for drivers that don't do
 * anything special in module init/exit.  This eliminates a lot of
 * boilerplate.  Each module may only use this macro once, and
 * calling it replaces module_init() and module_exit()
 */
#define module_platform_driver(__platform_driver) \
	module_driver(__platform_driver, platform_driver_register, \
			platform_driver_unregister)

像这种类似的还有 module_spi_driver(); module_i2c_driver();

模块入口还有很多,不过都是已封装了 module_init(); 为基础的。
个人编程也最好使用内核提供的宏接口,这样代码看起来更简洁、更符合规范。

都自己开始写驱动了,应该也不用我多说什么啦

二、hello world 实例

这个代码也是烂大街啦,网上、书里到处都有,这里也只做一个简单记录。

代码如下(示例):

#include 
#include 
MODULE_LICENSE("Dual BSD/GPL");
 
static int __init hello_world_init(void)
{
        printk(KERN_ALERT "%s: Hello, World\n", __func__);
        return 0;
}
static void __exit hello_world_exit(void)
{
        printk(KERN_ALERT "%s: Byebye, World\n", __func__);
}
 
module_init(hello_world_init);
module_exit(hello_world_exit);

当带有这个模块的 kernel 启动后,使用 dmesg | grep hello_world 就可以看到日志啦

也可以编译成模块,再使用命令加载或卸载模块


总结

主要是要熟悉驱动模块的入口,有关编译之类的这里不做介绍。

你可能感兴趣的:(Linux,driver,基础,内核,linux)