Linux?内核模块编程
Linux?内核模块编程是一个很重要的知识点。尤其是编写底层驱动程序时,一定会涉及到它。内核模块编程也是?Tiger哥学习?Linux?时第一节课所接触的知识。由此可以看出它的?important,?也可以看出其实它很?easy?。
一前言:
1.?什么是内核模块
1>?内核模块是具有独立功能的程序。它可以被单独编译,但是不能单独运行,它的运行必须被链接到内核作为内核的一部分在内核空间中运行。
2>?模块编程和内核版本密切相连,因为不同的内核版本中某些函数的函数名会有变化。因此模块编程也可以说是内核编程。
3>?特点:
模块本身不被编译进内核映像,从而控制了内核的大小;?模块一旦被加载,就和内核中的其他部分完全一样。
2?.?用户层编程和内核模块编程的区别
?应用程序内核模块程序使用函数libc?库内核函数运行空间用户空间内核空间运行权限普通用户超级用户入口函数main()module_init出口函数exit()module_exit编译gccmakefile链接gccinsmod运行直接运行insmod调试gdbkdbug?、?kdb?、?kgdb二?.?说了这么多,那么怎么编写一个内核模块的程序呢?
1.?我们先来看两个最简单的函数实例,也是几乎所有程序员在学习一门新语言时都会编写的程序:输出?hello world!
现在我们分别用模块编程输出?hello world!?,和在用户层编程输出?hello wrold?!。通过这两个程序我们来分析下如何来编写一个内核模块程序。
用户层编程:?hello.c
#include
int main(void)
{
printf("hello world/n");
}
内核编程?: module.c
#include #include #include MODULE_LICENSE("Dual BSD/GPL");static int hello_init(void){printk(KERN_ALERT "hello,I am edsionte/n");return 0;}static void hello_exit(void){printk(KERN_ALERT "goodbye,kernel/n");}module_init(hello_init);module_exit(hello_exit);//?可选?MODULE_AUTHOR("Tiger-John");MODULE_DESCRIPTION("This is a simple example!/n");MODULE_ALIAS("A simplest example");
Tiger-John?说明:
1.>?相信只要是学过?C?语言的同学对第一个程序都是没有问题的。但是也许大家看了第二个程序就有些不明白了。
可能有人会说:?Tiger?哥你没疯吧,怎么会把?printf()?这么简单的函数错写成了?printk()?呢。
也有的人突然想起当年在大学学?C?编程时,老师告诉我们“一个?C?程序必须要有?main()?函数,并且系统会首先进入?main()?函数执行?"?,那么你的程序怎么没有?main()?函数呢?没有?main()?函数程序是怎么执行的呢?
可能也会有更仔细的人会发现:怎么两个程序头文件不一样呢?不是要用到输入和输出函数时,一定要用到??这个头文件,你怎么没有呢?
--------------------------------------------------------------------------------------------
Tiger?哥很淡定的告诉大家其实第二个程序是正确的,现在我们就来看看到底如何来编写一个内核模块程序。
2.?内核模块编程的具体实现
第一步:?首先我们来看一下程序的头文件
#include
#include
#include
这三个头文件是编写内核模块程序所必须的?3?个头文件?。
Tiger-John?说明:
1>?由于内核编程和用户层编程所用的库函数不一样,所以它的头文件也和我们在用户层编写程序时所用的头文件也不一样。
2>?我们在来看看在?L inux?中又是在那块存放它们的头文件
a.?内核头文件的位置?:?/usr/src/linux-2.6.x/include/
b.?用户层头