http://blog.sina.com.cn/s/blog_6444798b0100q9k2.html
背景:操作系统:ubuntu10.04
shana@shana:/usr/src$ ls
linux-headers-2.6.22-14
linux-headers-2.6.22-14-generic
linux-source-2.6.22
linux-source-2.6.22.tar.bz2
shana@shana:/usr/src$
如果没有源码。(一般ubuntu 都没有吧)
查看一下可一下载的源码包(切记不要使用超级用户使用此命令否则……会提示没有此命令)
shana@shana:/usr/src$ apt-cache search linux-source
linux-source - Linux kernel source with Ubuntu patches
xen-source-2.6.16 - Linux kernel source for version 2.6.17 withUbuntu patches
linux-source-2.6.22 - Linux kernel source for version 2.6.22 withUbuntu patches
shana@shana:/usr/src$
我选择了 linux-source-2.6.22 - Linux kernel source for version 2.6.22with Ubuntu patches 这个~
然后 install 之
shana@shana:/usr/src$ sudo apt-get installlinux-source-2.6.22
下载完成后,在/usr/src下,文件名为:linux-source-2.6.22.tar.bz2,是一个压缩包,解压缩既可以得到整个内核的源代码:
注意 已经切换到超级用户模式
root@shana:/usr/src#tar jxvf linux-source-2.6.20.tar.bz2
解压后生成一个新的目录/usr/src/linux-source-2.6.22,所有的源代码都在该目录下。
进入该目录
开始配置内核 选择最快的原版的配置(默认)方式 (我是如此)
root@shana:/usr/src/linux-source-2.6.22# make oldconfig
当然你也可以使用 自己喜欢的配置方式 如 menuconfig ,xconfig(必须有GTK环境吧)。反正不用剪裁什么,所以不管那种方式能配置它就行了。
完成后,开始make 吧 这儿比较久 一般有1一个小时吧。(保证空间足够 我编译完成后 使用了1.8G)我分区时分给/目录30G的空间,我没遇到这问题。倒是我朋友遇到了。
shana@shana:/usr/src/linux-source-2.6.22$ make
shana@shana:/usr/src/linux-source-2.6.22$ make bzImage
当然,第一个make也可以不执行,直接make bzImage。执行结束后,可以看到在当前目录下生成了一个新的文件: vmlinux,其属性为-rwxr-xr-x。
然后 :
root@shana:/usr/src/linux-source-2.6.22#make modules
root@shana:/usr/src/linux-source-2.6.22#make modules_install
执行结束之后,会在/lib/modules下生成新的目录/lib/modules/2.6.22-14-generic/
。 在随后的编译模块文件时,要用到这个路径下的build目录。至此,内核编译完成。可以重启一下系统。
至此 内核树就建立啦 原来不是很难.....
写一个 最简单 最没用的驱动吧
我在 /home/shana/linux_q/ 目录下创建2个文本文件 hello.c Makefile
//hello.c
#include <linux/init.h>
#include <linux/module.h>
MODULE_LICENSE("Dual BSD/GPL");
static int hello_init(void)
{
printk(KERN_ALERT "Hello, world\n");
return 0;
}
static void hello_exit(void)
{
printk(KERN_ALERT"Goodbye, cruel world\n");
}
module_init(hello_init);
module_exit(hello_exit);
程序我就不解释了……
Makefile 文件
obj-m := hello.o
KERNELDIR := /lib/modules/2.6.20/build
PWD := $(shell pwd)
modules:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
modules_install:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules_install
如果以上你都完成了在 make 时出现这样的错误
shana@shana:~/linux_驱动开发$ make
make: 没有什么可以做的为 `modules'。
原因很简单 你肯定是从我这直接复制的吧~~~呵呵,Makefile格式错误啦~
解决办法就是 你把如 $(MAKE) -C $(KERNELDIR) M=$(PWD) modules_install 移动到行首然后按Tab 键自动对齐
这时里边的变量都变成绿色了~然后在 make 吧
shana@shana:~/linux_驱动开发$ make
make -C /lib/modules/2.6.22-14-generic/buildM=/home/shana/linux_驱动开发 modules
make[1]: Entering directory`/usr/src/linux-headers-2.6.22-14-generic'
CC [M] /home/shana/linux_驱动开发/hello.o
Building modules, stage 2.
MODPOST 1 modules
CC /home/shana/linux_驱动开发/hello.mod.o
LD [M] /home/shana/linux_驱动开发/hello.ko
make[1]: Leaving directory`/usr/src/linux-headers-2.6.22-14-generic'
shana@shana:~/linux_驱动开发$
shana@shana:~/linux_驱动开发$ ls -l
总用量 124
-rw-r--r-- 1 shana shana 303 2008-03-16 10:43 hello.c
-rw-r--r-- 1 shana shana 49039 2008-03-16 12:11 hello.ko
-rw-r--r-- 1 shana shana 687 2008-03-16 12:11 hello.mod.c
-rw-r--r-- 1 shana shana 25840 2008-03-16 12:11 hello.mod.o
-rw-r--r-- 1 shana shana 24360 2008-03-16 12:11 hello.o
-rw-r--r-- 1 shana shana 8344 2008-03-16 09:17linux_qudong_qu.txt
-rw-r--r-- 1 shana shana 266 2008-03-16 12:09 Makefile
-rw-r--r-- 1 shana shana 0 2008-03-16 12:11 Module.symvers
shana@shana:~/linux_驱动开发$
然后加载模块 (超级用户)
root@shana:/home/shana/linux_驱动开发# insmod ./hello.ko
按照书上的例子 会在终端显示 hello , world 但是运行后什么都没有出现 (原因不解)
root@shana:/home/shana/linux_驱动开发# insmod ./hello.ko
root@shana:/home/shana/linux_驱动开发#
查看加载模块
root@shana:/home/shana/linux_驱动开发# lsmod
Module Size Used by
hello 2560 0
已经加载上咯~~
删除模块
root@shana:/home/shana/linux_驱动开发# rmmod hello
root@shana:/home/shana/linux_驱动开发#
那程序的输出在那呢?书中说明 如果不出现在终端 则会写进 syslog 文件中
shana@shana:~/linux_驱动开发$ cat /var/log/syslog |grep world
Mar 16 12:14:53 shana kernel: [ 5937.529297] Hello, world
Mar 16 12:16:05 shana kernel: [ 6009.439036] Goodbye, cruelworld
shana@shana:~/linux_驱动开发$
至此 全部工作都完成了。是否对你有用呢?
======================================================================================
提示:查看显示当前内核版本号:uname -r
1.下载Linux源码:
首先查看可以下载的Linux内核源码包
- ljj@ljj-laptop:~$ sudo apt-cache search linux-source
- [sudo] password for ljj:
- linux-source - Linux kernel source with Ubuntupatches
- linux-source-2.6.32 - Linux kernel source for version 2.6.32 with Ubuntu patches
- ljj@ljj-laptop:~$ sudo apt-get install linux-source-2.6.32
下载完成后,在/usr/src下,文件名为:linux-source-2.6.32.tar.bz2,是一个压缩包,然后用
命令解压即可获得Linux内核的源代码:
- ljj@ljj-laptop:/usr/src$ sudo tar jxvflinux-source-2.6.32.tar.bz2
2.然后在Linux内核源码目录/usr/src/linux-source-2.6.32目录下面用老的方法配置好Linux内核:
- ljj@ljj-laptop:/usr/src/linux-source-2.6.32$ sudo makeoldconfig
3.然后执行:
- ljj@ljj-laptop:/usr/src/linux-source-2.6.32$ sudo makebzImage
4.然后编译模块:
- ljj@ljj-laptop:/usr/src/linux-source-2.6.32$ sudo makemodules
5.然后便可以安装模块了:
- ljj@ljj-laptop:/usr/src/linux-source-2.6.32$ sudo makemodules_install
以上步骤完成以后,会在/lib/modules目录下面生成一个文件夹linux-2.6.32-27-generic,至此你差不多已经成了,因为你已经构造好了内核树!!!
在这个过程中,当进行make modules的时候出现了问题。
是这个样子的:
LD [M]
ld: /ubuntu/omnibook/sections.lds: No such file: No such file ordirectory
make[2]: *** [ubuntu/omnibook/omnibook.o] Error 1
make[1]: *** [ubuntu/omnibook] Error 2
make: *** [ubuntu] Error 2
网上也看到了类似的提问。
解决方法:
$ sudo gedit/usr/src/linux/ubuntu/omnibook/Makefile
160: #EXTRA_LDFLAGS +=
$(src)/sections.lds
161: EXTRA_LDFLAGS +=$(PWD)/ubuntu/omnibook/sections.lds
改写成:
就可以继续了。160: EXTRA_LDFLAGS +=
$(src)/sections.lds
161: #EXTRA_LDFLAGS +=$(PWD)/ubuntu/omnibook/sections.lds
=============================================================================
现在我讲述在Ubuntu 10.04下安装的过程:
1.安装编译内核所需要的软件
build-essential、autoconf、automake、cvs、subversion
apt-get install build-essential kernel-packagelibncurses5-dev
libncurses5这个软件包在使用menuconfig配置内核的时候会用到。
2.下载内核源码
使用uname -r 命令查看当前的内核版本号,我的是2.6.32-25-generic,使用apt-cachesearch linux-source查看软件库的源码包,我查询到的源码包有:
linux-source - Linux kernel source with Ubuntu patches
linux-source-2.6.32 - Linux kernel source for version 2.6.32with Ubuntu patches
我选择linux-source-2.6.32 - Linux kernel source for version2.6.32 with Ubuntu patches
sudo apt-get install linux-source-2.6.32
下载好后cd /usr/src目录下就可以看见linux-source-2.6.32.tar.bz2,然后解压到当前的目录
sudo tar xjvf linux-source-2.6.32.tar.bz2
解压完毕,会生成linux-source-2.6.32目录
3.编译内核源码
在编译之前我们需要 Ubuntu原来内核的一个配置文件
这是我/usr/src目录下的文件预览:
drwxr-xr-x 4 root root 4096 2010-09-04 21:31 fglrx-8.723.1
drwxr-xr-x 24 root root 4096 2010-09-04 20:35linux-headers-2.6.32-25
drwxr-xr-x 7 root root 4096 2010-09-04 20:35linux-headers-2.6.32-25-generic
drwxr-xr-x 25 root root 4096 2010-09-16 21:39linux-source-2.6.32
-rw-r--r-- 1 root root 65846876 2010-09-01 22:41linux-source-2.6.32.tar.bz2
现在我们需要linux-headers-2.6.32-25-generic目录下的.config文件,我们把它拷贝到我们刚下好解压的目录,也就是linux-source-2.6.32
sudo cp /usr/src/linux-headers-2.6.32-25-generic/.config/usr/src/linux-2.6.32
接下来切换到root用户
sudo -i
cd /usr/src/linux-2.6.32
make menuconfig
终端会弹出一个配置界面
最后有两项:load a kernel configuration...
save a kernel configuration...
选择load a kernel configuration保存,然后在选择save akernelconfiguration再保存退出,并退出配置环境。
接下来我们开始编译
cd /usr/src/linux-2.6.32
make
记住一定要是管理员帐号运行,这个过程真的很久,如果你的cpu是双核的可以在make后面加个参数,make -j4.
make bzImage 执行结束后,可以看到在当前目录下生成了一个新的文件: vmlinux,其属性为-rwxr-xr-x。
make modules
make modules_install 这条命令能在/lib/modules目录下产生一个目录.4.测试驱动模块
这里就抄个程序测试了,初学者顾不了那么多了。
我在 /home/shana/linux_q/ 目录下创建2个文本文件 hello.c Makefile
//hello.c
#include
#include
MODULE_LICENSE("Dual BSD/GPL");
static int hello_init(void)
{
printk(KERN_ALERT "Hello, world\n");
return 0;
}
static void hello_exit(void)
{
printk(KERN_ALERT"Goodbye, cruel world\n");
}
module_init(hello_init);
module_exit(hello_exit);
Makefile 文件
obj-m := hello.o
KERNELDIR := /lib/modules/2.6.20/build
PWD := $(shell pwd)
modules:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
modules_install:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules_install
需要注意的是makefile的格式$(MAKE)前面要加个tab.
make 编译,产生如下文件:
hello.c hello.mod.c hello.o modules.order
hello.ko hello.mod.o Makefile Module.symvers
5.加载模块到内核去
sudo insmod ./hello.ko 这个命令把hello.ko加载到内核
sudo rmmod hello 这个命令是把hello这个模块移除掉
lsmod 这个命令可以查看当前所有的驱动模块
程序的输出结果可以在
/var/log/syslog文件中查看
Sep 16 21:50:10 wuyangyu-desktop kernel: [10428.551271]Hello,World
Sep 16 21:55:45 wuyangyu-desktop kernel: [10763.644605]Goodbye,cruel world
这是程序的输出。