Cool new FreeBSD 11/12 kernel developer trick

One of the cool new features in FreeBSD 11 is that we can use the system compiler as a cross compiler, eliminating the need to rebuild clang. While this allows buildworld to go much faster, there's another benefit that might not be immediately obvious.

For kernel development, this almost means we can forget about the usually required 'make kernel-toolchain' even when we're cross building. The system linker can't (yet) handle it, so the kernel fails to link if you've not done it. The good news is that you don't need to build gcc or clang for the kernel toolchain target, so you can build it quickly (in under a minute on my fast build machine, under 5 on my laptop VM). The trick is one command:
make kernel-toolchain TARGET=arm WITHOUT_{GCC,CLANG}{,_BOOTSTRAP}=t
If you are developing for amv6/v7, change TARGET=arm to TARGET_ARCH=armv6. I've not tried others, but suspect they will work as well as clang supports the target in question. This allows me to start building test kernels w/o the usual delay of building a kernel toolchain, especially on my laptop VM where  I'm chronically short on disk and always deleting the old obj tree.

This works on both 11.0 and 12.0-current. It likely will fail on 10.x since the system compiler as the cross compiler work hasn't been MFC'd there yet.


Quick hack: creating a pcDuino3 bootable image from FreeBSD 11.0's BANANA PI image.

Here's a tip about FreeBSD pre-configured armv6 images. For a given SoC, they are all (almost) the same. There's two difference for the Allwinner case (at least for the MP boards): u-boot and the hostname. Recently, I created a u-boot port for pcDuino3 as a slave port. Since I didn't care about the hostname, I thought I'd swap out the u-boot on the BANANA PI image. I snagged it from FreeBSD's download page and installed the u-boot-pcduino3 port. Allwinnner stores u-boot and a small initialization program in the first part of the SD after the MBR partition table. Other SoCs have different boot processes. Currently, you have to check the readme for each one. In the future, there will be a way to insert u-boot into any image.

So, to put the image on the SD card that showed up on my system as /dev/da2:
xz -d < FreeBSD-11.0-RC3-arm-armv6-BANANAPI.img.xz | dd of=/dev/da2 bs=1m
dd if=/usr/local/share/u-boot/u-boot-pcduino/u-boot-sunxi-with-spl.bin of=/dev/da2 bs=1k seek=8 conv=notrunc,sync
This puts the u-boot image (a SPL header which sets up the system to run u-boot coupled with u-boot) onto the disk. You can also uncompress the image you download and insert it there before pushing it out to the SD card. Since I also have a Banana PI I wanted to create an SD card for, I just changed it after it was on the image.

Unfortunately, every board needs a slightly different u-boot image. I have a number of changes I'm testing to help unify the u-boot ports. One of them adds metadata to each u-boot port that a generic imaging tool can use to make things better in the future.

Chain booting u-boot with u-boot

Recently, I needed to test u-boot before I flashed a new u-boot image into NAND. In the past, when I've googled it, I find a lot of screeds about how u-boot can't chain boot u-boot in the general case. Recently, I found a page for blackfin Linux that talks about doing just this. So, I got to thinking about trying again. I have a AT91SAM9G20. Atmel's boot process is split in two. at91bootstrap sets up the board enough to run u-boot. u-boot on Atmel boards can actually chain-boot.

So, how do I find out how to do it? I built u-boot for my board. 'objdump -f u-boot' after I built it showed:
u-boot:     file format elf32-littlearm
architecture: armv5te, flags 0x00000112:
start address 0x21f00000
Generally, u-boot is loaded at the same address it executes at. So, I confirmed with objdump -x, the full output is too long to quote here, but this is relevant:
 Idx Name          Size      VMA       LMA       File off  Algn
  0 .text         0002f5e4  21f00000  21f00000  00010000  2**5
which confirms the address. So, I booted up the old u-boot I wanted to replace and loaded u-boot.bin at 0x21f00000 and jumped to it:
Start AT91Bootstrap...

U-Boot 1.3.4 (Jul 24 2009 - 17:50:12)

NAND: 256 MiB
In: serial
Out: serial
Err: serial
Net: macb0
macb0: Starting autonegotiation...
macb0: Autonegotiation complete
macb0: link up, 100Mbps full-duplex (lpa: 0x45e1)
Hit any key to stop autoboot: 0
U-Boot> tftp 0x21f00000 u-boot.bin
macb0: link up, 100Mbps full-duplex (lpa: 0x45e1)
Using macb0 device
TFTP from server; our IP address is
Filename 'u-boot.bin'.
Load address: 0x21f00000
Loading: ####################
Bytes transferred = 288984 (468d8 hex)
U-Boot> go 0x21f00000
## Starting application at 0x21F00000 ...

U-Boot 2016.05-00018-g2f0dd66 (Sep 18 2016 - 21:38:36 -0600)

Crystal frequency: 18.432 MHz
CPU clock : 396.288 MHz
Master clock : 132.096 MHz
DRAM: 64 MiB
WARNING: Caches not enabled
NAND: 256 MiB
*** Warning - bad CRC, using default environment

In: serial
Out: serial
Err: serial
Net: macb0
Error: macb0 address not set.

Hit any key to stop autoboot: 0
And we're in...


Creating a quick DNS server with a Rapsberry Pi2 and FreeBSD 11.0-RC1

Raspberry Pi 2 and FreeBSD 11 and bind 9.9 for a name server

Just thought I'd outline the steps to bring a Raspberry Pi 2 up with FreeBSD and then create a DNS server with bind. This is for the Raspberry Pi2, but the only difference between this and any other supported board is the file you grab.

The TL;DR version

Download the image, use xz to decompress and dd to a SD card. Boot the SD card with a serial console, create a new account to log into. Install the appropriate packages. Configure named. Tell the world about it (router and registrar). Profit! All quite simple, though there were a few snags that are in the 'Long Version'

Long Version, so much detail

First, download the FreeBSD image from https://www.freebsd.org/where.html. I'm doing the SD Card Image for FreeBSD 11.0-RC1. This gave me the file FreeBSD-11.0-RC1-arm-armv6-RPI2.img.xz in my downloads area. If you're doing a different image, adjust below.

Next, I needed to create a microSD card for the RPi-2. I plugged a 4GB SD Card into my USB adapter, and the device appeared as da2 on my FreeBSD box.
 xz -d < ~/FreeBSD-11.0-RC1-arm-armv6-RPI2.img.xz | sudo dd of=/dev/da2 bs=1m
will uncompress it and splat it onto the SD card.

Next, I connected to my RPi2's serial port with tip and the Adafruit USB to TTY Adapter:
tip -115200 ucom1
When booting, I got this log. Yours might not be identical, but the login: at the end should be the same.

U-Boot 2015.04 (Aug 12 2016 - 16:50:57)

DRAM:  944 MiB
WARNING: Caches not enabled
RPI 2 Model B
MMC:   bcm2835_sdhci: 0
reading uboot.env

** Unable to read "uboot.env" from mmc0:1 **
Using default environment

In:    serial
Out:   lcd
Err:   lcd
Net:   Net Initialization Skipped
No ethernet found.
Hit any key to stop autoboot:  0 
Booting from: mmc 0 ubldr
reading ubldr
272013 bytes read in 213 ms (1.2 MiB/s)
## Starting application at 0x02000098 ...
Consoles: U-Boot console  
Compatible U-Boot API signature found @0x3ab4a4c8

FreeBSD/armv6 U-Boot loader, Revision 1.2
(root@releng2.nyi.freebsd.org, Fri Aug 12 17:05:59 UTC 2016)

Number of U-Boot devices: 1
U-Boot env: loaderdev='mmc 0'
Found U-Boot device: disk
  Checking unit=0 slice= partition=... good.
Booting from disk0s2a:
/boot/kernel/kernel data=0x72a864+0x17979c syms=[0x4+0x7e120+0x4+0x90fad]

Hit [Enter] to boot immediately, or any other key for command prompt.
Booting [/boot/kernel/kernel]...               
Using DTB provided by U-Boot at address 0x100.
Kernel entry at 0x0x2200100...
Kernel args: (null)
Copyright (c) 1992-2016 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-RC1 #0 r303979: Fri Aug 12 17:12:13 UTC 2016
    root@releng2.nyi.freebsd.org:/usr/obj/arm.armv6/usr/src/sys/RPI2 arm
FreeBSD clang version 3.8.0 (tags/RELEASE_380/final 262564) (based on LLVM 3.8.0)
VT: init without driver.
CPU: Cortex A7 rev 5 (Cortex-A core)
 Supported features: ARM_ISA THUMB2 JAZELLE THUMBEE ARMv4 Security_Ext
 WB enabled LABT branch prediction disabled
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  = 989851648 (943 MB)
avail memory = 956411904 (912 MB)
FreeBSD/SMP: Multiprocessor System Detected: 4 CPUs
random: entropy device external interface
kbd0 at kbdmux0
simplebus0: mem 0x3f000000-0x3fffffff on ofwbus0
local_intc0: mem 0x40000000-0x400000ff on simplebus0
generic_timer0: on ofwbus0
Timecounter "ARM MPCore Timecounter" frequency 19200000 Hz quality 1000
Event timer "ARM MPCore Eventtimer" frequency 19200000 Hz quality 1000
intc0: mem 0xb200-0xb3ff on simplebus0
bcmwd0: mem 0x10001c-0x100027 on simplebus0
gpio0: mem 0x200000-0x2000af on simplebus0
gpio0: read-only pins: 46,48-53.
gpio0: reserved pins: 48-53.
gpiobus0: on gpio0
gpioled0: at pin 35 on gpiobus0
gpioled1: at pin 47 on gpiobus0
gpioc0: on gpio0
iichb0: mem 0x205000-0x20501f on simplebus0
iicbus0: on iichb0
iic0: on iicbus0
iichb1: mem 0x804000-0x80401f on simplebus0
iicbus1: on iichb1
iic1: on iicbus1
spi0: mem 0x204000-0x20401f on simplebus0
spibus0: on spi0
bcm_dma0: mem 0x7000-0x7fff,0xe05000-0xe05fff on simplebus0
mbox0: mem 0xb880-0xb8bf on simplebus0
sdhci_bcm0: mem 0x300000-0x3000ff on simplebus0
mmc0: on sdhci_bcm0
uart0: mem 0x201000-0x201fff on simplebus0
uart0: console (115200,n,8,1)
vchiq0: mem 0xb800-0xb84f on simplebus0
vchiq: local ver 8 (min 3), remote ver 8.
pcm0: on vchiq0
bcm283x_dwcotg0: mem 0x980000-0x99ffff on simplebus0
usbus0 on bcm283x_dwcotg0
cpulist0: on ofwbus0
cpu0: on cpulist0
bcm2835_cpufreq0: on cpu0
cpu1: on cpulist0
cpu2: on cpulist0
cpu3: on cpulist0
fb0: on ofwbus0
fbd0 on fb0
VT: initialize with new VT driver "fb".
fb0: 1824x984(1824x984@0,0) 24bpp
fb0: fbswap: 1, pitch 5472, base 0x3d359000, screen_size 5428224
Timecounters tick every 10.000 msec
usbus0: 480Mbps High Speed USB v2.0
ugen0.1: at usbus0
uhub0: on usbus0
mmcsd0: 4GB at mmc0 41.6MHz/4bit/65535-block
bcm2835_cpufreq0: ARM 600MHz, Core 250MHz, SDRAM 400MHz, Turbo OFF
Release APs
Trying to mount root from ufs:/dev/ufs/rootfs [rw]...
warning: no time-of-day clock registered, system time will not be set accurately
uhub0: 1 port with 1 removable, self powered
Growing root partition to fill device
GEOM_PART: mmcsd0s2 was automatically resized.
  Use `gpart commit mmcsd0s2` to save changes or `gpart undo mmcsd0s2` to revert them.
mmcsd0s2 resized
ugen0.2: at usbus0
uhub1: on usbus0
uhub1: MTT enabled
mmcsd0s2a resized
super-block backups (for fsck_ffs -b #) at:
 1994944, 2493632, 2992320, 3491008,uhub1: 5 ports with 4 removable, self powered
 3989696, 4488384, 4987072, 5485760,
 5984448, 6483136, 6981824, 7480512
ugen0.3: at usbus0
smsc0: on usbus0
smsc0: chip 0xec00, rev. 0002
miibus0: on smsc0
ukphy0: PHY 1 on miibus0
ukphy0:  none, 10baseT, 10baseT-FDX, 100baseTX, 100baseTX-FDX, auto
ue0: on smsc0
ue0: Ethernet address: b8:27:eb:xx:xx:xx
ugen0.4: at usbus0
ukbd0: on usbus0
kbd1 at ukbd0
/etc/rc: WARNING: hostid: unable to figure out a UUID from DMI data, generating a new one
Setting hostuuid: 3b610f45-60b0-11e6-85fc-b827eb30ec4b.
Setting hostid: 0xd150b3f7.
Starting file system checks:
/dev/ufs/rootfs: clean, 745130 free (266 frags, 93108 blocks, 0.0% fragmentation)
Mounting local filesystems:.
ELF ldconfig path: /lib /usr/lib /usr/lib/compat
random: unblocking device.
Soft Float compatibility ldconfig path:
Setting hostname: rpi2.
Feeding entropy: .
smsc0: chip 0xec00, rev. 0002
ue0: link state changed to DOWN
ue0: link state changed to UP
Starting Network: lo0 ue0.
lo0: flags=8049 metric 0 mtu 16384
inet6 ::1 prefixlen 128 
inet6 fe80::1%lo0 prefixlen 64 scopeid 0x1 
inet netmask 0xff000000 
groups: lo 
nd6 options=21
ue0: flags=8843 metric 0 mtu 1500
ether b8:27:eb:30:ec:4b
media: Ethernet autoselect (100baseTX )
status: active
nd6 options=29
Starting devd.
Starting dhclient.
DHCPDISCOVER on ue0 to port 67 interval 3
DHCPREQUEST on ue0 to port 67
bound to -- renewal in 3600 seconds.
add host gateway lo0 fib 0: route already in table
add host ::1: gateway lo0 fib 0: route already in table
add net fe80::: gateway ::1
add net ff02::: gateway ::1
add net ::ffff: gateway ::1
add net :: gateway ::1
Generating host.conf.
Creating and/or trimming log files.
Starting syslogd.
Clearing /tmp (X related).
Updating motd:.
Mounting late filesystems:.
Configuring vt: blanktime.
Generating RSA host key.
2048 SHA256:FXp0GIg9YQO8QKDV4laoIrXLhUPcBQPaYeusHOnn4wI root@rpi2 (RSA)
Generating ECDSA host key.
256 SHA256:lYyCJFYZHx2W8slGyhe8CF6GIc8ejZZWcO4wTlRf/YI root@rpi2 (ECDSA)
Generating ED25519 host key.
256 SHA256:L2wqTBkNdGahTGswcpzG4ysvhU9uCPyjBtLGLczi6fI root@rpi2 (ED25519)
Performing sanity check on sshd configuration.
Starting sshd.
Starting cron.
Starting background file system checks in 60 seconds.
mount: /dev/ufs/rootfs: Device busy

Fri Aug 12 17:15:15 UTC 2
FreeBSD/arm (rpi2) (ttyu0)

login: root
Aug 12 17:15:19 rpi2 login: ROOT LOGIN (root) ON ttyu0
FreeBSD 11.0-RC1 (RPI2) #0 r303979: Fri Aug 12 17:12:13 UTC 2016

Welcome to FreeBSD!

Release Notes, Errata: https://www.FreeBSD.org/releases/
Security Advisories:   https://www.FreeBSD.org/security/
FreeBSD Handbook:      https://www.FreeBSD.org/handbook/
FreeBSD FAQ:           https://www.FreeBSD.org/faq/
Questions List: https://lists.FreeBSD.org/mailman/listinfo/freebsd-questions/
FreeBSD Forums:        https://forums.FreeBSD.org/

Documents installed with the system are in the /usr/local/share/doc/freebsd/
directory, or can be installed later with:  pkg install en-freebsd-doc
For other languages, replace "en" with a language code like de or fr.

Show the version of FreeBSD installed:  freebsd-version ; uname -a
Please include that output and any error messages when posting questions.
Introduction to manual pages:  man man
FreeBSD directory layout:      man hier

Edit /etc/motd to change this login announcement.
root@rpi2:~ # adduser
Username: imp
Full name: M Warner Losh
Uid (Leave empty for default): 1234
Login group [imp]: 
Login group is imp. Invite imp into other groups? []: wheel
Login class [default]: 
Shell (sh csh tcsh nologin) [sh]: tcsh
Home directory [/home/imp]: 
Home directory permissions (Leave empty for default): 
Use password-based authentication? [yes]: 
Use an empty password? (yes/no) [no]: 
Use a random password? (yes/no) [no]: 
Enter password: 
Enter password again: 
Lock out the account after creation? [no]: 
Username   : imp
Password   : *****
Full Name  : M Warner Losh
Uid        : 1234
Class      : 
Groups     : imp wheel
Home       : /home/imp
Home Mode  : 
Shell      : /bin/tcsh
Locked     : no
OK? (yes/no): yes
adduser: INFO: Successfully added (imp) to the user database.
Add another user? (yes/no): no
root@rpi2:~ # logout

FreeBSD/arm (rpi2) (ttyu0)

 So, now we have a remote login (or we could have used the default freebsd/freebsd user).

Next, we need to bootstrap the packages. In the RC1 release there's a snag. The quarterly release hasn't been created yet, so you have to override the location:
# env PACKAGESITE=pkg+http://pkg.FreeBSD.org/FreeBSD:11:armv6/latest pkg boostrap
The package management tool is not yet installed on your system.Do you want to fetch and install it now? [y/N]: yBootstrapping pkg from pkg+http://pkg.FreeBSD.org/FreeBSD:11:armv6/latest, please wait...Verifying signature with trusted certificate pkg.freebsd.org.2013102301... doneInstalling pkg-1.8.5_1...Extracting pkg-1.8.5_1: 100%
root@rpi2:/home/imp # 
Now, in the RC1 release, there's another snag, you have to change quarterly to latest in /etc/pkg/FreeBSD.conf. Once you do that, you can continue. Since this is a simple box, I'm just installing sudo, bind99 and emacs-nox11 on it. Don't need anything more than that.

root@rpi2:/home/imp # pkg install sudo bind99 emacs-nox11
Updating FreeBSD repository catalogue...Fetching meta.txz: 100%    944 B   0.9kB/s    00:01    Fetching packagesite.txz: 100%    5 MiB 525.0kB/s    00:09    Processing entries: 100%FreeBSD repository update completed. 21349 packages processed.The following 18 package(s) will be affected (of 0 checked):
New packages to be INSTALLED:sudo: 1.8.17bind99: 9.9.9P1emacs-nox11: 24.5_3,3gettext-runtime: 0.2.4libxml2: 2.9.3libedit: 3.1.20150325_2,1idnkit: 1.0_5gnutls: 3.4.13nettle: 3.2gmp: 5.1.3_3ca_root_nss: 3.22.2libtasn1: 4.8trousers: 0.3.13tpm-emulator: 0.7.4_1p11-kit: 0.23.2libffi: 3.2.1libidn: 1.31
The process will require 179 MiB more space.48 MiB to be downloaded.
Proceed with this action? [y/N]: yFetching sudo-1.8.17.txz: 100%  835 KiB 427.4kB/s    00:02    Fetching bind99-9.9.9P1.txz: 100%    4 MiB 583.4kB/s    00:08    Fetching emacs-nox11-24.5_3,3.txz: 100%   36 MiB 574.9kB/s    01:06    Fetching gettext-runtime- 100%  142 KiB 145.5kB/s    00:01    Fetching indexinfo-0.2.4.txz: 100%    5 KiB   5.0kB/s    00:01    Fetching libxml2-2.9.3.txz: 100%  735 KiB 376.5kB/s    00:02    Fetching libedit-3.1.20150325_2,1.txz: 100%  107 KiB 110.1kB/s    00:01    Fetching idnkit-1.0_5.txz: 100%  182 KiB 185.9kB/s    00:01    Fetching gnutls-3.4.13.txz: 100%    2 MiB 501.4kB/s    00:04    Fetching nettle-3.2.txz: 100%    1 MiB 378.8kB/s    00:03    Fetching gmp-5.1.3_3.txz: 100%  390 KiB 399.5kB/s    00:01    Fetching ca_root_nss-3.22.2.txz: 100%  323 KiB 330.3kB/s    00:01    Fetching libtasn1-4.8.txz: 100%  584 KiB 298.9kB/s    00:02    Fetching trousers-0.3.13.txz: 100%  390 KiB 399.6kB/s    00:01    Fetching tpm-emulator-0.7.4_1.txz: 100%   18 KiB  18.0kB/s    00:01    Fetching p11-kit-0.23.2.txz: 100%  199 KiB 203.4kB/s    00:01    Fetching libffi-3.2.1.txz: 100%   33 KiB  33.4kB/s    00:01    Fetching libidn-1.31.txz: 100%  196 KiB 200.9kB/s    00:01    Checking integrity... done (0 conflicting)[1/18] Installing indexinfo-0.2.4...[1/18] Extracting indexinfo-0.2.4: 100%[2/18] Installing gmp-5.1.3_3...[2/18] Extracting gmp-5.1.3_3: 100%[3/18] Installing gettext-runtime-[3/18] Extracting gettext-runtime- 100%[4/18] Installing ca_root_nss-3.22.2...[4/18] Extracting ca_root_nss-3.22.2: 100%[5/18] Installing libtasn1-4.8...[5/18] Extracting libtasn1-4.8: 100%[6/18] Installing tpm-emulator-0.7.4_1...===> Creating groups.Creating group '_tss' with gid '601'.===> Creating usersCreating user '_tss' with uid '601'.[6/18] Extracting tpm-emulator-0.7.4_1: 100%[7/18] Installing libffi-3.2.1...[7/18] Extracting libffi-3.2.1: 100%[8/18] Installing nettle-3.2...[8/18] Extracting nettle-3.2: 100%[9/18] Installing trousers-0.3.13...===> Creating groups.Using existing group '_tss'.===> Creating usersUsing existing user '_tss'.[9/18] Extracting trousers-0.3.13: 100%[10/18] Installing p11-kit-0.23.2...[10/18] Extracting p11-kit-0.23.2: 100%[11/18] Installing libidn-1.31...[11/18] Extracting libidn-1.31: 100%[12/18] Installing libxml2-2.9.3...[12/18] Extracting libxml2-2.9.3: 100%[13/18] Installing libedit-3.1.20150325_2,1...[13/18] Extracting libedit-3.1.20150325_2,1: 100%[14/18] Installing idnkit-1.0_5...[14/18] Extracting idnkit-1.0_5: 100%[15/18] Installing gnutls-3.4.13...[15/18] Extracting gnutls-3.4.13: 100%[16/18] Installing sudo-1.8.17...[16/18] Extracting sudo-1.8.17: 100%[17/18] Installing bind99-9.9.9P1...[17/18] Extracting bind99-9.9.9P1: 100%[18/18] Installing emacs-nox11-24.5_3,3...[18/18] Extracting emacs-nox11-24.5_3,3: 100%Message from ca_root_nss-3.22.2:********************************* WARNING *********************************
FreeBSD does not, and can not warrant that the certification authoritieswhose certificates are included in this package have in any way beenaudited for trustworthiness or RFC 3647 compliance.
Assessment and verification of trust is the complete responsibility of thesystem administrator.
*********************************** NOTE **********************************
This package installs symlinks to support root certificates discovery bydefault for software that uses OpenSSL.
This enables SSL Certificate Verification by client software without manualintervention.
If you prefer to do this manually, replace the following symlinks witheither an empty file or your site-local certificate bundle.
  * /etc/ssl/cert.pem  * /usr/local/etc/ssl/cert.pem  * /usr/local/openssl/cert.pem
***************************************************************************Message from trousers-0.3.13:To run tcsd automatically, add the following line to /etc/rc.conf:
You might want to edit /usr/local/etc/tcsd.conf to reflect your setup.
If you want to use tcsd with software TPM emulator, use the followingconfiguration in /etc/rc.conf:
To use TPM, add your_account to '_tss' group like following:
# pw groupadd _tss -m your_accountMessage from idnkit-1.0_5:===>   NOTICE:
The idnkit port currently does not have a maintainer. As a result, it ismore likely to have unresolved issues, not be up-to-date, or even be removed inthe future. To volunteer to maintain this port, please create an issue at:
More information about port maintainership is available at:
https://www.freebsd.org/doc/en/articles/contributing/ports-contributing.html#maintain-portMessage from bind99-9.9.9P1:***********************************************************************            _  _____ _____ _____ _   _ _____ ___ ___  _   _         **           / \|_   _|_   _| ____| \ | |_   _|_ _/ _ \| \ | |        **          / _ \ | |   | | |  _| |  \| | | |  | | | | |  \| |        **         / ___ \| |   | | | |___| |\  | | |  | | |_| | |\  |        **        /_/   \_\_|   |_| |_____|_| \_| |_| |___\___/|_| \_|        **                                                                    **   BIND requires configuration of rndc, including a "secret" key.   **    The easiest, and most secure way to configure rndc is to run    **   'rndc-confgen -a' to generate the proper conf file, with a new   **            random key, and appropriate file permissions.           **                                                                    **     The /usr/local/etc/rc.d/named script will do that for you.     **                                                                    ***********************************************************************root@rpi2:/home/imp # 
Although it says that the rc.d named script will do it, I went ahead and did the rndc-confgen -a:
root@rpi2:/home/imp # rndc-confgen -awrote key file "/usr/local/etc/namedb/rndc.key" 
next, we need to copy over the master zone and setup named.conf. Briefly, I commented out the part that binds to localhost and added a pointer to the master file for my zone. I setup stuff so secondaries could transfer out, and I could cross-mirror the secondaries.

So, once it was all running right, I changed rc.conf to enable it (as well as tweak the hostname from the default):
Now the fun part: telling my router to forward DNS packets (port 53) to my FreeBSD box, and then telling my registrar the new IP address of my DNS server. And after the obligatory password snafu, I was able to get everything up and happy.

Removed the default 'freebsd' account and changed the root password to something useful, and I was done.

A final though

I used to think I'd need to pay someone to host DNS for me. And that used to be cheaper in someone else's colo. However, with dirt cheap boards like the Raspberry Pi 2 and others like it, now I can host it myself for not much more than paying someone else do do it. And setting up the server was super easy. Wish blogspot would allow me to more easily attach text files, but it's an imperfect world.


Creating Logos for u-boot images

The Default Logo: Tux

By default, Das U-boot uses a penguin logo when it first starts up. This default looks something like this

While it's cool to have this for Linux users, FreeBSD users would like to see something more relevant. I recently got a pcDuino 3 board that I wanted to get FreeBSD running on. When I saw Tux still greeting me, I knew I had to do something. If nothing else, we should be branding the images made by the project with project logos and not the default which advertises a competitor.

The Quest

So, I set off on a quest to find the logo that would be best. It turns out to be not as simple a question as I thought jumping into this as I thought.

Logo vs Mascot

Traditionally, FreeBSD has had both the logo and the mascot as part of its boot sequence. The FreeBSD daemon that was used was based on artwork from the Walnut Creek CDROM which in turn was based on artwork drawn for Kirk McKusick by Lassiter. I realized that I'd have to do both. I'd make the logo the default, but also make it possible to have the mascot. While the Lassiter image appears to be the official mascot of the project, the Walnut Creek CDROM image is more widely viewed as the mascot of the FreeBSD project, so I had to select which one to use, or add yet another option.

Finding Good Artwork

The needs of u-boot is simple. Generally, you have an 80x80 image that's splashed up on the screen. While there is some wiggle room for the size of the icon, irregular sized icons just look sloppy in comparison to the default (there's several in the u-boot distribution to choose from, so I tried each one and was left dissatisfied each time).

A few web searches later, I found the best three examples to work from that I could: one with the FreeBSD logo, one with the Lassiter image, and a decent one of the Walnut Creek CDROM cd inserts and various books on FreeBSD (the older image from the 2.0 CDROM, not the newer one with daemon walking out of the CD that was used after).

The Lassiter image was by far the worst of the lot, but it was the best I could find. It proved too difficult to work with, so I eliminated it from my work. The logo and the Walnut Creek daemons would have to do.

Creating BMP images

Turns out this is harder than I would have thought.

To do the FreeBSD-associated daemon, I grabbed a copy from wikipedia's BSD daemon article and did the following:
convert freebsd-daemon.jpg -bordercolor white -channel RGBA -fuzz 20% -fill black -floodfill +0+0 white -resize 80x80\! -colors 200 -alpha off -type palette -compress none freebsd-daemon-1.bmp
To do the FreeBSD logo, I grabbed a copy from the FreeBSD web site and did the following:

convert logo-full.png -crop 172x172+2+2\! -resize 80x80 -colors 200 -alpha off -type palette -compress none -transparent-color black logo-full.bmp

This astute observer will notice a few things here. First, both images were 80x80. That's the default size. The u-boot tool, even with my fixes, only works with widths that are an even multiple of 4. I did 200 colors, but the limit is 240 (256 - 16).  Due to the way that uboot encodes the images, more than around 100 colors isn't going to have a big impact for either of these images (it takes the upper nibble from R G and B value that, and only that, so nuanced differences in colors don't matter). There's likely some fancy mode to optimize color generation in ImageMagick (where the convert program comes from), but I stopped before finding it.

Fixing U-Boot to have it join the 21st century

Turns out the bmp_logo utility that comes with u-boot has some serious limitations. First, it won't detect when you have a width that isn't a multiple of 4, and will generate a bad file instead that you won't discover is bad until you boot the box. Next, it doesn't check to see if the bmp is a compressed one or not with the same result. Ditto for number of colors. Same result. Those are all annoying, but the worst thing of all is that it won't handle any BMP that's newer than Windows 95. The BMP format has a field in a header that tells it how big the image hader is. bmp_logo, as distributed, assumes this length (40), but that only works for win95 and older (but not too old, super-antient BMPs likely would fail too). Any modern tool will generate the newer format (like ImageMagick does).

I've fixed the bmp_logo program locally, and merged a copy of the diffs into FreeBSD's repo for the sysutils/u-boot-olimex-a20-som-evb port (so all a20 and newer allwinner ports). I'm working to get this upstreamed.

The Results


Here's a slightly blurry shot of the logo I settled on. https://people.freebsd.org/~imp/20160814_104146.jpg

http://people.freebsd.org/~imp/20160815_234153.jpg uses the newest FreeBSD Foundation recommended logo...

The Daemon Formerly Known as Chuckie

Here's a blurry shot of the Walnut Creek daemon.  https://people.freebsd.org/~imp/20160814_124703.jpg

u-boot changes

I've created patches for the A20 Allwinnner ports. They will be committed shortly. I'll also be working to get these upstream into u-boot.


FreeBSD exposure on recent glibc DNS overflow

Recently, there's been much talk in the news about CVE-2015-7547 affecting almost all Linux-based routers and many distributions.

A quick analysis shows that FreeBSD's native libraries are completely unaffected. If you are running Linux emulation binaries, you may be at risk, and should update the linux emulation package.

Dag-Erling SmΓΈrgrav has a good blog with all the details.


Details on coming automatic module loading in FreeBSD

Automatic Module Loading

For a long time, I've wanted to add better, automatic module loading to FreeBSD. This past year, I started implementing that feature. Time and work pressures prevented me from completing it.

Some background

Every device that we have in our systems is enumerated in one of two ways. Either the bus gives us a list of all the devices, with certain per-device attributes (called plug and play data), or the device is attached through some other means. These latter devices are beyond the scope of this work, and there's generally very few of them in the system, and they aren't optional. The other devices, sometimes called 'self-enumerating' devices, have enough plug and play data for drivers in the system to decide if that driver can drive them or not. Most operating systems assign devices to drivers using this data. Some have the data encoded into tables in the filesystem (Windows, OS  X and Solaris), while others encode the data into the drivers (FreeBSD, NetBSD, OpenBSD, Linux, Dragon Fly BSD), though Linux offers some hybridization when it comes to certain devices. Except for FreeBSD, all these other OSes are beyond the scope of this work. And there's certainly room for debate over which approach is best, but we'll leave that behind as well.

Some busses on FreeBSD, like USB and PC Card, have very stylized probe routines. Drivers for devices on these busses generally call some bus-provided routine to match the device against a table that's basically the same for all drivers (though there's usually some stylized way to attach extra data). These drivers are easy to adapt to this new scheme because while some custom code needs to be written for each bus, each driver of that bus can generally use a macro to implement marking the PNP data (more on what marking means in a bit).

Other busses, like PCI, leave it entirely to the driver. So most of the drivers in the system have written their own matching routines that essentially loop through a table matching some attribute the bus provides to decide if the device is for them. These busses are harder to adapt.

But either way, most all drivers have some table of plug and play data that they use to filter their choice of devices. Since drivers are compiled into modules, this means most modules on the system have this data too. However, given the chaotic nature of the different busses, it's impossible for a program to find this data, unless it has very specific knowledge of each and every driver on the system (though for some classes of drivers, like USB and PC Card, it needn't know everything).

Finally, switching gears a bit, we have modules. Modules in the system record dependencies on other modules in the system using special macros. When the modules are installed, kldxref(8) runs through all of them, extracting these dependencies into a file called linker.hints that lives in the directory kernel and modules reside in.

General Theory

So, with that background, it's time to explore the design. What if we could take that chaotic state of affairs and somehow tame it. If we could create macros that we could use to mark the plug and play data, as well as associate various binary bits with the plug and play attribute provided by the bus driver? What if we could create records in the modules similar to what is used to mark module dependencies? Then, kldxref(8) would be able to comb through this data, record it in linker.hints and we'd need little other modifications to the system to make this data readily accessible.

That's exactly what my changes do. New types of records are inserted into the special section of modules that describe the plug and play table in the driver. These records contain a header that contains the length of each table entry, a pointer to the first entry, and a tiny little "script" or "description" of the table that ties this binary data to the bus-provided plug and play data. Each bus in the system that is of the stylized type described above defines its own macros to help its client drivers mark the data. Since all the data is the same for all the drivers, this means client drivers don't need to reinvent the wheel. Since we also pass the length of each table entry, drivers can use the common pattern of having the common data first, followed by whatever other data it needs for each device in the table.

However, that leaves more work for the non-stylized busses. While a few of these drivers have been converted, many remain.

Details about the marking

The first place to look for the details is . The first user-visible bit is a macro MODULE_PNP_INFO
#define MODULE_PNP_INFO(d, b, unique, t, l, n)
"d" is the description of the table (more on that below). "b" is the name of the bus. Unique is a unique string (typically the driver name). "t" is a pointer to the plug and play table. "l" is the length of each entry in the table. "n" is the number of entries.

The description is of the general form  (TYPE:pnp_name[/pnp_name];)* where TYPE is one of the following:
  • U8      uint8_t element
  • V8      like U8 and 0xff means match an
  • G16    uint16_t element, any value >= matches
  • L16     uint16_t element, any value <= matches
  • M16    uint16_t element, mask of which of the following fields to use.
  • U16     uint16_t element
  • V16     like U16 and 0xffff means match any
  • U32     uint32_t element
  • V32     like U32 and 0xffffffff means match any
  • W32     Two 16-bit values with first pnp_name in LSW and second in MSW
  • Z       pointer to a string to match exactly
  • D       like Z, but is the string passed to device_set_descr()
  • P       A pointer that should be ignored
  • E       EISA PNP Identifier (in binary, but bus publishes string)
  • K       Key for whole table. pnp_name=value. must be last, if present.
The pnp_name "#" is reserved for other fields that should be ignored.

All this is a bit complicated. However, it can be simplified greatly for the buses that are stylized. For example PC Card, the PCCARD_PNP_INFO macro just takes a pointer to the first element and figures the rest out from there (you can see how in sys/dev/pccard/pccardvar.h).


Kldxref(8) has been modified to find all these entries. The above description is fairly complex, but covers all known tables in the current system. kldxref takes the above, and filters it into a much smaller subset by expanding different fields in a format more suited to quick parsing. It parses into the following format:
The format output is the simplified string from this routine in the same basic format as the pnp string, as documented in sys/module.h (and above). First a string describing the format is output, the a count of the number of records, then each record. The format string also describes the length of each entry (though it isn't a fixed length when strings are present).
type    Output          Meaning
   I       uint32_t        Integer equality comparison
   J       uint32_t        Pair of uint16_t fields converted to native byte order. The two fields both must match.
  G       uint32_t        Greater than or equal to
   L       uint32_t        Less than or equal to
  M       uint32_t        Mask of which fields to test. Fields that take up space increment the count. This field must be first, and resets the count.
   D       string          Description of the device this pnp info is for
   Z       string          pnp string must match this
   T       nothing         T fields set pnp values that must be true for the entire table.

Values are packed the same way that other values are packed in this file. Strings and int32_t's start on a 32-bit boundary and are padded with 0 bytes. Objects that are smaller than uint32_t are converted, without sign extension to uint32_t to simplify parsing downstream.

Current State

While the recording side is fairly well finished and committed to the tree, the rest of it is still up in the air. This section describes suggested future work for anybody wishing to help.

The easiest thing to do is to convert a few drivers to record this info. This conversion usually goes fairly quickly after you've found a similar driver that's been converted. Some drivers "save" space by matching the vendor code, for example, in code, while the device is matched from a table. When converting these drivers, you need to add the vendor code to each line in the table, and modify the code to get the vendor from the table.

Some buses have few enough drivers that it would be beneficial to adapt them to a stylized bus. simplebus being an obvious candidate. While most of the SoCs that have simplebus use a monolithic kernel, it's never too early to plan for a more generic and modular future. Some work in this area is in review.

There's three different strategies to use this data. First, the boot loader already reads in the linker.hints file. It could be modified to parse this data (it currently ignores it) and look at the PCI devices in the system. This leaves a number of holes, however, and loading drivers from the bootloader currently has significant performance issues. Second, the kernel could parse this file and load drivers as needed. However, this is far from straight forward in the kernel, since module loading needs to be queued until after / is available, and even after boot, some insertion events may happen in contexts that won't allow for modules to be loaded directly. Third, a user land program (perhaps devd(8)?) could parse the loader.hints file and create devd.conf scripts. USB currently has a program that will generate its hints based on ELF sections, a design which informed the current implementation. Its generator knows the format, which the current design hopes to avoid.

So a good start has been made, but more work is needed before we can ship only a MINIMAL kernel with modules. See this space for more info in the future.

Good, cheap scope.

I recently found a good scope for my hacking needs on Banggood. Thought you might be interested in it. You can find it here. It's the All-sun EM125 25MHz 2 in1 Mini Handheld Digital Oscilloscope + Multimeter.

TL;DR: Great value for $100! I love it for portable use.

I've used this now for a few weeks. My needs for a scope are modest. I need to see what wave forms are going on in different circuits and/or trying to figure out baud rates for stubborn serial lines. This scope gives me that and more. It also has all the features of a high-end multi-meter, including capacitance. And has a DMM mode that is easy to use.

The scope is solidly constructed. Normally at the low end you have to put up with funky adapters, fragile connection, light-wight (flimsy) construction. The construction of this device suffers from none of those defects. It is as solid as any of the higher end test gear I've used over the years. The fit and finish is quite nice. The aesthetics are pleasing without being obnoxious. Again, a pleasant surprise given the cost. The bag that comes with it is durable and holds all the accessories that come with the scope with some room to spare for a few extras.

While it lacks some of the features found in higher end scopes, and I would never think to make high precision measurements with it to calibrate systems, it gives me enough of a window into what's going on that it is well worth the money. Years ago I had a low-end Tektronics 5MHz scope that set me back more than $100 and wasn't half as easy to use as this. The only feature I miss from it with this one is the second channel for triggering / comparison.

It doesn't have a fancy color display like some of the cheaper scopes I looked at. However, it has a higher sampling bandwidth. The display is crisp and useful. The actual performance of the scope is better than the color ones costing twice as much.

The only down side for a native English speaker is that some of the menus on it are in Chinese. And the manual is in Chinese. The scope is simple enough to use that a little trial and error was all that was needed to get the basics. And I used my smart phone and google translate to work out some of the other bits.

For about US$100, I think it's an excellent value. If you are looking for a cheap scope that's portable and gives you good results, this one is for you. Don't expect the precision of a $1k or $10k scope, though. It lacks a second channel, calibration inputs and the display is also a bit small for high precision work. It's worked out great for trouble shooting and reverse engineering.