Booting the Raspberry Pi from the network (aka PXE boot) allows you to use this small computer without the microSD memory card or the external flash drive connected to the USB port. In the internet you can find information how to boot the Raspberry Pi with PXE boot and NFS. In this article you will find information how to boot the Raspberry Pi with PXE boot and without NFS.
Prepare bootloader
Use Raspbian or other ready system which can be installed on the microSD memory card and update the bootloader in the Raspberry Pi by the following commands:
rpi-eeprom-config /lib/firmware/raspberrypi/bootloader/stable/pieeprom-2020-09-03.bin > boot.conf
Add/modify BOOT_ORDER, set it to BOOT_ORDER=0xf21
rpi-eeprom-config --out new-eeprom.bin --config boot.conf /lib/firmware/raspberrypi/bootloader/stable/pieeprom-2020-09-03.bin rpi-eeprom-update -d -f new-eeprom.bin
Preparing DHCP server with booting from network
In this case I used isc-dhcp-server. Add the following lines into the range section of your DHCP server:
option tftp-server-name "192.168.1.1"; # option 66 option vendor-class-identifier "PXEClient"; # option 60 option vendor-encapsulated-options "Raspberry Pi Boot"; # option 43
Restart/reload you DHCP server.
Building the bare kernel and busybox with cross compiling
First, make sure that all dependencies needed for cross compiling are installed such as git, bc, bison, flex, libssl-dev, make, libc6-dev, libncurses5-dev, crossbuild-essential-arm64.
Build busybox:
git clone --depth=1 --branch=1_33_0 https://git.busybox.net/busybox cd busybox make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- defconfig # with static link sed -i "s#^\# CONFIG_STATIC .*#CONFIG_STATIC=y#" .config LDFLAGS="--static" make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j4
Build Linux kernel:
git clone --depth=1 https://github.com/raspberrypi/linux cd linux KERNEL=kernel8 make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- bcm2711_defconfig make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- Image modules dtbs -j4
Preparing initramfs and testing
Create initramfs:
cd busybox make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- install CONFIG_PREFIX=../ramfs cd ../linux make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- INSTALL_MOD_PATH=../ramfs modules_install cd ../ramfs find . | cpio --create --format='newc' | gzip > /srv/tftp/initrd cd ..
Copy kernel and device trees:
cp linux/arch/arm64/boot/Image /srv/tftp/vmlinuz cp linux/arch/arm64/boot/dts/broadcom/*.dtb /srv/tftp/
Create /srv/tftp/cmdline.txt file with the following content:
console=serial0,115200 console=tty rootfstype=ramfs root=/dev/ram rw rootwait elevator=deadline
Create /srv/tftp/config.txt file with the following content:
disable_overscan=1 kernel=vmlinuz initramfs initrd arm_64bit=1
Downlod bootloader files:
cd /srv/tftp wget -q https://github.com/raspberrypi/firmware/raw/master/boot/{fixup,fixup4}.dat wget -q https://github.com/raspberrypi/firmware/raw/master/boot/{start,start4}.elf
Testing
If everything is ready, connect the Raspberry Pi to the computer ethernet port, connect the USB-C cable with power, connect the Raspberry Pi with the external screen and watch the boot process:
Sources
- https://brennan.io/2019/12/04/rpi4b-netboot/
- https://balau82.wordpress.com/2010/03/27/busybox-for-arm-on-qemu/
- https://wiki.beyondlogic.org/index.php?title=Cross_Compiling_BusyBox_for_ARM
- https://www.raspberrypi.org/documentation/linux/kernel/building.md