20120727

FreeBSD/arm booting on SAM9260-EK to multiuser

Woot!  After working hard to get the SAM9260-EK rescued, I'm able to boot SAM9260-EK to multiuser.

Here's the dmesg:
Copyright (c) 1992-2012 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 10.0-CURRENT #13 r238762:238811M: Thu Jul 26 23:10:37 MDT 2012
    imp@dune.bsdimp.com:/dune/imp/obj/arm.arm/dune/imp/FreeBSD/sys/SAM9260EK arm
CPU: ARM926EJ-S rev 5 (ARM9EJ-S core)
  DC enabled IC enabled WB enabled LABT
  8KB/32B 4-way Instruction cache
  8KB/32B 4-way write-back-locking-C Data cache
real memory  = 67108864 (64 MB)
avail memory = 61501440 (58 MB)
atmelarm0: 
at91_pmc0:  mem 0xdffffc00-0xdffffcff irq 1 on atmelarm0
at91_pmc0: Primary: 18432000 Hz PLLA: 198 MHz CPU: 198 MHz MCK: 99 MHz
at91_wdt0:  mem 0xdffffd40-0xdffffd4f irq 1 on atmelarm0
at91_wdt0: Watchdog disabled! (Boot ROM?)
at91_rst0:  mem 0xdffffd00-0xdffffd0f irq 1 on atmelarm0
at91_rst0: Reset cause: Software Request.
at91_pit0:  mem 0xdffffd30-0xdffffd39 irq 1 on atmelarm0
Timecounter "AT91SAM9 timer" frequency 6208000 Hz quality 1000
at91_pio0:  mem 0xdffff400-0xdffff5ff irq 2 on atmelarm0
at91_pio1:  mem 0xdffff600-0xdffff7ff irq 3 on atmelarm0
at91_pio2:  mem 0xdffff800-0xdffff9ff irq 4 on atmelarm0
at91_twi0:  mem 0xdffac000-0xdffaffff irq 11 on atmelarm0
iicbus0:  on at91_twi0
iic0:  on iicbus0
icee0:  at addr 0xa0 on iicbus0
at91_mci0:  mem 0xdffa8000-0xdffabfff irq 9 on atmelarm0
mmc0:  on at91_mci0
uart0:  mem 0xdffff200-0xdffff3ff irq 1 on atmelarm0
uart0: console (115200,n,8,1)
uart1:  mem 0xdffb0000-0xdffb3fff irq 6 on atmelarm0
uart2:  mem 0xdffb4000-0xdffb7fff irq 7 on atmelarm0
uart3:  mem 0xdffb8000-0xdffbbfff irq 8 on atmelarm0
uart4:  mem 0xdffd0000-0xdffd3fff irq 23 on atmelarm0
uart5:  mem 0xdffd4000-0xdffd7fff irq 24 on atmelarm0
uart6:  mem 0xdffd8000-0xdffdbfff irq 25 on atmelarm0
ate0:  mem 0xdffc4000-0xdffc7fff irq 21 on atmelarm0
miibus0:  on ate0
ukphy0:  PHY 0 on miibus0
ukphy0:  none, 10baseT, 10baseT-FDX, 100baseTX, 100baseTX-FDX, auto
ate0: Ethernet address: 3a:1f:34:08:54:54
ohci0:  mem 0xdfc00000-0xdfcfffff irq 20 on atmelarm0
usbus0 on ohci0
Timecounters tick every 10.000 msec
usbus0: 12Mbps Full Speed USB v1.0
Root mount waiting for: usbus0
ugen0.1:  at usbus0
uhub0:  on usbus0
uhub0: 2 ports with 2 removable, self powered
Root mount waiting for: usbus0
Root mount waiting for: usbus0
ugen0.2:  at usbus0
umass0:  on usbus0
Trying to mount root from ufs:/dev/da0s1a []...
mountroot: waiting for device /dev/da0s1a ...
da0 at umass-sim0 bus 0 scbus0 target 0 lun 0
da0:  Removable Direct Access SCSI-0 device 
da0: 1.000MB/s transfers
da0: 483MB (990976 512 byte sectors: 64H 32S/T 483C)
warning: no time-of-day clock registered, system time will not be set accurately

I'll have to try the macb driver to see if it is any faster than the ate driver. No clue if it is working well or not.
I'll have to migrate over to booting off the NAND from the Dataflash I'm booting off of now. Having the SD card in the slot during early boot hangs because on this board both the SPI0 dataflash and the MMC are hard wired to the same, well, wires. This means I should get the nand and nandfs stuff working on this board as well, so I can boot off of its 256MB flash.
Plus I need to get back to refactoring. After editing board_sam9260ek.c I can see that I need to extend the AT91RM9200 device stuff I've done to the sam9260 (and sam9g20). But I'm not sure how far I want to go down that path. But we need some way to have a generic pin mux system. Linux has a fine example.
However, I think that many of the issues that I'm running into may be solved by moving to device-tree stuff. Other ARM ports support this now, and Linux is moving that way. Newer Atmel CPUs will have DTS files. All boards supported by Linux appear to be getting DTS files to replace the custom code for each board. It seems that this is a good way to go. AT91RM9200 is the only one that seems to not have dts files, so I may need to write those from scratch.
But the bottom line is that I'm excited. I'd given up hope on this board, and now it is booting. Woo hoo!

20120713

AT91SAM9260-EK restored!

Quite some time ago, I received a AT91SAM9260-EK board from Atmel.  I tried to turn it on at the time, and it looked dead.  I put it on the shelf and got busy with other things: new jobs, a divorce, a new marriage, a son, and a new house.

Recently, I became interested in the Atmel SoCs again (Atmel's open source group recently gave me some hardware to evaluate some work).  I took this board out of the closet and it seemed dead.  But one night I had the serial port connected and noticed that the ROM recovery program printed something.  I tried to download things with my old AT91RM9200 spi recovery program, but that didn't work.  I tried running Atmel's SAM-BA on FreeBSD, but it couldn't communicate with the board.  I tried using openocd with SAM-ICE.  Sadly, the board was wired for ICE, not JTAG and the instructions for doing the conversion online didn't work.  Finally, in an act of desperation I installed Ubuntu in as a Virtual Machine image.  With that, it worked.

So now, I have new shiny to play with that should already be supported by FreeBSD so I can make sure that I'm not breaking any at91sam9 support with my recent changed.

20120607

Wish me luck: taking the git plunge

Wish me luck.

I just typed the following commands:

  • git clone https://github.org/freebsd/freebsd-head.git
  • cd freebsd-head
  • git branch army
  • git checkout army
and started my own local branch.  Wish me luck.  Oh, I've said it, but with git, I think I might need it.  I actually didn't type exactly the above, but that's what I should have typed.  git reset seems to have been my friend.  We'll see next time I pull from github...  and if I can get the rebase command to work for me better than mercurial has been working for me at work.

Now, to figure out how to do  a similar thing to patch queues, except I really want to just correct commits rather than use a whole different set of commands.

Unifying arm boot arg parsing

Greetings again,
Here's a slightly edited version of a post I made to the FreeBSD arm list, proposing a path forward to cleanup and unify boot arg parsing on arm and at the same time add support to all boards for parsing FreeBSD's /boot/loader metadata as well as Linux's uboot/redboot meta data. Thought you might be interested.
For too long parsing boot args in arm land has suffered from cut and paste code. This is inefficient and inflexible. This patch does something to fix that. First, it modifies all the arm ports to call parse_boot_param passing in the boot parameters from initarm as the first thing in each platform's implementation of that function. This is done really super early, importantly before we start using memory outside of the loaded kernel's text, data, and bss areas. I'd thought of moving this even earlier, into __start just before the call to initarm, but wasn't completely sure was quite right (it would be more code deleted, however, if I do that: please comment). The down side is that initarm was the only function we called in __start apart from mundane things like memcpy and that would change that, but that's kinda a weak argument I think. Also, it returns the last memory location, which would be lost if I called this from __start..
I've created a weak alias to tying this function to fake_preload_metadata. All but one of the ports do this now, and this moves them to a common standard that could be more easily changed.
For most ports, it replaces the call to fake_preload_metadata. As such, I've modified the signature of fake_preload_metadata to be the same as parse_boot_param and made it a weak alias. So, if you don't define one, you'll get the current behavior.
In a future patch, I'll likely be moving the mv platform's code into this routine (I'll create a default_parse_boot_param and create a weak alias pointing to that instead). I'll need to modify the mv port to then get the dtb blob via the metadata, or possibly create a new global for it so that other platforms might make use of that also.
In a patch after that, I may add a kernel option to enable creation of FreeBSD /boot/loader metadata from Linux's standard boot stuff. This will allow platforms to get more data from the Linux boot loader without going through the intermediate /boot/loader. But it should preserve a unified interface by having it behave just like /boot/loader, but without anything setup by its more advanced features like kernel environment variables or loadable modules.
If I've done things right by this point, then any ARM port can take advantage of these new features, not just the target I'm aiming at. In addition, anybody can use their own boot loader, if they so choose, and be able to write custom code that parses the args from it in whatever appropriate way might arise for their board. I know of at least one FreeBSD/arm user that has a heavily hacked boot2 boot loader that passes things into the kernel in a non-standard way. This will accommodate them, and others like them, while still providing the project with useful functionality.
Comments?
P.S. You can find the patch here.

20120603

Rearranging the deck chairs in the ARM port

Recently, I've been trying to catch up with some of the technical debt that the FreeBSD/arm port has accumulated.  Some of that technical debt was my fault, of course, but some of it wasn't.  I don't really much care whose fault things were,  but I would like to get things cleaned up.  Some of these are paths not taken.  Some are porting shims that never got properly connected.  There's also some features that were poo-poo-ed by some (including me) years ago that seem to make more sense now.

None of this stuff is terribly sexy.  Some of it will be addressed by the summer of code project that's working its way through some of the maze of twisty passages in initarm() that are subtly different between the different boards for no good reason.

We have no common place for boot loader code.  Some arm ports do use a common routine to fake up just enough metadata that debugging and other symbols work.  Some arm ports assume a full /boot/loader is present.  However, there's no common facility for getting information from via the Linux boot protocol, nor is there any provisions for having multiple boards supported by a single kernel.  There's no uniform interface to get this information that might be passed in by other means.  There's no real way for a board to get control early enough to get at meta-data a custom boot loader might pass in.

The first big thing that I'd like to comment on is a small change to the interface between locore.S' _start routine and the first port-specific code in initarm.  I've preserved the first 4 registers that were passed in on boot to _start().  Before, there'd be no way to access the Linux ATAGs, for example, by a port since these are passed in as arg 3.  To allow for future expansion, I'm just passing in one structure now.

In the coming weeks, I'll be implementing routines to parse these arguments based on standard boot protocols, while allowing customization for special needs.

In the coming months, I plan to expand our support for having multiple boards based on a single Atmel SoC.  Once I have the one at a time SoC code working, I hope to get multiple SoCs working in one kernel.  While the extra 'bloat' isn't optimal for many users, the convenience of being able to boot one kernel for installation, or trying out the system, is a feature that's been much requested.  I've already eliminated the need to have a compiled-in master clock frequency, with improved main clock detection with fallback for people using unconventional frequencies.

I'm also interested in sweeping into the tree many of the Atmel arm changes that have been accumulating in the PR database.  Some of these will be easy to integrate, while others may be difficult due to drift from the original submission.

Once we get a good baseline, I hope to merge these changes into 9.x and 8.x.  To date, the interfaces that have change have been purely internal ones we do not support.  External users may experience some bumpy waves if they haven't been working to get their changes merged upstream.  The more that you've submitted, the more I'm likely to go the extra mile to help smooth any transitions.  With luck, 8.3 and 9.2 will both benefit from these efforts.

20120602

FreeBSD Driver book

I recently received a complementary copy of the book FreeBSD Device Drivers by Josheph Kong. I also had the pleasure of meeting Josheph Kong at BSDcan 2012 a few weeks ago.
This book serves as a good introduction to all kinds of drivers and kernel modules in FreeBSD. It explores the basics of each kind of driver, complete with an example driver from the FreeBSD tree for each of the types of drivers that it describes. Joseph annotates the code to explain what each part of the code examples do, as well as to highlight the relevant areas for people wishing to write their own driver.
I'd recommend the book for anybody that needs an introduction to drivers. The walk throughs will get people up to speed, as well as introduce many of the uniquely FreeBSD quirks one needs to know to integrate with FreeBSD. The explanations are clear and concise and provide good coverage of the material.
Advanced developers will find some good nuggets in the book as well. Many of the explanations go into enough detail that even advanced users will learn things about FreeBSD from the book. Since the book sticks to the simple topics, some advanced users may be disappointed to find that some advanced topics have been omitted from this book. While many of them are very esoteric, the one I would have included would have been a discussion about how network drivers interact with struct ifnet. While other books cover that in detail for a generic BSD system, having that covered in this book would have been very beneficial. A companion book covering these topics would nicely fill the gaps here, should No Starch Press decide to publish it.
The FreeBSD world has been without any good device driver book in English for a long, long time. This book is a welcome addition. I hope it is but the first book of many from Joseph in this area.

20110529

Canon Rebel Xt and 32GB CF

Just thought I'd mention that I've been using a 32GB CF card with no special formatting in the Canon Rebel Xt. It has been working great for years.

20110202

How to run something other than login on a tty

Sometimes you don't want to run login on the console or other terminal. The reasons for this vary. Some appliances want to boot to a shell prompt on the console for debugging purposes (this console typically isn't exposed, so no security problems there). Sometimes you want to use init's restart feature to keep critical daemons alive. I've developed several control and measurement applications that used this feature. Sometimes your want to offer a menu driven interface to your users instead of a cli-based one.

Recently, I had to add support for a menu console to FreeNAS. I couldn't find any immediately available documentation on how-to do this, I had to dive into some little-configured recesses of FreeBSD to make this happen. Thankfully, no code changes to FreeBSD were required to make this work. I thought I'd do a quick how-to here to cover the basics.

We'll start with /etc/ttys. This is the file that has entries like the following:

ttyv0 "/usr/libexec/getty Pc" cons25 on secure

which tells init to run getty with the parameter Pc on /dev/ttyv0 with TERM set to cons25. Getty is a program, for those that don't know, that sets up the tty device for interactive use so that normal interaction works as you'd expect. While one can run programs without getty, especially on a 'device' that doesn't exist, I'll ignore that path for this post. This is about creating an interactive program that runs on a tty device.

The 'Pc' here is the key to understanding what getty is doing. Pc refers to the gettytab entry 'Pc' which looks something like:
P|Pc|Pc console:\
:ht:np:sp#115200:

which, according to the gettytab(5) man page means "Use 115200 baud, no parity, hard tabs". This is great if you want to run login to get an account and password, but what if you want to run a program other than login instead? Maybe one that doesn't know about tty sessions, stdin/stdout redirection etc?

The answer turns out to be fairly straight forward. You just tell tty to use a different entry. This scales well for a small number of programs, but not so well if you have dozens since you can't pass parameters to the final program. For my case, I just needed a menu for FreeNAS. I added the following entry:
#
# FreeNAS menu system entry
#
FreeNAS|freenas|FreeNAS Menu:\
:ht:np:sp#15200:lo=/etc/netcli.sh:al=root:

to /etc/gettytab. This tells getty to run /etc/netcli.sh as root. Since netcli.sh was mucking with the network it had to run as root, but there's no reason it couldn't run as a different user for safety. Once I had this entry in gettytab, I changed the above /etc/ttys line to look like:
ttyv0 "/usr/libexec/getty freenas" cons25 on secure

and sent init a hup with a "kill -1 1" command (the -1 is very important, otherwise you reboot your system). Once init reparsed /etc/ttys, netcli.sh started running.

Normally, that would be the end of it. However, in this case netcli really is a pyhton script. Why did I have to wrap it in a shell script that looks like:
#!/bin/sh
# Helper script to set the path for netcli menu
export PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin
exec /etc/netcli

When you run out of getty, you have a very restrictive shell. The python script called a bunch of other programs, so it needed to have a good path. Also, since the shell didn't need to stick around, I tossed the typical 'exec' at the end of it to save a little bit of memory on this embedded system.

And there you have it. All the steps to create a program that runs automatically at boot. If you have any other cool tricks, please feel free to comment here...

20110117

FreeBSD/mips for Cavium Octeon

I've recently improved the ABI selection in FreeBSD/mips. Now it is all handled via MACHINE_ARCH or TARGET_ARCH. mipsel and mipseb are the o32 32-bit versions. mips64eb and mips64el are for n64 64-bit versions.

I've knocked together a script for building an image for the Cavium Octeon eval boards that have CF that can boot using uboot from SDK 1.9.0 and 2.0.0 (and likely earlier versions, but I've not tested them). It creates two partitions: a FAT partition for the kernel and BSD partition for the rest of FreeBSD. It also takes care of building a big endian ufs system on a little endian system. You can find the script here. I've also create an image as well you can grab here. The script contains instructions for how to create the CF image.

Enjoy

20101202

New FreeNAS beta snapshot released (r5648)

We've released the next beta snapshot of FreeNAS.

You can read the release notes for all the details.

Here's a highlight of the issues that we've fixed since the last beta (r5606):
  • Upgrades from prior FreeNAS 8 beta releases are now supported.
  • zfs creation failures have been fixed. The gui would indicate it succeeded, but you couldn't share it.
  • ufs creation failures have been fixed.
  • booting off USB or SCSI cdrom is now supported.
  • Many disk initialization errors that showed up as odd failures have been corrected.
  • lagg has been introduced.
  • Errors in the network screen have been corrected.
  • The storage wizard no longer says 'of X' when creating the storage unit. This eliminates the confusing 1 of 3 -> 2 of 2 dialog heading.
  • Improved compatibility with IE and Safari.
  • The installer has been streamlined.
Also, I was pleasantly surprised today when I logged in and found 19 comments from my last blog entry. I'm not used to so many, so hadn't been checking. I'll be checking more here. I'll also write a blog entry to address many of the issues raised in them.


You can download the latest from sourceforge.

20101119

New FreeNAS Beta (r5606)

Just after the release of the first beta, a couple of serious problems came to life. As such, we've respun the release to fix these issues.

  • gmirror error displayed bogusly
  • the extremely long write times for disks
  • The lack of feedback during the installation (although with the significantly faster imaging, this is much less of an issue).
  • Default ownership and permission for Windows shares has been fixed
  • Shares are browseable by default now
  • The extra and redundant steps in the installer have been eliminated
  • The inconsistent menus in the installer have been made regular
  • A ZFS issue on reboot has been corrected
  • Multi-line config fields have been fixed
  • Problems with snmp have been resolve
  • proftpd's config file is now generated properly the second time
  • minor nits fixed in many places
You can find the release notes or the release. Stay tuned for more updates.

20101118

FreeNAS 8 Beta released

iXsystems is pleased to announced FreeNAS 8.0 Beta. FreeNAS 8.0 has undergone a complete rewrite. We've redesigned the GUI to be easier to use and extend. We've upgraded many technologies in the system for improved hardware support, faster I/O, better modularity, and easier upgrades. We trust that you'll find the system easier to use and, in time, much more feature rich than the current FreeNAS offering.

The base system has migrated from FreeBSD 7.x and the m0m0wall build system to FreeBSD 8.1-RELEASE and NanoBSD. The system startup has migrated from the older php scripts to the standard FreeBSD rc.d boot system. We've pushed many of the bug fixes and system improvements back into FreeBSD.

We've rewritten the GUI using Python and Django. We've completely removed the old php system. In addition to Django, we're using Dojango and Dojo to implement AJAX features. The new system is much more modular than the old system. We will use this modularity in a future version for easy integration of custom features into your FreeNAS box.

The installer has been rewritten using pc-sysinstall, the future FreeBSD installation technology. The scripts have a similar feel to the old PHP scripts for users of the current system. The ISO now is only an installer. You can no longer run in live mode from a CDROM.

The installation types have changed; there's no longer an embedded or full install, nor can the image be installed on a data disk. You must now install FreeNAS onto a dedicated device. FreeNAS supports USB flash, CompactFlash, hard drives, ssd or any other mass storage device supported by FreeBSD.

FreeNAS 8.0 features ZFS version 14.

FreeNAS 8.0 beta has retained the core functionality of a storage appliance. The media center features of the box have not been reimplemented in the core FreeNAS package. A media center add-on package will provide this functionality in the future. We've focused on creating a robust, easy-to-use, and extensible system. We're creating the base to allow other types of packages to be added, such as printer support, scanner support, or home automation.

To help prioritize what current features are turned into packages in future FreeNAS releases, please visit http://support.freenas.org/ to provide feedback. Please add feature requests tickets. If a feature you would like to see in FreeNAS already has a ticket please just subscribe to it add a small comment, even if it's a "++." It will help us better judge and meet community needs.

You can download FreeNAS from Source Forge and read all the release notes on our wiki.

20101028

Using devfs.conf as a porting aide

I've recently been given the task of moving some software from FreeBSD 4.x to FreeBSD 6.x on a consulting basis. This move was very simple and easy, except for one area: serial device names.

In the great tty-rewrite to make it MP safe that was done, there were a number of name changes that were unavoidable when making the tty layer more uniform between drivers. Unfortunately, sio was one of the drivers that had its names changed. This company used many multi-port expansion cards, so finding all the places where /dev/cuaaX was hard coded was difficult.

To validate the rest of the software, I created the following /etc/devfs.conf file to allow the old names to work while I hunted down all the places they were used.


# 4.x compat names on 6.x
link cuad0 cuaa0
link cuad0.init cuaia0
link cuad0.lock cuala0
link ttyd0.init ttyid0
link ttyd0.lock ttyld0


These blocks were repeated for each of the serial devices in the system (I wrote a quick script to generate them for all 12 devices). One thing to remember is that the 11th device is named "/dev/cuada" not "/dev/cuad10", so you need to print the unit number as hex.

You could easily extend this to FreeBSD 7 the names changed again when FreeBSD moved from sio to uart.


# 6.x names on 7.x system
link cuau0 cuad0
link cuau0.init cuad0.init
link cuau0.lock cuad0.lock
link ttyu0 ttyd0
link ttyu0.init ttyd0.init
link ttyu0.lock ttyd0.lock


again, it is a simple matter to look over the unit numbers necessary.

Note, this will only work for devices that are statically created at boot time. If you have a number of usb serial devices on a newer FreeBSD system that are replacing an older sio based FreeBSD 4.x system, you may need to use devfs.rules to accomplish this transition, which is beyond the scope of this article.

20101001

New FreeNAS alpha

After a few unforeseen delays, we have a new FreeNAS snapshot available over at source forge. As an experiment, we are distributing these snapshots using xz as well as bzip2 compressed images. It makes a big difference.

What's new?

First and foremost, we have a completely new GUI look and feel. We've imported dojango into the GUI to take advantage of Dojo JavaScript Toolkit. The flow of the interface is much nicer, it looks better, and we've added additional help to make it easier to use. We think you'll like this new GUI. We've made dozens of improvements over the past few weeks to the GUI. We hope you like the new location for enabling shares.

We've also added support for Apple's AFP protocol to the new GUI. You can now use the GUI to export CIFS, AFP and NFS shares (which we'll be calling Windows, Apple and Unix shares in the GUI). We've added back-end support for FTP as well. The major protocols are now all supported, although some media options are still unimplemented.

This image has a universal booting feature. The first image was difficult to use on some VM systems since they were exclusively SCSI disks (appearing as da0, rather than the ad0 that was hard-coded into the fstab). We've added support for using UFS filesystem labels to nanobsd, so we're now able to produce an image that you can put on any kind of disk that FreeBSD supports and have it boot, since it finds the partitions for /, etc by looking for a label on the filesystem rather than insisting on ad0s1a.

At the present time, we support only adding NEW volumes to the system. If you add a volume to the system, we will always initialize it. This means that you shouldn't (yet) attach old volumes to FreeNAS 8. We will try to correct this problem for the forthcoming FreeNAS 8 beta. While we've made every effort to make things reliable, we've not put this software through a complete QA cycle, so it should be used for testing purposes only.

20100929

PC-BSD install without a bootable DVD

Recently, I tried to get PC-BSD onto an older system. This system didn't support booting off of USB, nor did it support swapping in a DVD player for the CD player that was shipped with the system. The computer seemed to be fast enough to support PC-BSD. Since all I really wanted was something that could play some games that my 4-year-old wanted, I wasn't willing to spend a ton of money on a new computer just yet. Better to wait a year or two until we really needed something better.

PC-BSD only installing off a memory stick or off a DVD these days. I opted to go the DVD route because this computer didn't support booting off USB media as far as I could tell (I tried it on two machines: an old HP eVectra 933MHz box, and a slightly newer Dell Optiplex GX270).

The summary of this hack is 'Copy all the files from /boot on the ISO image onto a hard disk that has been made bootable and use a USB expansion box to store the real DVD'.

First, I needed to create a bootable hard disk. I put the hard disk that was going to be installed into the system info a USB expansion box and plugged it into my FreeBSD system. This gave me a disk as 'da0'. This disk had an old Windows installation on it. All commands are run as root. You are advised to triple check your typing, as transposed letters and such might have adverse effects.

Relabeling the Disk

Since I had an old windows install on the disk, I just needed to delete the old windows partition and create a FreeBSD one.
  1. gpart delete -i 1 da0
  2. gpart add -t \!165 da0
  3. gpart create -s bsd da0s1
  4. gpart add -t \!7 da0s1
Did the trick. Your milage may vary at this stage. I've also used "gpart delete -i X da0" and "gpart destroy da0" to totally wipe a GPT scheme off the disk in the past. If you do that, you'll also need "gpart create -s mbr da0" before proceeding to step 2 above. There's lots of other ways to skin this cat too involving dd, but since gpart has been added to the system, its so easy to use I prefer it for quick tasks like this so I don't have to remember "do I need to blank the front of the disk, or the end of the disk..."

Making the disk bootable

Next we need to make the disk bootable. This is a lot easier than it used to be in days of yore:
  1. gpart bootcode -b /boot/boot0 da0
  2. gpart bootcode -b /boot/boot da0s1
We have to make it bootable twice due to the multi-stage boot-loader that FreeBSD has (other systems are likely similar). "boot0" just prompts for which partition to boot (doing the first one by default). "boot" will then load /boot/loader to finish out the booting process and hand control over to FreeBSD's kernel.

Copying The Files

The pc-bsd installer for the DVD just loads a ram disk, and then runs off that. All the early stages of the boot loader need are contained in /boot. This includes the kernel, the third stage boot loader and various config files and scripts. So the next steps are to copy these files from the cd onto the bootable hard disk we just made. This assumes that the mdconfig command below prints "md0" for unit 0. If it prints anything else, you'll need to adjust accordingly. Also, if you are reading this in the future, you may need to change the PCBSD iso name.

  1. newfs /dev/da0s1a
  2. mount /dev/da0s1a /mnt
  3. mdconfig -f PCBSD8.1-x86-DVD.iso
  4. mount -t cd9660 /dev/md0 /cdrom
  5. mkdir /mnt/boot
  6. cd /cdrom/boot
  7. tar cf - . | (cd /mnt/boot; tar xvf -)
  8. cd /
  9. umount /mnt
  10. umount /cdrom
  11. mdconfig -d -u 0

Moving the disk

At this point, I had to unplug the USB expander from the first system, remove the hard drive and install it into my target box. I also grabbed my UBS DVD player and connected it to the box with a copy of the DVD I burned from the above file. I selected hard disk as the boot media in the bios and let the system boot. It booted off the hard disk, but then started looking for the proper cd device. Luckily for me, it found the DVD on cd1 instead of cd0 (which is what was built-in to the Dell I was booting off of). It then became a 'normal' PC-BSD installation, which is described in detail elsewhere.

Hopefully, people find these instructions useful. Since I only had one of these systems, I didn't create any kind of script to make it easier. Sorry.

[[ Updated to fix problem noted in the comments ]]

20100921

FreeNAS 8 -- Update

If you are following the commit messages to FreeNAS, you'll already know that FreeNAS 8 is shaping up nicely. If not, allow me to summarize some of the progress here.

In the past two weeks we've managed to break the gui completely, and put it back together. In the process, we've moved from a fairly static system to a more dynamic DOJO driven system that's much easier to use. It is less cluttered, while still providing escape hatches to the more complicated stuff. In addtion, we've written an installer (really, used the installer from PC-BSD, now part of FreeBSD-current). We've upgraded all the ports to FreeBSD 8.1-RELEASE (basically about 6 weeks newer ports). We'll need to do security updates before beta on some of these as well, so we've added the ability to patch the ports tree (which should also mean we'll retain much of the flexibility that the legacy FreeNAS system has wrt upgrades).

All of this is building to a new alpha snapshot. We're nearing the feature complete phase and want to get at least one more alpha out the door before we go to beta, most likely early next month. Watch this space for updates.

If you've been trying to follow the process at a source code basis, you may have run into a problem. While the build system does a good job at applying new patches to FreeBSD's src and ports tree, it doesn't do a very good job when the patch has been updated. Its unclear to me what the best way to manage this process is, since it can be hard to manage a new ports tree, new src and ports patches, as well as preserve the '-b' functionality of nanobsd which allows for fast builds after an initial build.

So, if you encounter problems updating your tree from an earlier snapshot, there's an easy work around. If you define 'force_update=1' in your environment, then you'll force the do_build.sh script to update your src and ports trees (it is needed if you have a June 24th ports tree from before the cut over). This will force csup to run, which 'fixes' all the files that have been patched. I've enhanced do_build.sh so that it will force all the patches to be reapplied when you do this. It is best to avoid the -n and -b flags to do_build.sh when doing this, since you really want a fresh build after the latest series of changes.

Later this week, we'll have another alpha snapshot ready. The last bit of GUI work should be done tomorrow (we need to add back the ability to control sharing/exporting of volumes which was lost in the great GUI reshuffle). We'll also need to test it to make sure the basics work and then we'll put binaries up to share. The installer may even be ready too, so that might also include ISO images you can boot and use to install the images into a CF.

Finally, we've reworked Olivier Cochard-Labbé's to nanobsd for device label support to be more flexible. As a result, they are now in both FreeNAS, as well as in FreeBSD. The practical upshot is that now a single image can boot off CF (where the root device is /dev/ad0s1a), a VirtualBox container (where it might be /dev/ada0s1a or /dev/ad0s1a) or a USB Stick/VMWare container (where it would be /dev/da0s1a). This should solve some difficulty people reported using VMWare in the first alpha, as well as provide a nice, flexible system to have a single image for all media types going forward. Briefly, we can label things within NanoBSD so they appear as /dev/ufs/FreeNASs1a so that the root filesystem can be found on any underlying media. If you're interested in the details of this, check out glabel and the -L option to tunefs and newfs.

As always, we welcome feedback. We'll have something in place soon to help collect and organize the feedback from the beta tests. I'll announce it after we go live.

20100919

My BSDTalk Interview

I just gave Will Backman over at BSDTalk an interview on FreeNAS 8, NanoBSD, ZFS and embedding FreeBSD. You can check it out at the BSDtalk blog. Hope you all enjoy.

Another FreeNAS Alpha snapshot is slated for early this week. Stay tuned. It will include a revamped user interface, local user support, FreeBSD 8.1-RELEASE ports and a few other goodies.

20100906

FreeNAS 8 -- First alpha snapshots

My blog has been somewhat quiet lately. I've been busy with other things lately.

The biggest of the other things is FreeNAS. iXsystems stepped up to the plate late last year when FreeNAS was going to become a Linux based platform.

The iXsystems engineering team has moderized FreeNAS in a number of ways. We wanted a platform that was more extensible than the current m0m0wall-based framework allowed. We wanted to create a platform that could be expandable by modules (possibly not even written by us). We wanted to make it easier to upgrade the base FreeBSD release, as well as leverage more base FreeBSD technology that has been integrated into the system since FreeNAS was originally developed.

We've migrated the build to be NanoBSD based. This allows us to leverage the embedded work that has gone into NanoBSD. It also allows us to push some of the features that are important to FreeNAS back into the base FreeBSD distribution. NanoBSD gives us the flexibility that we need. Since we're using the FreeBSD package system to add ports and packages, users will be able to add their own packages (we'll likely expand the basics to use the PBI's that PC-BSD produces for ease of installation). We're using the normal rc.d system, so upgrading is easier as well.

On the GUI side we've moved to using django. This is a python-based front-end to sqlite3 which is extensible and easy to use. While we've kept things rather plain so far, we plan on jazzing things up a bit now that we have the basics working fairly well. Since the GUI is based on django, we'll be able to allow packages to hook into the GUI to present a united interface to the user.

The GUI calls into a middleware layer that manages the services on the box. This middleware is responsible for generating updated config files, as well as starting, stopping and restarting daemons on the system. The same code generates the files at boot as well. Having all the configuration data in one database makes it easier to upgrade from release to release, since you don't have to merge your changes into the config files: the system takes care of that details.

If you'd like to read about the nuts and bolts about trying out the latest snapshot, you can check out my forum post on the topic over at the FreeNAS forums.

20100828

What is all the TBEMD stuff

I've been getting questions about what TBEMD means in my commits to FreeBSD head.

First, I'll tell you the name. TBE stands for TARGET_BIG_ENDIAN. For the MIPS and ARM ports, it is an environment variable that you have to set to build these targets for big endian (otherwise they default to little endian). MD is Must Die. A few years ago, there was an action movie whose title was more memorable than the file "Romeo Must Die." So I just stole the name for this branch.

So why must TARGET_BIG_ENDIAN die? It breaks things. For all the other platforms that FreeBSD supports, you just set TARGET and/or TARGET_ARCH to do cross builds. You know everything you need to know from the MACHINE and MACHINE_ARCH in the resulting image. In addition, the build system segregates things so you can build all the targets in one tree..But for mips and arm, you don't know what endian a binary is, the obj tree will collide if you try to build both little endian and big endian binaries at the same time. There's also other, more subtle issues. For example, TARGET_BIG_ENDIAN isn't set on big endian mips, so a native biuldworld tries to build little endian binaries (oops).

So, mips will be moving to mipsel (for little endian) and mipseb (for big endian). Arm will move to arm (for little endian) and armeb (for big endian). You could fill an entire email archive with all the possible other names and why they are better or worse than these names. History, however, trumps all those arguments: these are the names used elsewhere and we're just following convention.

Once tbemd is completely merged, you'll be able to build both endians of MIPS in the same object tree, for example, and all the other issues I've discovered. It also helps with new architectures as we move into powerpc64 (already merged) and mips64 (to be done after tbemd is collapsed). It will also mean we can have different packages for the different endians now.

20100814

The dangers of forgetting svn add

I spent a lot of time before the 8.1 release adding code to transparently map COMPAT_IA32 to COMPAT_FREEBSD32. I tested all kinds of different scenarios to make sure that it works, that it got error messages from old config programs, etc.

Today I got a complaint that COMPAT_IA32 doesn't work in 8.1-RELEASE. Linux module was failing to load properly. I thought it was really odd and that the folks complaining must be doing something wrong.

It turns out that I did something wrong. When I originally merged the work, I modified the options file, but didn't add the new options-compat file to stable/8 tree, so it didn't get merged into the releng/8.1 tree used to create 8.1. The result is that COMPAT_IA32 just fails silently in 8.1-RELEASE.

All that hard work ruined because I forgot to do a svn add... How disappointing.