首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

PC_linux以及ARM_linux下驱动开发第一例实践

PC_linux以及ARM_linux下驱动开发第一例实践

今天尝试了linux下的驱动开发,花了一个上午的时间终于在PCARM上跑成功了经典驱动教材LINUX设备驱动程序》的第一个例子 hello.c。看似简单的程序折腾了我不少时间。



由于我用的redhat9.0,以及arm上以前烧录的是linux2.4.20内核因此只能用《LINUX设备驱动程序》第二板中的源代码,《LINUX设备驱动程序》第三版的源代码是for 2.6的内核的。2.42.6的驱动模型做了改动,因此开发的过程,有点不大一样,有兴趣的人可以自己在网上搜索看看。不过我也会简单比较一下不同点.



首先拿到hello.c的源代码:

Ldd2(《LINUX设备驱动程序》的简称)给的如下:



/*



* $Id: hello.c,v 1.10 2001/07/17 10:30:02 rubini Exp $


*/


#define MODULE

#include <linux/module.h>



/*



* These lines, although not shown in the book,



* are needed to make hello.c run properly even when



* your kernel has version support enabled




*/





int init_module(void)
{ printk("<1>Hello, world\n"); return 0; }

void cleanup_module(void)
{ printk("<1>Goodbye cruel world\n"); }



你会发现这个程序其实是有问题的:我做了简单修改:



/*



* $Id: hello.c,v 1.10 2001/07/17 10:30:02 rubini Exp $


*/


#define MODULE

#include <linux/module.h>



/*




* These lines, although not shown in the book,



* are needed to make hello.c run properly even when



* your kernel has version support enabled



*/



MODULE_LICENSE("GPL");
//
添加这句话,否则在PC上编译的时候会出现

//警告,没有注册

//2.6的注册不同:

//MODULE_LICENSE("Dual BSD/GPL");

#include <linux/kernel.h>
//
添加了这个头文件printk函数在里面

int init_module(void)
{ printk("<1>Hello, world\n"); return 0; }

void cleanup_module(void)
{ printk("<1>Goodbye cruel world\n"); }



//2.6内核中这两个函数改成了

/*

static int hello_init(void)

{


printk(KERN_INFO " Hello World enter\n");



return 0;


}



static void hello_exit(void)

{


printk(KERN_INFO " Hello World exit\n ");


}



module_init(hello_init);

module_exit(hello_exit);

*/



程序修改好后就可以编译了:

#gcc –I /usr/src/linux2.4/include/linux –c hello.c

//说明:写内核或内核模块不能用写应用程序时的系统调用或函数库

//
-I
后面是就是编译模块专用的内核库路径

//注意
这里编译驱动模块
只需编译到 *.o格式就可以了



编译好后我们执行:

#lsmod
//
看看现在有那些驱动在内核中

#insmod hello.o
//
加入我们刚刚编译的驱动


//
这里可能会报linux版本不匹配的错误

解决方法:1.无视它
改用#insmod –f hello.o

2. 有人提供这样的建议:

进入/usr/include/linux/目录

version.h第一句

#define UTS_RELEASE 2.4.20-1"

改成

#define UTS_RELEASE "2.4.20",这样就可以了。以你自己为准

这时候我们查看打印信息:printk函数相关内容与优先级这里不赘述,自己查看~

由于我们在xwindow下使用的是虚拟终端,所以终端不回打印,在这里查看:

#cat /var/log/messiges

发现已经有Hello, world输出了

接下来:

#rmmod hello
//
卸载驱动,注意不是hello.o

同样在messiges里有good bye输出了





//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

//
分隔线

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

接下来我们交叉编译该文件,方法与上面一样

代码稍微修改一下,需要删除:



MODULE_LICENSE("GPL");
//
这句话,否则交叉编译不过去,不明,达人指教下!!



然后我们编译:



/opt/host/armv4l/bin/armv4l-linux-gcc –D__KERNEL__-I /usr/src/linux-2.4/include/linux/ -DMODULE –c hello.c



//
/opt/host/armv4l/bin/armv4l-linux-gcc
我的交叉编译gcc

//
–D__KERNEL__
-DMODULE
代表编译的是内核模块

//
-I
同上



这时生成了hello.o,载到arm板子上,执行

#insmod –f hello.o
//
无视版本警告

//会直接输出打印信息 hello world 因为这不是虚拟终端

#rmmod hello
//
卸载
打印信息 goodbye
返回列表