第一个驱动程序

从搭建后平台,到第一个驱动的程序下载并成功执行,又经历了颇多挫折:

首先就是驱动源码,可以照搬别人的源码,写一个hello程序,不过这里有一个很大的问题,就是头文件问题,不同版本的内核,头文件的位置是不一样的,这里要注意。可以参考上篇博客,在此不再细说。

其次就是源码树问题,因为在编译驱动模块时要用到源码树,ubuntu安装时自身并没有源码,如果,要编译的驱动是在ubuntu上运行,那就需要安装源码,方法不再细说。因为我们编译的驱动是要在开发版上运行的,所以就需要开发板内核对应的源码,因为我们在系统移植的时候,已经下载过linux内核,解压在/work/kernel/linux-2.6.30目录下。

hello.c的源码为:

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

MODULE_LICENSE("GPL");


static int __init EmbedSky_hello_init(void)
{
	printk("<1>\n Hello,EmbedSky\n");
	printk("<1>\n This is first driver program.\n\n");
	return 0;
}

static void __exit EmbedSky_hello_exit(void)
{
	printk("<1>\n Exit\n");
	printk("<1>\n Goodbye EmbedSky!\n\n");
}


module_init(EmbedSky_hello_init);
module_exit(EmbedSky_hello_exit);

然后就是编译成ko,天嵌手册上是直接将hello.c加入源码树,在源码树中修改makefile文件,将hello.c编译成模块。不过觉得这种方法太麻烦,可以在任意位置任建目录,把源码放进去,再写一个makefile,通过命令:make -C  源码树目录 M=模块源码目录 modules 来生成ko文件。

在这里遇到了很大一个麻烦,就是当要编译模块的源码位置,如果在模块源码位置编译,用$(pwd)代替当前目录,这样编译make时会出现很大的错误,错误代码如下:


make[1]: `include/asm-arm/mach-types.h' is up to date.
  CHK     include/linux/utsrelease.h
  SYMLINK include/asm -> include/asm-arm
  CALL    scripts/checksyscalls.sh
:1097:2: warning: #warning syscall fadvise64 not implemented
:1265:2: warning: #warning syscall migrate_pages not implemented
:1321:2: warning: #warning syscall pselect6 not implemented
:1325:2: warning: #warning syscall ppoll not implemented
:1365:2: warning: #warning syscall epoll_pwait not implemented
  GZIP    kernel/config_data.gz
  IKCFG   kernel/config_data.h
  CC [M]  kernel/configs.o


刚出现这个错误时,一直纠结于stdin,不知道怎么修改,后来看到了一篇帖子,说可以通过修改$(pwd)来解决,说是不支持pwd,必须把pwd换成模块源码所在的目录,开始觉得不应该是这里的问题,因为我echo $(pwd)时,就会显示当前的目录,所以就没改。然后试了n多方法,包括天嵌移植手册中不另写makefile,直接在源码中makefile修改,还是不行。不得以时才替换pwd,然后竟然成功了,虽然现在还不知道以前为啥错了。


最终的makefile

all:
	make -C /work/kernel/linux-2.6.30 M=/work/nfs_root/hello modules 
clean:
	make -C /work/kernel/linux-2.6.30 M=/work/nfs_root/hello modules clean
	rm -f modules.order 
	
obj-m  =hello.o


然后就Succeed.

其实在这里我还犯了一个低级的错误,就是源码树的位置,以前看的博客中,说的是建立在宿主机ubuntu下的源码树,和板子用的内核源码树可是大相径庭,make时,源码树的位置一定要搞清,在板子上运行的驱动,源码树是板子的源码树,而不是宿主机ubuntu的!


你可能感兴趣的:(出现问题及解决方案,嵌入式)