标题:
PC_linux以及ARM_linux下驱动开发第一例实践
[打印本页]
作者:
m1_ljp
时间:
2013-3-15 14:01
标题:
PC_linux以及ARM_linux下驱动开发第一例实践
今天尝试了
linux
下的
驱动
开发
,花了一个上午的时间终于在
PC
和
ARM
上跑成功了经典驱动
教材
《
LINUX
设备驱动
程序
》的第一个例子
hello.c
。看似简单的程序折腾了我不少时间。
由于我用的
redhat9.0
,以及
arm
上以前烧录的是
linux2.4.20
的
内核
因此只能用《
LINUX
设备驱动程序》第二板中的
源代码
,《
LINUX
设备驱动程序》第三版的源代码是
for 2.6
的内核的。
2.4
与
2.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
欢迎光临 电子技术论坛_中国专业的电子工程师学习交流社区-中电网技术论坛 (http://bbs.eccn.com/)
Powered by Discuz! 7.0.0