1,什么是内核源码树?
内核源码树我现在的理解就是整个linux内核源代码,它是编译驱动的前提。Ubuntu系统默认情况下是没有的。内核源码树是要自己下载的。
2,为什么要编译内核源码树?
驱动最终以*.ko的形式生成,insmod的本质就是将ko文件与运行的内核进行链接的过程。类似于编译helloworld的链接。
1. 下载内源代码,位置www.kernel.org. (注意:源码树内核的版本要和驱动程序运行的目标平台的内核版本一致)
apt-cache search linux-source //搜索内核版本
apt-get install linux-source-2.6.22 //下载内核
tar xvf linux-source-2.6.20.tar.bz2 //解压内核
2. 配置内核
进入解压过的内核目录,开始配置内核选择最快的原版的配置(默认)方式。
root@desktop# make oldconfig
当然也可以使用其他配置方式,如 menuconfig, xconfig(必须有GTK环境)。反正不用剪裁什么,所以不管那种方式能配置它就行了。
3. 编译内核
如果你使用交叉编译器,则需要修改Makefile。 开始编译内核。(保证硬盘空间足够)
root@desktop# make
root@desktop# make bzImage
当然,第一个make也可以不执行,直接make bzImage。执行结束后,可以看到在当前目录下生成了一个新的文件: vmlinux, 其属性为-rwxr-xr-x。
root@desktop# make modules_install
执行结束后,会在/lib/modules下生成新的目录/lib/modules/2.6.22-14-generic/。在编译驱动模块时,要用到这个路径下的build目录。
//hello.c
#include<linux/init.h> //初始换函数
#include<linux/kernel.h> //内核头文件
#include<linux/module.h> //模块的头文件
MODULE_LICENSE("Xiongyao BSD/GPL");
static int hello_init(void)
{
printk(KERN_ALTER"Hello, world\n"); //模块运行在内核态,不能使用用户态C库函数中的printf函数,而要使用printk函数
//打印调试信息
return 0;
}
static int hello_exit(void)
{
printk("KERN_ALTER"Goodbye,Hello world\n");
}
module_init(hello_init);
module_exit(hello_exit);
Makefile 文件
obj-m:=hello.o //生成目标文件
KERNELDIR:=/lib/modules/3.2.31/build
PWD :=$(shell pwd)
modules:
(这里要用一个tab键)$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
modules
(这里用一个tab键) $(MAKE) -C $(KERNELDIR)M=$(PWD) modules_install
最好关键的一步到了,所有准备就绪,进入makefile的那个目录
www.linuxidc.com @linux:~$ sudo make
make -C /lib/modules/3.2.31/build M=/home/xiongyao
make[1]: 正在进入目录 `/usr/src/linux-source-3.2.0/linux-source-3.2.0'
LD /home/xiongyao/built-in.o
CC [M] /home/xiongyao/hello.o
Building modules, stage 2.
MODPOST 1 modules
CC /home/xiongyao/hello.mod.o
LD [M] /home/xiongyao/hello.ko
make[1]:正在离开目录 `/usr/src/linux-source-3.2.0/linux-source-3.2.0'
上面证明已经成功了
然后加载模块
#sudo insmod ./hello.ko
本应该会在终端显示hello,world 但是终端什么也没有显示(以后在去解决)
查看加载模块
#sudo lsmod
里面已经生成了hello
hello 2560 0
^_^,已经加载上了
删除模块
#sudo rmmod hello
那么程序的输出到底在哪里呢?在网上看到,如果不出现在终端,则会下进syslog中
#cat /var/log/syslog |grep world
#Hello,world
#Goodbye,linux world
现在所有工作全部完成了,希望做这个Hello World 是我进入linux驱动的第一步~,相信你们也能编译的!成功的编译成功的。
本篇文章来源于 Linux公社网站(www.linuxidc.com) 原文链接:http://www.linuxidc.com/Linux/2012-12/75891.htm
在编译驱动之前,一定要编译源码树, 其次搭建合适的gcc,再次在Makefile的时候一定要注意格式
1 $MAKE 之前要有tab
2,obj-m:=hello.o 一定要有等于 (因为这个问题一直出现没有 linux/init.h文件,大爷的)
3,KDIR := 要指定到相应的源码树 比如 KDIR := /usr/linux/linux-2.6.31.14