树莓派简单操作系统制作之一:树莓派4B U-boot移植并加载裸机程序

1. 背景

用树莓派开发裸机程序第一步肯定是需要把编译好的程序copy到树莓派的内存中,之后才是让其执行。关于树莓派的启动流程,本篇将不详细介绍,后续有时间会更新博客或者找网上更棒的大神博主来做引用。本篇仅作简单介绍,有疏漏错误之处。欢迎补充指正。

1.1 传统的方法

首先需要准备一个保存有树莓派正常可以起来的Linux系统的TF卡(会分为两个分区,boot分区保存了正常系统所需的内核,设备树及一些配置文件,通常是fat分区?windows主机可以识别。另外一个分区是filesystem?是系统的根文件系统,为ext4格式,通常windows不能正常识别,Linux主机可以,切记不要听Windows系统的给格式化了,否则TF卡插树莓派上就没了根文件系统)。
启动流程上讲,树莓派本身固化有一段引导程序,树莓派上电以后就会通过VideoCore执行这一段程序,这段程序会读取boot分区中的config.txt(很重要)文件,根据文件的内容来对系统进行初始化配置,最终通过读取config.txt文件中的kernel的值选择加载的程序然后转入执行。(通常这里的值或者说是缺省的值为Linux系统的内核)。
如何将我们编写的裸机程序传输到开发板,传统的方法,是首先将程序文件copy到TF卡,通过修改树莓派本身引导加载程序识别的TF卡中的config.txt文件,通过修改其kernel变量对应的值将其修改为指向我们的裸机程序的二进制文件。
传统的方法优点就是简单,只需要改一次config.txt文件,后面只需要将编好的二进制程序copy到TF卡中,然后上电,树莓派就会根据指示去加载我们的程序之后执行。但是缺点也很明显,如果我们开发的是裸机程序,那么我们就避免不了对程序进行修改调试,需要不断的copy编译好的程序到TF卡,那是很痛苦的一件事情。不光需要读卡器进行数据的copy,还要TF卡在树莓派上不断的插拔,浪费时间不说,会对树莓派的插槽也会有一定的物理损坏(毕竟树莓派日益紧俏,都要成理财产品了),同时次数多了对TF卡中的文件系统也可能会被破坏(笔者就曾被搞坏过文件系统,重新做可以起树莓派系统的TF卡比较麻烦)。

1.2 通过Uboot的方法

uboot本身就是引导加载程序,此方法原理如下,系统的初始化引导之后进入uboot程序,Uboot通过串口会有简单的命令行,这样可以通过网络tftp工具从远端加载二进制程序,然后执行go命令执行我们编译出的二进制裸机程序。
这样做的好处是,仅仅需要一次拔出TF卡将我们的u-boot二进制程序放入TF卡,并修改config.txt中的kernel变量指向u-boot,然后插到树莓派,就可以通过串口对uboot进行控制,完成一系列操作。功在当代,利在千秋。

2. 步骤

如果只是起到加载裸机程序的目的,可以选择我编译好的uboot,如果需要学习一下uboot的移植步骤,可以参考以下步骤。

2.1编译U-boot

以下在Linux主机上执行(Ubuntu,Debian等)

2.1.1 安装交叉编译器

交叉编译器,又称交叉编译工具链,顾名思义,就是可以在一个CPU架构上编译可以在另一个架构上可以执行的程序。比如本例中,我们在x86上编译arm64上可以正常运行的程序。关于如何安装交叉编译器,网上有很多方式,比如ubuntu系统上最简单的方法是通过执行apt install gcc-aarch64-linux-gnu cpp-aarch64-linux-gnu就可以完成交叉编译器的安装。不过本着学习的原则,我们选择自己利用Cross-ng构建适用于树莓派ARM64的交叉工具链。安装方法及遇到的问题同时可参考:Crosstool-ng编译及构建交叉编译器出错及解决办法

1)获取crosstool

执行"git clone git://crosstool-ng.org/crosstool-ng"命令

2)安装必要组件

$ sudo apt update
$ sudo apt install  bison flex gawk automake libncurses5-dev python3-dev autoconf help2man make libtool libtool-bin -y
$ sudo apt install texinfo
$ sudo apt install bzip2

3) 编译安装cross-ng-master

$ ./bootstrap
$ ./configure 
$ make
$ sudo make install

4)配置并安装工具链

修改成树莓派4的默认配置

$ ct-ng aarch64-rpi4-linux-gnu

同时,可执行“ct-ng menuconfig” 命令进入配置页面,在配置界面里面打开 “Paths and misc options” 如图:
在这里插入图片描述
输入图片说明 其中“Local tarballs directory ”表示构建工具链中所需要的源码包下载路径,“Working directory”为构建过程中中间文件的路径,“Prefix director”表示构建完成后交叉编译器安装路径。可以按自己需要进行配置。 最后执行以下命令构建编译器

$ ct-ng build

环境配置 安装工具链后,一般将工具链命令的路径添加到系统路径中,方便后续调用。

$ export PATH=$PATH:/home/dengml/crosstool/x-tools/aarch64-rpi4-linux-gnu/bin

其中/home/dengml/crosstool/x-tools/aarch64-rpi4-linux-gnu/bin为我自己编译安装的交叉编译器地址。为避免每次开机都配置路径,可以配置环境使其每次开机自动配置 ,配置方法如下:

$ vim /etc/profile

在里面加入:

export PATH=$PATH:/home/dengml/crosstool/x-tools/aarch64-rpi4-linux-gnu/bin

使生效

source profile

2.1.2 获取并编译U-boot源码

git clone https://github.com/u-boot/u-boot (下载源码)
cd u-boot
# 使用刚才下载的交叉工具链
export CROSS_COMPILE=aarch64-linux-gnu-(目的是指向编译器)
make distclean (清除之前编译源码的缓存,首次执行会很快,因为没有缓存)
make rpi_4_defconfig (选择树莓派4的默认配置)
make -j4 (编译)

编译常见问题以及解决办法
Q: include/image.h:1394:12: fatal error: openssl/evp.h: No such file or directory
A: sudo apt install libssl-dev
编译完成后会在uboot目录下产生一个u-boot.bin的二进制文件

2.2 更改树莓派配置,使进入U-boot

将2.1节中生成的u-boot.bin文件cp到能正常启动树莓派系统的TF卡的boot分区中,修改config.txt的内容为以下内容:

# Run in 64-bit mode
arm_64bit=1

[cm4]
# Enable host mode on the 2711 built-in XHCI USB controller.
# This line should be removed if the legacy DWC2 controller is required
# (e.g. for USB device mode) or if USB support is not required.
#otg_mode=1

[all]
kernel=u-boot.bin
enable_uart=1
core_freq = 500

2.3 连接串口

本文采用的是USB转ttl的串口控制器,连接方法为主机侧通过USB连接宿主机,另一端将串口线接上树莓派如下图所示(最好连接一下地线,信号稳定)。
raspberry_gpio

在windows主机(需要提前安装完成串口工具的驱动)上打开mobaxterm,选择串口并配置波特率为115200,在ubuntu或者其它Linux系统主机上,推荐使用minicom,可以通过minicom -S命令对串口进行初始配置,比如修改波特率为115200,和默认的串口设备,然后通过minicom -D /dev/ttyUSBx进入板子的串口控制台( /dev/ttyUSBx为串口控制器设备名称,依据实际情况确定)。U-boot,启动后可以在串口控制台看到一下log,
(to do)

2.4 搭建tftp服务器

**这里需要注意的是需要搭建tftp服务器,而不是ftp服务器。**关于如何在ubuntu搭建tftp服务器,网上有很多教程,在这里我们主要介绍在windows宿主机采用Tftpd32 工具搭建出tftpd服务器,如遇到网络防火墙的原因导致其它机器访问失败可以先关闭掉。
tftpd32官网下载程序,下载portable绿色免安装版本,解压并打开运行,如下图所示:
(todo)
此工具是一个小型的文件共享工具,可以支持多种功能,比如完成作为tftp文件传输的服务端或者客户端,在这里我们仅作为tftp服务端,可以在此界面配置tftp服务器存放服务器端文件的路径。uboot通过网络从windows宿主机加载程序到树莓派ram。

2.5 配置uboot环境

前面我们讲到怎么编译,并通过串口进入到uboot控制台,现在我们需要通过串口配置uboot加载在宿主机的程序到树莓派。

  1. 首先需要连接网线到树莓派,需要注意的是,树莓派连接的网络需要和宿主机在同一局域网下(直连或者连接同一路由器)。
# 设置树莓派的ip地址
setenv ipaddr 192.168.1.101
# 设置路由网关
setenv gatewayip 192.168.1.1
# 设置子网掩码(与宿主机一致)
setenv netmask 255.255.255.0
# 设置宿主机(windows主机)ip,本例中为192.168.1.6
setenv serverip 192.168.1.6
# 保存配置信息
saveenv

以上命令设置控制台的串口 设置网络挂载的根文件系统的路径 设置ip地址,服务器地址,网关,子网掩码,网络设备号等。配置完成后可以看到Saving Environment to FAT… OK, 说明配置成功。此时可以用ping 192.168.1.6命令检查是不是与宿主机相通。
我们可以通过tftp <树莓派的RAM地址> <文件名>来获取文件,命令的含义是将宿主机tftp服务器设置的路径中的指定文件加载到树莓派RAM上的确定地址上。可以通过下面的命令设置u-boot的启动命令

setenv bootargs "tftp 0x80000 kernel8.img; go 0x80000"
saveenv

通过以上方法,可以实现u-boot上电之后自动从远端加载名为kernel8.img的文件,并将其放在0x80000的RAM位置上。然后u-boot跳转到程序加载的位置执行。
通过以上方法,我们调试我们的裸机程序的时候就可以直接将编译好的二进制程序(本人将其命名为kernel8.img)放在宿主机端的tftp服务器路径中,重启树莓派,树莓派就可以自动去加载程序到指定地址并执行。如下图:
(todo)

3. 说明

如有遗漏或者错误之处,欢迎指正,另外有想了解或者需要补充的这方面的内容或者知识的,虽然我不一定会但是欢迎沟通交流,一块学习。

后续补充,未完待续。

猜你喜欢

转载自blog.csdn.net/weixin_43328157/article/details/130241572
今日推荐