搭建linux驱动开发环境(配合LDD阅读)

来源:互联网 发布:普华永道部门 知乎 编辑:程序博客网 时间:2024/04/30 11:30
转自:http://www.cnblogs.com/yiru/archive/2012/11/26/2789681.html(博主:勒达与天鹅)
仅供学习参考

在学习ldd需要搭建linux驱动开发环境,在网上找到这篇文章http://xuxd32.blog.163.com/blog/static/481219332011814112045622/
按照上面这篇文章的步骤会遇到许多困难,经过近2天的摸索和修改之后,终于成功。
以下为修正后的文章。
 
 
在看《Linux Device Driver Third Edition》的时候,作者其中提到Setting Up Your Test System。他只是指出:为2.6.X编写模块,首先,要求你在Linux系统上构建和配置内核树,对于2.6版本的内核来说,已有的头文件已经足够了,但是2.6的模块链接着内核源码树中的对象文件。这样模块加载器将更健壮,但是也要求这些对象文件存在。所以驱动开发的第一件事情就是构建内核源码树。
     他没有提到如何构建,我从网上找了一些资料,构建了自己的内核树,写出来大家分享一下,本人用的是Ubuntu  Linux 10.10 装在虚拟机里面,要求你的虚拟机硬盘容量最少不低于10G,本人10G,仍有提示硬盘容量不够,但是还是完成了内核树的构建,15G硬盘容量应该够了。
  首先查看自己的linux内核的版本,在终端中输入: uname -r
  可以看到自己的内核版本,我的内核版本为:2.6.32-35-generic
  然后进入 usr/src/下查看是否有linux-source 文件,一般是没有的,至少我的ubuntu没有
  没有就去网上查找,在终端中输入: apt-cache search linux-source
  可以看到结果:
   linux-source - Linux kernel source with Ubuntu patches
   linux-source-2.6.35 - Linux kernel source for version 2.6.35 with Ubuntu patches
  选择同自己内核相应的linux-source版本安装。在终端中输入:
  sudo apt-get install linux-source-2.6.35

    下载完毕后在/usr/src/下有个名为linux-source-2.6.35 的文件夹,在该文件夹里面有linux-source-2.6.35.tar.bz2    ,解压到/usr/src/linux-source-2.6.35/目录下。
    解压方法,在终端中输入: sudo -i 切换到根用户下,定位到/usr/src/linux-source-2.6.35/目录下,在终端中输入:tar jxvf linux-source-2.6.35.tar.bz2 
    解压得到文件源代码文件,该源代码文件夹名称为linux-source-2.6.35,进入该目录,注意此时在终端中应该是这样的:
   
    开始配置内核,选择最快的原版的配置(默认)方式:在终端中输入:make oldconfig
    
    完成后,先去配置/usr/src/linux-source-2.6.35/ubuntu/omnibook/Makefile文件。
    不然会出现ld: /ubuntu/omnibook/sections.lds: No such file: No such file or directory错误
    在根用户下打开该Makefile文件,将其中的PWD=$(shell pwd)剪切到ifeq ($(KERNELRELEASE),) 前面。然后保存。
    
    然后编译模块,定位到源代码文件夹下,在终端中输入: make modules
    等待将近1个小时,该编译完成。完成之后,安装模块,在终端中输入:make modules_install
    至此,源码树构建完成,重启系统,
    将《Linux Device Driver Third Edition》中的第一个例子运行下吧。    
   

文中代码:helloworld.c

#include <linux/init.h>
#include <linux/module.h>
MODULE_LICENSE("GPL");

static int hello_init(void){
    printk(KERN_ALERT "hello world!\n");
    return 0;
}

static int hello_exit(void){
    printk(KERN_ALERT "Goodbye cruel world!\n");
    return 0;
}

module_init(hello_init);
module_exit(hello_exit);

 

Makefile文件内容:

ifneq ($(KERNELRELEASE),)
obj-m := hello.o
else
PWD := $(shell pwd)
KVER ?= $(shell uname -r)
KDIR := /lib/modules/$(KVER)/build
all:
    $(MAKE) -C $(KDIR) M=$(PWD)
clean:
    rm -rf .*.cmd *.o *.mod.c *.ko .tmp_versions *.symvers *.order
endif

 

编译,在终端中输入:make

make -C /lib/modules/2.6.32-35-generic/build M=/source/test/ldd
make[1]: Entering directory `/usr/src/linux-headers-2.6.32-35-generic'
  LD      /source/test/ldd/built-in.o
  CC [M]  /source/test/ldd/hello.o
/source/test/ldd/hello.c: In function '__exittest':
/source/test/ldd/hello.c:16: warning: return from incompatible pointer type
  Building modules, stage 2.
  MODPOST 1 modules
  CC      /source/test/ldd/hello.mod.o
  LD [M]  /source/test/ldd/hello.ko
make[1]: Leaving directory '/usr/src/linux-headers-2.6.32-35-generic'

查看生成的模块 modinfo hello.ko

加载模块 insmod hello.ko

未提示出错。成功

查看已加载模块 lsmod
删除模块 rmmod hello.ko

为什么加载和删除模块时没有显示源码中printk的打印信息?书中说明,如果不出现在终端,则会写进 syslog 文件中
 cat /var/log/syslog |grep world(或者全部打印,看最后两行)

Nov 28 11:07:47 ubuntu64 kernel: [ 6942.233442] hello world!
Nov 28 11:08:00 ubuntu64 kernel: [ 6955.202296] Goodbye cruel world!

啊哈哈哈哈哈哈哈哈,成功!!!!

驱动开发实验环境搭建完成。

0 0
原创粉丝点击