您的位置:首页 > 其它

分析几个我在加载动态字符驱动模块时候遇到的问题

2012-03-23 09:02 281 查看
在搭建好nfs网络后,我现在做的是尝试加载一个最简单的动态字符驱动模块。hello_word_driver,功能是在装载的时候输出hello,world ,在卸载的时候输出Goodbye, cruel world。

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");

return 0;

}



module_init(hello_init);

module_exit(hello_exit);

Makefile的程序如下

ifneq ($(KERNELRELEASE),)

obj-m := hello.o

else

KDIR=/lib/modules/2.6.24.4/build

all:

make -C $(KDIR) M=$(PWD) modules

clean:

rm -f *.o *.ko *.mod.c *.mod.o *.order *.symvers

endif

步骤一:

Makefile 如何编写 其中 KDIR的路径指向的是什么?这个问题纠结了我很长时间。最后弄清楚了,必须是内核树的路径,即内核目录的路径。(就以我使用的ubuntu11.10为平台移植这个helloworld驱动,那么这个路径指向的是 lib/modules/3.0.0-12-generic/build ,可以通过uname -r的指令查看当前系统内核版本。)所以我要使用的是内核为2.6.24的开发板linux,开发板是由扬创公司提供的。所以在完成在hello_world_driver目录里面进行make的之前,首先要有2.6.24源代码的内核树,所以接下来我就对2.6.24内核源代码的内核树进行了建立。

步骤二:

对内核树的建立过程,要先从配置源代码开始,开始使用扬创开发板提供的2.6.24源代码,然后使用里面的config_T35C_TS改成.config,然后使用make menuconfig对内核进行编译。然后直接保存以后,输入make指令。
这时候出现的问题是make : arm-linux-gcc 命令未找到,此时根据博文http://blog.sina.com.cn/s/blog_7d3976fc01012c2d.html 我就是用
sudo -s进入 root指令 ,根据文中的要求,
我更改
gedit /etc/profile,
在最后加上
export PATH=$PATH:/usr/locla/arm/4.3.1/bin
最后奇怪的是我最后一句话已经加了,就是根据扬创实验手册上面的要求假的,但是使用root后,居然可以make了。
然后又碰到一个问题,出错信息:CC kernel/bounds.s

cc1: error: invalid option `abi=aapcs-linux'

make[1]: *** [kernel/bounds.s] Error 1

make: *** [prepare0] Error 2
原因:旧编译器可能是用OABI的,而配置内核时又选择了使用EABI的,修改内核配置:

Kernel Features ---->Use the ARM EABIto compile the kernel
这个问题虽然在我后面使用的在kernel.org的代码里面没有出现,但是在扬创的代码里面出现了,而且去掉后确实好了,参考博文http://blog.csdn.net/yming0221/article/details/6603901
最后使我放弃使用扬创源代码的原因是因为在配置好源代码后,输入make后,提示出现提示缺少
include/asm-arm/unistd_32.h,而且我查看了很多linux内核源代码,居然都没有asm-arm这个文件夹,更别提找不到unistd_32.h这个头文件,所以这个问题至今没有解决,但是我查找的都是之后的版本,可能这个版本之前的源代码里面有,但没有去找,所以没有解决。
没有办法,我只得从网上下来2.6.24的源代码,然后使用扬创开发板提供的config_T35C_TS,放入2.6.24的源代码里面,并改名为.config,并在对menuconfig进行简单的配置,最后进行make。
此时遇到2个问题:
1 :因为重启过ubuntu 所以,所以在make后提示,提示arm-linux-gcc 命令未找到。然后使用上述方法解决。
2 : 出现一些警告,而且在make modules_install之前,所以看到一篇博文,得以解决
http://athurg.blog.35.cn/?tag=warning-syscall-not-implemented。虽然警告不影响结果,但是这篇博文确实得以解决。
3 :花了一点小时间在小细节上面,把make modules_install误打成make modules-install,可能收到那个uboot里面更新内核的时候输入 run
kernel-install的影响。所以以为是问题2中的警告导致问题3的出现,才去解决问题2。告诫自己要细心~!!!!!

步骤三:

在解决好以上问题后,顺利编译出hello.ko.通过nfs传送到开发板的/mnt文件夹里面去 ,然后进行insmod 最后出现问题,
[root@utu-Linux]\$ insmod -f hello.ko

hello: version magic '2.6.24 mod_unload ARMv4 ' should be '2.6.24.4 mod_unload '

insmod: cannot insert 'hello.ko': invalid module format
字面意思上面好像是编译的内核版本号不符吧,我下载的内核源代码是2.6.24的啊,在minicom里面输入uname -r发现 :2.6.24.4,开发板的linux内核版本。和我下载的内核源代码版本有一些区别。通过查看博文http://blog.csdn.net/dg1683wen/article/details/6861044
在ubuntu中进入2.6.24的源代码,进入menuconfig 继续配置General config ->(
)Local version -> 括号中加入如下内容:“.4”保存退出,再重新编译内核,驱动模块,加载模块,结果终于成功:
[root@utu-Linux]\$ insmod hello.ko

Hello, world

[root@utu-Linux]\$ rmmod hello.ko

Goodbye, cruel world

小结:经过几天的软磨硬泡,终于在开发板上面加载最简单的字符驱动模块。
1对驱动程序的.c和makefile文件进行编写
2对源代码内核树的建立,
make menuconfig
使用开发板提供的config进行覆盖,修改Makefile文件第193对arm的支持,“ARCH=(SUBARCH)” "CROSS_COMPILE ?="修改为“ARCH=arm” “CROSS_COMPILE=arm-linux-”。及对机器码进行修改
,arch/arm/mach-s3c2440/mach-s3c2440.c的MACHINE_START(S3C2440,”SMDK2440")这一行中的s3c2440,然后看379行将362改为5244(扬创开发板的机器码,好像在uboot里面可以更改)。这要参考天谴开发板手册,吐槽下扬创(开发板给的资料很不给力!)。当然这里我主要是建立内核树,所以只是进行小的修改,使用扬创的config文件进行覆盖。内核配置完后,
make 对内核进行编译
make bzImage 编译压缩形式的内核

make modules 编译选择的模块
make modules_install
(要重新配置编译,make disc'le'a)
3 移植到开发板。
insmod
rmmod
lsmod 查看加载的驱动
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐