这篇文章上次修改于 479 天前,可能其部分内容已经发生变化,如有疑问可询问作者。
关于环境搭建的内容请看之前的文章:折腾网络启动
编译树莓派4B的 iPXE
iPXE 有一个适配树莓派的 piPXE 仓库,但是并没有发布适配树莓派4B的 Releases,需要自己编译。
git clone https://github.com/ipxe/pipxe.git
修改Makefile
将所有的 RPi3
替换为 RPi4
修改IPXE_TGT
的值为 bin-arm64-efi/snp.efi
git submodule update --init --recursive
更新子模块
vim ipxe/src/config/general.h
修改 iPXE 的配置文件,开启nfs
和menu
功能,也可以开启你需要的功能
...
#define DOWNLOAD_PROTO_NFS /* Network File System Protocol */
...
...
#define PXE_MENU /* PXE menu booting */
...
开始编译
make
我在编译的时报出codecs.lookup('ucs-2') LookupError: unknown encoding: ucs-2
的错误,看样子是 edk2 与 python3.9 兼容性还有点问题,我的办法是去下载 edk2 stable 版本 relsease 进行替换
mv edk2 edk2.old
wget https://github.com/tianocore/edk2/releases/download/edk2-stable202111/edk2-edk2-stable202111.zip
unzip edk2-edk2-stable202111.zip
mv edk2-edk2-stable202111 edk2
这样编译就能过了
编译好的文件在ipxe\src\bin-arm64-efi\snp.efi
嫌麻烦可以用我编译好的固件
创建 Archlinuxarm 客户端系统
首先需要创建 Archlinuxarm 系统 SD 卡,然后在树莓派上,修改系统。我尝试通过 chroot 的方法修改系统,但是测试引导没有成功。
将系统安装到 SD 卡的方法就不演示了,直接看官网说明
官网只提供了一个根目录压缩包,没有 IMG 镜像,这很 Arch(Windows用户震怒
记得使用 AArch64 版本,ARMv7 版本没有 vmlinux 文件,iPXE 引导可能会有问题
修改系统
将 SD 卡插入树莓派,启动系统
修改方法和上一篇文章基本一致,修改 mkinitcpio
让其支持 NFS
网络启动
pacman -S mkinitcpio-nfs-utils nfs-utils
vim /etc/mkinitcpio.conf
......
MODULES=(nfs broadcom)
BINARIES=(/usr/bin/mount.nfs)
HOOKS=(base udev autodetect modconf block filesystems keyboard fsck net)
......
生成initramfs
mkinitcpio -c /etc/mkinitcpio.conf -g /boot/initramfs-linux.img -k 5.15.1-1-ARCH
使用
ls /usr/lib/modules
查看当前系统的可用内核如果出现找不到
fsck.nfs
的错误,可以在配置文件中关闭fsck
这个 HOOKS,重新生成。
开启 dhcp
服务,修改fstab
关闭本地挂载
systemctl enable dhcpcd
vim /etc/fstab
服务端配置
DHCP 和 TFTP
将编译好的树莓派4B版 iPXE 传输到 TFTP 文件夹下
修改dnsmasq.conf
,添加 aarch64 iPXE 引导支持
...
dhcp-match=set:aarch64,option:client-arch,11
dhcp-match=set:aarch32,option:client-arch,10
dhcp-boot=tag:aarch64,ipxe/bootaa64.efi
# 建议将这个条目放在底部
dhcp-boot=tag:ipxe,ipxe/boot.ipxe
NFS 服务
把 SD 卡中的系统导出为.img
镜像文件,传输到服务器(将内存卡挂载也可以)
挂载镜像
mkdir archlinuxarm-mount
losetup -P /dev/loop0 archlinuxarm-copy.img
mount /dev/loop0p2 archlinuxarm-mount/
mount /dev/loop0p1 archlinuxarm-mount/boot/
修改 NFS 服务配置,让其支持 mount 的文件夹
vim /etc/exports
/data/boot/ 192.168.xx.0/24(rw,sync,no_root_squash,crossmnt)
重启服务
systemctl restart nfs-kernel-server
修改 boot.ipxe
(iPXE MENU)
添加启动项
...
item --key r nfs_raspi_netboot (R)ArchlinuxARM NetBoot NFS
...
...
:nfs_raspi_netboot
echo Boot Raspberry Pi NETBOOT
set server_ip 192.168.xx.xx
set nfs_path /data/boot/archlinuxarm-mount
kernel nfs://${server_ip}${nfs_path}/boot/Image
initrd nfs://${server_ip}${nfs_path}/boot/initramfs-linux.img
imgargs Image initrd=initramfs-linux.img nfsroot=${server_ip}:${nfs_path} netboot=nfs ip=dhcp rootwait
boot || goto failed
然后就可以使用 iPXE 强大的引导功能了,这也是我折腾 UEFI+iPXE 启动的原因之一(主要是想给吃灰派找点事干
...
chain --autofree https://boot.netboot.xyz
通过 UEFI 启动 iPXE
树莓派4B 内嵌了一块小EEPROM
,可以在没有内存卡下工作,但是需要特定的 PXE 环境引导(之后会讲到)
为了让其兼容 iPXE 需要一张内存卡,让 UEFI 使用通用的 PXE 加载 iPXE
下载 Raspberry Pi 4 UEFI Firmware Images ,删除原来 boot
分区的文件,将 UEFI Images 的文件解压到这里
将 SD 卡插入树莓派,UEFI 没有检测到本地系统便会开始尝试 PXE 引导
丢掉 SD 卡,尝试无盘启动
树莓派4B 的EEPROM
在没有检测到内置储存的时候便会尝试进行网络启动。这样就可以在没有内存卡下运行系统,方便做多节点部署,节省一点买内存卡的钱。
首先更新系统,同时会更新 EEPROM
中的固件
sudo apt update && sudo apt full-upgrade
使用Raspbian查看本机的序列号
cat /proc/cpuinfo
....
Hardware : BCM2835
Revision : d03114
Serial : 10000000xxxxxxxx #最后8位
Model : Raspberry Pi 4 Model B Rev 1.4
在 TFTP 共享文件夹目录创建以树莓派序列号最后8位的文件夹
然后将内存卡 boot 分区的文件复制到这个文件夹下
cd tftproot
mkdir xxxxxxxx #树莓派序列号后8位
cd xxxxxxxx
wget https://github.com/pftf/RPi4/releases/download/v1.32/RPi4_UEFI_Firmware_v1.32.zip
unzip RPi4_UEFI_Firmware_v1.32.zip
# 我这里直接下载UEFI,懒得传了
修改 dnsmasq.conf
,添加以下内容:
...
pxe-service=0,"Raspberry Pi Boot"
# 使用了这条配置BIOS PXE启动方式好像会失效
把内存卡拔下,通电开机试试
无盘启动 Raspbian
树莓派 UEFI 固件现在对树莓派硬件支持并不完整,比如不能支持 WIFI 等,如果要使用完整的功能就需要使用官方提供的方式引导。
首先把 SD 卡中的系统导出为.img
镜像文件,传输到服务器(和上面一致)
挂载镜像
mkdir raspbian-mount
losetup -P /dev/loop1 raspbian-copy.img
mount /dev/loop1p2 raspbian-mount/
mount /dev/loop1p1 raspbian-mount/boot/
删除 TFTP 文件夹内树莓派序列号文件夹的内容,然后将 Raspbian 系统内存卡的 boot 分区内的文件复制过去
cd tftproot/
mv xxxxxxxx xxxxxxxx-uefi #xxxxxxxx是树莓派序列号后8位
mkdir xxxxxxxx && cd xxxxxxxx
sftp root@nfs-server
get -R /data/boot/raspbian-mount/boot/* ./
修改 cmdline.txt
让内核在启动时通过 nfs 挂载根目录
console=serial0,115200 console=tty1 rw root=/dev/nfs nfsroot=192.168.xx.xx:/data/boot/raspbian-mount,v4,tcp ip=dhcp elevator=deadline rootwait
记得修改fstab
关闭本地挂载,以免启动报错
参考
Raspberry pi无盘网络启动(network booting)
Network Booting
PXE无盘启动树莓派集群
How can I mount a Raspberry Pi Linux distro image?
mkinitcpio (简体中文))
Setup armv7h chroot under x86_64 host (Archlinux/Archlinuxarm biased)
Raspberry Pi 4? #2
Raspberry Pi PXE Boot – Network booting a Pi 4 without an SD card
已有 3 条评论
请问ipxe引导文件的编译,make后您写的生成snp.efi,但是直接下的文件名为bootaa64.efi,请问编译方法都一样,只是改名了吗?
@小黎 对的,应该是bootaa64.efi这个文件
请问ipxe引导文件的编译,make后您写的生成snp.efi,但是直接下的文件名为bootaa64.efi,请问编译方法都一样,只是改名了吗?