其中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开发流程