mail

valettearnaud

Netboot a raspberry 2 B with U-boot

When developing a low-level OS for the rpi, constantly swapping SD cards between the Pi and your machine quickly becomes a hassle. Every small change means physically removing the SD card, writing new files, reinserting it, and rebooting–wasting precious time.

A network boot setup eliminates this friction by allowing the Pi to fetch and boot your latest program&|kernel directly from a TFTP server. Unfortunately the units made before rpi 3 B aren't capable of doing so.

In this article U-boot is used as a mean to extend rpi2b on this specific feature, making iterative OS development much smoother.

Files needed:

  • <your_board>.dtb
  • bootcode.bin
  • start.elf
  • fixup.dat

The latest boot files are in the Raspberry Pi firmware repository:

git clone --depth=1 https://github.com/raspberrypi/firmware.git
  • bootcode.bin: firmware/boot/bootcode.bin
  • start.elf: firmware/boot/start.elf
  • fixup.dat: firmware/boot/fixup.dat
  • DTB files: firmware/boot/*.dtb

Copy them to your SD card’s boot partition.

Files to create

All these files should be present on your boot partition:

u-boot.bin

Do replace arm-none-eabi- with your cross-compiler of choice, given you're not already on arm.

git clone git://git.denx.de/u-boot.git
cd u-boot
make ARCH=arm CROSS_COMPILE=arm-none-eabi- rpi_2_defconfig
make ARCH=arm CROSS_COMPILE=arm-none-eabi-

This will generate u-boot.bin, do store it in the boot partition of your SD card.

config.txt

Do replace the device_tree value with your board .dtb file. The raspberry pi 2 B uses a broadcom 2836, but is is possible the adequate .dtb file isn't called bcm2836. Note that without some of these options, the rpi cannot use the eth, which is necessary for us.

kernel=u-boot.bin
enable_uart=1
hdmi_force_hotplug=1
hdmi_safe=1
hdmi_drive=2
device_tree=bcm2836-rpi-2-b.dtb
boot_delay=1
dtoverlay=dwc2

boot.scr

That's the file u-boot uses as a bootscript. You can generate one based on a boot.txt file you will write as needed. Here we set tftp up to netboot any binary <your_program> at the instruction located at 0x8000. This binary should be accessible from your tftp host, reachable at the provided serverip/tftpserverip.

Here you can find more informations about what command you can use to boot, bootm, bootz anything.

I use go because I set up my kernel _start section at a specific offset, and I want to precisely execute this very precise instruction.

setenv company arva
printenv company
setenv ipaddr 192.168.1.101
setenv serverip 192.168.1.56
setenv tftpserverip 192.168.1.56
saveenv
tftpboot 0x8000 <your_program>
go 0x8000

Your file should end with a carriage return!

Then:

<path_to_u-boot_repo>/tools/mkimage -T script -d boot.txt boot.scr

TFTP server

On your host machine, set up a TFTP service: Arch documentation. Here, we used /srv/tftp/ as a root folder to serve. This is where <your_program> is located.

Launch

Once this is done, you can :

  1. Plug your raspberry pi unit to an ethernet cable
  2. (optional) plug it to HDMI to contemplate the u-boot splash screen
  3. Power it on

The unit should directly find the boot.scr bootflow and your kernel/program should be launched: you don't have to modify anything on that SD card anymore and can do continuous development without having to touch the unit.

Rebooting the unit will reload the kernel from tftp, you even can directly copy your kernel on build to /srv/tftp/ in your Makefile for example.

...
kernel7.img: $(BUILD_DIR)/kernel.elf
  mkdir -p $(IMG_DIR)
  $(ARMGNU)-objcopy -O binary $< $(IMG_DIR)/kernel7.img
  cp $(IMG_DIR)/kernel7.img /srv/tftp/kernel7.img
...

Created: 2026-07-14 Tue 10:05

Validate