20170511

v7 compilation for simple .c's in /usr/src/cmd.

After about 4 and a half hours of build time, I have results to share. There's 110 .c files in /usr/src/cmd. 85 of these compile and link (it's unclear if they run). 25 have a compile or link error:

  • accton, sa (lack of acct in libc)
  • ar, nm, prof, ranlib, size, strip (mismatch between NMAGIC/OMAGIC and ARMAGIC_X)
  • arcv (obsolete conversion program written in old style)
  • clri, dcheck, dump, dumpdir, icheck, mkfs, ncheck, quot, restor (inode differences)
  • dmesg (message buffer issues?)
  • getty (freaks out compiler)
  • graph (missing symbols for curses and libm stuff)
  • osh (old shell? Written in funky style)
  • ps, pstat (proc definition differences)
  • tc (silly compiler issue, trivial to fix, but I have not Tek4015 terminals)
So 10 classes of issues for the affected files. Not too terrible. But there's other issues that will need looking into. 'ld' compiles fine, but it works on pdp11 a.out files, for example. cc compiles, but doesn't have the venix specific switches. I've written a shell script to do this, not a Makefile, and the commands used aren't quite right. Venix appears to support different amounts of stack under the data segment (but without docs, it's hard to know what flags I need), but none of my binaries have those. There's NMAGIC and OMAGIC binaries that have different meanings, and so on. All this makes the 'file foo /bin/foo' differ. Plus I haven't done the more complicated commands, nor have I poked at the compiler apart from cc, nor the kernel really at all, nor the libraries, nor the .y files. And factor.s and prime.s are pdp-11 assembler, so I'd have to pull those in from somewhere.

But given that almost all the normal commands compiled just fine, and many appear to work gives me hope that I might be able to reconstruct the sources used to build at last parts of the system. For some reason, that's appealing to me, but I can't really articulate a reason why, or come up with why that might be useful. Though it seems like a fun background project to celebrate the 40th anniversary of Version 7 in a couple of  years. Though running it on a 35 year old computer at that point may limit its appeal...

Rebuilding v7 sources on Venix, early results

I just started rebuilding the v7 sources on my Venix Rainbow on a lark. I'll post a full writeup, but here's a two early things I've learned.

First, it takes 1 minute to compile cat.c into cat. Yes, one full minute. On my normal server, it takes .1s of elapsed time. This is a 600x speedup since then, likely more since clang isn't known for being gentle on system resources.

Second, some compiler error messages are classic:
"getty.c", line 12: compiler error: insane structure member list
I have always thought getty to be rather opaque to use. The code is somewhat simple, but that simplicity doesn't lead to easy understanding in this case.

Most things not dealing with the filesystem are building w/o a problem. This is a pleasant surprise. Though the speed at which they are building isn't going to set any records. About 5% have issues that prevent compilation or linkage out of the box, though the problems look easy to fix. I started the build at 9:30. It's now 2 hours later and we're to building 'grep'. We're on pace for a rebuild of just the trivial foo.c -> foo programs taking 5-6 hours. This isn't for the more complicated programs like make or tar that have their own subdirectory.


20170507

Rainbow Venix with BSW Enhancements

I've taken some time to look at the Venix disks. I've managed to read them all after retrying the read errors enough. I've created new disks and installed it on my system. I'll go through all that in a forthcoming post since there's lots of fiddly bits.

This post I'll expose what BSW is. It's the Boston Software Works. It was a company that was run by Larry Campbell from 1985 until 1995. They had a number of different products over the years. Through about 1988 they offered their enhanced version of Venix for $800 a copy (not their choice on the price).  It was normal Venix, only better. Larry posted the following to mod.newprod on Usenet back in December1986 describing what it was. I've edited the formatting a bit, and trimmed the headers:
The Boston Software Works (BSW) is now distributing an improved version of VENIX/Rainbow.  VENIX/Rainbow is a complete UNIX(tm) system for the DEC Rainbow 100, developed by VenturCom, Inc. of Cambridge, Mass. It is a V7-based system, with extensions such as plot(3) drivers for the Rainbow color graphics board and DEC LA50 printer, semaphores, and shared memory.
Standard VENIX/Rainbow requires and supports the DEC RD51 winchester disk (10MB) only.
The Boston Software Works enhancements to VENIX/Rainbow include:
  1. Support for any disk physically connectible to the Rainbow. Our development system runs a 70MB Micropolis disk.
  2. Virtual consoles, as found in VENIX on IBM-compatible machines, and also in XENIX and Microport System V/AT.
  3. Support for the NEC V20 chip, which replaces the Intel 8088 for a 10-15% performance gain.
  4. Support for simultaneous use of a monochrome display (for terminal/console use) and a color graphics display (for graphics).
  5. Ports (on an as-is basis) of several public domain programs, such as the Usenet news software, rn, smail, and Jove, an excellent EMACS subset.
  6. Support for the CHS dual-winchester controller.
The price (single copy) for VENIX/Rainbow is $795 and includes a complete manual set.
I've installed both the original Venix/Rainbow and this enhanced version. The enhanced version is the way to go. It knows how to cope with the larger disk I installed in my Rainbow, and the installation process was much less painful (though there were some up-front gotchas that I wound up having to re-run WUTIL to get through).
These are all cool things. The only issue that I've seen is that the .o's aren't included so it's impossible to rebuild the kernel with these neat, new features without significant hassle. The other problem is that while I can get stable file transfer on MS-DOS with LCTERM at 9600 baud, I can't with Venix. 4800 is error prone even. Messing with the serial chip seems to also trigger the dreaded Interrupts Off message, so I've not messed with it too much. Still don't know if that's my Rainbow going bad, or other issues (have some spare parts arriving soonish). The maximum throughput is only 240-300 CPS anyway with LCTERM, so maybe I'll just run at 2400 or 3600 baud.
Not listed above: it kinda seems like it is reading my clikclok. I did have to fix the 'date' command to grok Y2k though (well, since I don't have the sources, I used the Unix v7 sources from TUHS). If this keeps up, I'll put together a distribution of useful things from V7 :).
I'll blog more when I've run through another install and worked out how to boot in MESS (it has a bug when booting directly off the hard drive, but maybe the BOOT program will fix that).

[[ Edited May 8, 2017 to supply link to original mod.newprod article on google groups ]]

20170501

Rainbow 100 Windows 1.0 disks, redux

Rainbow 100 Windows 1.0 Disks

OK. I never thought I'd find myself writing a blog about Microsoft Windows of all things. However, that's what I'm doing.

A while ago, on the cctalk mailing list I mentioned that I had Windows 1.0 disks for the Rainbow. I didn't think anything of it until someone contacted me about it. I'd never looked at them in the 15 years they've been in my collection. You needed the Graphics Option card, and I don't have one so I just filed it away in the back of my brain. I never looked into the situation further.

So, it turns out that the publicly available Rainbow Windows 1.0 disks are really not quite right. They are a collision between the Rainbow 100 version, and the VAXmate version. And evidentially, neither quite work. This collection has been cargo culted around in the three decades since they became available, but they didn't work. it was well known, but the archives contained what they contained and successive generations of hackers tried, and failed, to disentwingle the resulting mess. The mess is still available at archives of archives of archives, for example at Classic CMP there's a copy of the "goodnight" archive which is an incomplete copy of the various BBS archives that existed in the last 80's and early 90's.

Sometime in 2001, Arun Welsh and I corresponded about the DEC Rainbow. I forget the details, but if memory serves, he had a ton of disks that he was looking to get rid of and wanted to see them find a good home. The details are frankly fuzzy after 16 years. I got these disks and took out a few of the interesting bits, but mostly it was a collection of files that were available elsewhere so I didn't look too closely at the collection. But DEC Windows 1.03 stuck in my brain for some reason.

Recently, that boast I made in cctalk generated some email requesting a copy. Since I had my Rainbow out and was messing with it, I thought I'd oblige them. Once upon a time, I could read Rainbow disks, but that was a dozen hardware iterations ago, so I fired up my old machine and read the files in. There's two sets. One was Rainbow MS Windows and was 7 disks. It contained what appears to be a copy of the Goodnight archives with the entertwingled set of files. The other was 4 disks of DEC Windows 1.03.

The other one proved more interesting. It was a different set of files. It came with a letter tucked into the one of the disks giving permission to upload the set of disks to any BBS (including the recipient's BBS, who wasn't Arun, I've forgotten his connection to this mystery). If there's interest, I can post this letter.

Early repots suggest this is a good copy. If they prove true, I wonder how hard it would be to get things corrected in all the online archives.

I've uploaded to a github repo I've created. These files are under 'decwin' while the putative copy of the goodnight archives is under 'rbwin'. I've also uploaded a copy of wutil 3.2 source and binaries. I plan on uploading the Venix binaries there as well, once I get things sorted out and post instructions on how to install them either on real hardware, or in an emulator.

20170421

Lining up

Turns out I didn't need to look for exotic formats to solve this problem.

I had physical copies of the disks with 10 sectors per track. Since I couldn't get tar to line up, I posited that there must be missing sectors. Turns out I was missing something, but it wasn't sectors. That turned out to be a dry well.

What's going on is actually a lot simpler. I managed to get Venix installed on my Rainbow (I'll write up how in my next blog, it's fun to login to my rainbow from upstairs while it's down in the basement).

On the Rainbow 100, under both CP/M and MS-DOS there's an interleave of 2, but no per-track offset. This is done by having the logical sectors ride on top of the physical. So, if I write logical sectors in the order 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, it gets put on the disk in sectors with the labels 1, 6, 2, 7, 3, 8, 4, 9, 5, 10. Why go through this crazy arrangement? For performance. This helps sequential performance. After I read sector 1, I have half a disk rotation (at 300rpm or 5/s that's about 10ms) to queue up the read for sector 2. If I have a slow system, this can help performance a lot, since I don't have to wait for the disk to rotate a full rotation if I'm not fast enough to setup the transfer for second immediately. This is often impossible on slower systems since the inter sector gap is maybe 20-40 bytes. 40 bytes transfers at 250kHz, 320bits at 250kHz is about 100 micro seconds. At 4.8MHz that the Rainbow runs at, this is 5000 instructions. But since there's latency between when the transfer is complete to the controller, and the system interrupts this can easily have less than 10 microseconds to respond. On the Rainbow, it takes tens of microseconds to setup the command to read the floppy. Given such a tight time budget, you can get a big gain by requiring only 100ms to get the next sector instead of 200ms.

This is well known and well documented in the Rainbow community. I had to cope with it when I wrote IMPDRIVE back years ago by translating the requested sector so that it would read the proper sector when reading 3.5" floppies which don't do this.

There's another way to get better performance. MS-DOS and CP/M don't do this. But Venix does. If you want to reduce the amount of time that you have to wait for sector 1 to spin by the head when stepping from the previous track, you can skew the sectors another way. If you shift the start of the interleave sequence above to be something like 8, 4, 9, 5, 10, 1, 6, 2, 7, 3. This gives you half a rotation to get the head moved and settled. If sector 1 is right under the head by the time the head is done moving and the host gets its command to the floppy controller, we don't have to wait an average of half a rotation.

So to sort out this, I dd'd one of the disks under Venix ono the disk. Tar was able to read it readily there, but couldn't on raw images. So, I wrote a program to undo these effects. Once I did that, I was able to read the images with tar.

Once I was able to decode the images, I discovered that the floppies I'd read out under dos using rbimg. icreate.exe is used to read it out, and iwrite.exe can be used to recreate them. These days, this is the gold standard to preserve disks. Well, non-copy protected disks. If you want to preserve the disk in all its glory, use a disk imaging solution like Kryoflux.

20170418

Not lining up

Close, but not quite

So, it looks like I'm getting closer. I read the disks with the 'physical' read option, which did sector skewing. Now that I've looked at them, I think that was a mistake. It looks like they are meant to be read in a logical mode, so I'm redoing a few to analyze again.

So I wrote a program to try to sort that out. It did work, but not quite. It got things almost right, but over-shot the mark when it came to getting the second or third file from the tar ball. It looked for all the world like there were missing sectors or something.

On a lark, I decided to try to read 11 sectors instead of 10 that RX-50's are usually formatted at. And I was able to read all 11, and the data for the 11th doesn't seem to match anything else. But we still have a mismatch, and I'm trying to chase that down. Well, 11th sector for tracks 2 and larger. So, I need to try to figure out why I'm not seeing extra data between the files.

So it looks like I'll have to do this again to get all the bits.... I think I need to puzzle this out with some friendly files that have text (include files) in them. maybe there's 12 sectors, though that would be unprecedented for these drives. You can do 800k like the RX-50, and also 880k for the amiga, but I don't think you could fit much more than that on a track, but who knows, maybe there is 12 sectors and I'm messing up.

Then again maybe I should just wait for the Kryoflux to show up so I can image the entire disk, including the boot disk.

20170417

Peering into the Venix Disks with read errors

As you may recall from last time, I had 5 errors on two disks I'm trying to read for the Rainbow Venix Floppy project.

The specific errors were on two disks. 76/3, 77/7 and 78/5 on the "User 3" disk and 78/5 and 79/5 on "User 2". The program I was using to read the disks didn't report the kind of error, so I'll have to augment it to do so.

This is very concerning to me, so I though I'd take a closer look what's on the disks. It appears that the disks are much simpler than I'd though. The first two tracks (10k) is nothing at all. Then we have what appears to be a TAR file after that. So, it looks like, worst case, we have at most 5 files that are corrupted, and more likely only a couple. The distance on User 2 is only 5k, while the distance on User 3 is 11k. There's a good chance that there will just be one file that's affected.

If I wanted to try to extract these disks, there's another wrinkle. I thought a simple dd to remove the first 10k would do the trick. However, there's a snag. I read these in the physical mode. The RX-50s, at least as used on the Rainbow, have a sector interleaving starting with track 2. The actual sectors are labeled as 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 on the disk (that's the order I read them out in). However, it appears that these sectors correspond to 1, 6, 2, 7, 3, 8, 4, 9, 5, 10, so I'll have to write a stupid filter to de-interlace them. Otherwise TAR throws all kinds of fits.

Unix v7 Tar files, btw, have fixed 512-byte headers. Wasteful, to be sure, but great for data recovery. A quick grep from hexdump shows what's on the 'User 1' disk:

00001400  2f 75 73 72 2f 61 64 6d  2f 00 00 00 00 00 00 00  |/usr/adm/.......|
00001800  2f 75 73 72 2f 62 69 6e  2f 00 00 00 00 00 00 00  |/usr/bin/.......|
00001c00  2f 75 73 72 2f 62 69 6e  2f 61 64 62 00 00 00 00  |/usr/bin/adb....|
00009200  2f 75 73 72 2f 62 69 6e  2f 72 61 6e 6c 69 62 00  |/usr/bin/ranlib.|
0000c600  2f 75 73 72 2f 62 69 6e  2f 63 61 6c 00 00 00 00  |/usr/bin/cal....|
0000e000  2f 75 73 72 2f 62 69 6e  2f 61 63 00 00 00 00 00  |/usr/bin/ac.....|
00010800  2f 75 73 72 2f 62 69 6e  2f 62 63 00 00 00 00 00  |/usr/bin/bc.....|
00011400  2f 75 73 72 2f 62 69 6e  2f 64 6f 73 63 6f 70 79  |/usr/bin/doscopy|
00014400  2f 75 73 72 2f 62 69 6e  2f 63 62 00 00 00 00 00  |/usr/bin/cb.....|
00014600  2f 75 73 72 2f 62 69 6e  2f 64 63 00 64 63 00 2d  |/usr/bin/dc.dc.-|
00015000  2f 75 73 72 2f 62 69 6e  2f 63 61 6c 65 6e 64 61  |/usr/bin/calenda|
00016c00  2f 75 73 72 2f 62 69 6e  2f 63 6f 6c 00 00 00 00  |/usr/bin/col....|
0001a200  2f 75 73 72 2f 62 69 6e  2f 64 6f 73 00 00 00 00  |/usr/bin/dos....|
00020400  2f 75 73 72 2f 62 69 6e  2f 64 65 72 6f 66 66 00  |/usr/bin/deroff.|
00021e00  2f 75 73 72 2f 62 69 6e  2f 65 67 72 65 70 00 00  |/usr/bin/egrep..|
00026a00  2f 75 73 72 2f 62 69 6e  2f 66 67 72 65 70 00 00  |/usr/bin/fgrep..|
00027a00  2f 75 73 72 2f 62 69 6e  2f 67 72 61 70 68 00 00  |/usr/bin/graph..|
0002be00  2f 75 73 72 2f 62 69 6e  2f 69 70 6c 6f 74 00 00  |/usr/bin/iplot..|
00031a00  2f 75 73 72 2f 62 69 6e  2f 6c 65 78 00 00 00 00  |/usr/bin/lex....|
00039e00  2f 75 73 72 2f 62 69 6e  2f 73 70 6c 69 6e 65 00  |/usr/bin/spline.|
0003c400  2f 75 73 72 2f 62 69 6e  2f 6c 70 73 74 6f 70 00  |/usr/bin/lpstop.|
0003f800  2f 75 73 72 2f 62 69 6e  2f 6d 34 00 00 00 00 00  |/usr/bin/m4.....|
00042a00  2f 75 73 72 2f 62 69 6e  2f 6e 65 71 6e 00 00 00  |/usr/bin/neqn...|
0004a600  2f 75 73 72 2f 62 69 6e  2f 6e 72 6f 66 66 00 00  |/usr/bin/nroff..|
00054600  2f 75 73 72 2f 62 69 6e  2f 73 70 65 6c 6c 00 00  |/usr/bin/spell..|
00054c00  2f 75 73 72 2f 6c 69 62  2f 74 6d 61 63 2f 74 6d  |/usr/lib/tmac/tm|
00055600  2f 75 73 72 2f 62 69 6e  2f 79 61 63 63 00 00 00  |/usr/bin/yacc...|
so there's lex, yacc, and several familiar filters. Transferring from the Rainbow is being super slow since I'm sending them via old-reliable KERMIT, so I've only looked at the first file.

All in all, I'd say this is encouraging news. I'll transfer the other disks and see what's missing to see if it is worth trying to delve further into the missing bits or not. If nothing else, it means we can use whatever data we can for those 5 sectors and the reduced functionality may be almost nothing. And there's a chance we can get a second copy of the affected files from the boot disk or something.

20170415

Rainbow 100 Venix/86R Disks Found

Recently, there was a post on an obscure retro-computing blog. It said that someone had acquired a Rainbow 100, which isn't so unusual (though there's only a few on the market). The part that was interesting was that it said it included VENIX disks. After some email back and forth, the owner sent the disks to me for reading.

After fighting for a week with PCs (more on that in another blog), I decided to search to see if there was a Rainbow native solution. Turns out that there was something called RBIMG by PrintStar (Jeff Armstrong) which I was able to get going on my old Rainbow 100B. It came with source because the Venix disks were mostly good, but some sectors requires a number of retries. It appears to be a Version 7 Unix for the PC.

I've read in the Boot disk, a bunch of Xfer Disks (not sure what they are), All the User and System utilities and an BSW extension disks. That's the good news. The bad news is that I still have a few sectors that aren't doing so hot. User3 disk has 3 errors, User2 disk has 2 errors and the boot disk has 1 error.

The Boot disk's one error, though, seems intentional. I've actually booted the Venix disk on my Rainbow, and it comes up. It also tells me the serial number after what sounds like a read error. I'm not yet sure what scheme that Venix uses, so that one might be solvable. It's cool to see a unix kernel that's only 45k in size.

So I'm 5 errors away from having a full set of disks. My thought was that maybe these disks were produced with a 1.2MB drive instead of a real RX-50, so diversity being good, I'm going to try to bring up an old PC I have sitting on the E-Waste pile. I have newer ones, but the BIOS doesn't support 1.2MB drives in those, which may be a clue that 1.2MB drives won't work at all in them (the literature on the web is spotty on this topic, but seems to indicate that latter-day systems cost-reduced 360k/1.2MB support out of the controller). More on those trials and tribulations in a newer post.

20170411

Installing FreeBSD-current with 11.0R installation image

Just a quick blog to document a trick.

Boot the install image (or even just a boot-only image). Get a Shell. At the shell, type
# env UNAME_r=12.0-CURRENT bsdinstall auto
and it will get the latest 12.0-current build installed. Thanks to Allan Jude for alerting me of this trick.

Making Cables

Tonight I assembled my cables I'll need to read my Rainbow 100B ST-251-1 hard drive I've had for a long time to get a backup.

I recently purchased a MFM ST-506 emulator which supports reading and writing old hard disks. To read the ST-252-1 I need the old standard two-cable (20-pin and 34-ping) to connect it to the emulator. This will give me a final backup, and also make it easy for me to snag the data from the drive.

Once I get this done, I'll switch to using the emulator to access the drive so I'll have continuous backups. It will also make it possible for me to explore Venix if the Venix disks that I just got are still good.... Still need to read them. I've hit a few snags in reading them from FreeBSD, which appears to have broken ISA DMA in 11.x, so I'll have to install 10.x instead of -current.

We'll see how it goes...

20170405

Compiling sdcc for FreeBSD

In preparation for a possible new project, I needed to build sdcc, a compiler that targets a bunch of 8-bit architectures. You can find information about sdcc at their sourceforge page: http://sdcc.sourceforge.net/

Usually, this is just a port away. But due to looking at the wrong tree, I thought I had to compile it myself. The port and package are great, and are what people should normally be using, but the problems showed the need to use a trick or three to get the job done. I thought I'd document them here, since they are minimal and easy to write up.

FreeBSD's compiler doesn't default to having /usr/local/include in its include path, or /usr/local/lib in its library path. Normally, one would try to get around this by just add --prefix /usr/local to the configure command. However, that doesn't work for the sdcc stuff (since it is already the default). You have to explicitly add more things to the command line. After some digging, it turns out it's only a few variables to worry about:


./configure CC=clang CXX=clang++ CPPFLAGS="-I/usr/local/include -L/usr/local/lib" CFLAGS="-I/usr/local/include -L/usr/local/lib"
 The key ones here are CPPFLAGS and CFLAGS.

With that, I have a build sdcc. But it's a pain to install. The port / package is much easier for that reason alone.

20160919

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.

20160918

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:
EXEC_P, HAS_SYMS, D_PAGED
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
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
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:
RomBOOT
Start AT91Bootstrap...


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

DRAM: 64 MB
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 10.0.0.5; our IP address is 10.0.0.4
Filename 'u-boot.bin'.
Load address: 0x21f00000
Loading: ####################
done
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)

CPU: AT91SAM9G20
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
U-Boot>
And we're in...

20160818

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)

DRAM: 944MB
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.
sema_sysinit
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
ofwbus0:
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
cryptosoft0:
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: FILE SYSTEM CLEAN; SKIPPING 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.
Setting up harvesting: [UMA],[FS_ATIME],SWI,INTERRUPT,NET_NG,NET_ETHER,NET_TUN,MOUSE,KEYBOARD,ATTACH,CACHED
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
options=600003
inet6 ::1 prefixlen 128 
inet6 fe80::1%lo0 prefixlen 64 scopeid 0x1 
inet 127.0.0.1 netmask 0xff000000 
groups: lo 
nd6 options=21
ue0: flags=8843 metric 0 mtu 1500
options=80009
ether b8:27:eb:30:ec:4b
media: Ethernet autoselect (100baseTX )
status: active
nd6 options=29
Starting devd.
Starting dhclient.
DHCPDISCOVER on ue0 to 255.255.255.255 port 67 interval 3
DHCPOFFER from 10.0.0.5
DHCPOFFER from 10.0.0.3
DHCPREQUEST on ue0 to 255.255.255.255 port 67
DHCPACK from 10.0.0.5
bound to 10.0.0.245 -- renewal in 3600 seconds.
add host 127.0.0.1: 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:0.0.0.0: gateway ::1
add net ::0.0.0.0: 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
Password:
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
Goodbye!
root@rpi2:~ # logout

FreeBSD/arm (rpi2) (ttyu0)

login: 
 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.19.8.1indexinfo: 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-0.19.8.1.txz: 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-0.19.8.1...[3/18] Extracting gettext-runtime-0.19.8.1: 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:
tcsd_enable="YES"
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:
tcsd_enable="YES"tcsd_mode="emulator"tpmd_enable="YES"
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:
https://bugs.freebsd.org/bugzilla
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):
named_enable=yes
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.




20160815

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

Logo

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

[update]
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.

20160217

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.

20160109

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)

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.