This article describes how I installed FreeBSD on two different Allwinner based SoC’s.
Background
Recently I bought a NanoPi NEO and a OrangePi Zero from ebay just for fun, HOPING that FreeBSD would run nicely on them. But at first glance things arent that easy. There is no official images for example. But on the other hand there is a image building tool available at FreeBSD’s official github. This article will describe how I got FreeBSD running on these neat ARM computers. Happily this workflow works for both the Neo and the Zero.
Building the image
We need a u-boot image for the NanoPi. In the ports tree there is a lot of diffenret images but not for the nanopi, so what I did was simply to make a copy of the orange-pi-one port and edited it. I basically created my own local port for the NanoPI u-boot. This is what I did:
$ git diff origin/master u-boot-nanopi-neo/Makefile diff --git a/sysutils/u-boot-nanopi-neo/Makefile b/sysutils/u-boot-nanopi-neo/Makefile new file mode 100644 index 000000000000..552ba8c1c79f --- /dev/null +++ b/sysutils/u-boot-nanopi-neo/Makefile @@ -0,0 +1,10 @@ +# $FreeBSD: head/sysutils/u-boot-orangepi-one/Makefile 431327 2017-01-12 22:49:08Z imp $ + +MAINTAINER= imp@FreeBSD.org +MASTERDIR= ${.CURDIR}/../u-boot-master + +MODEL= nanopi-neo +BOARD_CONFIG= nanopi_neo_defconfig +FAMILY= allwinner + +.include "${MASTERDIR}/Makefile"
Amazingly this port compiled and installed without any problems.
Then I fetched the build tool “crochet” from github and created a branch for my changes
$ git clone https://github.com/freebsd/crochet.git Cloning into 'crochet'... remote: Counting objects: 5124, done. remote: Total 5124 (delta 0), reused 0 (delta 0), pack-reused 5124 Receiving objects: 100% (5124/5124), 8.13 MiB | 2.06 MiB/s, done. Resolving deltas: 100% (2643/2643), done. $ cd crochet $ git branch nanopi $ git checkout nanopi Switched to branch 'nanopi'
To define the NanoPI NEO board I was heavily inspired by the work of Jared McNeill. I basically copied his board definitions with a few changes to suit my setup. Here is the end result:
$ git diff origin/master diff --git a/board/NanoPi-NEO/overlay/boot/loader.conf b/board/NanoPi-NEO/overlay/boot/loader.conf new file mode 100644 index 0000000..9c0640f --- /dev/null +++ b/board/NanoPi-NEO/overlay/boot/loader.conf @@ -0,0 +1,3 @@ +# Hack to get loader to find dtb. +nanopi-neo.dtb_type="dtb" +nanopi-neo.dtb_load="YES" diff --git a/board/NanoPi-NEO/overlay/etc/fstab b/board/NanoPi-NEO/overlay/etc/fstab new file mode 100644 index 0000000..65563ce --- /dev/null +++ b/board/NanoPi-NEO/overlay/etc/fstab @@ -0,0 +1,4 @@ +/dev/mmcsd0s1 /boot/msdos msdosfs rw,noatime 0 0 +/dev/mmcsd0s2a / ufs rw,noatime 1 1 +md /var/log mfs rw,noatime,-s15m 0 0 +md /var/tmp mfs rw,noatime,-s12m 0 0 diff --git a/board/NanoPi-NEO/overlay/etc/rc.conf b/board/NanoPi-NEO/overlay/etc/rc.conf new file mode 100644 index 0000000..b1ee7a6 --- /dev/null +++ b/board/NanoPi-NEO/overlay/etc/rc.conf @@ -0,0 +1,14 @@ +hostname="nanopi-neo" +ifconfig_awg0="DHCP" +sshd_enable="YES" + +# Nice if you have a network, else annoying. +ntpd_enable="YES" +ntpd_sync_on_start="YES" + +sendmail_submit_enable="NO" +sendmail_outbound_enable="NO" +sendmail_msp_queue_enable="NO" + +# CPU frequency scaling +powerd_enable="YES" diff --git a/board/NanoPi-NEO/setup.sh b/board/NanoPi-NEO/setup.sh new file mode 100644 index 0000000..b93c728 --- /dev/null +++ b/board/NanoPi-NEO/setup.sh @@ -0,0 +1,34 @@ +KERNCONF=GENERIC +UBLDR_LOADADDR=0x42000000 +SUNXI_UBOOT="u-boot-nanopi-neo" +SUNXI_UBOOT_BIN="u-boot.img" +IMAGE_SIZE=$((1000 * 1000 * 1000)) +TARGET_ARCH=armv6 + +UBOOT_PATH="/usr/local/share/u-boot/${SUNXI_UBOOT}" + +allwinner_partition_image ( ) { + echo "Installing U-Boot files" + dd if=${UBOOT_PATH}/u-boot-sunxi-with-spl.bin conv=sync of=/dev/${DISK_MD} bs=1024 seek=8 + dd if=${UBOOT_PATH}/u-boot.img conv=notrunc,sync of=/dev/${DISK_MD} \ + bs=1024 seek=40 + disk_partition_mbr + disk_fat_create 32m 16 1m + disk_ufs_create +} +strategy_add $PHASE_PARTITION_LWW allwinner_partition_image + +allwinner_check_uboot ( ) { + uboot_port_test ${SUNXI_UBOOT} ${SUNXI_UBOOT_BIN} +} +strategy_add $PHASE_CHECK allwinner_check_uboot + +strategy_add $PHASE_BUILD_OTHER freebsd_ubldr_build UBLDR_LOADADDR=${UBLDR_LOADADDR} +strategy_add $PHASE_BOOT_INSTALL freebsd_ubldr_copy_ubldr . + +# Put the kernel on the FreeBSD UFS partition. +strategy_add $PHASE_FREEBSD_BOARD_INSTALL board_default_installkernel . +# overlay/etc/fstab mounts the FAT partition at /boot/msdos +strategy_add $PHASE_FREEBSD_BOARD_INSTALL mkdir -p boot/msdos +# ubldr help and config files go on the UFS partition (after boot dir exists) +strategy_add $PHASE_FREEBSD_BOARD_INSTALL freebsd_ubldr_copy boot diff --git a/nanopi_config.sh b/nanopi_config.sh new file mode 100644 index 0000000..acedcf7 --- /dev/null +++ b/nanopi_config.sh @@ -0,0 +1,9 @@ +board_setup NanoPi-NEO +option ImageSize 3900mb # for 4 Gigabyte card + +option Growfs +option Email peter@framkant.org +option CompressImage +option User peter + +FREEBSD_SRC=/usr/src12
The few things I needed to change from Jared’s board definition was the few ugly lines in loader.conf and also I added conv=sync to the first dd in setup.sh because FreeBSD gave an error otherwise. If someone knows why I need the two lines in loader.conf please tell me.
Support for these boards are added piece by piece in the HEAD branch of FreeBSD. So I checked out a specific source tree with “HEAD” or basically FreeBSD 12-CURRENT.
$ svn co https://svn0.us-west.freebsd.org/base/head /usr/src12 [..]
After this I was ready to build the Image:
$ ./crochet.sh -c nanopi_config.sh Starting at Sat Jul 1 11:40:10 CEST 2017 Loading configuration from nanopi_config.sh Board: NanoPi-NEO Option: ImageSize 3900mb Option: Growfs Option: Email peter@framkant.org Option: CompressImage Option: User peter Source version is: 320481 Building FreeBSD version: 12.0 Image name is: /usr/local/crochet/work/FreeBSD-armv6-12.0-GENERIC-320481.img Building FreeBSD version: 12.0 Object files are at: /usr/local/crochet/work/obj/arm.armv6/usr/src12 Found suitable FreeBSD source tree in: /usr/src12 Found U-Boot port in: /usr/local/share/u-boot/u-boot-nanopi-neo Building FreeBSD armv6 world at Sat Jul 1 11:40:13 CEST 2017 (Logging to /usr/local/crochet/work/_.buildworld.armv6.log) Building FreeBSD armv6-GENERIC kernel at Sat Jul 1 13:04:58 CEST 2017 (Logging to /usr/local/crochet/work/_.buildkernel.armv6-GENERIC.log) Building FreeBSD armv6-GENERIC ubldr at Sat Jul 1 13:10:54 CEST 2017 (Logging to /usr/local/crochet/work/ubldr-armv6-GENERIC/_.ubldr.armv6-GENERIC.build.log) Creating a 3900MB raw disk image in: /usr/local/crochet/work/FreeBSD-armv6-12.0-GENERIC-320481.img Installing U-Boot files Installing U-Boot files 417+1 records in 418+0 records out 428032 bytes transferred in 3.867684 secs (110669 bytes/sec) 385+1 records in 386+0 records out 395264 bytes transferred in 3.055042 secs (129381 bytes/sec) Partitioning the raw disk image with MBR at Sat Jul 1 13:43:51 CEST 2017 gpart create -s MBR md13 md13 created Creating a 32m FAT partition at Sat Jul 1 13:43:51 CEST 2017 with start block 1m and label BOOT active set on md13s1 Creating an auto-sized UFS partition at Sat Jul 1 13:43:52 CEST 2017 md13s2 created /dev/md13s2a: 3685.4MB (7547776 sectors) block size 32768, fragment size 4096 using 6 cylinder groups of 626.09MB, 20035 blks, 80256 inodes. super-block backups (for fsck_ffs -b #) at: 192, 1282432, 2564672, 3846912, 5129152, 6411392 tunefs: soft updates set Using inode 4 in cg 0 for 4194304 byte journal tunefs: soft updates journaling set tunefs: NFSv4 ACLs set Mounting all file systems: Mounting FAT partition 1 at /usr/local/crochet/work/_.mount.boot Mounting UFS partition 1 at /usr/local/crochet/work/_.mount.freebsd Installing ubldr in /usr/local/crochet/work/_.mount.boot Installing FreeBSD world at Sat Jul 1 13:43:55 CEST 2017 Destination: /usr/local/crochet/work/_.mount.freebsd Overlaying board-specific files from /usr/local/crochet/board/NanoPi-NEO/overlay 1 block Installing FreeBSD kernel at Sat Jul 1 13:51:34 CEST 2017 Destination: /usr/local/crochet/work/_.mount.freebsd Installing all ubldr files in boot 1394 blocks Adding user peter with password peter Unmounting /usr/local/crochet/work/_.mount.boot Unmounting /usr/local/crochet/work/_.mount.freebsd Releasing md13 Compressing image DONE. Completed disk image is in: /usr/local/crochet/work/FreeBSD-armv6-12.0-GENERIC-320481.img Copy to a suitable memory card using a command such as: dd if=/usr/local/crochet/work/FreeBSD-armv6-12.0-GENERIC-320481.img of=/dev/da0 bs=1m (Replace /dev/da0 with the appropriate path for your card reader.) Finished at Sat Jul 1 13:59:39 CEST 2017
Writing to SD card
After this there was a simple task of writing the image file to a SD card left:
$ ssh torus 'cat /usr/local/crochet/work/FreeBSD-armv6-12.0-GENERIC-320481.img.xz' | unxz | sudo dd of=/dev/rdisk2 bs=1m 0+408362 records in 0+408362 records out 3899999744 bytes transferred in 36.899393 secs (105692788 bytes/sec)
Booting the NanoPI
After writing the image to SD I just inserted the card, network and power to my NanoPI and after a while I got this in the logs of my router:
Jul 1 19:05:02 gw dhcpd: DHCPDISCOVER from 02:81:14:26:0a:0e via bridge0 Jul 1 19:05:03 gw dhcpd: DHCPOFFER on 172.25.0.182 to 02:81:14:26:0a:0e (nanopi-neo) via bridge0 Jul 1 19:05:05 gw dhcpd: Wrote 0 deleted host decls to leases file. Jul 1 19:05:05 gw dhcpd: Wrote 0 new dynamic host decls to leases file. Jul 1 19:05:05 gw dhcpd: Wrote 36 leases to leases file. Jul 1 19:05:05 gw dhcpd: DHCPREQUEST for 172.25.0.182 (172.25.0.1) from 02:81:14:26:0a:0e (nanopi-neo) via bridge0 Jul 1 19:05:05 gw dhcpd: DHCPACK on 172.25.0.182 to 02:81:14:26:0a:0e (nanopi-neo) via bridge0
Now it was a simple task to log in to the device using peter/peter:
$ ssh 172.25.0.182 Password for peter@nanopi: Last login: Sat Jul 1 17:16:05 2017 from lune.pean.org FreeBSD 12.0-CURRENT (GENERIC) #0 r320481: Sat Jul 1 13:10:46 CEST 2017 Welcome to FreeBSD! [..]
Boot messages
$ dmesg KDB: debugger backends: ddb KDB: current backend: ddb 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 12.0-CURRENT #0 r320481: Sat Jul 1 13:10:46 CEST 2017 peter@torus.pean.org:/usr/local/crochet/work/obj/arm.armv6/usr/src12/sys/GENERIC arm FreeBSD clang version 4.0.0 (tags/RELEASE_400/final 297347) (based on LLVM 4.0.0) WARNING: WITNESS option enabled, expect reduced performance. VT: init without driver. CPU: ARM Cortex-A7 r0p5 (ECO: 0x00000000) CPU Features: Multiprocessing, Thumb2, Security, Virtualization, Generic Timer, VMSAv7, PXN, LPAE, Coherent Walk Optional instructions: SDIV/UDIV, UMULL, SMULL, SIMD(ext) LoUU:2 LoC:3 LoUIS:2 Cache level 1: 32KB/64B 4-way data cache WB Read-Alloc Write-Alloc 32KB/32B 2-way instruction cache Read-Alloc Cache level 2: 512KB/64B 8-way unified cache WB Read-Alloc Write-Alloc real memory = 536870912 (512 MB) avail memory = 507977728 (484 MB) FreeBSD/SMP: Multiprocessor System Detected: 4 CPUs arc4random: no preloaded entropy cache random: entropy device external interface kbd0 at kbdmux0 ofwbus0: aw_ccu0: on ofwbus0 clk_fixed0: on aw_ccu0 clk_fixed1: on aw_ccu0 clk_fixed2: on aw_ccu0 aw_gate0: mem 0x1f01428-0x1f0142b on aw_ccu0 aw_modclk0: mem 0x1f01454-0x1f01457 on aw_ccu0 simplebus0: on ofwbus0 aw_ccung0: mem 0x1c20000-0x1c203ff on simplebus0 aw_reset0: mem 0x1f014b0-0x1f014b3 on simplebus0 iichb0: mem 0x1f02400-0x1f027ff irq 36 on simplebus0 iichb0: could not find clock device_attach: iichb0 attach returned 2 regfix0: on ofwbus0 regfix1: on ofwbus0 regfix2: on ofwbus0 iichb0: mem 0x1f02400-0x1f027ff irq 36 on simplebus0 iichb0: could not find clock device_attach: iichb0 attach returned 2 iichb0: mem 0x1f02400-0x1f027ff irq 36 on simplebus0 iichb0: could not find clock device_attach: iichb0 attach returned 2 aw_sid0: mem 0x1c14000-0x1c143ff on simplebus0 iichb0: mem 0x1f02400-0x1f027ff irq 36 on simplebus0 iichb0: could not find clock device_attach: iichb0 attach returned 2 awusbphy0: mem 0x1c19400-0x1c1942b,0x1c1a800-0x1c1a803,0x1c1b800-0x1c1b803,0x1c1c800-0x1c1c803,0x1c1d800-0x1c1d803 on simplebus0 iichb0: mem 0x1f02400-0x1f027ff irq 36 on simplebus0 iichb0: could not find clock device_attach: iichb0 attach returned 2 iichb0: mem 0x1f02400-0x1f027ff irq 36 on simplebus0 iichb0: could not find clock device_attach: iichb0 attach returned 2 gic0: mem 0x1c81000-0x1c81fff,0x1c82000-0x1c83fff,0x1c84000-0x1c85fff,0x1c86000-0x1c87fff irq 30 on simplebus0 gic0: pn 0x1, arch 0x2, rev 0x1, implementer 0x43b irqs 160 iichb0: mem 0x1f02400-0x1f027ff irq 36 on simplebus0 iichb0: could not find clock device_attach: iichb0 attach returned 2 iichb0: mem 0x1f02400-0x1f027ff irq 36 on simplebus0 iichb0: could not find clock device_attach: iichb0 attach returned 2 gpio0: mem 0x1c20800-0x1c20bff irq 14,15 on simplebus0 gpiobus0: on gpio0 gpio1: mem 0x1f02c00-0x1f02fff irq 34 on simplebus0 gpiobus1: on gpio1 iichb0: mem 0x1f02400-0x1f027ff irq 36 on simplebus0 iichb0: could not find clock device_attach: iichb0 attach returned 2 iichb0: mem 0x1f02400-0x1f027ff irq 36 on simplebus0 iichb0: could not find clock device_attach: iichb0 attach returned 2 gpioregulator0: on ofwbus0 iichb0: mem 0x1f02400-0x1f027ff irq 36 on simplebus0 iichb0: could not find clock device_attach: iichb0 attach returned 2 iichb0: mem 0x1f02400-0x1f027ff irq 36 on simplebus0 iichb0: could not find clock device_attach: iichb0 attach returned 2 generic_timer0: irq 0,1,2,3 on ofwbus0 Timecounter "ARM MPCore Timecounter" frequency 24000000 Hz quality 1000 Event timer "ARM MPCore Eventtimer" frequency 24000000 Hz quality 1000 rtc0: mem 0x1f00000-0x1f00053 irq 31,32 on simplebus0 iichb0: mem 0x1f02400-0x1f027ff irq 36 on simplebus0 iichb0: could not find clock device_attach: iichb0 attach returned 2 iichb0: mem 0x1f02400-0x1f027ff irq 36 on simplebus0 iichb0: could not find clock device_attach: iichb0 attach returned 2 iichb0: mem 0x1f02400-0x1f027ff irq 36 on simplebus0 iichb0: could not find clock device_attach: iichb0 attach returned 2 iichb0: mem 0x1f02400-0x1f027ff irq 36 on simplebus0 iichb0: could not find clock device_attach: iichb0 attach returned 2 iichb0: mem 0x1f02400-0x1f027ff irq 36 on simplebus0 iichb0: could not find clock device_attach: iichb0 attach returned 2 iichb0: mem 0x1f02400-0x1f027ff irq 36 on simplebus0 iichb0: could not find clock device_attach: iichb0 attach returned 2 cpulist0: on ofwbus0 cpu0: on cpulist0 cpufreq_dt0: on cpu0 cpu1: on cpulist0 cpu2: on cpulist0 cpu3: on cpulist0 a31dmac0: mem 0x1c02000-0x1c02fff irq 4 on simplebus0 a10_mmc0: mem 0x1c0f000-0x1c0ffff irq 5 on simplebus0 mmc0: <MMC/SD bus> on a10_mmc0 ehci0: mem 0x1c1d000-0x1c1d0ff irq 12 on simplebus0 usbus0: EHCI version 1.0 usbus0 on ehci0 ohci0: mem 0x1c1d400-0x1c1d4ff irq 13 on simplebus0 usbus1 on ohci0 gpioc0: on gpio0 aw_wdog0: mem 0x1c20ca0-0x1c20cbf irq 20 on simplebus0 uart0: mem 0x1c28000-0x1c283ff irq 23 on simplebus0 uart0: console (115384,n,8,1) gpioc1: on gpio1 awg0: mem 0x1c30000-0x1c30103,0x1c00030-0x1c00033 irq 35 on simplebus0 miibus0: on awg0 ukphy0: PHY 0 on miibus0 ukphy0: none, 10baseT, 10baseT-FDX, 100baseTX, 100baseTX-FDX, auto, auto-flow ukphy1: PHY 1 on miibus0 ukphy1: none, 10baseT, 10baseT-FDX, 100baseTX, 100baseTX-FDX, auto, auto-flow awg0: Ethernet address: 02:81:14:26:0a:0e iichb0: mem 0x1f02400-0x1f027ff irq 36 on simplebus0 iichb0: could not find clock device_attach: iichb0 attach returned 2 aw_thermal0: mem 0x1c25000-0x1c253ff irq 37 on simplebus0 gpioled0: on ofwbus0 cryptosoft0: Timecounters tick every 1.000 msec usbus0: 480Mbps High Speed USB v2.0 usbus1: 12Mbps Full Speed USB v1.0 ugen0.1: at usbus0 uhub0: on usbus0 ugen1.1: at usbus1 uhub1: on usbus1 mmcsd0: 16GB at mmc0 50.0MHz/4bit/65535-block Release APs WARNING: WITNESS option enabled, expect reduced performance. arc4random: no preloaded entropy cache Trying to mount root from ufs:/dev/mmcsd0s2a [rw,noatime]... arc4random: no preloaded entropy cache uhub1: 1 port with 1 removable, self powered arc4random: no preloaded entropy cache uhub0: 1 port with 1 removable, self powered GEOM_PART: mmcsd0s2 was automatically resized. Use `gpart commit mmcsd0s2` to save changes or `gpart undo mmcsd0s2` to revert them. lock order reversal: 1st 0xcd331e88 bufwait (bufwait) @ /usr/src12/sys/kern/vfs_bio.c:3539 2nd 0xc3470000 dirhash (dirhash) @ /usr/src12/sys/ufs/ufs/ufs_dirhash.c:281 stack backtrace: lock order reversal: 1st 0xc345d5d4 ufs (ufs) @ /usr/src12/sys/kern/vfs_subr.c:2602 2nd 0xcd331e88 bufwait (bufwait) @ /usr/src12/sys/ufs/ffs/ffs_vnops.c:280 3rd 0xc345c934 ufs (ufs) @ /usr/src12/sys/kern/vfs_subr.c:2602 stack backtrace: random: unblocking device. awg0: link state changed to DOWN awg0: link state changed to UP
For now I have only tested that the machine boots with network and the serial console. During my research I found alot of post about problems with USB for example.
Awesome! Can it build pfsense on the build?
Can you share the .img of the build?