搭一个Linux内核驱动框架 - 如何写一个Linux内核驱动?
通俗一点的问题就是“如何写一个内核驱动?”
新手往往并不明白驱动的具体定义是什么,我们往往拿到一款芯片,然后要给这个芯片写一个驱动代码,但是这个驱动代码到底是什么样子的?应该怎么写?就是面临的第1个问题。其实我们通常说的驱动是一个很模糊的概念,也是很多概念的集合。狭义上的驱动就是 ”驱动操作系统上一个外设运行的软件“,比如我们买了一个新显卡,就需要安装一下显卡驱动,显卡才能跑起来。对于驱动工程师来说,驱动就是实现上述功能的代码,也就是我们常说的“写一个驱动”。
那么,到底如何写一个“驱动代码”呢,对于Linux驱动工程师来说,就是要搭一个驱动的代码框架,最简单常见的框架就是下面这个样子的(Linux驱动的hellow world)。
#include <linux/init.h>
static int __init hello_world_init(void)
{
return 0;
}
static void __exit hello_world_exit(void)
{
}
module_init(hello_world_init);
module_exit(hello_world_exit);
新手看了就纳闷了,因为上面根本没有 驱动driver 2字,这是因为驱动在内核中是以模块的形式存在的,写一个驱动其实就是写一个驱动模块,也就是要先搭一个模块代码的框架,要想学会写驱动,就要先学会写模块,用模块。
模块其实就是给内核写的一种插件。内核有很多种插件类型,模块就是其中的一种,而驱动就是一种模块的实现。
代码写完了,那如何让他跑起来呢,请先阅读Linux内核模块的编译和运行 - 如何让驱动跑起来?
当我们insmod的时候,就会自动运行module_init函数,这个函数的头文件是<linux/init.h>,至于为什么,以及module_init是被如何调用的,请阅读
扩展阅读:Linux内核模块的运行原理 - 模块是如何跑起来的?。
======================================================================================================================================================
模块运行的时候没有任何反应,因为在 hello_world_init 的时候直接返回了,那我们怎么调试代码的运行呢,那就需要加一些打印,内核中的打印使用 printk函数,这个函数的头文件在 <linux/printk.h>
#include <linux/printk.h>
static int __init hello_world_init(void)
{
printk("hello world module.\n");
return 0;
}
insmod后,通过 dmesg命令就可以看到打印内容
dmesg
当然,也可以使用命令
cat /proc/kmsg
其实printk的用法很多
扩展阅读:
======================================================================================================================================================
好了,我们现在以及会使用模块了,接下来就是在模块中实现驱动功能。
扩展阅读: