Interfacing FreeBSD with U-Boot

I came across this presentation last week:-

www.bsdcan.org/2008/schedule/attachments/49_2008_uboot_freebsd.pdf

It's almost 10 years old, so I'm wondering why it's such a struggle to get FreeBSD installed on a Seagate GoFlex Home unit. It seems quite a few people have managed it but it's difficult (for me...) to find some simple instructions on how to do so. I haven't yet worked out if I should be building a FreeBSD U-Boot to load FreeBSD...
 
After a couple of weeks away, I've decided to try and get FreeBSD installed on my GoFlexHome within the next week or so trying to follow the instructions in the Wiki. Unfortunately the instructions seem to be written for someone who has already gone through the process previously. I'm somewhat in the dark because there is no mention as to how to get to the first instruction - Build world... It doesn't define
${SRC}.. Is this the latest FreeBSD src, or is it some specific src for ARM computers. I can only speculate, but will try using
http://ftp.freebsd.org/pub/FreeBSD/releases/amd64/11.0-RELEASE/src.txz and see how I get on.
 
Surprisingly

make -j 8 buildworld TARGET_ARCH=arm


ran to completion (in about 90 mins) without reporting any errors. I don't how to check if this worked as it should.

Unfortunately

make buildkernel TARGET_ARCH=arm KERNCONF=DB-88F6XXX


Stopped with an error.

(Just noticed why... - OOPS)
 
Make sure before any of this you set your environment correctly. I am guessing that Arm5 builds are called arm.
Code:
setenv TARGET_ARCH arm
setenv TARGET arm
Then build your u-boot with the FreeBSD patches applied. Make sure compiled uboot is in the correct location. After that you build the rest:

Code:
make buildworld TARGET_ARCH=arm -DWITH_FDT
make buildkernel TARGET_ARCH=arm KERNCONF=DB-88F6XXX
make installworld TARGET_ARCH=arm DESTDIR=/mnt
make distribution TARGET_ARCH=arm DESTDIR=/mnt
make installkernel TARGET_ARCH=arm KERNCONF=DB-88F6XXX DESTDIR=/mnt
Make sure you use DWITH_FDT as this includes the FDT files and uboot in the build. You might also need a hook to uboot in the KERNCONF.
 
I know you are avoiding building uboot but that has to go first.
So just for learning take a look at your RaspberryPi 1 u-boot port to get an idea what a compiled uboot port looks like.
It is located in this directory: /usr/local/share/u-boot/uboot-rpi/
Here you will see the bin file and config.txt and all the pieces.

Take a look at the ports tree and uboot ports and figure out what goes into the official port of u-boot-rpi.

Remember that crochet has the uboot patches in thier NewBoardExample.
https://github.com/freebsd/crochet/tree/master/board/NewBoardExample/files
They might need fixup for your port but do show what is needed.
FreeBSD needs the uboot API to be compiled in for FreeBSD hooks.
Linux does not use the API so it must be compiled in for FreeBSD usage.

/usr/local/share/u-boot/uboot-db-88f6xxx/
You will need a similar structure for your DB-88F6XXX uboot port. It must also reside in this uboot directory structure to be found for compilation.

Something more to ponder. Bootblock.
Some Arm boards use no partition for the bootblock and most use the fat type.
I would study your existing Arch Linux disk structure.
Find out where the boot code needs to reside for uboot.

https://wiki.freebsd.org/FreeBSD/arm/crossbuild

FreeBSD will actually boot with only a handful of files in the root directory of the fat drive or nfs share.
 
Make sure before any of this you set your environment correctly. I am guessing that Arm5 builds are called arm.
Code:
setenv TARGET_ARCH arm
setenv TARGET arm
Then build your u-boot with the FreeBSD patches applied. Make sure compiled uboot is in the correct location. After that you build the rest:
Not sure which patches you are referring to...
Code:
make buildworld TARGET_ARCH=arm -DWITH_FDT
make buildkernel TARGET_ARCH=arm KERNCONF=DB-88F6XXX
make installworld TARGET_ARCH=arm DESTDIR=/mnt
make distribution TARGET_ARCH=arm DESTDIR=/mnt
make installkernel TARGET_ARCH=arm KERNCONF=DB-88F6XXX DESTDIR=/mnt
Make sure you use DWITH_FDT as this includes the FDT files and uboot in the build. You might also need a hook to uboot in the KERNCONF.

I managed to make buildworld buildkernel , but I'm trying trying to formalise the process taking your example into account.

How does this look?
Code:
cd /
fetch http://ftp.freebsd.org/pub/FreeBSD/releases/amd64/11.0-RELEASE/src.txz
tar zxf src.txz
cd /usr/src
setenv TARGET_ARCH arm
setenv TARGET arm
make -j 8 buildworld TARGET_ARCH=arm -DWITH_FDT
make -j 8 buildkernel TARGET_ARCH=arm KERNCONF=DB-88F6XXX
make installworld TARGET_ARCH=arm DESTDIR=/mnt
make distribution TARGET_ARCH=arm DESTDIR=/mnt
make installkernel TARGET_ARCH=arm KERNCONF=DB-88F6XXX DESTDIR=/mnt
 
I know you are avoiding building uboot but that has to go first.
So just for learning take a look at your RaspberryPi 1 u-boot port to get an idea what a compiled uboot port looks like.
It is located in this directory: /usr/local/share/u-boot/uboot-rpi/

I'm not sure where to find this...
 
I know you are avoiding building uboot but that has to go first.

Before I manage to build uboot, I'd like to see I can launch FreeBSD on my GoFlexHome, given that I've managed to build an ARM version.
As far as I can tell I might be able to load FreeBSD if I put the correct parameters in uEnv.txt. This is used to load Debian:-

Code:
console=ttyS0,115200
uimage=/boot/uImage
initrd=/boot/uInitrd
fdt_file=/boot/dts/kirkwood-pogo_e02.dtb 
fdt_addr=0x1c00000
uimage_addr=0x800000
initrd_addr=0x1100000
loadfdt=ext2load ${type} ${disk}:1 ${fdt_addr} ${fdt_file}
loaduimage=ext2load ${type} ${disk}:1 ${uimage_addr} ${uimage}
loaduinitrd=ext2load ${type} ${disk}:1 ${initrd_addr} ${initrd} 
set_bootargs=setenv bootargs console=$console root=LABEL=rootfs rootdelay=10 $mtdparts
load_debian=setenv type usb; setenv disk 0; run set_bootargs; echo Running loadfdt ...;run loadfdt; echo Running loaduinitrd ...;run loaduinitrd; echo Running loaduimage ...; run loaduimage 
bootm=run load_debian; echo Booting from ${type} ${disk}:1 ...; bootm ${uimage_addr} ${initrd_addr} ${fdt_addr}

Any suggestions would be appreciated.
 
Did you remember that you need to remove IPSEC_NAT_T
https://lists.freebsd.org/pipermail/freebsd-arm/2017-April/015993.html
This post really has everything you need.



Here are the notes from the u-boot-rpi2 port:

U-Boot loader and related files for Raspberry Pi 2

To install this bootloader, copy ALL the files in the share/u-boot/u-boot-rpi2
directory to the first partition, formatted as FAT32, on an SD card.

This version is patched so that:
* ELF and API features are enabled.
* The default environment is trimmed to just what's needed to boot.
* The saveenv command writes to the file uboot.env on the FAT partition.
 
Did you remember that you need to remove IPSEC_NAT_T
https://lists.freebsd.org/pipermail/freebsd-arm/2017-April/015993.html
This post really has everything you need.

I really appreciate the help, but I find this post very difficult to follow.

Code:
Marvell>> dhcp
BOOTP broadcast 1
*** Unhandled DHCP Option in OFFER/ACK: 28
*** Unhandled DHCP Option in OFFER/ACK: 28
DHCP client bound to address 10.6.6.26
*** Warning: no boot file name; using '0A06061A.img'
Using egiga0 device
TFTP from server 10.6.6.1; our IP address is 10.6.6.26
Filename '0A06061A.img'.
Load address: 0x800000
Loading: *
TFTP error: 'File not found' (1)
Not retrying...
Marvell>> printenv addr_rd
addr_rd=0x1100000
Marvell>> tftpboot $addr_rd dockstarwoipsecnatt
Using egiga0 device
TFTP from server 10.6.6.1; our IP address is 10.6.6.26
Filename 'dockstarwoipsecnatt'.
Load address: 0x1100000
Loading: #################################################################
        #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         ###########################################################
done
Bytes transferred = 6587876 (6485e4 hex)
Marvell>> go $addr_rd
## Starting application at 0x01100000 ...
Copyright (c) 1992-2017 The FreeBSD Project.
Copyright (c) 1979, 1980, 1983, 1986, 1988, 1989, 1991, 1992, 1993, 1994
        The Regents of the University of California. All rights reserved.
FreeBSD is a registered trademark of The FreeBSD Foundation.
FreeBSD 11.0-STABLE #0 r316330: Sat Apr  1 10:45:38 CEST 2017
    root at node:/usr/obj/arm.arm/usr/src/stable/11/sys/DOCKSTARWOIPSECNATT arm

I know this is a tftp request for a file, but what does DOCKSTARWOIPSECNATT refer to? Is it kernel.bin, ubldr or something else.
And where does addr_rd come from?

I entered dhcp in my /boot/uEnv.txt on the FAT partition of the USB stick and the loader read it and downloaded gpxelinux.0 from my PXE server, so I guess if I copied my equivalent of DOCKSTARWOIPSECNATT to gpxelinux.0 then I might get a chance to see if FreeBSD starts to boot.

Here are the notes from the u-boot-rpi2 port:

U-Boot loader and related files for Raspberry Pi 2

To install this bootloader, copy ALL the files in the share/u-boot/u-boot-rpi2
directory to the first partition, formatted as FAT32, on an SD card.

This version is patched so that:
* ELF and API features are enabled.
* The default environment is trimmed to just what's needed to boot.
* The saveenv command writes to the file uboot.env on the FAT partition.

Unfortunately I don't know which notes you are referring to... In any case I already have a bootloader, I'm just missing the parameters to boot FreeBSD. The uboot.env may show me what I need but I don't know where to find it.
 
what does DOCKSTARWOIPSECNATT refer to
This is the name of the custom kernel he compiled without IP_SEC_T
So he took the dockstar kernconf and modified it and named the new kernconf file DOCKSTARWOIPSECT
This is what the manual says to do it. Save the original and make a new kernconf. He simply annotated his with the features.

Unfortunately I don't know which notes you are referring to
These are the notes from the port for RPi2 u-boot. It simply shows what is patched up. So stock uboot needs API and ELF support.
This is not provided and needs to be compiled in.

This is why your Linux u-boot will fail.
 
This is the name of the custom kernel he compiled without IP_SEC_T
So he took the dockstar kernconf and modified it and named the new kernconf file DOCKSTARWOIPSECT
This is what the manual says to do it. Save the original and make a new kernconf. He simply annotated his with the features.


These are the notes from the port for RPi2 u-boot. It simply shows what is patched up. So stock uboot needs API and ELF support.
This is not provided and needs to be compiled in.

This is why your Linux u-boot will fail.

I'm now at a point where my Linux U-Boot has started to boot FreeBSD but gets stuck at the FreeBSD Loader> prompt
Code:
GoFlexHome> boot
starting USB...
USB0:   USB EHCI 1.00
scanning bus 0 for devices... 2 USB Device(s) found
      scanning usb for storage devices... 1 Storage Device(s) found
reading ubldr
280361 bytes read in 88 ms (3 MiB/s)
CACHE: Misaligned operation at range [01000098, 0102acc8]
CACHE: Misaligned operation at range [0102acd0, 0102b873]
CACHE: Misaligned operation at range [0102b874, 0102d25c]
CACHE: Misaligned operation at range [0102d25c, 0102d2b8]
CACHE: Misaligned operation at range [0102d2b8, 01031da6]
CACHE: Misaligned operation at range [01031db0, 010334ac]
CACHE: Misaligned operation at range [010334b0, 01036548]
## Starting application at 0x01000098 ...
Consoles: U-Boot console

Compatible U-Boot API signature found @0x7b12860

FreeBSD/arm U-Boot loader, Revision 1.2

(root@Multiboot, Thu Jul 20 09:36:42 BST 2017)

DRAM: 128MB

Number of U-Boot devices: 2

U-Boot env: loaderdev='usb 0:1'

Found U-Boot device: disk

  Checking unit=0 slice=1 partition=<auto>... good.

Booting from disk0s1:

can't load 'kernel'

Type '?' for a list of commands, 'help' for more detailed help.

loader> boot

can't load 'kernel'

no bootable kernel

What I'm missing is a list of files which should be on the FAT partition of mu USB stick. The instructions at

https://cooltrainer.org/freebsd-kirkwood/building/

only shows one file


[SIZE=5][B]Install the kernel[/B][/SIZE]
[LIST=1]
[*]mount -t msdosfs /dev/da0s1 /root/usb
[*]cp /usr/obj/arm/usr/src/sys/DOCKSTAR-COOLTRAINER/kernel.bin /root/usb
[*]umount /root/usb
[/LIST]


I think I'm only a few short steps from getting a login prompt.
 
Did you ever manage to compile u-boot with ELF and API support? loader will need those hooks. Linux version of u-boot will not boot FreeBSD.
Everything I read says u-boot needs patching to work with FreeBSD.
 
Did you ever manage to compile u-boot with ELF and API support? loader will need those hooks. Linux version of u-boot will not boot FreeBSD.
Everything I read says u-boot needs patching to work with FreeBSD.

I haven't built U-Boot. bodhi on the doozan forum helped me get FreeBSD ubldr loaded from an ArchLinux U-Boot. When I get it all working properly I'll provide notes.
 
While in ubldr can you do an ' ls'? The idea here is to figure out if ubldr sees the correct device, and files on that device.
 
Did you ever manage to compile u-boot with ELF and API support? loader will need those hooks. Linux version of u-boot will not boot FreeBSD.
Everything I read says u-boot needs patching to work with FreeBSD.
What's a good source of u-boot for FreeBSD?
I've tried this one, but it doesn't do much with BeaglBone Black, there is no even interactive prompt, just keeps spitting out:
Code:
U-Boot SPL 2016.03-34558-g080c499 (Jul 31 2017 - 11:25:06)
Trying to boot from MMC1
But I don't want MMC1, I want to boot from MMC0!
 
I don't have the latest FreeBSD image for BBB, but one from June 2 is using u-boot 2014-10.
I've built u-boot from git with added API support as per this crochet doc.
Now I'm able to start ubldr.bin from u-boot environment! According to the doc mentioned above, ubldr doesn't have any board specific code, thus this should work on any board.
So, ubldr starts the kernel, but now the problem is with FDT. The latest u-boot's fdt tools complain about the dtb included in the FreeBSD image:
Code:
libfdt fdt_check_header(): FDT_ERR_BADMAGIC
It likes the one I copied from Linux, however, the kernel doesn't like it (probably), it stops at:
Code:
. . . .
sdhci_ti0: <TI MMCHS (SDHCI 2.0)> mem 0x48060000-0x48060fff irq 20 on simplebus0
mmc0: <MMC/SD bus> on sdhci_ti0
sdhci_ti1: <TI MMCHS (SDHCI 2.0)> mem 0x481d8000-0x481d8fff irq 21 on simplebus0
mmc1: <MMC/SD bus> on sdhci_ti1
sdhci_ti2: <TI MMCHS (SDHCI 2.0)> mem 0x47810000-0x47810fff irq 22 on simplebus0
Fatal kernel mode data abort: 'External Abort' on read
trapframe: 0xc0b0aca8
FSR=00001008, FAR=ff910114, spsr=60000093
r0 =c07f1b80, r1 =ff910000, r2 =00000114, r3 =00000000
r4 =00000001, r5 =c2d43e18, r6 =fffffc18, r7 =c2d43e00
r8 =c07b8824, r9 =c2d43e00, r10=c2ccd300, r11=c0b0ad80
r12=00000000, ssp=c0b0ad38, slr=c0693e4c, pc =c0693fd8

[ thread pid 0 tid 100000 ]
Stopped at      ti_sdhci_attach+0x4a0:  ldr     r0, [r2, r1]
db>
 
Okay, back to the original question.
After experimenting with the latest u-boot I understood how those things work (more or less).
Assuming that u-boot already exists for a particular board, it can be re-compiled with API support by adding 3 lines in the config file (see the doc mentioned above):
<uboot_sources>/include/configs/someboard.h:
Code:
#ifndef CONFIG_SPL_BUILD
#define CONFIG_API
#define CONFIG_CMD_ELF
#define CONFIG_SYS_MMC_MAX_DEVICE 1
#endif
When booting, u-boot suggests pressing space for interactive shell. Let's activate the shell. FreeBSD kernel is loaded by ubldr.bin, so let's load and run it:
Code:
load mmc 0:1 0x82000000 ubldr.bin
go 0x82000000
The loader will stop since does not know how to load a DTB (a compiled device tree description). To load a DTB and boot the default kernel:
Code:
load -t dtb /path/to/dtb
boot
If all the above works, those things can be automated, but such a manual boot is a good way to test the system first.

In theory, the board's DTB can be loaded by u-boot. By my understanding, ubldr.bin assumes it's at 0x88000000. However, in that case the kernel stops at some point as I mentioned in the previous post.
 
While in ubldr can you do an ' ls'? The idea here is to figure out if ubldr sees the correct device, and files on that device.
I couldn't get ls to show anything. The only useful command I found was
loader> ubenv show

Code:
uboot.loaderdev=usb 0:1

uboot.boot_bsd=run load_bsdenv; boot

uboot.loadbootenv=load ${type} ${disk}:1 ${loadaddr} /boot/uEnv.txt

uboot.fatdev=usb 0:1

uboot.pxefile_addr_r=0x00100000

uboot.bootm=echo Booting from ${disk} ...; run setargs; bootm ${loadaddr};

uboot.api_address=7b12860

uboot.importbootenv=echo Importing environment (uEnv.txt)...; env import -t $loadaddr $filesize

uboot.scriptaddr=0x00000000

uboot.ethaddr=00:10:75:2E:AE:0F

uboot.fdt_addr=0x800000

uboot.baudrate=115200

uboot.uimage=/boot/uImage

uboot.zimage=/boot/zImage

uboot.ethact=egiga0

uboot.bootcmd=usb start;fdt addr 0x100;fatload ${fatdev} ${loadaddr} ${bootfile} && bootelf ${loadaddr}

uboot.load_bsdenv=usb start; load usb 0:1 0x810000 /boot/uEnv.txt; env import -t 0x810000 $filesize

uboot.kernel_addr_r=0x01000000

uboot.bootz=echo Booting from ${disk} ...; run setargs; bootz ${loadaddr} - ${fdt_addr};

uboot.filesize=44729

uboot.bootfile=ubldr

uboot.mtdids=nand0=orion_nand

uboot.fdt_file=/boot/dtbs/kirkwood-goflexnet.dtb

uboot.fdtfile=db88f6281.dtb

uboot.setargs=setenv bootargs console=${console},${baudrate} ${optargs} root=/dev/sd${letter}1 rw rootwait ${mtdparts}

uboot.loadaddr=0x02000000

uboot.load=echo Attempting to boot from ${type} ${disk}:1...;if run loadbootenv; then run importbootenv;fi;echo Checking if uenvcmd is set ...;if test -n $uenvcmd; then echo Running uenvcmd ...;run uenvcmd;fi;echo Running default loadzimage ...;if run loadzimage; then run loadfdt;run bootz;fi;echo Running default loaduimage ...;if run loaduimage; then run bootm;fi;

uboot.bootdelay=3

uboot.fileaddr=2000000

uboot.mtdparts=mtdparts=orion_nand:1M(u-boot),-(rootfs)

uboot.loadfdt=load ${type} ${disk}:1 ${fdt_addr} ${fdt_file}

uboot.ramdisk_addr_r=0x02100000

uboot.loadzimage=load ${type} ${disk}:1 ${loadaddr} ${zimage}

uboot.loaduimage=load ${type} ${disk}:1 ${loadaddr} ${uimage}

uboot.console=ttyS0
 
Does 'ls' work better if you do an usb start first?

Among other things

loader> ubenv show

shows
Code:
uboot.bootcmd=usb start;fdt addr 0x100;fatload ${fatdev} ${loadaddr} ${bootfile} && bootelf ${loadaddr}

uboot.load_bsdenv=usb start; load usb 0:1 0x810000 /boot/uEnv.txt; env import -t 0x810000 $filesize

One thing that confuses me is does /boot/uEnv.txt refer to uEnv.txt in a /boot directory of the FAT partition or is the FAT partition regarded as /boot.

Still trying to figure out the file layout of the FAT partition...
 
Back
Top