SDHC purchased

Today, while I was ordering a new keyboard for my laptop (a 1-year-old is very hard on them), I ordered a 4GB SDHC card. When it arrives, I plan on expanding FreeBSD's support for SDHC. I had been waiting for the card to arrive to post this, but so far it has taken two weeks and no SDHC card. I bought it on ebay, but the buyer was located in Hong Kong, so my card is now stuck in customs. Let this be a warning to others.

The SDHC card implements the SD Card's 2.0 specification. It is unclear to me if the only change is in the commands sent to the card, or if additional hardware support is required to make things work.

I'll keep everybody posted.


Building bootable FreeBSD/i386 images

From time to time I hear people complain at how hard it is to build an image from the FreeBSD sources. This week, I'll explain how I built a bootable i386 image on a USB flash device and also make some observations about the results.

Recently, I needed to create a bootable i386 image. The easiest way was to build one on my amd64. Here's what I did. I setup my environment for the build (steps 1-3), built FreeBSD/i386 userland and kernel (steps 4 and 5), prepared the flash (steps 6-11), installed userland and the kernel (steps 12 and 13), added the extra files needed for boot (steps 14-18). The detailed commands follow:

  1. setenv MAKEOBJDIRPREFIX /blah
  2. setenv TARGET i386
  3. setenv TARGET_ARCH i386
  4. make buildworld
  5. make buildkernel KERNCONF=GENERIC
  6. fdisk -I da0
  7. fdisk -B da0
  8. bsdlabel -w da0s1 auto
  9. bsdlabel -B da0s1
  10. newfs /dev/da0s1a
  11. mount /dev/da0s1a /mnt
  12. make installworld DESTDIR=/mnt
  13. make installkernel DESTDIR=/mnt KERNCONF=GENERIC INSTALL_NODEBUG=t
  14. make distrib-dirs DESTDIR=/mnt
  15. make distribution DESTDIR=/mnt
  16. echo /dev/da0s1a / ufs rw 1 1 > /mnt/etc/fstab
  17. echo ifconfig_DEFAULT=DHCP > /mnt/etc/rc.conf
  18. echo hostname=demo >> /mnt/etc/rc.conf

I put all this on an SD card and inserted that into an usb adapater and booted the laptop with it. FreeBSD's base system isn't too big these days, only 205MB for a full system.

% df /mnt
Filesystem 1024-blocks Used Avail Capacity Mounted on
/dev/da0s1a 484822 205570 240468 46% /mnt

This can easily be trimmed, but with a 512MB SD card for $5 at Office Max, there's little point in trimming for the project I needed the flash for. I just needed something that I could boot to transition my FreeBSD/amd64 laptop to a FreeBSD/i386 laptop.

If one needed to reduce the amount of space used by an installation, then there's a number of options than can be used to reduce the footprint of the system. In my experience, it is best to build everything without these options, then use the WITHOUT_* options on the installworld step to keep the image size down. It is easy to cut FreeBSD's footprint in half with these options. In addition, the kernel is 28MB with all its modules, and this can easily be reduced below 5MB in most cases.

nanobsd can be used to automate this process, as can TinyBSD. I'll save for another column the techniques I have used in the past to reach 16MB.

Cross debugger

GDB Cross building on FreeBSD

I recently had to build a gdb that worked on our development host, but understood arm binaries and core files. It turns out to be fairly easy to do this in the FreeBSD tree. I did this on RELENG_6, but the same techniques will work for RELENG_7 or -CURRENT.

The Cookbook
  1. % setenv TARGET_ARCH arm
  2. % cd /usr/src/gnu/usr.bin/binutils
  3. % make depend all
  4. % cd ../gdb
  5. % make depend all
  6. % cd gdb
  7. # make install
These steps assume one is using csh-like shell. Commands prefixed by '%' can be run with anybody with write privs to the source tree. Commands prefixed by '#' need to be executed by root. These instructions will install a gdb-${TARGET_ARCH} in /usr/bin that can be used to look at core files, or connect to a gdbserver on the target platform. As of this writing, the arm gdbserver glue hasn't been written or committed to FreeBSD's CVS tree. The author will happily review patches and commit them if they are good enough.

Running the debugger

You can run the debugger just like you would other binaries.

  1. gdb-arm binary binary.core
to get a where listing of where one went off the tracks in binary 'binary' or look at a forced core dump.

That's it! Pretty simple, all in all, to create the cross debugger.

The cross-gdb port

As has been pointed out in feedback, one can also use the devel/gdb-cross port to make this even easier. I've not used this method. Maybe I'll investigate and report in another posting.