Sunday, 31 March 2013
Linux内核编程:
网上有很多关于内核编程的资料,但是讲的都不是很详细。这两天,我通过网上的各方资源也成功地进行了内核编程。其实,说起来,入门很简单。只需要几个步骤。
1、首先,必须搞清楚内核源代码在哪,应该不必要重新编译内核,但是因为我第一次进行内核变成时没编译成功(原因其实是代码写错了),所以花了近两个小时编译了一个最新稳定的内核版本3.8.5.之前我用的应该是3.2.5.编译内核的步骤我下次再补上,这次主要讲内核编程。注意到所有内核编程基本都要有这几行代码:
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
必须先让编译器找到linux这个文件夹,当然这是Makefile干的事,所以Makefile文件十分重要,否则即使c代码写法正确,也无法编译成功。所以在Makefile中必须找到这个linux文件。linux源代码(仅我的经验,不足为信)一般放在/usr/src/下,这个目录下的linux/可能只是个文件链接(跟网站链接一样,是个指向另一个实际文件夹指针),如果没有linux/文件夹,应该有类似linux-3.8.5/或linux-headers-3.2.0-23/的文件夹。具体写法可以看第3步,以上只是先声明存在这样一个首要的问题。
2、内核编程
/***************************************/
//Kernel Programming//hello.c#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
MODULE_LICENSE("GPL");
static int hello_init(void){
printk(KERN_ALERT "hello, I am Segoold!\n"); return 0;
}
static void hello_exit(void){
printk(KERN_ALERT "goodbye, kernel\n");
}
module_init(hello_init);
module_exit(hello_exit);
MODULE_AUTHOR("Segoold Chou");
MODULE_DESCRIPTION("This is a simple example!\n");
MODULE_ALIAS("A simplest example");
/***************************************/
代码不多作解释,值得稍微注意的就是module_init()和module_exit()是程序的入口和出口地址,而不是通常的main()。
3、Makefile
内核编程必须要有Makefile,不像一些简单的c代码可以直接用gcc编译。
我看了两篇关于Makefile的文件,经过调试,都能够正确运行。
#*****************************************
#Makefile --1
obj-m += hello.o
CURRENT_PATH := $(shell pwd)
LINUX_KERNEL:=$(shell uname -r)
LINUX_KERNEL_PATH:=/usr/src/linux-$(LINUX_KERNEL)
all:
make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) modules
clean:
make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) clean
#******************************************
其中,CURRENT_PATH是当前项目的相对地址(可以按Alt+Ctrl+t弹出终端输入shell命令:pwd查看),LINUX_KERNEL是内核版本号(即3.8.5),LINUX_KERNEL_PATH是内核的绝对路径,这里一定要回头看第1步,要切实查看你当前linux内核文件存放路径,如果和以上的一样,那么这个Makefile就没错了。
当然还有另外一些写法:
#******************************************
#Makefile --2
ifneq ($(KERNELRELEASE),)
mymodule-objs:= hello.c
obj-m += hello.o
else
PWD :=$(shell pwd)
KVER := $(shell uname -r)
KDIR :=/lib/modules/$(KVER)/build
all:
$(MAKE) -C $(KDIR) M=$(PWD)
clean:
rm -rf *.o *.mod.c *.ko *.symvers *order *.markers *-
endif
#******************************************
这里的内核路径非常有趣,在/lib/modules/(你当前系统的版本号,如3.8.5)/build/下,因为这个build/也是类似上面linux/的指针,直接指向绝对地址/usr/src/linux-3.8.5/。
4、make
完成上面的步骤后,在当前项目目录下,运行make命令,就会生产hello.ko文件,及模块目标文件。如果没有,则是c代码或Makefile错误,根据提示排除错误。
5、运行内核程序
运行内核程序时,必须有root 权限,即在命令前加sudo .
下面是我做实验时输入的代码情况:
chou@chou-Lenovo-V370:~/.../hello$ sudo rmmod hello.kochou@chou-Lenovo-V370:~/.../hello$ sudo insmod hello.ko
chou@chou-Lenovo-V370:~/.../hello$ sudo dmesg -c[20983.740911] goodbye, kernel
[20988.152406] hello, I am Segoold!
chou@chou-Lenovo-V370:~/.../hello$
最后别忘了删除模块:
chou@chou-Lenovo-V370:~/.../hello$ sudo rmmod hello.ko
以上就是编写内核程序入门级的教程了。