linux驱动开发之HelloWorld_移动开发_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > 移动开发 > linux驱动开发之HelloWorld

linux驱动开发之HelloWorld

 2014/5/9 18:32:47  迷途的孤舟  博客园  我要评论(0)
  • 摘要:最近实习,公司项目搞的是平板开发,而我分配的任务是将驱动加载到内核中。准备工作,必要知识了解:加载有两种方式,一种是动态加载和卸载即模块加载,另一种是直接编译进入内核;驱动的种类很多,分为char(字符设备)block(块设备)input(输入设备)network(网络接口)等等。作为小白一个,从最简单的HelloWorld开始。HelloWorld源程序:#ifndefMODULE#defineMODULE#endif#include<linux/init.h>
  • 标签:Linux helloworld 开发

      最近实习,公司项目搞的是平板开发,而我分配的任务是将驱动加载到内核中。

  准备工作,必要知识了解:加载有两种方式,一种是动态加载和卸载即模块加载,另一种是直接编译进入内核;驱动的种类很多,分为char(字符设备) block(块设备) input(输入设备) network(网络接口) 等等。

      作为小白一个,从最简单的HelloWorld开始。

      HelloWorld源程序:

#ifndef MODULE
#define MODULE
#endif

#include <linux/init.h>
#include <linux/module.h>

MODULE_LICENCE("GPL");

static int hello_init(void)  
{     
        printk("Hello world\n");
        return 0;
}   
    
static void hello_exit(void)
{   
        printk("Goodbye World\n");
}   
    
module_init(hello_init);
module_exit(hello_exit);

此程序非常简单,但需注意的是对于一个驱动程序,有一个入口函数hello_init(),相当于main函数,此处两个头文件问题比较大,后面在说!

建立好源程序之后,需要一个makefile文件,来执行此程序:

obj-m := HelloWorld.o
KDIR  := /lib/modules/$(shell uname -r)/build
PWD   := $(shell pwd)
default:
    【tab】make -C $(KDIR) M=$(PWD) modules
在Helloworld源文件和Makefile文件所在目录下直接make,这是以上一般网上教程的做法,但我这却无法编译通过,报的错误是:无法找到该文件或目录,经过一番努力,发现问题在内核源码树上。

      为什么要装内核源码树呢?原因是源码树中有相应的头文件和函数的实现,没有源码树,自己写的应用程序就没办法执行起来。驱动程序中自己写的要包含哪些头文件,都是在源码树下的文件夹里,这个都包含在内核里了。

      驱动程序作为一个模块连接到内核模块并运行在内核空间里。引用LDD上的一句话“因为2.6内核的模块要和内核源代码树中的目标文件连接,通过这种方式, 可得到一个更加健壮的模块加载器,但是需要这些目标文件存在于内核目录树中”。这里提到的内核目录树就是我们在运行我们自己构造的模块前,需要在我们的系统中已经配置好内核源代码树,然后在把构造好的目标模块和内核树连接起来再运行。

      查看自己的系统里有没有配置好内核树的方法:在/lib/modules/2.6.35-30-generic目录下面,看看有没有build文件夹,如果有的话,说明我们的系统里已经有内核树了,如果没有的话,就需要自己构建一个内核树了。

  构造内核树的步骤如下:

1、安装编译内核所需的软件(要用 make menuconfig命令的话得安装,用make oldconfig的话就不用安装)。

class="codebox">
sudo apt-get install build-essential kernel-package libncurses5-dev fakeroot


2、下载内核源码

apt-cache search linux-source


执行用这条命令系统会提示你安装适合你内核版本的内核源码

 apt-get install Linux-source-2.6.35


执行这条命令就会自动下载并安装适合我系统内核的Linux-source-2.6.35这个内核源码

3、解压内核源码包
进入/usr/src/,能找到linux-source-2.6.35.tar.bz2,用解压命令解压之。

tar jxvf linux-source-2.6.32.tar.bz2



4、拷贝/boot目录下的config-2.6.35-30-generic到刚才解压好的目录下并改名为.config

 sudo cp /boot/config-2.6.35-30-generic /usr/src/linux-source-2.6.35/.config



5、切换到root用户,进行内核配置

sudo -i
      cd /usr/src/linux-source-2.6.35
      make menuconfig


接着会出现一个配置界面,选择最后面的两个选项:
load an Alternate configuration File 和 save an Alternate configuration File
分别保存并退出,再退出配置环境。
6、编译内核
这个内核的编译要在管理员账号下运行

#cd /usr/src/linux-source-2.6.35
      #make


如果电脑是双核的话可以在make后面加个参数,例如:

make -j4

make的过程时间比较长,我在虚拟机里编译用了2小时左右。。。

再执行

#make bzImage

结束后,可以看到在当前目录下产生一个vmlinux文件。

7、编译模块
在编译模块时候可能会出现如下问题:
(ld: /ubuntu/omnibook/sections.lds: No such file: No such file or directory)

解决方法是:
在/usr/src/linux-source-2.6.35/ubuntu/omnibook/Makefile中的ifeq($(KERNELRELEASE),)的前面增加一句:

 PWD=$(shell pwd)



然后再开始编译模块

#make modules

再执行

make modules_install

命令后在/lib/modules目录下面产生一个目录

后再测试HelloWorld模块:

1、加载模块到内核中:

#insmod ./HelloWorld.ko

2、lsmod 这个命令可以查看当前所有的驱动模块,结果应该显示hello 692 0

#lsmod|grep HelloWorld

3、把hello这个模块移除掉

#rmmod HelloWorld

4、由于printk不会把结果输出到终端中,所以用如下命令查看结果:

dmesg |grep world

编译通过,会产生HelloWorld.ko文件

但出现的另一个问题是可以加载,但无法卸载,待解决。

 

 

发表评论
用户名: 匿名