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

 

这就是我的流程,刚开始学具体步骤还不太搞懂,先照猫画虎来一遍总归是有益处的。

      

 

 

posted @ 2013-11-07 09:19  阿尔登  阅读(635)  评论(1)    收藏  举报