5、联网更新并安装最新的树莓派Raspbian OS,编译生成PCIe ko驱动文件

5.1、更新树莓派系统
进入VNC虚拟桌面之后,打开里面的CMD窗口,输入update指令,将树莓派系统更新到最新版本,因为出厂的时候,树莓派核心板里面的系统不一定是最新的,另外,在进行更新的时候,一定要保证树莓派的Wifi能上网。
具体操作的指令过程如下:
1) 首先通过更新存储库软件包列表:sudo apt update
2) 更新完成后,再运行升级命令:sudo apt dist-upgrade
3) 按照所有提示进行操作,然后等待树莓派升级完成后,键入:sudo apt clean
这条指令可以将升级过程中已下载的所有不需要的文件清除掉,节省空间。
4) 输入重启指令:sudo reboot
树莓派重新启动后,即可进入最新版本的Raspbian OS!
5.2、在树莓派系统里面添加后续需要参与编译的Headers和Build文件夹
使用树莓派编译Linux驱动时,需要在/lib/moudles/*/ 目录下存在build文件夹以及相关的头文件,但是树莓派为了节省内存空间,所以出厂原生的Raspbian系统是没有这个Build文件夹的。此时,我们需要安装Linux Headers内核相关文件。
同理,树莓派下的Linux Headers安装不同于其他平台,需要使用带管理员权限的命令进行安装:sudo apt install raspberrypi-kernel-headers
安装完成后,打开树莓派/lib/modules/5.10.17-v7l+路径,就有了相应的build文件夹了,如图9-61所示。这个Build里面包含了很多树莓派系统所需要的编译文件。

细心的用户,发现了,在modules文件夹里面有4个跟Raspbian系统相关的文件夹,如图9-62所示,为什么我们选择的是5.10.17-v7l+?是因为我们买的这个工业级树莓派CM4里面的CPU ARM内核是Cortex-A72,对应的版本是V7L,用户可以通过输入sudo uname -a查看到,如图9-63所示。里面还有一个V8的,这个说明Raspbian树莓派系统支持V8架构的ARM芯片,在后续Pro6这本书里面,我们重点给用户介绍国产的RK3399芯片,就是V8架构,支持64位Linux系统。


5.3、从Xillybus官网上下载Linux系统下的FPGA PCIe接口c文件和makefile文件(通过VNC拷贝到树莓派里面并进行解压)
首先,在浏览器里面输入Xillybus.com,然后找到PCIe资料的下载链接:http://xillybus.com/pcie-download/,在这个页面的下方找到支持Linux系统的PCIe驱动源文件,如图9-64所示。下载下来的是一个名为“xillybus.tar.gz”压缩包,里面主要包含Makefile编译约束,udev文件和简单的C语言测试程序。

接下来,用户有两种方式可以将这个xillybus.tar.gz文件拷贝到树莓派上,一是用U盘拷贝,二是用VNC远程虚拟桌面直接传输,这里推荐大家用VNC来操作。在VNC虚拟桌面的上方隐藏了一个工具栏,如图9-65所示。

将鼠标移到VNC虚拟桌面中间顶部,出现工具栏之后,点击中间的“Transfer files”按钮,在弹出来的对话框里面将我们刚刚从Xillybus官网上下载到本地电脑的压缩包文件传输到树莓派桌面上,如图9-66所示。

然后点击树莓派左上角的“新建文件夹”按钮,在pi根目录下,新建一个名为“Xillybus-PCIe”的文件夹,如图9-67所示。

再把树莓派桌面上的压缩包文件“xillybus.tar.gz”利用鼠标左键按住之后,直接拖拽到刚刚新建的“Xillybus-PCIe”文件夹里面,如图9-68所示。

然后右击“xillybus.tar.gz”压缩包,选择“提取到此处”,如图9-69所示。相当于将这个压缩包里面的文件解压出来,当然,熟悉Linux指令的用户,也可以通过命令的方式来完成拷贝和解压,这里选择利用VNC和鼠标进行操作,可以简化Linux开发调试门槛。
解压之后,可以看到里面一共有2个文件夹和1个README.TXT文件,如图9-70所示。其中,README文件告诉用户这些文件的含义,比如,里面的两个文件夹,分别存放的文件是用来做什么的:
* module - The kernel module source + udev file
* demoapps - Sample C userspace programs for trial and hacking
其中,module文件夹里面的是用来编译生成ko驱动文件所需的makefile和各种c和h文件以及rules文件;demoapps文件夹里面是给用户参考的PCIe应用程序示例,后续我们就是基于这些例程进行改写之后,生成Linux下的so动态链接库的,类似Windows系统下的DLL。


至此,关于Linux系统下的Xillybus源文件准备工作就完成了。
5.4、查看树莓派Raspbian OS系统位宽
在开始编译Xillybus驱动文件之前,我们还需要确认一下当前树莓派里面安装的Linux系统位宽,到底是32位还是64位系统,因为这个位宽决定了后续编译KO文件时的条件选择。我们可以在LXterminal终端里面输入指令:getconf LONG_BIT,然后回车就能看到,如图9-71所示。返回的是32,说明当前的Linux系统是32位的,如果返回的是64,就是64位系统。

5.5、在Linux系统下编译Xillybus文件并生成KO驱动文件(神电测控已经提前编译好了,可以跳过这一步)
Xillybus官方提供的Linux系统源文件里面有两处需要进行修改,否则编译的时候会报错。第一处是把/home/pi/Xillybus-PCIe/xillybus/module文件夹里面的xillybus_pcie.c文件里面的这个头文件“linux/pci-aspm.h”声明给注释掉,如图9-72所示。这个aspm里面包含的是一套对PCIe总线进行电源管理的函数,感兴趣的用户可以上网找一下这方面的资料自行研究。

另外就是,前面我们获取的树莓派Raspbian系统位宽是32位的,而Xillybus官方提供的xillybus_pcie.c源文件里面默认支持的是64位的系统,所以我们需要将里面的这段代码注释掉,或者添加if条件语句,如图9-73所示。使其强行支持32位的Linux系统,这样后续Linux对PCIe板卡进行驱动加载和枚举的时候,分配的地址和Memory空间就不会错乱,如果是32的Linux系统,这里不做任何处理的话,后续识别PCIe FPGA板卡的时候,会出现图9-74所示的错误,也就是Memory所需空间无法正常分配,当然了,如果用户在树莓派或者RK3399上面移植的是64位Linux系统,那么这里就不需要添加if语句了!!!


xillybus_pcie.c文件根据使用环境修改完成后,保存关闭,然后我们就可以使用Linux gcc编译器来编译这些c文件和makefile文件生成ko驱动文件了。具体过程如下:
1) 首先判断一下树莓派Raspbian系统里面是否存在gcc编译器,用户可以通过在LXterminal终端里面输入指令:sudo gcc,如果返回的是“command not found”,说明这台树莓派系统里面没有安装过gcc编译器。则跳入2),如果窗口返回的是“gcc: no input files”,说明Linux系统里面已经安装了gcc,则跳入3).
2) 因此,我们需要在线给树莓派里面安装一下gcc编译器,用户可以输入指令:sudo apt-get install gcc make kernel-devel-$(uname -r),安装成功后,再执行sudo gcc可以看到返回的信息变了,如图9-75所示。

3) 接下来,利用cd命令定位到Xillybus-PCIe文件夹里面的module文件夹,也就是这个目录:Xillybus-PCIe/xillybus/module,如图9-76所示。

4) 然后,我们直接输入sudo make指令对module文件夹下的所有文件进行编译,如果编译过程没有任何错误提示,如图9-77所示,说明编译成功了,并且module文件夹里面多出来了很多后缀名为ko的驱动文件,如图9-78所示。其中,最为重要的两个ko驱动文件就是xillybus_core.ko和xillybus_pcie.ko,从源文件和PCIe驱动加载过程来看,前者xillybus_core.ko是被后者xillybus_pcie.ko调用的。


5) 接下来,我们以管理员权限的命令将上面编译出来的两个ko文件拷贝到树莓派Raspbian OS的内核驱动文件夹里面,具体的路径可以参考下面的命令,如图9-79所示。需要注意的是,modules后面的系统版本可以通过uname -a命令查看到。打开命令行里面的路径,可以看到两个ko文件成功地拷贝进来了,如图9-80所示。
sudo cp xillybus_core.ko /lib/modules/5.10.17-v7l+/kernel/drivers/char/
sudo cp xillybus_pcie.ko /lib/modules/5.10.17-v7l+/kernel/drivers/char/


5.6、在树莓派里面安装支持Xilinx FPGA PCIe接口的KO驱动(通过lsmod和lspci可以查看插到树莓派上的PCIe板卡识别状态,必须要创建出16个文件才算是成功(8上8下))
1) 拷贝成功后,我们还需要将ko驱动文件安装到树莓派Linux系统里面去,可以输入指令:depmod -a,来完成静态安装,如图9-81所示。如果用户不放心的话,还可以通过sudo make install指令强行安装ko驱动文件,如图9-82所示。


2) 当通过depmod -a指令获取到所有的文件依赖关系后,用户还需要通过sudo modprobe xillybus_pcie指令来加载所有跟Xillybus驱动相关的模块到系统里面来,如图9-83所示。

3) 为了判断Xillybus驱动是否成功安装和加载,用户可以通过输入lsmod指令进行查询,如图9-84所示。可以看出,两个xillybus相关的ko驱动都加载和运行了,其中xillybus_core有一个被xillybus_pcie调用的进程。

4) 最后一步是,将树莓派关机,断电,然后把我们Pro4开发宝典里面的FPGA bit文件生成bin文件之后固化到黑金的AX7103 FPGA开发板上,然后利用PCIex8转PCIex1转接线接到树莓派上,实物接线,如图9-85所示。给树莓派上电,大约10s之后,FPGA开发板上的LED1指示灯闪烁起来,说明我们的PCIe FPGA开发板成功地被树莓派识别和加载了,这是因为FPGA里面运行的bit文件我们加入了PCIe通信IP核代码,不熟悉的用户可以参考我们编写的Pro4开发宝典,这里不再赘述了!

5) 然后打开VNC进入树莓派虚拟桌面,在LXterminal命令终端里面输入lspci指令,查看我们的PCIe FPGA板卡是否被树莓派成功识别了,如图9-86所示。

6) 上面这个lspci命令无法看到具体的系统识别和加载过程,如果用户希望能够看到树莓派Linux系统对PCIe FPGA设备的完整加载过程,可以输入这个指令:grep -i xillybus /var/log/syslog | less,如图9-87所示,它可以将系统日志里面所有关于xillybus关键字的信息全部找出来。可以看出,Linux系统识别成功后,一共创建了16个读写文件,这是因为我们在FPGA里面下载的bit文件里面包含的PCIe通道是8上8下,共计16个独立的通道,每个通道对应一个文件名,对PCIe设备的读写操作实际上就是对映射出来的文件进行读写。
