【树莓派学习笔记】树莓派4B上运行uboot并从网络启动linux内核(上)
参考:https://hechao.li/2021/12/20/Boot-Raspberry-Pi-4-Using-uboot-and-Initramfs/
前言
树莓派的多数教程上,都是将linux系统下载进入SD,并从SD卡启动。但是对于编写linux驱动这种特定场景来说,每次更改都要把改动拷贝进入U盘实在太过繁琐,严重打击学习热情。所以本文通过在树莓派上运行uboot,并通过uboot网络启动linux内核的方式解决上述问题。
1. 硬件需求与软件版本汇总
1.1 硬件需求
- 树莓派4B(内存大小不限)
- linux桌面端运行环境,本文使用虚拟机安装ubuntu20.04.
- SD卡和读卡器
- CH340 USB转TTL模块(可选)
- 杜邦线(至少三根)(可选)
1.2 软件版本汇总
2. 前期准备
SD卡仅用来存储树莓派的启动引导文件,uboot的执行文件以及设备树文件。
2.1 查找SD卡的设备名
linux命令如下:
$ dmesg | tail
命令窗口输出如下:
[ 2719.343068] sd 33:0:0:1: [sdc] 60751872 512-byte logical blocks: (31.1 GB/29.0 GiB)
[ 2719.345290] sd 33:0:0:1: [sdc] Write Protect is off
[ 2719.345294] sd 33:0:0:1: [sdc] Mode Sense: 21 00 00 00
[ 2719.353076] sd 33:0:0:1: [sdc] Write cache: disabled, read cache: enabled, doesn’t support DPO or FUA
[ 2719.359180] sd 33:0:0:0: [sdb] Attached SCSI removable disk
[ 2719.587175] sdc: sdc1 sdc2
[ 2719.612387] sd 33:0:0:1: [sdc] Attached SCSI removable disk
[ 2720.761882] FAT-fs (sdc1): Volume was not properly unmounted. Some data may be corrupt. Please run fsck.
[ 2735.040898] EXT4-fs (sdc2): recovery complete
[ 2735.049551] EXT4-fs (sdc2): mounted filesystem with ordered data mode. Opts: (null). Quota mode: none.
从上图可知,新插入的SD的卡设备为sdc,接下来我们将对SD卡进行格式化及分区。
2.2 删除原有的分区
2.2.1 fdisk命令如下:
$ sudo fdisk /dev/sdc
注:其中sdc为2.1.1章节中获取的设备名称,需要更换为自己的设备名称
命令窗口输出:
Welcome to fdisk (util-linux 2.34).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.
Command (m for help):
2.2.2 删除原有分区:
Command (m for help): d
Command (m for help): d
Partition number (1,2, default 2):
2.2.3 直接回车确认
Partition 2 has been deleted.
2.2.4 继续删除:
Command (m for help): d
仅剩一个分区,不会询问Partition number:
Command (m for help): d
Selected partition 1
Partition 1 has been deleted.
2.2.5 查看SD卡基本信息:
Command (m for help): p
Command (m for help): p
Disk /dev/sdc: 28.99 GiB, 31104958464 bytes, 60751872 sectors
Disk model: MassStorageClass
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x638274e3
2.2.6 保存并退出:
Command (m for help): w
- 如果出现如下信息,则未删除成功,需要先将挂载的设备卸载。
Command (m for help): w
The partition table has been altered.
Failed to remove partition 1 from system: Device or resource busy
Failed to remove partition 2 from system: Device or resource busy
The kernel still uses the old partitions. The new table will be used at the next reboot.
Syncing disks.
查找挂载的设备:
lsblk -f | grep sdc
注:其中sdc为2.1.1章节中获取的设备名称,需要更换为自己的设备名称
sdc
├─sdc1 vfat system-boot B084-2C85 147.5M 41% /media/fyh/system-boot
└─sdc2 ext4 writable a6ba7311-aab8-46ea-aad2-6a42bf57300d 24.9G 9% /media/fyh/writable
其中/media/fyh/***/字段为挂载设备,本例中为/media/fyh/system-boot与/media/fyh/writable。
卸载设备:
sudo umount /media/fyh/system-boot /media/fyh/writable
注:其中**/fyh/system-boot与/fyh/writable**为本小节中获取的文件名称,需要更换为自己的
2.3 增加两个分区
2.3.1 fdisk命令如下:
$ sudo fdisk /dev/sdc
注:其中sdc为2.1.1章节中获取的设备名称,需要更换为自己的设备名称
命令窗口输出:
Welcome to fdisk (util-linux 2.34).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.
Command (m for help):
2.3.2 新建第一个分区:
Command (m for help): n
一路回车:
Welcome to fdisk (util-linux 2.34).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.
Command (m for help): n
Partition type
p primary (0 primary, 0 extended, 4 free)
e extended (container for logical partitions)
Select (default p):
Using default response p.
Partition number (1-4, default 1):
First sector (2048-60751871, default 2048):
Last sector, +/-sectors or +/-size{K,M,G,T,P} (2048-60751871, default 60751871):
分区大小100M,下一个选项Y:
Last sector, +/-sectors or +/-size{K,M,G,T,P} (2048-60751871, default 60751871): +100M
…
Do you want to remove the signature? [Y]es/[N]o: Y
Last sector, +/-sectors or +/-size{K,M,G,T,P} (2048-60751871, default 60751871): +100M
Created a new partition 1 of type ‘Linux’ and of size 100 MiB.
Partition #1 contains a vfat signature.
Do you want to remove the signature? [Y]es/[N]o: Y
The signature will be removed by a write command.
2.3.3 新建第二个分区全部回车默认选项:
Command (m for help): n
Command (m for help): n
Partition type
p primary (1 primary, 0 extended, 3 free)
e extended (container for logical partitions)
Select (default p):
Using default response p.
Partition number (2-4, default 2):
First sector (206848-60751871, default 206848):
Last sector, +/-sectors or +/-size{K,M,G,T,P} (206848-60751871, default 60751871):
Created a new partition 2 of type ‘Linux’ and of size 28.9 GiB.
保存并退出:
Command (m for help): w
Command (m for help): w
The partition table has been altered.
Calling ioctl() to re-read partition table.
Syncing disks.
2.4 格式化分区
# 第一个分区初始化为fat32格式
sudo mkfs.vfat -F 32 -n boot /dev/sdc1
# 第二个分区初始化为ext4格式
sudo mkfs.ext4 -L root /dev/sdc2
注:其中sdc为2.1.1章节中获取的设备名称,需要更换为自己的设备名称
2.5 挂载分区
sudo mount /dev/sdc1 /mnt/boot
sudo mount /dev/sdc2 /mnt/root
注:其中sdc为2.1.1章节中获取的设备名称,需要更换为自己的设备名称。
如果boot和root目录不存在请事先创建一下
sudo mkdir /mnt/boot
sudo mkdir /mnt/root
3. 构建交叉工具链
通常我们的PC机一般是X86架构的,而树莓派4B是arm架构的,由于架构的差异导致在PC上编译生成的可执行文件无法在树莓派上直接运行。虽然我们也可以直接在树莓派4B上编译,但是通常PC相对树莓派来说有性能优势。交叉编译工具就是可以用PC的性能编译出树莓派上可直接运行的工具。
本例中使用crosstool-NG构建适用于树莓派ARM的交叉工具链。
建议在开始前一个树莓派专用的文件夹,用于存放所有工具及文件。
#在用户目录建立文件夹
mkdir ~/raspberry4B
#进入该文件夹
cd ~/raspberry4B
3.1 安装必要组件
# 安装必要的组件
$ sudo apt install gperf bison flex texinfo help2man gawk automake libncurses5-dev python3-dev -y
3.2 下载 crosstool-NG源码
运行以下命令时,可先进入想下载安装目录。
$ git clone https://github.com/crosstool-ng/crosstool-ng
$ cd crosstool-ng/
# 切换到1.25.0分支
$ git checkout crosstool-ng-1.25.0 -b 1.25.0
3.3 构建并安装crosstool-NG
$ ./bootstrap
$ ./configure --prefix=${PWD}
$ make
$ make install
# 将编译工具加入环境变量
$ export PATH="${PWD}/bin:${PATH}"
3.4 配置corsstool-NG
# 查看可构建的交叉编译器
$ ct-ng list-samples
# 使用aarch64-rpi4-linux-gnu编译器
$ ct-ng aarch64-rpi4-linux-gnu
3.5 构建工具链
$ ct-ng build
4. u-boot
u-boot是一种bootloader,类似于PC中的BIOS,用于引导linux内核的运行。本章主要介绍u-boot的源码下载,配置,编译与生成可执行文件的过程。
4.1 下载u-boot源码
# 回到树莓派目录
$ cd ~/raspberry4B
$ git clone git://git.denx.de/u-boot.git
$ cd u-boot
# 切换到v2021.10分支
$ git checkout v2021.10 -b v2021.10
4.2 配置并编译u-boot
# 将aarch64-rpi4-linux-gnu交叉编译器的路径作为环境变量
$ export PATH=${HOME}/x-tools/aarch64-rpi4-linux-gnu/bin/:$PATH
# 选择树莓派4的参数做配置
$ make CROSS_COMPILE=aarch64-rpi4-linux-gnu- rpi_4_defconfig
# 编译生成可执行文件
$ make CROSS_COMPILE=aarch64-rpi4-linux-gnu- -j4
未完待续
下半篇内容:
- u-boot在树莓派上的运行
- linux内核的配置与编译
- 根文件系统的构建
- u-boot启动变量的设置
- 内核启动与串口控制台