一、环境搭建
配置 VMware 使用双网卡
对于初学者,
VMWare
设置为使用双网卡是最方便的:
- NAT 网卡:Ubuntu 通过它上网,只要 Windows 能上网,Ubuntu 就能上网
- 桥接网卡:Ubuntu 通过它跟开发板联通
配置交叉编译工具链
交叉编译的概念及原因:
所谓的交叉编译就是:在一种平台上编译,编译出来的程序,是放到别的平台上运行,即编译的环境和运行的环境不一样,属于交叉编译。之所以要有交叉编译,主要原因是:1)嵌入式系统中的资源太少,交叉编译出来的程序,板子所要运行的环境中,各种资源,都相对有限,所以很难进行直接的本地编译。最常见的情况是:在进行嵌入式开发时,目标平台,即嵌入式开发板,比如是最大主频200MHz的ARM的CPU,加上32M的RAM,加上1G的Nand Flash等等。在如此相对比较紧张的硬件资源的前提下,在已经运行了嵌入式Linux的前提下,是没法很方便的直接在嵌入式Linux下,去本地编译,去在ARM的CPU下,编译出来,供ARM的CPU可以运行的程序的。因为编译,开发,都需要相对比较多的CPU,内存,硬盘等资源,而嵌入式开发上的那点资源,只够嵌入式(Linux)系统运行的,没太多剩余的资源,供你本地编译。2)而在x86的平台下(复杂指令)直接编译出的程序不能在ARM平台下(精简指令)运行,所以需要用到交叉编译工具链。
那么明白了什么是交叉编译,那我们来看看什么是交叉编译链。
编译过程包括了预处理、编译、汇编、链接等功能。既然有不同的子功能,那每个子功能都是一个单独的工具来实现,它们合在一起形成了一个完整的工具集。同时编译过程又是一个有先后顺序的流程,它必然牵涉到工具的使用顺序,每个工具按照先后关系串联在一起,这就形成了一个链式结构。 用于交叉编译的工具链,就叫做交叉工具链。即那些工具,即编译的gcc,链接的ld,以及相关的工具,用于交叉编译的,工具链,叫做交叉工具链。
交叉编译工具链用来在 Ubuntu 主机上编译应用程序,而这些应用程序是在 ARM 等其他平台上运行。设置交叉编译工具主要是设置 PATH, ARCH 和 CROSS_COMPILE 三个环境变量。
-
PATH:
PATH
环境变量用于指定系统在执行命令时搜索可执行文件的路径。在交叉编译中,你需要确保系统能够找到交叉编译工具链中的工具,如编译器、链接器、调试器等。- 通过将交叉编译工具链的路径添加到
PATH
中,你可以直接在命令行中使用交叉编译工具,而不需要每次都输入完整的路径。 - 例如,假设交叉编译工具链的路径为
/opt/cross/bin
,你可以将其添加到 PATH
中:export PATH=/opt/cross/bin:$PATH
。
-
ARCH:
ARCH
环境变量用于指定目标平台的体系结构。在交叉编译中,它告诉编译器和其他工具应该针对哪种体系结构生成代码。- 设置
ARCH
变量有助于确保编译器和其他工具正确地理解目标平台的体系结构,从而生成与目标平台兼容的代码。 - 例如,如果你的目标平台是 ARM 架构,你可以设置
ARCH=arm
。
-
CROSS_COMPILE:
CROSS_COMPILE
环境变量用于指定交叉编译工具链中的前缀。这个前缀通常是编译器和其他工具的名称的一部分,用于区分交叉编译工具链和本地编译工具链。- 在交叉编译中,设置
CROSS_COMPILE
变量是非常重要的,因为它告诉编译器和其他工具应该使用交叉编译工具链中的工具而不是本地环境中的工具。 - 例如,如果交叉编译工具链中的编译器名称是
arm-linux-gcc
,那么你可以设置 CROSS_COMPILE=arm-linux-
。
开发板挂载Ubuntu的NFS目录
什么是
NFS
协议?
NFS 实现了一个跨越网络的文件访问功能,如下图可以简要说明其原理。NFS 最大的特点是将服务端的文件系统目录树映射到客户端,而在客户端访问该目录树与访问本地文件系统没有任何差别,客户端并不知道这个文件系统目录树是本地的还是远在另外一台服务器。
我们为什么要挂载
ubuntu
的
nfs
目录?
我们有些时候需要多次调试开发板文件系统内的某个应用程序,这就需要多次进行编译拷贝等操作,所以我们在前期进行调试时可以直接让开发板使用 ubuntu 的
nfs
目录下文件系统来进行远程调试,用以提高调试效率,加快研发速度。
在这一脚本命令中打开了nfs系统服务,具体过程尚不清楚
二、编译bootloader
Bootloader 是在操作系统运行之前运行的一段代码,用于引导操作系统。 通常每个操作系统都有一组专属的引导加载程序。引导加载程序通常可以通过多种方式引导操作系统内核,还有各种命令用于调试或修改内核运行环境。这里主要介绍U-boot。
U-Boot 是一个开源的主引导加载程序,用于引导设备的操作系统内核,并 含有多种命令以便调试系统。它适用于多种计算机体系结构,包括 68k
,
ARM
, Blackfin,
MicroBlaze
,
MIPS
,
Nios
,
SuperH
,
PPC
,
RISC-V
和
x86
。
不同的开发板对应不同的配置文件,配置文件位于 u-boot
源码的 “configs/
”目录。uboot官网的源码一般不能直接拿来用,得做适当的修改。将编译完的uboot文件烧写到板子上。(编译uboot之前必须配置好工具链等开发环境)
三、编译内核
为什么编译驱动程序之前要先编译内核?
⚫ 驱动程序要用到内核文件:
比如驱动程序中这样包含头文件:#include <asm/io.h>,其中的
asm 是 一个链接文件,指向 asm-arm 或
asm-mips,这需要先配置、编译内核才会生成 asm 这个链接文件。
⚫ 编译驱动时用的内核、开发板上运行到内核,要一致:
开发板上运行到内核是出厂时烧录的,你x86上编译驱动时用的内核是你自己编译 的,这两个内核不一致时会导致一些问题。所以我们编译驱动程序前,要把自己 编译出来到内核放到板子上去,替代原来的内核。
⚫ 更换板子上的内核后,板子上的其他驱动也要更换:
板子使用新编译出来的内核时,板子上原来的其他驱动也要更换为新编译出来的。所以在编译我们自己的第 1 个驱动程序之前,要先编译内核、模块,并且放到板子上去。
编译内核整体流程:
不 同 的 开 发 板 对 应 不 同 的 配 置 文 件 , 配 置 文 件 位 于 内 核 源 码 arch/arm/configs/目录。
1、 编译完成 zImage 后才可编译设备树文件;
2、编译完成后,在 arch/arm/boot 目录下生成 zImage 内核文件, 在arch/arm/boot/dts 目录下生成设备树的二进制文件
。把这
2
个文件复制nfs
目录下备用;
3、编译安装内核模块到Ubuntu;
4、安装内核和模块到开发板上;假设:在 Ubuntu 的/home/book/nfs_rootfs 目录下,已经有了 zImage、dtb 文件,并且有 lib/modules 子目录(里面含有各种模块)。接下来要把这些文件复制到开发板上。
注意:一般情况下,以上重新编译内核的步骤就足够了,若要重头构建整个系统,可以使用buildroot,系统被破坏时可以选择使用烧写工具。
Buildroot 的用法:
Buildroot
是一组
Makefile
和补丁,可简化并自动化地为嵌入式系统构建完整的、可启动的 Linux
环境
(
包括
bootloader
、
Linux
内核、包含各种
APP 的文件系统)
。
Buildroot
运行于
Linux
平台,可以使用交叉编译工具为多个目标板构建嵌入式 Linux
平台。
Buildroot
可以自动构建所需的交叉编译工具链, 创建根文件系统,编译 Linux
内核映像,并生成引导加载程序用于目标嵌入式系统,或者它可以执行这些步骤的任何独立组合。例如,可以单独使用已安装的交 叉编译工具链,而 Buildroot
仅创建根文件系统。
3)
使用
Yocto
开发板使用 NFS 根文件系统
注意
:所谓根文件系统就是类似
Windows
的
C 盘
,里面存放有必须的
APP
、库文件、配置文 件。通过 NFS
可以把
Ubuntu
的某个目录,当作板子的“
C
盘”──
Linux
中称之为根文件系统。
Buildroot 编译完成之后生成的 rootfs.tar.bz2,可以解压之后放到 NFS 服务器上作 为 NFS
文件系统供开发板使用。使用
NFS
文件系统,便于程序的开发调试。所谓
NFS
服务器, 就是我们在 VMWare
上运行的
Ubuntu
。
使用
NFS
根文件文件系统时,我们一般还会在
u-boot
使用
tftpboot
命令从
Ubuntu
或 Windows 中下载内核文件
zImage
和设备树文件。这时,
Ubuntu
上既要配置
NFS
服务,也要 配置 TFTP
服务。
原文链接:https://blog.csdn.net/zqixiao_09/article/details/50783528
原文链接:https://blog.csdn.net/zqixiao_09/article/details/51822943