- 嵌入式Linux设备驱动程序开发指南(原书第2版)
- (西)阿尔贝托·利贝拉尔·德·洛斯里奥斯
- 4227字
- 2025-02-18 04:55:54
1.9 为NXP i.MX7D处理器构建嵌入式Linux系统
i.MX7D处理器系列配备了Arm Cortex-A7内核和Cortex-M4内核,最高运行频率可达1.2 GHz。i.MX7D处理器支持多种类型的存储器,包括16/32位DDR3L/LPDDR2/LPDDR3-1066、四路SPI存储器、NAND、eMMC和NOR。通过AVB、PCIe和USB支持包括千兆以太网在内的若干种高速连接。提供并行和串行的显示器和摄像头接口,以及直接连接电泳显示器(EPD)的方式。
可以在下面链接中查到关于这个系列处理器的相关信息:https://www.nxp.com/products/processors-andmicrocontrollers/applications-processors/i.mx-applications-processors/i.mx-7-processors/i.mx-7dualprocessors-heterogeneous-processing-with-dual-arm-cortex-a7-cores-and-cortex-m4-core:i.MX7D。
基于MCIMX7SABRE的开发试验:本试验将使用基于i.MX7D应用处理器的SABRE智能设备开发板。开发板的相关文档可在下面的链接查看:https://www.nxp.com/support/developer-resources/hardware-development-tools/sabre-development-system/sabre-board-for-smart-devices-based-on-the-i.mx-7dual-applicationsprocessors:MCIMX7SABRE。
本书中使用开发板MCIMX7SABRE开发i.MX7D处理器的驱动程序,这些驱动程序也可以很容易地移植到开发板ARROW IMX7 96单板上。这块开发板的相关资料,可在下面的链接查询:https://www.96boards.org/product/imx7-96/。
1.9.1 简介
为了在Linux主机上得到Yocto工程,必须安装下面列出的软件包和工具。一个重要的考虑因素是主机上的硬盘空间要足够大。例如:在运行Ubuntu系统的机器上构建时,最少要为X11后台程序预留50 GB的空间。推荐的空间大小是至少120 GB,这足够存放所有要编译的后台程序了。
下面执行的指令都是在Ubuntu 14.04 64位系统上测试过的。
1.9.2 主机软件包
构建Yocto工程需要安装一些必要的软件包,这些包也记录在Yocto工程的文档中。比较关键的一些主机软件包是:

Ubuntu 14.04主机需要安装的软件包是:

1.9.3 设置repo
工具
repo
工具被开发出来,主要是用来方便对多个Git仓库的管理。相较于从每个仓库逐个下载,repo
工具可以用一条命令下载所有的仓库。使用下面的命令来安装这个工具:
1. 建一个目录。下面的命令在你的主目录下创建了一个目录,并命名为bin

2. 下载工具:

3. 设置工具的可执行权限:

4. 把文件夹路径添加到环境变量PATH中,下面这条命令可以添加到你的.bashrc
文件中,这样在以后启动的每个shell或者终端中,PATH环境变量都会自动生效。

1.9.4 Yocto工程的安装和映像构建
NXP Yocto工程的BSP版本目录包含一个“sources”目录,这个目录里包含构建工程的方法文件、一个或者多个构建目录,还有一组设置环境的脚本。
构建工程的方法来自于社区和NXP。把Yocto工程文件下载到“sources”目录。用相应构建方法来建立这个工程。
下面的例子演示了如何从NXP的Yocto工程社区下载BSP配置文件。在这个例子中,这个工程会创建一个名为“fsl-release-bsp”的目录。

当处理完成的时候,源代码被存放到目录fsl-release-bsp/sources
下。你可以反复使用repo sync
命令来同步最新代码。在repo
初始化的过程里,如果发生错误,请删除.repo
目录然后再运行repo
初始化命令。
脚本fsl-setup-release.sh
简化了i.MX机器的环境设置过程。在使用这个脚本的时候,需要指定要构建机器的名称和要使用的图形后端。脚本会为指定机器和图形后端建立一个目录和配置文件。
对于meta-fsl-bsp-release
,i.MX会提供全新的或者更新的机器配置文件以替换meta-fsl-arm
机器配置文件。这些文件把脚本fsl-setup-release.sh
拷贝到meta-fsl-arm/conf/machine
目录里。
在开始构建之前必须先初始化。在这个步骤里,会建立构建目录和本地配置文件。在构建之前的初始化过程中,必须选择一种发布方式。在设置目标机器imx7dsabresd
时,要选择构建目录build_imx7d
和fsl-imx-x11
发布方式:

在做完这些设置后,执行环境将被重定向输出到build_imx7d
文件:

如果你要打开一个新的终端,在构建之前,你必须重新加载fsl-setup-release.sh
脚本:

构建Yocto工程会消耗大量的资源,包括时间和磁盘存储空间,特别是构建多个目录的时候。有些方法可以优化这些问题,例如使用共享的状态缓存(缓存构建时的状态)和共享的下载目录(保存下载包)。可以在local.conf
文件里设置路径,这个文件在fsl-release-bsp/build-x11/conf
目录下,使用以下命令来添加状态信息:

同时要注意在机器中创建这些目录:

这些目录需要设置适当的权限。当构建多个目录的时候,共享状态信息缓存会有帮助作用,每一个目录都使用共享缓存信息来最小化构建时间。共享的下载目录能把下载文件时间最小化。如果没有这些设置,Yocto工程默认会创建共享状态缓存目录和下载目录。当你想要进行一次完整的构建时,你需要移除状态缓存目录和临时目录。

构建新的Linux映像:

当构建完成的时候,映像文件将生成在指定的目录里。如果你正在使用另一个构建目录和机器配置则此目录是不一样的。

最后你要把这些映像文件写到SD卡里。下面是使用笔记本电脑自带的SD读卡器时所使用的命令:

如果你使用的是扩展的USB SD读卡器,请使用下面的命令:

在这里,/dev/sdX
对应的是主机系统分配给SD卡的设备节点。
1.9.5 Yocto之外的工作
你可能觉得在不使用Yocto的情况下开发内核驱动程序和应用程序更方便。Yocto项目SDK试图帮助你完成这些工作。Yocto项目SDK包括以下几个方面:
1. 一个交叉编译工具链。
2. 两个sysroot:
- 一个属于目标设备:包含适用于目标设备的头文件和库文件。确保生成的映像文件符合目标设备。
- 一个属于主机设备:包含适用于主机的工具。这些工具可确保在构建目标sysroot时,一切保持一致并按预期工作。
3. 一个环境脚本,设置必要的变量以使它们协同工作。
使用Yocto工程构建一个SDK有以下几种方法:
- 使用
bitbake meta-toolchain
。这个方法仍旧需要单独提取并安装目标设备sysroot。 - 使用
bitbake image –c populate_sdk
。这个方法比上一个方法有了重大改进,因为它会生成一个工具链安装程序,这个程序包含与目标设备匹配的sysroot。
谨记,在新的终端里使用任何bitbake命令之前,必须先运行安装脚本建立运行环境:

当bitbake命令运行完毕后,工具链安装程序将被放在tmp/deploy/sdk
的build
目录下。工具链安装程序包含匹配目标根文件系统的sysroot。可以用下面的命令来生成:

在主机上开发应用程序时,为了适合不同的目标体系结构,你需要使用交叉编译工具。这次将使用Yocto SDK,SDK已经提前安装到目录/opt/fsl-imx-x11/4.9.11-1.0.0
。在终端上运行如下命令,可以看到SDK目录的具体内容:

4.9.11-1.0.0
文件夹包含导出SDK环境变量的脚本。sysroots
文件夹包含SDK工具、库文件、头文件和两个子文件夹,一个是给主机(x86_64)使用的,另一个是给目标设备(cortexa7hf)使用的。你可以通过文件后缀名获得一些关于SDK的信息:
- cortexa7hf:适配于Crotex-A7带有硬件浮点计算功能的SDK(带有浮点运算单元)。
- neon:支持neno处理器。
- linux:支持Linux操作系统。
- gnueabi:gnu嵌入式应用接口。
在安装SDK之前,你需要先运行环境变量脚本:

这些脚本将导出下面的几个环境变量:
- CC:带有目标编译选项的C编译器。
- CFLAGS:附加的C编译参数,用于C编译器。
- CXX:C++编译器。
- CXXFLAGS:附加的C++编译参数,用于CPP编译器。
- LD:链接器。
- LDFLAGS:链接参数,用于链接器。
- GDB:调试器。
- PATH:SDK二进制文件路径。
可以使用如下的命令看到所有的环境变量:

编译器现在在当前路径中了:

$CC提供了目标设备gcc选项:

- arch选项armv7ve:适用于armv7ve体系结构的编译。
- float-abi选项hard:二进制应用的硬件浮点单元的支持(fpu)。
- fpu选项neno:支持ARM NEO协处理器。
- sysroot:存放库文件和头文件的地方。
下面写一个简单的例子来验证工具链是否安装正确。打开文本编辑工具gedit,写一个小程序:

添加如下的代码:

如果用下面的命令编译它,会显示有错误发生:

发生错误的原因是设置的编译器支持的ARM处理器不明确,在调用编译器时要设置正确的C编译参数。可以使用C编译器($CC)直接编译app.c
文件:

使用UNIX命令“file”,你可以确定文件类型(参见:man file),并检查文件适用的体系结构和链接方法:

1.9.6 构建Linux内核
内核的配置和构建是独立于Yocto构建系统的。把内核源文件从Yocto的tmp
目录(使用bitbak创建映像文件时产生的目录)拷贝到你自己的内核目录:

你也可以从NXP的内核仓库下载内核源代码:

在编译内核之前,最好确保内核源码是干净的并且没有遗留之前构建产生的文件:
- clean:移除构建产生的大部分文件,但是保留config文件和支持构建外部模块的文件。
- mrproer:移除所有构建产生的文件、config文件和各种备份文件。
- distclean:在mrproper的基础上再移除编辑器备份文件和补丁文件。

通常最容易的办法是从使用默认配置开始,这样可以根据你的需要来定制内核。imx_v7_defconfig
位于arch/arm/configs
目录下,以它为例:

当你想定制内核配置的时候,最简单的办法就是使用内核内建的配置系统。最常用的一种配置系统就是menuconfig工具。使用一个没有配置environment-setup-cortexa7hf-neon-poky-linux-gnueabi
的终端,使用命令“cd /”在menuconfig中搜索:

配置驱动程序开发过程中需要的以下内核设置:

保存配置并从menuconfig退出。
一旦内核配置完毕,就可以编译生成可引导内核映像以及所选择的动态内核模块。默认情况下U-Boot系统使用的内核映像类型是zImage。在编译内核前,请确保在终端里已经使用environment-setup-cortexa7hf-neon-poky-linux-gnueabi
脚本建立了编译环境:

从Linux内核3.8版开始,每一个ARM单板的内核要求对应唯一的设备树二进制文件。因此需要为目标设备构建和安装正确的dtb文件。所有的设备树文件都存放在arch/arm/boot/dts/
目录下。为了构建单个设备树文件,找到所使用单板对应的dts文件的名称,将.dts扩展名替换为.dtb。编译后的设备树文件放置在arch/arm/boot/dts/
目录下。运行下面的命令编译并构建设备树文件:

构建所有的设备树文件:

默认情况下,大多数的驱动文件没有被集成到Linux内核映像中(例如zImage)。这些驱动被构建为动态模块,存放于内核树中,文件后缀为.ko(内核对象)。这些.ko文件就是内核的动态模块。一旦内核文件被改动,通常推荐的做法是重构内核模块并安装它们。否则内核模块将不能被加载和运行。构建内核模块的命令如下:

使用下面的命令,单步编译内核映像、模块和所有的设备树文件。

内核映像、内核模块和设备树文件被编译后,就可以安装了。对于内核映像,可以通过把zImage文件复制到系统读取内核映像的位置来安装。将设备树二进制文件复制到内核映像被复制到的文件夹下。你将从TFTP服务器读取内核映像和设备树文件:

在为处理器i.MX7D和SAMA5D2开发驱动程序的过程中,你将在主机上使用TFTP和NFS服务器,SD卡中只需要存储U-Boot引导加载器。引导加载器将从TFTP服务器上获取Linux内核映像文件,内核将从NFS服务器上挂载根文件系统。无论是更改内核还是根文件系统,都无须烧写SD卡。
1.9.7 安装TFTP服务器
如果你还没有运行过TFTP服务器,请按照下面的步骤在Ubuntu 14.04主机上安装和配置TFTP服务器:

tftpd-hpa
配置文件安装在/etc/default/tftpd-hpa
目录下。它默认使用/var/lib/tftpboot
作为TFTP的根目录。为了让所有的用户都能访问这个目录,使用下面的命令修改目录的权限:

使用netstat –a | grep tftp
检查TFTP服务器的状态。如果没有结果,很可能是服务器没有启动。为了安全起见,可以使用如下命令停止服务后再重新启动服务:sudo service tftpd-hpa stop
和sudo service tftpd-hpa start
。
1.9.8 安装NFS服务器
如果你还没有运行过NFS服务器,请使用下面的步骤在Ubuntu 14.04主机上安装和配置NFS服务器:

/nfsroot
将被作为NFS服务器的根目录,因此目标根文件系统将从Yocto构建目录里解压出来:

接下来将NFS服务器配置到/nfsroot
文件夹。编辑/etc/exports
文件并加入下面这句代码:

然后重启NFS服务器使最新的配置生效:

为了安装内核模块,可以使用与make
命令类似的命令,但是需要添加一些参数来说明模块安装的路径。这个命令将在此安装路径下创建一系列的文件和文件夹,例如lib/modules/<kernel version>
,这个目录下包含适用于当前内核的驱动模块。这个路径应该是目标文件系统的根目录。

1.9.9 设置U-Boot环境变量
给MCIMX7SABRE单板上电。在你的主机系统中运行并配置minicom来观察系统启动过程。配置如下:波特率115200,8位数据,1位停止位,无奇偶校验位。确保硬件和软件流控制被禁用。按任意键停止U-Boot启动过程。
要执行网络引导,请在U-Boot提示符下设置如下环境变量:

重启你的单板;它现在就可以从网络启动了。