环境:ISE 14.4 + WIN7_64bit+VMware 9.0+Ubuntu 10.04 _i386版本
本文是作者试图为Zedboard编写linux驱动,可是在官方下载了对应的ISE 14.4的工程文件后,成功添加了自己定义的IP核,并且导入了SDK,生成了FSBL和BOOT.bin,并添加上了zImage、根文件系统、修改后的设备树,满以为会很顺利,可是一路走来是困难多多啊!最后在@马岷-没上大学老师和@王康康+中南同学的热心帮助下,终于搞定了!真的是非常谢谢,要不是他们,我估计现在还在纠结着呢,现在就本人在这一路中遇到的一些问题分享给大家,希望能够避免一些麻烦吧!
准备工作:
1、下载https://github.com/Digilent/linux-digilent对应的内核源码,方法
git clone https://github.com/Digilent/linux-digilent (最好创建自己存放源码的目录,笔者存放在/home/jefby/zed)
2、http://www.digilentinc.com/Products/Detail.cfm?NavPath=2,400,1028&Prod=ZEDBOARD
到该网站下载Linux Hardware Design for ISE 14.4文件
具体步骤:
1、编译内核,构建内核源码树
在官网https://github.com/Digilent/linux-digilent下载对应的内核源码,建议直接git clone,笔者就是因为麻烦,所以自己下载了zip文件,然后在linux下各种编译,各种调试,可是总是出现如图1所示的问题,
图1
搞了一天多,可总是出现这个错误,尝试了各种办法,也尝试着去Xilinx的论坛发帖,也去Zedboard的论坛去发了话题,可是一直没消息,最后,晚上的时候经@马岷-没上大学老师指点,才发现原来是自己下载的源码有问题,并且编译内核的方法不对,笔者刚开始是怎么做的呢?
make xilinx_zynq_defconfig
make ARCH=arm CROSS-COMPILE=arm-xilinx-gnueabi-
其实正确的步骤应该是
make ARCH=arm CROSS-COMPLIE=arm-xilinx-gnueabi- digilent_zed_defconfig
(第一步应该配置内核,生成正确的.config文件)
make –j2(第二步才能正确的编译内核,说明下j2是指用两个处理器,笔者在VMware里面配置了双核,主要是为了速度问题,也可以直接make)
这样就成功构建了内核源码树,内核文件在目录<linux-源码目录>/arch/arm/boot/zImage下,将其拷贝到SD卡里面,另外,笔者在过程中还遇到了一个问题,如图2所示:
图2
这个问题是驱动程序和内核版本不兼容,在linux下因为各个内核版本之间可能的接口实现不同,故对版本的检查是非常严格的,笔者因为刚开始没按官方的步骤走,跟官方编译的内核不同,所以会出现这个问题。
2、编写测试驱动程序
我们可以试着编写一个简单的Hello,world!驱动程序来测试模块是否能够正确的插入内核,Hello,world!详细代码如下所示:
#include <linux/init.h>
#include <linux/module.h>
MODULE_LICENSE("Dual BSD/GPL");
MODULE_AUTHOR("jefby");
static int hello_init(void)
{
printk(KERN_ALERT "Hello, world!\n");
printk(KERN_ALERT "I'm jefby!\n");
return 0;
}
static void hello_exit(void)
{
printk(KERN_ALERT"Goodbye, cruel world\n");
}
module_init(hello_init);
module_exit(hello_exit);
Makefile文件如下所示:
obj-m := hello.o
KERNELDIR := /home/jefby/zed/linux-digilent(这个地方是你的内核源码目录)
PWD := $(shell pwd)
modules:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
modules_install:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules_install
clean:
rm *.o *.ko
然后新建文件夹,将这两个文件放进去,切换到该文件夹下,直接make。如图3所示
图3
然后将编译成功的hello.ko文件拷贝到你的U盘里面,此时,将和从网站http://www.digilentinc.com/Products/Detail.cfm?NavPath=2,400,1028&Prod=ZEDBOARD下载的DSD-0000414 ,Linux Hardware Design for ISE 14.4文档中的sd_image中的所有文件拷贝到SD卡里面,并用第一步构建的内核文件zImage替换掉原文件夹中的zImage,然后,连接上电源,使用USB Cable线将USB和UART口连接起来,并打开超级终端,新建一个简单的串口连接,如此,便出现如下所示的启动界面,
图4
说明我们编译的内核是正确的,此时,将U盘和USB-OTG线连接起来,如图5所示,即表示我们的U盘设备名为/dev/sda4
图5
此时,将其挂载到目录/mnt下,
Mount /dev/sda4 /mnt
切换到hello.ko文件目录下,输入命令insmod ./hello.ko
如图6所示,
图6
输出Hello,world!I'm jefby!,即驱动模块成功加载,如此便大功告成了!下一步我们就要编写自己的IP核,并为其在linux下编写驱动程序,实现简单的功能了!
最后,对于这次纠结了这么久的问题,自己做了下简单的总结:
1、官方的文档是非常重要的,需要认真阅读,笔者在编译内核的闲暇时间中,无意中打开了从digilent官网下载的文档Digilent Embedded Linux Guide,忽然发现这上面竟然有详细的内核编译方法,而我自己以前也看过,但是当时就简单的只是看了一下,并没有上心,出现问题了也没有去看文档,只是自己在瞎整,不应该啊!
2、对于下载的文件需要校验下数据是否正确,笔者因为偷懒,没有用git clone,直接用迅雷下载的是zip版本的,结果数据有错,怎么编译都不成功!
3、出现错误了先要仔细思考可能出现错误的地方,并具体分析,这样长此以往,对自己的提升很快。
4、实在解决不了的问题,请上论坛发贴求助,这次真的是非常感谢@马岷-没上大学老师