四时宝库

程序员的知识宝库

嵌入式 linux 开发(嵌入式Linux开发书籍)

其中10.1.1.*就是你自己网段的地址信息。

最后重启 nfs

sudo systemctl 重新启动 nfs 内核服务器

测试nfs的安装

安装完成后就可以安装nfs客户端了

sudo apt 安装 nfs-common

然后创建本地文件夹目录

sudo mkdir -p /opt/nfs-客户端

最后,安装它

sudo mount -t nfs 10.1.1.160:/opt/nfs /opt/nfs-客户端

当/opt/nfs下创建文件之后,也可以看到/opt/nfs-client目录,说明成功。

2.2 树莓派开发环境搭建

2.2.1 硬件连接

树莓派4上实际硬件引脚分布如上图,其中需要连接串口RX、TX、GND。

准备一张8GB以上的SD卡,然后打开Raspberry Pi Imager,选择要刻??录到其中的Raspberry Pi镜像。

这一步的目的是因为Raspberry Pi启动过程需要从SD卡加载第一阶段启动文件。

默认情况下,烧写的固件连接串口后是没有任何输出的,需要自行修改SD卡里的config.txt文件,在最后添加下面这句话就可以了。

启用_uart=1

这样通过mobaxterm工具打开串口,接上电源之后就可以看到如下输出

然后输入用户名和密码如下

raspberrypi 登录名:pi 密码:raspberry

这样就可以使用默认的Raspberry Pi 4串口调试功能了。

2.2.2 树莓派4b启动过程分析

简单说一下树莓派4b的启动过程,上电后树莓派会自动加载位于SD卡文件中的bootcode.bin文件,这个文件加载到树莓派的GPU中运行,程序初始化PLL,DDR等,然后读取SD卡文件中的start4.elf文件执行,这个文件执行过程中会读取config.txt文件,根据配置脚本选择可执行固件。

做嵌入式开发的时候,底层的启动逻辑必须非常清楚,这样无论如何都能理清问题,从而保证硬件和软件层面的一致性。

上图基本展示了一个通用的嵌入式Linux启动过程,并且很好的描述了各个阶段的特点和功能点。

Broadcom BCM2711 在 Raspberry Pi 4b 上的启动过程遵循以下步骤。

第一阶段引导加载程序:

第一阶段BootROM一般嵌入在芯片中,在GPU中执行,而ARM内核处于复位状态。

树莓派4b的BootROM是通过EEPROM来加载的,4b之前都是SD卡上的bootcode.bin文件。

第二阶段引导加载程序:

此阶段的启动固件从 SD 卡、网络、USB 等加载。

在 Raspberry Pi 4 上,使用 SD 卡中的 start.elf 二进制文件。

start.elf文件在SD文件系统中找到config.txt文件,然后根据其中的信息进行启动过程的处理。

本文主要通过修改config.txt配置文件来进行uboot的启动流程。

3.交叉编译工具的安装及uboot的编译

3.1 安装arm 64位交叉编译环境

因为需要编译64位的程序,所以这里需要安装arm 64位的交叉编译环境。

从上述网站进入

建议下载gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu.tar.xz。

下载完成后,移动到指定目录。

#创建文件夹sudo mkdir -p /opt/linaro #解压到指定文件夹路径sudo tar -xvf gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu.tar -C /opt/linaro

更新环境变量

sudo vim?/ .bashrc

在最后添加以下内容

别名 crosscompiler='export KERNEL=kernel8;export ARCH=arm64;export CROSS_COMPILE=/opt/linaro/gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-'

更新环境

源 ~/.bashrc

3.2 在树莓派上编译uboot

首先你需要下载代码

git 克隆

正常下载完成图如下:

然后切换分支并开始编译。

cd u-boot git checkout v2020.04-rc3

编译之前,首先需要安装编译所需的程序

sudo apt 安装 u-boot-tools bison bc make flex libssl-dev ncurses-*

安装完成后,执行

交叉编译器

该命令定义在环境变量中,可以设置环境变量。

制作 rpi_4_defconfig

只需使用默认配置进行编译。

制作-j $(nproc)

编译后的uboot.bin文件是可以在Raspberry Pi 4b上直接执行的程序。

3.3 在树莓派上运行u-boot

到这一步就可以把编译好的u-boot程序放到Raspberry Pi 4b上并运行了。

将树莓派的SD卡插入电脑,将SD卡里的config.txt重命名为config.txt.bak,并新建一个config.txt。

arm_control=0x200 内核=u-boot.bin dtoverlay=disable-bt

这三行意思是

arm_control=0x200 #因为树莓派4b支持64位架构,所以这个用来表示运行64位程序

使用 uboot

kernel=u-boot.bin # kernel表示正在运行的固件

启用串行端口

dtoverlay=disable-bt #设计树莓派4时,如果打开串口调试,则无法使用蓝牙

将SD卡插入电脑,可以看到uboot正常启动。

4.树莓派4b上Linux编译下载

4.1 编译Raspberry Pi Linux 源代码

树莓派4b的uboot功能已经完成,接下来我们开始编译树莓派的Linux内核。

Raspberry Pi有单独维护的Linux代码分支,可以使用以下命令下载。

git 克隆--分支 rpi-5.6.y

进入Linux目录

新建目录,用于存放编译好的固件

创建目录 rpi_hw

开始编译

使 O=rpi_hw bcm2711_defconfig

删除 MMC/SD/SDIO 驱动程序

使 O=rpi_hw 菜单配置

进入设备驱动程序并选择删除 MMC/SD/SDIO 卡支持。

保存配置后,就可以编译了。

使 O=rpi_hw -j $(nproc)

为什么我们应该删除 MMC/SD/SDIO 驱动程序?

这是因为需要编译从网络启动的驱动,所以不需要在Raspberry Pi的SD卡上进行操作。

编译完成后,可以在rpi_hw/arch/arm64/boot中找到编译好的文件。

将编译好的Linux内核文件放入

sudo cp rpi_hw/arch/arm64/boot/Image /srv/tftp/

4.2 运行编译好的Linux固件

当通过uboot将编译好的固件加载到RAM中并运行时,首先需要了解Raspberry Pi 4b的内存分布情况。

通过uboot中的bdinfo命令可以看到树莓派4b上有两个bank,第一个bank在0x00000000,第二个bank在0x40000000。

当Raspberry Pi 4b从SD卡加载Image文件时,它会被加载到地址0x8000的DRAM中并开始运行。

当然也可以在uboot中设置地址,Linux会重新定位代码。

此时需要在uboot中设置启动信息。

首先设置uboot的静态IP地址

setenv ipaddr 10.1.1.100 #设置开发板静态地址(自定义) setenv serverip 10.1.1.160 #设置服务器地址 setenv netmask 255.255.255.0 saveenv reset

以上操作设置了IP地址,接下来设置启动

setenv kernel_addr_r 0x8000 setenv 内核映像 setenv netboot 'tftp ${kernel_addr_r} ${kernel} && booti ${kernel_addr_r} - ${fdtcontroladdr}' setenv bootcmd 'run netboot' setenv bootargs 'console=ttyAMA0' saveenv reset

可以显示如下:

上次启动后出错

这是正常的,目前没有rootfs。但现在Linux内核可以正常加载和调试。

接下来,将其挂载到 rootfs 上。

5. 根文件的使用

本文将不讨论制作通用根文件系统的过程,而将重点描述如何使用它。

5.1 在uboot中设置启动项

首先在uboot中设置路径。

设置环境 nfsroot /opt/nfs/

设置启动参数

setenv bootargs“控制台=ttyAMA0,115200 root=/dev/nfs rw nfsroot=${serverip}:${nfsroot},v3,tcp ip=$ipaddr:$serverip::$netmask:off”

保存配置

保存环境变量

5.2 插入SD卡并挂载到虚拟机

首先,将 USB 驱动器挂载到虚拟机

可以看到出现了两个磁盘

在:

rootfs 是 Linux 根文件系统

boot 是一个可以在 Windows 上访问的 ext32 文件

您可以将 rootfs 中的所有文件复制到 /opt/nfs/

sudo cp * /opt/nfs/ -R

在/opt/nfs目录下新建一个文件夹,将boot里的所有文件复制到其中。

sudo mkdir -p /opt/nfs/file sudo cp * /opt/nfs/file/

5.3 修改文件脚本

需要修改

sudo vim etc/fstab

添加以下文件

10.1.1.160:/opt/nfs/file /boot nfs 默认值,vers=4.1,proto=tcp 0 0

其目的是为了屏蔽默认的二项列表,只需要在nfs中挂载文件系统即可。

修改完之后,插入SD卡,就可以正常从tftp获取Linux内核固件,从nfs文件系统挂载根文件系统。

如果您发现需要密码,或者您忘记了密码,您可以输入

cd /opt/nfs/ sudo vim /etc/passwd

删除中间的 x。

在Linux中,默认的x表示需要密码才能进入。

6. 总结

本文对树莓派的整个Linux系统环境以及树莓派的启动进行了分析,并对树莓派的开机引导、u-boot加载Linux内核、挂载nfs文件系统等做了一些实验。

最后一部分制作自己的根文件系统,这里用的是树莓派默认的根文件系统,如果需要自己裁剪制作,可以自定义。

整个嵌入式Linux开发和环境搭建流程可以在Raspberry Pi 4b上得到很好的测试,掌握了嵌入式开发的流程和工具之后,开发应用程序和驱动会非常方便、高效。

由于时间关系,有些实验还没有完成,比如Linux上的应用程序开发,驱动开发,jlink调试等。

在Raspberry Pi 4b上学习如何使用和启动Linux非常方便,而且价格也很合理。这是一个很好的开发平台。

原标题:详解树莓派4嵌入式Linux开发流程

发表评论:

控制面板
您好,欢迎到访网站!
  查看权限
网站分类
最新留言
    友情链接