Rapsberry Pi 0 - U-Boot and (rpi foundation) kernel
Toolchain
Note: if you built your own toolchain using toolchain-ng, you can of course use that. There are however some pre-built toolchains in the raspberry repos:
- GCC 4.7
wget -Oraspberrypi-tools.tar.gz https://github.com/raspberrypi/tools/archive/master.tar.gz
tar xf raspberrypi-tools.tar.gz
# remove the "-x64" for 32bit systems
export PATH=$PWD/tools-master/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin/:$PATH
wget -Oraspberrypi-tools.tar.gz https://github.com/raspberrypi/tools/archive/master.tar.gz tar xf raspberrypi-tools.tar.gz export PATH=$PWD/tools-master/arm-bcm2708/arm-rpi-4.9.3-linux-gnueabihf/bin/:$PATH
Firmware tools (bootloader etc):
https://github.com/raspberrypi/firmwaremkdir -p firmware cd firmware wget https://github.com/raspberrypi/firmware/raw/master/boot/bootcode.bin wget https://github.com/raspberrypi/firmware/raw/master/boot/fixup.dat wget https://github.com/raspberrypi/firmware/raw/master/boot/start.elf because of enable_uart=1, see below wget https://github.com/raspberrypi/firmware/raw/master/boot/bcm2708-rpi-zero-w.dtb # insert sdcard, mount... cp bootcode.bin fixup.dat start.elf /run/media/$USER/boot/
U-Boot
Note: we don't really need u-boot to boot the kernel on raspberry, the
bootcode.bin
/start.elf
bootloader is capable of
loading it, but u-boot gives us more flexibility (loading kernels from usb/network,
manually booting with different commandlines without having to edit
config.txt
etc.)
git clone git://git.denx.de/u-boot.git cd u-boot # check out a version that does not need GCC 6 # (you can use master if you compiled your own toolchain with newer GCC) git checkout -b build v2017.11 # ls configs/*rpi* export CROSS_COMPILE=arm-linux-gnueabihf- # rpi_2_defconfig for rpi2 make rpi_defconfig make menuconfig time ionice -c3 nice -n10 make -j5 # i5-2520M (4core): real 0m22.268s user 0m58.988s sys 0m7.912s # i7-8750H (12core): real 0m6.128s user 0m48.096s sys 0m5.251s # TODO might need apt install libssl-dev bc # insert sdcard, mount... # we "pretend" u-boot is kernel ;) cp u-boot.bin /run/media/$USER/boot/kernel.img
Kernel
https://github.com/raspberrypi/linux/wget https://github.com/raspberrypi/linux/archive/rpi-5.3.y.tar.gz tar xf rpi-5.3.y.tar.gz cd linux-rpi-5.3.y/ export ARCH=arm export CROSS_COMPILE=arm-linux-gnueabihf- #defconfig make help | grep bcm # or # ls arch/arm/configs/bcm* #device tree ls arch/arm/boot/dts/*rpi* # bcm2709_defconfig for rpi2 make bcmrpi_defconfig # we will also need modules later: make -j5 zImage dtbs modules time ionice -c3 nice -n10 make -j5 zImage dtbs # i5-2520M (4core): real 11m54.312s user 43m8.471s sys 2m48.369s # i7-8750H (12core): real 2m48.009s user 13m53.905s sys 1m1.443s # insert sdcard, mount... cp arch/arm/boot/zImage /run/media/$USER/boot/ cp arch/arm/boot/dts/*rpi*.dtb /run/media/$USER/boot
Booting
TODO Set up serial uart correctly on wifi boards
echo 'dtoverlay=miniuart-bt' >>/run/media/$USER/boot/config.txt
Boot the RPi with the sd card, you should see u-boot comming up on the serial console.
In u-boot:
#load kernel load mmc 0:1 $loadaddr zImage #load device tree load mmc 0:1 $fdt_addr_r $fdtfile # run kernel (finally) setenv bootargs 8250.nr_uarts=1 earlyprintk console=ttyS0,115200 bootz $loadaddr - $fdt_addr_r
Let's automate this a bit
setenv loadmmc 'load mmc 0:1 $loadaddr zImage ; load mmc 0:1 $fdt_addr_r $fdtfile' setenv bootcmd 'run loadmmc ; bootz $loadaddr - $fdt_addr_r' setenv bootargs 8250.nr_uarts=1 earlyprintk console=ttyS0,115200 saveenv
The saveenv
command will save the current environment to a file
named uboot.env
on the sd card and will automatically load it on
next boot.
Unless interupted at boot, u-boot will then execute the contents of the
bootcmd
env variable. Note that we also split the file loading
part to a separate variable, so if we want to tweak some things, we can
interupt the automatic boot process and just type run loadmmc
to have the kernel and device tree loaded.