Ubuntu10.04搭建linux内核驱动开发环境
最近在看著名的《linux设备驱动程序》,所以打算搭建个相应的实验环境来练手。结果搞了三天终于搞定了。。。期间有些错误、经验记录下。
最开始,我手头有个linux2.6.11版本的kernel,我是想在这个版本上搭建。先是装了个Ubuntu11.04的虚拟机,然后开始编译内核,结果出错。具体的也不是太清楚,可能是编译工具版本太高,而内核太老。然后我又想装个内核是2.6.10的Ubuntu 5.0.4,但是问题又出来了,它的软件源太老了,基本不能用,工具链都下载不下来。在安装的时候,apt-get install 命令出错,哪个包broken,这个情况是你的源列表文件sources.list修改导致配置混乱造成的,开始不懂,后来网上知道的。
下边开始,是我试验过正确的搭建方法。我是找到一篇文章讲的是10.04上如何搭建。下面基本摘自那篇文章,有一点自己的修改。
一、准备开发工具
开发工具主要有gcc、gdb、make
在Ubuntu中可以通过下面这个命令安装:
$apt-get install build-essential
二、下载Linux源代码
linux源码可以通过以下几种途径获得:
1)直接去www.kernel.org下载
2)通过包管理工具下载源码
用下面指令查看可用的源码包:
$ sudo apt-cache search linux-source
linux-source - Linux kernel source with Ubuntu patches
linux-source-2.6.32 - Linux kernel source for version 2.6.32 with Ubuntu patches
在Ubuntu中可以通过下面这个命令下载:
$apt-get install linux-source-(版本号)
$sudo apt-get install linux-source-2.6.32
下载后的文件linux-source-2.6.32.tar.bz2在/usr/src目录中,解压:
$su – root
$cd /usr/src
$tar jxvf linux-source-2.6.32.tar.bz2
解压后在/usr/src目录下产生了一个linux-source-2.6.32源码目录
(ps.我是在kernel.org下载的源码版本是2.6.32,比Ubuntu10.04自带的2.6.32.21还低。。。)
三、编译内核
依次执行下列命令(必须都执行,否则编译错误,如果不是root用户,命令前加sudo):
1) 配置内核
$su – root
$cd /usr/src/linux-source-2.6.32
$ sudo cp ../linux-headers-2.6.32-21-generic/.config ./.config
$make oldconfig
2) 编译内核
2.6版本后前两步不需要,直接make即可
//$make prepare
//$make scripts
$make
3)安装模块
$make modules
$make modules_install
执行结束之后,会在/lib/modules下生成新的目录/lib/modules/2.6.32
四、生成镜像文件
1)生成内核镜像文件
$make bzImage
执行完成后将在arch/i386/boot/目录下生成bzImage镜像文件,使用下面命令安装到系统的/boot目录下:
$sudo make install
sh /usr/src/linux-source-2.6.32/arch/x86/boot/install.sh 2.6.32 arch/x86/boot/bzImage \ System.map "/boot"
命令完成后在/boot目录下,将多了vmlinuz-2.6.32和System.map-2.6.32两个文件
2)生成要载入ramdisk的映像文件
如果linux系统按照在scsi磁盘上,这部是必须的,否则可以跳过。我的linux是装在vmware上的,用的是虚拟的scsi磁盘,所以必须 要这一步。输入命令:
mkinitramfs -o /boot/initrd.img-linux2.6.32 2.6.32
第二个参数是版本号,必须和/lib/modules/目录下新内核对应的模块的文件夹名字一致,即2.6.32。
五、使用新编译的内核
Ubuntu采用Grub引导,要使用新内核,必须配置grub。
1) 更改grub配置,显示启动菜单
$su – root
$gedit /etc/default/grub &
注释GRUB_HIDDEN_TIMEOUT=0语句,及改成#GRUB_HIDDEN_TIMEOUT=0后保存
2)更新启动配置文件
$update-grub
执行命令后,该命令自动搜索/boot文件夹,将相应的镜像加入/boot/grub/grub.cfg启动菜单,并根据/etc/default/grub内容更新配置文件。
更新后,将增加如下内容:
menuentry 'Ubuntu, with Linux 2.6.32' --class ubuntu --class gnu-linux --class gnu --class os {
recordfail
insmod ext2
set root='(hd0,5)'
search --no-floppy --fs-uuid --set 4aaa411a-c1ab-4c9e-94bf-770717be6d9a
linux /vmlinuz-2.6.32 root=/dev/sda8 ro quiet splash
}
menuentry 'Ubuntu, with Linux 2.6.32 (recovery mode)' --class ubuntu --class gnu-linux --class gnu --class os {
recordfail
insmod ext2
set root='(hd0,5)'
search --no-floppy --fs-uuid --set 4aaa411a-c1ab-4c9e-94bf-770717be6d9a
echo 'Loading Linux 2.6.32 ...'
linux /vmlinuz-2.6.32 root=/dev/sda8 ro single
echo 'Loading initial ramdisk ...'
}
3) 手工更改配置文件
因为是SCSI,须手工加入启动时需要的ramdisk的映像文件, initrd开头部分:
menuentry 'Ubuntu, with Linux 2.6.32--class ubuntu --class gnu-linux --class gnu --class os {
recordfail
insmod ext2
set root='(hd0,5)'
search --no-floppy --fs-uuid --set 4aaa411a-c1ab-4c9e-94bf-770717be6d9a
linux /vmlinuz-2.6.32 root=/dev/sda8 ro quiet splash
initrd /initrd.img-linux2.6.32 ///!!!!!!!这是新加的
}
menuentry 'Ubuntu, with Linux 2.6.32 (recovery mode)' --class ubuntu --class gnu-linux --class gnu --class os {
recordfail
insmod ext2
set root='(hd0,5)'
search --no-floppy --fs-uuid --set 4aaa411a-c1ab-4c9e-94bf-770717be6d9a
echo 'Loading Linux 2.6.32...'
linux /vmlinuz-2.6.32 root=/dev/sda8 ro single
echo 'Loading initial ramdisk ...'
initrd /initrd.img-linux2.6.32 ///!!!!!!!这是新加的
}
修改完成并保存后,重新启动系统,应该出现让你选择内核的菜单。
六、准备Helloworld源代码和Makefile文件
$mkdir hello
$cd hello
$gedit helloworld.c Makefile &
helloworld.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 = helloworld.o
K_DIR = $(shell uname -r) PWD = $(shell pwd)
all:
make -C /lib/modules/$(K_DIR)/build M=$(PWD) modules //这里命令需要前边空一个tab的大小
clean:
make -C /lib/modules/$(K_DIR)/build M=$(PWD) clean //这里命令需要前边空一个tab的大小
七、编译并安装模块
1)编译
$cd ~/hello
$make
2)安装模块
$sudo insmod helloworld.ko
查看 $ lsmod | grep helloworld
3)移除模块
$rmmod helloworld
查看 $lsmod | grep helloworld
4)查看模块信息
$dmesg | tail
这就是我的流程,刚开始学具体步骤还不太搞懂,先照猫画虎来一遍总归是有益处的。

浙公网安备 33010602011771号