Some time ago I was part of the effort to add Wandboard support to Crochet-FreeBSD. I wrote a blog posting about it here. An explanation of how Crochet-FreeBSD boots the Wandboard is below:
The Wandboard uses U-Boot as its initial boot-loader. A number of patches to the U-Boot source are required, and you can view them here.
Creating the Disk Image
First, when Crochet builds the disk image for Wandboard, it first writes an MBR to the disk. This is in setup.sh, in the method "wandboard_partition_image".
The second step is for Crochet to write the U-boot binary to the disk in the method "wandboard_uboot_install". The binary artefact it writes is "u-boot.imx". It writes directly to the disk, 1024 bytes into the disk, like this:
sudo dd if=${WANDBOARD_UBOOT_SRC}/u-boot.imx of=/dev/${DISK_MD} bs=512 seek=2
At this point the image has U-boot at the 1024th byte of the disk. When the Wandboard starts, it looks for a boot loader at disk offset 1024, according to this. So, we now have a disk image that has U-boot at the right spot on the disk to boot it.
The next step in building the image is adding a FAT partition to hold the FreeBSD kernel. This is accomplished in setup.h using
disk_fat_create 50m 32 16384
This creates a 50 MB FAT partition of type 32 at disk offset 16384. 16384 was chosen to ensure that the first partition on the disk starts well into the disk, and beyond the U-boot loader. The FreeBSD kernel is written to this partition like this:
cp ${FREEBSD_OBJDIR}/sys/${KERNCONF}/kernel . cp ${FREEBSD_OBJDIR}/sys/${KERNCONF}/kernel.bin .
The final step in image creation is creating a UFS partition for the FreeBSD file system. This is done with the method "disk_ufs_create". I've chosen to write both kernel and kernel.bin. kernel.bin is straight-up executable binary code. kernel is the ELF binary wrapped around kernel.bin. It's notable that one of the patches that was made to U-Boot was to enable it to load ELF binaries.
Booting FreeBSD with U-Boot
Once the image is created we have:
- Partitioned the disk as MBR
- Written U-Boot to the disk at offset 1024 (0x400).
- Written the Kernel to a FAT partition on the disk
- Written the FreeBSD file system to a UFS partition on the disk
So, when the Wandboard starts, it'll look at disk offset 0x400, and find U-boot. It'll start U-boot, and we'll have to configure U-boot to find the FreeBSD kernel and start it. This is done with uEnv.txt. When U-boot starts it'll look for eEnv.txt on the first partition in the system, which in this case is the FAT partition we wrote the kernel to. Inside that file it'll find:
uenvcmd=fatload mmc 0:1 12000000 kernel.bin;go 12000000;
These instructions tell U-Boot to load the file "kernel.bin" from the FAT partition at "mmc 0:1". The kernel will be loaded at memory address 12000000 and then control will be passed to 12000000. The memory address 0x12000000 was specified in the kernel configuration for Freescale. Check here.
Once the kernel starts, it will look for the FreeBSD filesystem. If you look at the kernel source here, you will find that the Wandboard kernel looks for its filesystem at "ufs:mmcsd0s2a\". That is "the UFS file system on the 2nd slice of the first mmc disk". Specifically:
# U-Boot stuff lives on slice 1, FreeBSD on slice 2. options ROOTDEVNAME=\"ufs:mmcsd0s2a\"
One important aspect of this boot strategy is the fact that it doesn't use loader(8). This means that any configuration that would have been set up in /boot/loader.conf doesn't get set up. A notable disadvantage is accepting the terms for the urtwn driver, and loading kernel modules.
February 20, 2014 - 8:46 am
[…] is my 3rd blog posting on the topic of the Crochet-FreeBSD ARM boot process. The other two are here and here. At long last, I have the Crochet-FreeBSD build for Wandboard working properly, with […]