安装主线内核,配置并构造内核树

http://blog.sina.com.cn/s/blog_6444798b0100q9k2.html


背景:操作系统:ubuntu10.04 

 
  本文是参考了网上多篇帖子而写的算不上什么原创。唯一值得欣慰的只不过在本机上实现罢了。因为毕竟失败了几次。也因为本人是初学驱动编程很多简单的问题在我来说是相当的困难的。望有识之士不要笑话。最后,希望本文能给刚学驱动而还没开头的人提供一些帮助。
          首先申明,本文有参考到别人写的文章。
   (http://www.linuxidc.com/Linux/2010-11/29904.htm)
  (http://xiaonannanya.blogbus.com/logs/72097165.html)


      刚看 O'REILLY写的《LINUX 设备驱动程序》时。作者一再强调在编写驱动程序时必须建立内核树。所谓内核树,我的理解和网上资料说的一致就是内核源码的一种逻辑形式。那怎么建立呢?为此上网“翻云覆雨”起来而结果却是“惨败而归“。为此托了一天又4个小时(当然包括吃饭睡觉的时间),连个简单的 hello wrold都没实现。(书中p22页最简单也最没用的驱动事列)
    不过功夫不负有心人。在今天终于弄明白了怎么回事。下面就请让我慢慢道来吧。
    先查看自己OS使用的内核版本:
  shana@shana:~$ uname -r
  2.6.22-14-generic

  如果安装系统时,自动安装了源码。在 /usr/src目录下有对应的使用的版本目录。例如下(我是自己下的)

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内核源码包

  1. ljj@ljj-laptop:~$ sudo apt-cache search linux-source
  2. [sudo] password for ljj:
  3. linux-source - Linux kernel source with Ubuntupatches
  4. linux-source-2.6.32 - Linux kernel source for version 2.6.32 with Ubuntu patches
然后选定要下载的源码包:
  1. ljj@ljj-laptop:~$ sudo apt-get install linux-source-2.6.32

下载完成后,在/usr/src下,文件名为:linux-source-2.6.32.tar.bz2,是一个压缩包,然后用

命令解压即可获得Linux内核的源代码:

  1. ljj@ljj-laptop:/usr/src$ sudo tar jxvflinux-source-2.6.32.tar.bz2

2.然后在Linux内核源码目录/usr/src/linux-source-2.6.32目录下面用老的方法配置好Linux内核:
  1. ljj@ljj-laptop:/usr/src/linux-source-2.6.32$ sudo makeoldconfig

3.然后执行:
  1. ljj@ljj-laptop:/usr/src/linux-source-2.6.32$ sudo makebzImage
这个过程大概需要半个小时左右。。。执行完成后会在当前目录下面生成一个文件vmlinux.o

4.然后编译模块:
  1. ljj@ljj-laptop:/usr/src/linux-source-2.6.32$ sudo makemodules
这个过程又是大概半个小时。。。

5.然后便可以安装模块了:
  1. 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]  ubuntu/omnibook/omnibook.o
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

  这是程序的输出。

http://blog.sina.com.cn/s/blog_6444798b0100q9k2.html http://blog.sina.com.cn/s/blog_6444798b0100q9k2.html
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值