Audio Ripping on FreeBSD

For years I've been batching up my new CDs to rip all at the same time. Sometimes, this means doing a couple a month. Other times, like this year, it means catching up with 12 months of backlog. And while my ripping habits likely are uninteresting to readers, what I've learned over the years may be helpful.

Years ago I installed the 'abcde' port, and update it from time to time. Having it in-place, and configured, makes all the difference in the world. I use cdparanoia as my reading method since it is the slow but reliable choice.

There are many silly process things that make things go faster. First, make sure that you have all the CDs in the cases that you have stacked up. A few days before I start to rip, I go through the stack to make sure that none are on walk-about. Next, grab a bottle of windex, and a lint-free cloth. Wash each of the CDs, assembly line style. Sometimes I only do this for the discs that fail, but often times it helps things go so much faster that it can be worth the up front time.

Once I have the discs prepped, I pick a time that I'm not using my laptop too much to do the ripping. For me, this is often my work day, since I look at it from time to time for email and irc messages only. My laptop DVD player isn't the best in the world, but that's OK. The ones that rip quickly, I don't have to do anything about. The ones that are scratched badly, I put aside for later. The easy ones are boring, since abcde makes them boring, so I'll not describe the process much further. Each disc takes about 10 minutes to rip and transcode them.

The scratched discs are more of a challange. I've used a lot of players over the years. They vary widely in their quality. The cheapo player I have in my laptop copes with most of the discs. If I see too many + signs in a disc, I'll set it aside for later. Here, too many is 'more + than spaces in the output' when I look over at the screen several times. Or if there's any 'V' indications on any of the tracks. These usually take longer to do anyway, and get in the way of breezing through the easy CDs. Each year, I have maybe 5 discs that are stubborn, out of maybe 30 that I do. Long term averages are that 1 in 10 newly purchased 'used' disc show this. Discs that have been knocking around in the car for months are more likely to suffer from this as well. Really stubborn ones are more like 1 in 100, but more on that in a bit.

I have a special CD-ROM (not DVD) that I use for the scratched discs. Of all the drives I've tested/used over the years, this one has the best success rate by far of any of them. This one happens to be a 52x/20x/20x IDE drive branded by HP I got at Target, of all places, several years ago. I can take a disc that has 20-30 V's on it with my cheapo laptop setup, and sometimes get a good read with this player. Often, the discs just read quickly, and that's the end of it.

Sometimes, however, the disc is badly damaged and is that it is very slow. I was able to rescue a Moxie Froovis CD and a Phil Collin's greatest hits CD with this drive. But it took a week each of reading. When the drive is connected to a server, it doesn't matter so much that it is doing this. The CPU time isn't all that great during the week, so it doesn't interfere with the normal server operations. I look in on them once an hour at first, then once a day until the songs are done. Since I rarely have more than one or two of these a year, the extra time isn't that big a deal.

At one point, I had a dozen laptops with CD Roms that I could use for ripping. I thought this would be great, since I could do so many in parallel. It turns out that the CD Rom drives in these were even cheaper than the one I'm using today. I spent so much time running between the laptops that I didn't get any work done. And the CPUs in these boxes were all, at best, squirrel powered, so they couldn't handle the encoding as well as my 2GHz HP Pavilion laptop does now. At the time, I just did it serially on the server I had (which was a 666MHz Intel), and changed it every hour or two. I could still run it remotely, so I wasn't running back to the server room except to change a disc.

Today, with iTunes and other music places online, the art of coaxing bits off of audio CDs seems a bit passe. However, it is still something I find I'm doing a lot. Used CDs cost almost nothing, compared to $1/song for iTunes. Plus, format shifting is so much easier with audio CDs than with iTunes. Also note: I'm not talking about sharing my collection over the internet, just making the archival copies, and format shifted copies, as allowed by law and court decision. I still have most of the original CDs, and those I no longer have had been destroyed by my two-year-old when he was younger... But that's a story for a different time...


DLink DIR-615 Rev C1

Today I saw that Office Depot had a DIR-615 on sale for $40.00. It was a new hardware revision: C1. I took a chance that it was a new non-Ubimax based router. I'm glad I did, at least so far.

The router is based around the Atheros AR9130 CPU. This is MIPS based, so there's a good chance that I'll be able to put FreeBSD onto it. We'll see how it goes.

I'll report more when I get a chance to examine the RAM and Flash parts, as well as map out the serial port to see what is reported there. Stay tuned.


More CardBus fixes

After I committed my previous set of CardBus fixes, reports came in about interrupt storms, first with 16-bit cards, and later with 32-bit cards. These have been corrected in my latest fixes. We always act the CSTS interrupt when we see it. In addition, I've changed the acking of the 16-bit ExCA register to only happen when there's a "R2" or 16-bit card in the slot. Otherwise we now skip it. Hopefilly, this will help the shared interrupt case as well by eliminating some PCI bus cycles...

The CSTS bit is interesting. It is the least well documented bit in the CardBus standard. It is unclear when it fires from reading the standard, but seems to be related to the card finishing its reset sequence. How this differs from the power-up interrupt, I'm not sure. I think we could further optimize the bring up of CardBus cards with it.

In addition, I noticed there's a READY bit in the ExCA CSC register. We're currently doing busy waits to bring up the cards, including a couple of millisecond long DELAYs. I'll have to look into the prospect of using that interrupt to get around these issues there.

Finally, I'm looking in earnest at the Alchemy Au1550 CPU for the OpenMicroServer port I'm doing. I've noticed that it uses a 16-bit PC Card interface. Maybe I'll finally need to rewrite the old PCIC driver from OLDCARD to make use of it (snagging the exca routines to make that easier). The OpenMicroServer has a CF card attached to it.


Cardbus Fixes

I just checked into the tree some CardBus fixes. The biggest change was to the power-up sequence, as well as transitioning to using filters for the card change events. These two changes are somewhat intertwined, unfortunately, since the latter exposed some holes in the former. In a nutshell, we now register a filter for the card status change events. This means we can mark the card as bad right away before any additional interaction can happen to the card. We defer doing anything about the badness for a little bit (basically until the machine is idle enough for the cardbus kernel thread to run). The interlock mechanism is also much ligher weight, having moved from mutexes and CVs to simple msleeps. Fast interrupts require some care to get right, so I hope I've gotten it all right. The move is dictated by what you can and cannot do in a fast interrupt handler.

Before making these changes, my atheros card would often reset for no reason. After these changes, I've not had it reset until I started using a kernel without the changes. I'm not sure why this would make such a big difference, and I hate mysteries. They indicate that there's something I don't understand, which I also hate. I'd be interested to see if I still see this when the fully integrated code is committed and looped back (I have several trees, and I most frequently run an unmodified kernel from svn, but sometimes also run one of these trees). There's a small chance that one of my other local changes could be the cause, but given what they are it seems doubtful. Still, a good datapoint if it is.

In addition, these fixes add a retry option for the BadVcc errors that we'd see sometimes. These are annoying on some machines, and often times the best way to get around them was to reload the driver. They don't happen at all on TI based chipsets that I've seen (at least more recent ones). Instead, they were confined to the Ricoh chipsets. Since I switched my laptop a couple of years ago, I haven't seen them. These changes post-date the change, but have been tested lightly on another Ricoh laptop that I have. They've been heavily tested on the TI laptop. They are based only on the description of the problem in the NetBSD PR, since the implementations are so different for the different BSDs in this area.

Finally, I did some comment tweaking and shuffling. I also managed a style change or two. These should have absolutely no effect on the running code, but hopefully help the reader of the code understand it better. Past experience has shown that these types of commits are most likely to provoke comment, even though the other two parts of my commits are actually quite a bit more important.

Oh, why the flurry of commits? I was low on disk space, so I thought I'd go clean up. 11MB free just isn't enough. So I was looking around and discovered I still had a CVS tree and was going to blow it away. I did a final update just to see what changes I had. I'm glad I did, since I found these, and a few others. I still have more local changes there than I realized. Sometimes I guess it is good to run out of disk space and go on a cleaning spree? It also makes for smaller backups when you don't have top copy 5GB of /usr/obj and kernel build trees...

Moving towards board files

I've spent a little bit of time implementing the start of board files for the arm port. The initial push has been for the at91 subport only, and many improvements could be made to this. I've written up my initial thoughts on this on the FreeBSD wiki FreeBSD Arm Boards. It could use much improvement, I'm sure.

One idea that hasn't been reflected there yet, was shown to me by Sam Laffler who suggested using linker sets to allow boards to 'probe', 'init' and other standardized functions. This is an interesting idea and I plan on working on adding it to the above links when Sam has results to share.

I'd also like to expand the above wiki page to be a 'best practices' guide for all architectures where there's great diversity of boards/cpus/etc (eg, not the homogeneous env that x86 provides).

I'm also soliciting comments on the above boards in addition to the above. Send them to me, or post them here.


Cassio Fiva's screen dead

I was very fortunate enough to get a Casio Fiva MCP-205 given to me in 2000. I've used this laptop for years. I built Mozilla on it once, and melted the frame around the LCD! This resulted in a new warning in the Mozilla build instructions. Since Casio is a Japanese company, and I got this as the result of my contacts in Japan at the time, my news of melting the Fiva spread like wild fire there. Recently, when I was in Tokyo for AsiaBSDCon people were asking me about it.

I've been using this laptop to do background builds, as a mobile terminal, firewire debugging platform, etc since I got it. Recently, i had put the laptop on the shelf. I'd not used it in the past 6 months or so for a variety of reasons. Last night I thought I'd give it a spin again, since I need a nice mobile platform. Sadly, while it was in storage the screen was cracked. I cannot get any text on the screen at all. I don't have the VGA cable so I could keep this laptop around as a server, since there's no console access. I cannot find an LCD to replace it, but I imagine that it would be expensive. More expensive than a modern netbook, which would be better for the FreeBSD project anyway...

It is sad to see this laptop give up the ghost. Every time I used it, I was reminded of the good times in Japan. I'll hang onto the laptop for a little while on the off chance I can turn up a replacement LCD, but I fear it is dead.



I'm in California this weekend for MeetBSD, celebrating FreeBSD's 15th birthday!

Come on out and join the fun.


Marvell ARM support in svn

Rafal Jaworowski just committed support for a number of Marvell Processors. There are a number of commits going into the tree. He's just completed the first of these:
Introduce low-level support for new Marvell core CPUs: 88FR131, 88FR571.

From an earlier email message, we know that Rafal is working on support for Marvell 88F5182, 88F5281, 88F6281, and MV78100 SoCs.

The following peripherals will likely be supported:
  • EHCI USB 2.0
  • Ethernet
  • GPIO
  • Interrupt controller
  • L1, L2 cache
  • Timers, watchdog, RTC
  • TWSI (I2C)
  • UART

This is a fairly mature port that is going into the tree. It works with NFS or USB mounted root filesystems. The port is self hosted. Kernel and world builds succeed on the box. The box also boots to multiuser mode. Rafal has created a web page with all this information on it on the FreeBSD wiki at http://www.wiki.freebsd.org/FreeBSDMarvell

This is way cool news! Good Job Rafal.

Note: Much of this information was taken from a posting Rafal made to arm@freebsd.org.


gxemul update

Oleksandr Tymoshenko posted a patch to gxemul that allows FreeBSD/mips to boot on it.

I've committed it to the gxemul port. So now if you have gxemul or later, you can run FreeBSD/mips, the MALTA kernel. I'll post a howto and a pointer to a image in a few days.


SD/MMC work

Recently, I've pushed many bug fixes from Alexander Motin to the SD/MMC stack. He's submitted a driver for the SD Assocaition's standard SD Host Controller, and fixed many of these minor issues as part of doing that. I've tested these improvements on my AT91RM9200 system that boots off an SD card.

There should be more support for MMC cards, as well as SDHC cards forthcoming. In addition, once I get a chance to review the sdhc driver, it too may be ready to head into the tree. I know that if I had such a working driver, I'd be able to work more on SDHC and MMC card support. The current AT91RM9200 box I have makes it difficult...

Stay tuned for more updates.


FreeBSD/mips updated

Here's an update in status to the FreeBSD/mips tree. David O'Brien has been working through issues one at a time to get things building, primarily getting gcc support merged in. After learning from David that more patches were needed than were in my blog, I spent some time collapsing changes from p4 into the main tree. I've updated my patches, and confirmed they work.

First, you can find the patches from my FreeBSD drop box. These patches are 42k right now. This is from my tree that I pulled at revision 183198, taken at 3:30pm MDT September 19th, 2008, for the nit-pickers out there. At this level, I'm able to apply the patch, do a buildworld and all the kernels except SENTRY5 build. To build things:

% svn update
% fetch http://people.freebsd.org/~imp/MipsSvn.diff
% patch -p0 < MipsSvn.diff
% setenv TARGET mips
% make buildworld
% make buildkernel KERNCONF={ADM5120,IDT,MALTA,QEMU}

I've just done the build testing at this point. Stay tuned in the coming days for how to setup a qemu or gxemul image and how to run this in emulated. I hope to get instructions for how to deal with real hardware a little bit after that. Right now the ADM5120 kernels are a little too big for the hardware that I have and it will take some time to sort out.

Hopefully we'll have these last 42k of patches into the tree in the coming weeks. I'll keep everybody posted. There are some additional fixes in p4 as well on top of this which I'm still sorting out, but those should be going in as well.


FreeBSD embedded (mips, powerpc, arm) update

The last week or so has show a spike up in FreeBSD embedded platform work. Fixes for mips and powerpc have gone into the tree. Support for a new ARM platform is getting ready to be committed. FreeBSD/mips is almost self-hosting in the svn tree (it has been in the p4 tree for some time). FreeBSD/powerpc and FreeBSD/arm continue to mature.

Thanks to a flurry of activity over the weekend by David O'Brien, the number of patches needed for FreeBSD/mips has been reduced to a set for libpam and for binutils. David cleaned up the diffs for gcc and pushed them into the tree in a manner that allows for easier upstream committing.

In addition, David has cleaned up a number of dangling nits in the build. This is the result of a slight mismatch between p4 and the code in FreeBSD's svn tree. Oleksandr Tymoshenko has looped back most of these changes into p4, and is working on resolving the conflicts that were generated. Once this is sorted out, Oleksandr or myself will generate a new set of diffs and go for the final push into the tree.

I'm looking forward to having a good base for FreeBSD/mips in the tree. I've been busy with a number of other projects and haven't given it the time that I really want to give.

On the PowerPC side of the ledger, Marcell Moolenaar and Rafal Jaworowski have been polishing uboot boot loader support in the FreeBSD/powerpc subversion tree. In addition, some bug fixes to and code polishing of the low level Book E PowerPC support have been committed. Many of these improvements were obtained from Semihalf consulting.

On deck to be committed soon is support for Marvell's Orion NAS chips. This code has been in perforce for a while now and is nearly ready for the FreeBSD tree. I'll keep everybody posted when that happens. I hope to have my DLINK DIR-615 Rev A1 working by then with this code, but time has been tight and there's already too many different projects afoot in my life.


Sandbox pictures

I've had several requests for pictures of my son playing in the sandbox. I'll go one better and show pictures of my son and I playing in the sandbox. My wife took them just after I filled it with sand.

Now, all I have to do is make a lid for the box to keep the local cats and racoons out.



I debated writing about this. After all, it isn't about hacking code. Instead, it is about hacking together a sandbox. It is about making stupid design choices and then over engineering "solutions" to those problems. It is a cautionary tale about doing the design right from the start and sometimes "free" lumber costs a lot in time and effort.

So, I wanted to make a 4'x4' (just a little over 1m x 1m) sandbox for my 2 year old. He loves sand in the parks and I wanted him to have a place to play in the back yard. My wife suggested we just get one of those turtles, but I wouldn't hear of it. After all, I had a bunch of 2x4's in the garage. Why pay good money for a plastic turtle when I could just build a simple box out of the 2x4's.

I wanted a 4" depth of sand, so I figured I'd have to stack the 2x4's. Rather than just buy a couple of 2x8's and bolt them together, I had to use 2x4's. Of course, I had planned on stacking them, but what I hadn't planned well was how to do it. I wound up with small 2x2's as wooden cleats. So I get the box put together. It was fairly straight forward to do this. I connected the two halves of the box with short 2x2's. I proudly showed it to my wife who immediately said "those sharp edges sticking out look dangerous." She was talking about the 2x2's. Once I saw it from her point of view, I realized she was right.

Now, rather than spend $8.00 on 2 2x6's or 2x8's for the box, I spent $9.86 on 12 6" ceramic coated screws to hold the box together. I then drilled holes and recessed the heads (why? I don't know, just seemed like a good idea even though they were on the bottom). I drove the screws in and removed the 2x2 cleats. The box looked great! And I even managed to add the trip onto another trip to a near by store, so I didn't blow a ton of time and gas getting them. That was luck, pure and simple, since usually for things like this I'm making another trip...

I then went to put it where we'd agreed and realized I had no bottom. I had to do something about a bottom. I thought I'd just use some of the yard fabric I had left over from all my landscaping chores. Turns out that I left all that at my old house. So instead I took and old tarp with a tear in it and cut a 4'x4' section and laid it on the ground and put the sandbox on top of it. I then filled it with the play sand I'd been lugging around in my car for a week while I finished the box. Time will tell if I secured things in place well enough or not. I was planning on going to the store to get a bunch of rebar to drive into the ground to keep the box from moving, but I realized just how crazy this was getting and I just made a couple of wooden wedges to hold the thing in place. We'll see how that works out, but they are likely good enough, and were scrap anyway...

In the end, I spent 4 hours building this box. While a turtle would have saved me a bunch of time, and would likely have cost about the same as what I spent on wood, nails and screws (all but the last one had already been purchased, but I did pay for them). I'd have been done in 30 minutes. Of course, I wouldn't have gotten to use the power tools, and I really like the idea of building things for my son. I put the sand in tomorrow and we'll see how well he likes the box.

So, am I crazy? Did I go overboard on trying to save a nickle only to cost myself a ton of time? Maybe. Did I have fun putting it together? You bet! Was it worth it? Yes...


Low hanging fruit

Tonight was low hanging fruit night. I went through all the PRs that had "pccard" or "cardbus" and committed the easiest of the fixes. When I did this with USB last year there were maybe 50 of them I committed over the course of a few weeks. For PC Card and CardBus, there were maybe 5 or 6 that I was able to commit. And a similar number of stale ones. Unlike USB, there's only a few PC Card and CardBus bugs in the PR database, at least that are flagged as such.

I find this surprising, since any CardBus card that uses I/O ports hasn't worked in a while. And CardBus card whose CIS is stored in "Expansion ROM" won't work. There's a bunch of problems with some of the newer "ed" cards as well for PHY handling. At least I've recently solved some of the power issues, or I'd be feeling pretty low about the state of affairs. Fortunately, most people want a CardBus slot for a wireless card these days, and atheros chipsets are memory mapped.

The ExpressCard stuff is stalled at the moment while I ponder a difficult problem with resource allocation. There's likely a simple solution to this problem that I'm not seeing, but it likely requires thinking a little outside the box to make it totally effective.


Summer tree cleaning

As you may know, I'm a user of the p4 side repository to do large code development. With the switch to svn, I wasn't sure I'd still need to do that, so I let my trees there go for a while. It is clear to me that I'll need to use p4 a little while longer. So, I cleaned up my newcard tree.

Why do I need to cleanup at all? That's a good question. You'd think that you'd only have code cooking in the tree that was destined to be committed, so no cleanup is needed. Merging conflicts, sure, but no cleanup. Well, it turns out that sometimes perforce doesn't do quite the right thing when there's a loop back of new files into FreeBSD. If I create a file in perforce, and then later merge it into FreeBSD, then the $FreeBSD$ tag is messed up. Over time, you get lots of these files in the perforce tree, and you have to basically just copy the FreeBSD version over them.

The other reason to clean up is that code can cook for too long. I have several projects in my newcard tree that just didn't work out. I didn't get them into the tree quickly enough and the problems they were designed to clean up have been solved in other ways. Or they fixed problems in the MD code, and now that FreeBSD has grown more machines more code needs to be changed. Sometimes you change the new MD code. Other times, you just junk the old stuff since the improvements were so marginal that it isn't worth carrying those stones in your kit bag anymore.

Sometimes projects are only half-baked. I had a number of interesting ideas that turned out to not be such a good idea. That turned out to not be a big enough savings, or that some other key developer in the project didn't like. It happens. Some ideas are great, while others seem to be grating on others.

So all of these are reasons to cleanup the tree. I've managed to reduce my diffs from 200k down to 100k. Most of the 100k that's left could easily be described as half-baked. The biggest half-baked thing is a port of the NetBSD improvements to mii. The second biggest are a collection of hacks and bug fixes to the pccard/cardbus layer. Those always take a lot of time to sort out.

It is one of the more pedestrian things that I need to do when hacking. But if the litter piles up too high, it becomes increasingly difficult to see what should go into the tree, and what shouldn't so nothing does and many of my cool hacks don't benefit people, and I don't benefit from the wider exposure of the code. Nobody tests my private tree but me... Everybody notices when you put something even a little stinky into the main FreeBSD tree.

I debated about not blogging about it. However, one reason people have told me they read my blog is that they learn how to be better engineers from some of the things I do. They usually don't tell me if they are emulating things I do because they think they are good, or if they are avoiding the things I do because they think they are bad. Maybe a little of both... Documenting the mundane from time to time may bring better balance. Or it may put my readers to sleep... It is hard to say without feedback...


T-Mobile Dash experiment

I have two cell phones. One of this is my iPhone, made by Apple and running Apple's version of FreeBSD. The other is the T-Mobile Dash. I usually use my iPhone, but this weekend I was using the Dash to see how well it worked. It was no better or worse than the iPhone in the one area that I'd hoped it would be better at: call quality.

In the process of trying it out, I discovered the uipaq driver in FreeBSD. I wanted to use the Dash as a tethered phone. It is the whole reason I got it. Since the iPhone doesn't officially support tethering, I thought I'd give the Dash a try.

The uipaq driver was added to FreeBSD 7.0, ported from NetBSD which ported it from OpenBSD. Its roots go way back to the old Compaq iPaqs that were made years ago. This same basic interface has gone through only minor evolution in the interceding years. Unfortunately, I wasn't able to make it work with my phone due to some minor issues else where.

In the process of trying, I discovered there was no man page, so I snagged one from NetBSD and hacked it to account for the differences with FreeBSD. In searching how to setup the phone as a ppp link, I stumbled into a PR that greatly expanded the number of devices the driver recognizes and made it committable, I discovered that it wasn't built as a module, and I discovered that an old PDA I had in the garage would work with this driver, in addition to my HCT dash. All the easy problems I fixed...

So I moved the rock up the hill a little. I'll try another day to see if I can track down the issues that were else where in the kernel and see if I can punch entirely through to the other side. The lack of a tether solution has been the biggest disappointment with the iphone that I've had. While a number of interesting hackers are possible in that area, none of them are as easy and as simple as my old Sprint Samsung SPC-7600 was. The Dash also has bluetooth, which I'll give a spin after I can get it to connect with the wires...

None of this would be necessary if Apple didn't have such a tight control on what one can and cannot put on the phone. Well, control isn't the real issue. Rather, the issue is that they choose to control it in a way I don't like. If they controlled it in every way the same way I wanted to configure it, I doubt very many people would care... Since they don't, a lot of people are very interested in hacking it... but that's starting to get off topic...


Quick device_get_children cleanup

Hans Petter Selasky submitted a bug against the rather poor error handling of device_get_children a while ago. When the usb4bsd stuff he's trying to get into the tree was posted for review, one of the issues was with device_get_children() as it related to device_delete_children().

This reminded me of original issue. I've gone through the tree and done an audit of the device_get_children calls. I think that the issues have been resolved. However, it looks like there's a lot of code in the tree looking for siblings and such. This suggests a close review of the code to pull out common routines into subr_bus might be in order. Each of these hand-rolled routines had slightly different bugs in the error handling...

Mid august mips status update

Just wanted to jot out a quick status update on FreeBSD/mips.

A few weeks ago, diffs were sent out for review. The 6 patches are now down to three. gcc.diff, binutils.diff and pam.diff remain uncommitted.

pam.diff (now pam3.diff) has been receiving feedback from DES and others and is getting close. The first iteration was really far away from being commit quaility, but the last iteration may be the one that goes in.

gcc.diff has received feedback recently. Gonzo and I are in the process of digesting and understanding the feedback. We hope to produce a revised patch shortly, as there are a number of minor issues.

binutils.diff has had no comments. One person volunteered to look at it and commit it, but so far we're still waiting for feedback to make the patch better, or for it to be committed. If we don't hear anything one way or the other, I'll don my flame resistant suit and push it into the tree. There's really no issues with the patch that I can see. What is going to be a challenge is doing the vendor import of a few upstream files. Hopefully the volunteer will pull through and I won't have to learn how to do this in the new svn world. :-)

All the other diffs have been committed to the tree. It was gratifying to get positive feedback on them all, since I was worried more of them would have maintainer timeouts.

You can see the current set of patches in gonzo's patch directory. Grab only the latest pam patch there. The cddl.diff patch should be removed shortly, as I just committed it.

Had I been paying closer attention, I'd have written all this up for the FreeBSD status report.


Slimming down the NSLU kernel

A few days ago, I wrote about the NSLU kernel config file being committed to FreeBSD's svn tree. The default compressed kernel is about 1.6MB, but the size of the partition of the NSLU2's flash is 1.25MB, a gap of just under 300kB. With some hacking, I've been able to reduce the size of the kernel to fit.

The default kernel's text+data size is 3,425,844 bytes. Compressed, with the appropriate headers, this drops to 1,591,109 bytes. However, the goal is 1,310,720 bytes. We're short by at least 294,553 bytes of fitting into the kernel portion of the flash on the NSLU.

My first thought was to start cutting things out. I removed IPv6 (options INET6) since I didn't need it for my setup. This saved 210,797 bytes in the uncompressed kernel and 74,115 bytes in the compressed kernel. This one option shaved 5% (compressed) of the kernel size. A move in the right direction, but more was needed.

Next, I recalled from previous attempts that there's many inline functions that don't need to be inlined. There's a small performance gain from inlining these functions, but it can add a lot to the kernel. So I added three options to the kernel config:
This resulted in a size reduction of 432,984 bytes (uncompressed) and 87,289 bytes (compressed). This is also a significant savings, and meant that we'd saved 161,404 bytes in the compressed kernel so far. We were still ~133,000 bytes shy of the mark.

At this point I noticed that there were a lot of things in the kernel that weren't required for boot, and that had shown up as being larger. When doing the size reduction, often times I use the 'size' command to get the top 20 .o files to see if there's junk that can just be omitted from the kernel. In this case, I saw that usb, scsi and releated drivers consumed a lot of space. This could be loaded from a number of modules after boot if I was booting from a RAM disk. Since the plan was to put an initrd-like ram disk in the other partition of the flash, I went ahead and removed these pieces:
#device usb
#options USB_DEBUG
#device ohci
#device ehci
#device ugen
#device umass
#device scbus # SCSI bus (required for SCSI)
#device da # Direct Access (disks)
This trimming saved 278,837 bytes (uncompressed) and 133,520 bytes (compressed). This was huge, and brought the total trimmed up to 294,924 bytes. This is just barely over the line, so I thought I'd go for a little more.

Another big area of the kernel is the code brought in with 'options miibus' configuration line. This brings in all the phy drivers on the off chance you'll need it. In many embedded systems, you know which phy driver you have, and can wire in only the one or ones you need. Since I wasn't planning on using this box as a general purpose router, that needed to work with any Ethernet dongle that was plugged into the USB port, I went ahead and transitioned to this configuration. The NSLU has a RealTek Phy that needs the rlphy driver. This means that I changed the config file like so:
#device miibus # NB: required by npe
device mii
device rlphy
This option shaved a few more bytes off the total. 80,012 bytes (uncompressed) and 25,156 bytes (compressed).

At the end of all this, the compressed kernel had been reduced from 1,625,125 bytes down to 1,286,193 bytes, for a savings of 320,080 bytes. This was enough margin for me to feel comfortable trying to burn it into my NSLU. Unfortunately, I ran out of time tonight to try it, so the story of that experiment will wait for another post. Also, I don't know how to make blogspot do tables, or I'd have made some nice tables with all this data for this log.

There's likely more options that can be explored to squeeze even more bytes out of the kernel. bzip2 might be a good place to get maybe 10% more space back (at these sizes, an extra 100kB compressed, or 250kB uncompressed). The exploder for bzip2 is bigger and uses more memory.

Looking at the .o files that are laying around that pci.o is kinda big, suggesting that we need to break it up some more. In previous experiments, separating out the MSI and PCIe stuff helped quite a bit. I'm unsure what the best newbusly way to extract this functionality might be, but it could save us 20kB uncompressed (maybe 8k compressed, iirc).

There's a number of other places code is agresively inlined, these could be investigated. there's
a few things in the tree tagged as standard that likely could be made to be options. There's much room here to explore a number of different options to reduce the kernel size even further if the need presents itself.

The nfs server option is about 45kB. Soft updates run about the same. nfsv4 also eats a lot of memory (looks to be 55kB).

However, for all these options, it would be nice is the NAS could have RAID, FAT, ntfs, smbfs and ext2fs support as well. Continuing to trim would allow this more easily. Or at least eliminate the need for loadable modules.

This is to say, there's a lot of areas for further research and documentation. I didn't even look at using a /boot/loader either. Maybe that can be helpful... Maybe I'll turn that into a research paper for one of the conferences... Either the continued size reduction thing, or using /boot/loader.

Finally, I've uploaded the changed NSLU config file in case my verbal descriptions here were insufficient.


PCI Bridge hacks

Recently, someone sent me a new ExpressCard. This isn't the first ExpressCard that I've had. However, this one is PCIe based. I plugged it in, and it didn't work. I had no idea where to begin tracking it down, so I've added some information to pcib device. Now, we report the all the bus numbers that are relevant. Turns out after a little more digging the memory allocation on the bridge is wrong. None was allocated by the BIOS and FreeBSD isn't picking up the slack. That's the next set of problems to solve.... After that, I'll look at the hotplug functionality...


FreeBSD/avr32 spotted in the wild

A very preliminary port to the AVR32 has been spotted in the wild. Arnar Mar Sig posted a dmesg of FreeBSD/avr32. You can find his post through this link.

For those of you unfamiliar with the AVR32 architecture, it is an architecture that is used primarily in embedded applications. AVR may be initials familiar to many readers as microcontrollers. Atmel took its know-how and created a 32-bit version of this architecture basically from scratch.

You can find more information about the processor at atmel's web site, or at wikipedia.

The work here clearly is preliminary, but it is very cool none the less. FreeBSD embedded is on the move...

[[ typos corrected, I hope :-) ]]


The dog ate my homework.

People have reacted favorably to a recent commit that I made where I said that my dog chewed up a card so I couldn't test it. I thought people would be interested in seeing this card.

First, the commit message:
Convert to new style PC Card front end driver. Add support for the
NEC PC-9801N-J02 and PC-9801N-J02R. I can't test the former because
it requires resources that conflict with my laptop. I can't test the
latter because my dog chewed up my -J02R card and it didn't survive
well enough for me to test.

You can see the whole commit here if you are into that as well.

Several people remarked this was the first time someone used "The dog ate my homework" excuse in the project. So I thought I'd produce pictures of the card for your enjoyment.

Here's a shot of the top. Notice how one of the teeth punctured the outer shell...

Here's a shot of the bottom. The damage doesn't show up well in the photo, but there's many teeth marks here.

Finally, the force of the chewing popped open the case. Here's a shot of the inside. Notice how the pins to the PCMCIA connector are severed. Otherwise, the card is in great shape...


Minor PC Card work

I have a large collection of PC Cards. Well over 100, maybe over 200 cards. These cards are my test bed for the FreeBSD PC Card (both 16-bit and 32-bit) software that I maintain. Sometimes, I take cards out of the boxes at random at times and try them. Other times, I'll take all the cards that are affected by a certain driver change and test them. When I did that recently, I found a hole in the PC Card system.

This hole is very minor. There's no way for a driver to select the configuration entry that is used for the card. Usually, this doesn't matter one bit at all. Drivers work perfectly fine with the configuration that's automatically selected for cards. The PC Card spec has evolved over the years to the point where it is all automated. Certainly for 32-bit cards, but also for most 16-bit cards, even multifunction ones.

However, there's some older cards, some of them interesting to me, that need some special hand holding. These cards perform better with different entries, or activate both the ethernet and the modem on the card, instead of just the modem, when a different entry is selected. Trouble was, there was no way to do this in FreeBSD easily.

I just committed some changes to the PC Card system that will allow 16-bit PC Cards to select the configuration entry entry they will use. There are some restrictions. First, it can only be done in the probe routine for the driver. Second, the driver's probe routine must return 0. Big problems happen if the card is merely 'bidding' on a device and tries to set the right configuration. This may seem harsh, until you realize that if a probe routine knows enough about the card to try to set a configuration entry, then it isn't a generic driver anymore.

Also, as a nice side effect of this work, I've made things more robust for people that insert a card, only to discover that they didn't have the driver for it loaded. There used to be many sharp edges in this code that could cause resource leaks when just the right sequences of load/unload of drivers and removal and insertion of the cards happened. Now, it is all done in one routine, so things should be more robust. Please contact me if I somehow messed that up.

So this is one more ripple effect of the IF_NEEDSGIANT removal patches. I never would have looked at this stuff had I not been testing patches for John Baldwin. It is interesting the sorts of trails one finds oneself down when trying to help others out, as well as test some hardware that would otherwise be laying around.


NSLU2 support committed to FreeBSD/arm

I just committed the basic Linksys NSLU2 support to the subversion tree. It boots and runs on an NFS root. We're currently lacking support for the leds, the buttons and the on-board flash. Here's some basic instructions if you want to try it on your NSLU2. They are adapted from Sam Leffler's README file for the AVILA, which is adapted from other sources, including Olivier Houchard's and my instructions that have appeared.

  1. Build world
  2. Setup NFS root
  3. Configure diskless system
  4. Build and Install Kernel
  5. Put Kernel in tftp area
  6. Boot from redboot

Build world

The FreeBSD handbook can help you find the sources, etc Once you have them, and they are from -CURRENT after 8am on 2008-08-03, you can proceed to build the world. Each section is cumulative from the previous section for simplicity sake.

setenv TARGET arm
setenv TARGET_CPU_TYPE xscale
make buildworld

Setup NFS root

Find a server that has some disk space. You'll need about 250MB of space for a full FreeBSD image.

setenv ROOT /data/freebsd/roots/slug
make installworld DESTDIR=$ROOT
mergemaster -m $SRC/etc -D $ROOT -i -A arm

Setup diskless system
diskless(8) gives a good overview in how to do this. It is left as an exercise for the read to come up with all the settings. Usually /etc/rc.conf and /etc/fstab must be configured. /etc/ttys is another one that usually needs some tlc. If there's enough demand, I'll write about this in the future.

Build and install the kernel

make KERNCONF=NSLU buildkernel
make KERNCONF=NSLU DESTDIR=$ROOT installkernel

Note: the NSLU kernel is configured with the root filesystem mounted via NFS over the npe0 wired interface.

You should now have an NFS-mountable root filesystem with a kernel. The final step is to setup network diskless booting from the board. It is assumed you have a DHCP server operating on your network and the server is configured to supply the necessary information in the DHCP lease. If you run the ISC DHCP server the following configuration information is an example of how to do this:

option root-opts code 130 = string; # NFS / mount options

host slug {
hardware ethernet 00:d0:12:02:47:68;
filename "kernel-slug.nfs";
option root-path "";
option root-opts "nolockd";

Note: the root-opts item specifies the root filesystem should be mounted with the nolocked option; this just short-circuits file locking requests so you don't get complaints from programs that use the pidfile(3) routine (e.g. devd)

Install kernel in tftp area

Place the kernel in the TFTP area for booting from the prom monitor. If your TFTP server returns file from /tftpboot (default) then do something like:
cp $ROOT/boot/kernel/kernel /tftpboot/kernel-slug.nfs

Boot using Redboot

+(hit control C here)
RedBoot> ip -h -l
IP: Gateway:
Default server:
RedBoot> load -b 0x200000 kernel-avila.nfs
Using default protocol (TFTP)
Address offset = 0x40000000
Entry point: 0x00200100, address range: 0x00200000-0x004db2d4
RedBoot> go

Here's a complete transcript of my doing this. The .gz file listed below really isn't the simple gz file, but rather kernel.gz.tramp from the kernel build. Also, I've hacked my NSLU to have a serial port, which make development like this easier. See the web for instructions on how to do a no-mod breakin.

+Ethernet eth0: MAC address 00:14:bf:68:47:ba
IP:, Gateway:
Default server:, DNS server IP:

RedBoot(tm) bootstrap and debug environment [ROMRAM]
Red Hat certified release, version 1.92 - built 15:16:07, Feb 3 2004

Platform: IXDP425 Development Platform (XScale)
Copyright (C) 2000, 2001, 2002, Red Hat, Inc.

RAM: 0x00000000-0x02000000, 0x000723a0-0x01ff3000 available
FLASH: 0x50000000 - 0x50800000, 64 blocks of 0x00020000 bytes each.
== Executing boot script in 2.000 seconds - enter ^C to abort
RedBoot> ip -l -h
IP:, Gateway:
Default server:, DNS server IP:
RedBoot> load -b 0x200000 kernel.nslu.gz
Using default protocol (TFTP)
Address offset = 0xf0000000
Entry point: 0x00200074, address range: 0x00200000-0x003830fc
RedBoot> go
KDB: debugger backends: ddb
KDB: current backend: ddb
Copyright (c) 1992-2008 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 8.0-CURRENT #12: Sun Aug 3 00:09:07 MDT 2008
CPU: IXP425 266MHz rev 1 (ARMv5TE) (XScale core)
DC enabled IC enabled WB enabled LABT branch prediction enabled
32KB/32B 32-way Instruction cache
32KB/32B 32-way write-back-locking Data cache
real memory = 33554432 (32 MB)
avail memory = 25894912 (24 MB)
ixp0: on motherboard
pcib0: on ixp0
pci0: on pcib0
ohci0: irq 28 at device 1.0 on pci0
ohci0: [ITHREAD]
usb0: OHCI version 1.0
usb0: on ohci0
usb0: USB revision 1.0
usbd_get_string: getting lang failed, using 0
uhub0: on usb0
uhub0: 3 ports with 3 removable, self powered
ohci1: irq 27 at device 1.1 on pci0
ohci1: [ITHREAD]
usb1: OHCI version 1.0
usb1: on ohci1
usb1: USB revision 1.0
usbd_get_string: getting lang failed, using 0
uhub1: on usb1
uhub1: 2 ports with 2 removable, self powered
ehci0: irq 26 at device 1.2 on pci0
ehci0: [ITHREAD]
usb2: EHCI version 1.0
usb2: companion controllers, 3 ports each: usb0 usb1
usb2: on ehci0
usb2: USB revision 2.0
uhub2: on usb2
uhub2: 5 ports with 5 removable, self powered
ixpclk0: on ixp0
ixpiic0: on ixp0
iicbb0: on ixpiic0
iicbus0: on iicbb0 master-only
iicbus0: at addr 0
iic0: on iicbus0
ixpwdog0: on ixp0
uart0: on ixp0
uart0: [FILTER]
uart0: console (115200,n,8,1)
uart1: on ixp0
uart1: [FILTER]
ixpqmgr0: on ixp0
ixpqmgr0: [ITHREAD]
npe0: on ixp0
npe0: [ITHREAD]
npe0: remember to fix rx q setup
miibus0: on npe0
rlphy0: PHY 1 on miibus0
rlphy0: 10baseT, 10baseT-FDX, 100baseTX, 100baseTX-FDX, auto
npe0: Ethernet address: 00:14:bf:68:47:ba
npe1: on ixp0
npe1: [ITHREAD]
npe1: remember to fix rx q setup
npe1: Cannot find my PHY.
device_attach: npe1 attach returned 6
ixpclk0: [FILTER]
Timecounter "IXP425 Timer" frequency 66666600 Hz quality 1000
Timecounters tick every 10.000 msec
bootpc_init: wired to interface 'npe0'
Sending DHCP Discover packet from interface npe0 (00:14:bf:68:47:ba)
npe0: link state changed to UP
Received DHCP Offer packet on npe0 from (accepted) (no root path)
Sending DHCP Request packet from interface npe0 (00:14:bf:68:47:ba)
Received DHCP Ack packet on npe0 from (accepted) (got root path)
npe0 at server boot file kernel.slug
subnet mask router rootfs rootopts nolockd
Adjusted interface npe0
Trying to mount root from nfs:
warning: no time-of-day clock registered, system time will not be set accurately
warning: no time-of-day clock registered, system time will not be set accurately
Interface npe0 IP-Address Broadcast
Loading configuration files.
No suitable dump device was found.
Entropy harvesting: interrupts ethernet point_to_point kickstart.
Starting file system checks:
mount_nfs: can't update /var/db/mounttab for
Setting hostuuid: 1c728616-1dd2-11b2-9fa6-0014bf6847ba.
Setting hostid: 0xb1c1273a.
Mounting local file systems:.
Setting hostname: slug.
net.inet6.ip6.auto_linklocal: 1 -> 0
DHCPREQUEST on npe0 to port 67
ip length 328 disagrees with bytes received 332.
accepting packet with data after udp payload.
bound to -- renewal in 900 seconds.
lo0: flags=8049 metric 0 mtu 16384
inet6 fe80::1%lo0 prefixlen 64 scopeid 0x2
inet6 ::1 prefixlen 128
inet netmask 0xff000000
npe0: flags=8843 metric 0 mtu 1500
ether 00:14:bf:68:47:ba
inet6 fe80::214:bfff:fe68:47ba%npe0 prefixlen 64 scopeid 0x1
inet netmask 0xffffff00 broadcast
media: Ethernet autoselect (100baseTX )
status: active
Additional routing options:.
Starting devd.
Additional IP options:.
Mounting NFS file systems:.
Creating and/or trimming log files:.
Starting syslogd.
/etc/rc: WARNING: Dump device does not exist. Savecore not run.
ELF ldconfig path: /lib /usr/lib /usr/lib/compat
Initial arm initialization:.
Additional ABI support:.
Clearing /tmp (X related).
Starting local daemons:.
Updating motd.
Mounting late file systems:.
Starting cron.
Local package initialization:.
Starting inetd.
Starting background file system checks in 60 seconds.

Thu Jan 1 00:00:39 UTC 1970

FreeBSD/arm (slug) (ttyu0)

login: root
Jan 1 00:03:24 slug login: ROOT LOGIN (root) ON ttyu0
Last login: Thu Jan 1 00:42:28 on ttyu0
Copyright (c) 1992-2008 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 8.0-CURRENT (NSLU) #12: Sun Aug 3 00:09:07 MDT 2008

Welcome to FreeBSD!

Before seeking technical support, please use the following resources:

o Security advisories and updated errata information for all releases are
at http://www.FreeBSD.org/releases/ - always consult the ERRATA section
for your release first as it's updated frequently.

o The Handbook and FAQ documents are at http://www.FreeBSD.org/ and,
along with the mailing lists, can be searched by going to
http://www.FreeBSD.org/search/. If the doc distribution has
been installed, they're also available formatted in /usr/share/doc.

If you still have a question or problem, please take the output of
`uname -a', along with any relevant error messages, and email it
as a question to the questions@FreeBSD.org mailing list. If you are
unfamiliar with FreeBSD's directory layout, please refer to the hier(7)
manual page. If you are not familiar with manual pages, type `man man'.

You may also use sysinstall(8) to re-enter the installation and
configuration utility. Edit /etc/motd to change this login announcement.

nslug# ntpdate harmony
3 Aug 07:04:18 ntpdate[582]: step time server offset 1217746845.716155 sec
slug# date
Sun Aug 3 07:04:19 UTC 2008
slug# df
Filesystem 1K-blocks Used Avail Capacity Mounted on 55871592 49741636 1660230 97% /
devfs 1 1 0 100% /dev 55871592 49741636 1660230 97% /pe


When worlds collide

Recently, I had to check out a linux tree at work from cvs. I only knew the repository, but didn't know the module to check out. So I made my best guess and started building the kernel. After plowing through a couple of little things, I hit the wall with:

scripts/Makefile.build:17: /pe/imp/xxx/linux-2.6.xxx/net/core/Makefile: No such file or directory
gmake[2]: *** No rule to make target `/pe/imp/xxx/linux-2.6.xxx/net/core/Makefile'. Stop.

Guess what someone forgot to do when they were doing the cvs import :-)


MIPS Diffs

Although FreeBSD/mips has been committed to the tree, a few stragglers haven't been pushed into the tree for various reasons. Oleksandr Tymoshenko and I have been honing them down and have just published a set for review.

If you'd like to try FreeBSD/mips out, you can grab these patches from Oleksandr's directory. There's four diffs included. Please send any feedback to arch@freebsd.org.


Minor wi(4) hacking

I finally had some time, a need for wireless connectivity in the shop and found my stash of old Prism 2, 2.5 and 3 cards. I thought I'd try them out with the new vap stuff.

First, there's a new filter on the firmware revisions in the driver. Very old versions of the firmware basically don't work without a lot of coaxing and workarounds. They are no longer supported. In addition, symbol cards are fairly rare and there's no readily available documentation for them, so support for them was removed as well. This filtering is a good thing, since it will keep people from using cards that are known to be broken. However, I had to fix a bug in the interrupt registration to make this work out OK (and to also stop spontaneous panics sometimes on attach if there was a lot of interrupt activity on a shared interrupt). I basically moved the interrupt registration to the end of the attach function, rather than the beginning and solved both problems.

All of these cards that I had don't have new enough firmware to support WPA. This highlights another problem: wpa_supplicant doesn't filter out WPA APs when it is looking for things to attach to, or otherwise provide a meaningful error message that would tell the user the reason that WPA isn't working is that their card is too old/lame to support this new-fangled stuff....

I wound up solving my problem with an atheros card that just worked, once I found them...


Taking a break from FreeBSD core team

As has been recently announced, the FreeBSD project has selected a new core team. The project elects a new team every two years. This time, I've decided to take a break from the core team. I have a new son and I want to spend more time with him and the rest of my family.

I've had a great time on the core team. I've been serving now for 8 years. I've really enjoyed being on the core team and leading the project through some difficult times. Since my son and family are taking a lot of my time these days, I have limited time to spend on the FreeBSD project. I've done my time in the administrative side of the project for a while, and I want to spend my limited time working to make FreeBSD a better platform for the embedded platforms. I'm taking a 2 year break. We'll see how things are in 2 years...

I wish the new core team luck, although they are good people and they won't need my luck to be successful.


Quick Guide to FreeBSD hostap for FreeBSD 8

I have a need to setup an access point. Many of the discussions on the web include all kinds of extra goodies that one normally sets up with the access point. But I just needed an access point: no dhcp, bridging, etc. Here's how I did it.

Recently, some really cool stuff when into the kernel for wireless. This is the VAP stuff, or the virtual access point code. This allows freebsd to decouple the code for doing access points, and a bunch of other stuff, from the code to drive the wireless hardware. Great in concept, and quite useful with some of the advanced wireless hardware.

However, it did change the way things were configured. The handbook is now out of date. Until it can be updated, here's what I did, with some explanations about each step.

First, I needed to create an rc.conf setup for my needs. Here's the one I came up with.

create_args_wlan0="wlanmode hostap mode 11g"

devd_enable turns on the devd(8) process. This process is responsible for dealing with the different device events in the system. This is the hook that we use for hot-plug insertions, which is how we configure the wireless devices.

wlans_ath0 is used to create the virtual interface wlan0 associated with ath0. This is how all the wireless stuff is setup now. You configure the basics with the wlan_IF=wlanX command, and set more specific stuff via the wlanX interface.

create_wlan0 gives the arguments with which to create the wlan interface. There are many that can only be created at wlanX creation time, and it happens that hostap is one of them. I'm not 100% sure that I need to bother with the 11g mode command or not here, but it seems to work.

ifconfig_wlan0 sets the device's IP address. In my example, I wanted the interface to have an IP address, but not be bridgable since I didn't have any other interfaces on the laptop I wanted to be the AP for the thing I'm doing.

hostapd_enable turns on the hostapd daemon. You won't get far without this, so we turn it on.

We've enabled a daemon, and now it is time to configure it. Here's the config file that I used for hostapd.conf:

ssid=bsdimp hacking blog

itnerface specifies which interface to use. Duh! However, this needs to be the wlan device, not the hardware device.

hw_mode sets the hardware into 802.11g. Not sure if this is needed, but it works for me.

macaddr_acl is wide open: it allows anybody to connect. As you may have noticed, this setup is very permissive. It has nothing locked down at all. It should be the first thing you do as an experiment before proceeding on to enabling WPA or WPA2 to get a reasonable level of security.

auth_algs sets which authorization algorithms can be used. See the hostapd man page for details.

ssid sets the name of the network you are serving.

The rest can be gleaned from the manual.

Chances are this post should be updated, so if you have any suggestions on how to do that, please leave then as comments.


Minor mips reorg and plans for the future

In trying to bring the MIPS tree more into line with idealized FreeBSD practices, I've moved the SoC directories up one level in the hierarchy. Future changes will make it easier to define different boards, as well as stylizing these sorts of things across different CPU architectures. I need this for the Plat'Home OpenMicroServer work I've started on, so I'll use that to drive these changes.

For the curious, I've moved mips/mips32/adm5120 -> mips/adm5120, likewise with the idt, malta, and sentry5 directories. While all of these were, strictly speaking, mips32 CPUs, having them in their own subdirectory doesn't make a lot of sense. There's never going to be so many of them that having an extra layer of indirection is going to help. Also, mips32 is ambiguous. Does it mean the MIPS ISA known as MIPS32 and MIPS32r2? Does it mean that the ports are running in 32-bit mode? It wasn't clear where a 32-bit kernel for a mips64 processor would live. Also, the idt parts aren't completely mips32 compliant in a couple of minor details. Is that non-compliance enough to move them elsewhere?

The next set of changes will try to tease apart the boot loader environment from the SoC that it is running on. While many SoCs have their own bootloader, often times one may also run uboot on the same hardware. In addition, things like uboot are used in many different platforms, so duplicating that code will grow tiresome.

Once the boot loader stuff is better abstracted, the next set of problems will be how to create a system that can run on multiple different boards of the same SoC. At first, this will be statically compiled, but eventually it will be dynamic.

Another key component of this work, whose overall goal is to make it easier to add board support to FreeBSD embedded platforms, will be an overhaul of the hints system. While it can be made to work, there are some practical problems it solves poorly that are desirable to have solved better. For example, it has no good way to tie attributes or parameters to hardware. Today, one can only tie them to a driver instance, which itself can be tied to hardware.

Finally, the last planned component in this work is a simplification of creation of busses with attributes and fixed or semi-fixed children. You can't have variants of hints loaded today that say "If I'm running on a AT91RM9200, use this set, but if I'm runnning on an AT91SAM9620 use this other set of hints" to enumerate the busses. This makes it hard to achieve the dynamic selection of boot code to run needed to allow kernels to boot on a variety of boards.

Most of this is low-level code janitor stuff. However, it is code janitor stuff that's needed and will be important to FreeBSD's success in the future.


Adding a Serial Port to a D-LINK DIR-615

A while ago, I added a serial port to the D-LINK DIR-615 (HW Rev A1). Today, I'll document how I did it.

First, you'll need a level converter circuit. There are many on the network. You can find a good write up on them and links from adding a serial port to a NSLU2. I always use the Parallax USB2SER that I bought years ago. It is very reliable, and I've had several provide years of good service to me. They convert 3.3V directly into a USB serial port, which vastly simplifies power and cabling. Since that's what I used for this project, all the instructions are geared towards it.

First, you'll need to disassemble the D-LINK DIR-615. There's only two screws so this is easy. Place the D-Link with the label with the serial number face up. There are four rubber feet on the bottom of this unit. Carefully pry up the two nearest to the Ethernet ports. Remove the screws found under them. The screws are clearly visible in this photo.

Carefully remove the lid. It should pry off just above the plastic bar that runs over the ethernet ports. You'll see a green PC board. On the right hand side of the unit, you'll find a header with 4 pins labeled CON5. They are labeled VCC, TX, RX, GND. This is the serial port. In my unit, it was hidden under the internal antenna, so the photos show it moved over a bit. Note also in figure two the board says "DIR635B1" on it...

I connected these pins to a ribbon cable and ran them out to a header that my USB2SER could fit on. I connected them so that they would match up to my USB2SER which had pins in the order GND, RX, TX, RES. The last one is unconnected. TX should go to RX, RX to TX and GND to GND. I didn't connect VCC, since it wasn't needed. USB2SER gets its power from the USB port. I reconnected everything and plugged the USB2SER into my computer. I threaded the ribbon cable out through the holes in the plastic, which is what you see in the first photo. Here's everything hooked up. I didn't include a photo of the USB2SER plugged into the serial port of my laptop for obvious reasons...

I see that it has a uboot bootloader:

% tip ucom0
U-Boot 1.1.1 (Jan 19 2007 - 11:08:07)
CAMEO uBoot Linux Loader version:

DRAM CS[0] base 0x00000000 size 32MB
DRAM Total size 32MB
before entry mvFlashInit
Flash: flashStructGet manu 0x89 id 0x17
INTEL 28F640J3A (64 Mbit)
Size: 8 MB,Bus Width: 1, device Width: 1.
Flash base: 0xff800000,Number of Sectors: 64 Type: REGULAR.
[8192kB@ff800000] Flash: 8 MB
Addresses 20M - 0M are saved for the U-Boot usage.
Mem malloc Initialization (20M - 16M): Done
*** Warning - bad CRC, using default environment

Soc: 88F5181 B1
CPU: ARM926 (Rev 0) running @ 500Mhz
SysClock = 166Mhz , TClock = 166Mhz

USB 0: host mode
PCI 0: PCI Express Root Complex Interface
PCI 1: Conventional PCI, speed = 33000000
Net: egiga0 [PRIME]
Hit any key to stop autoboot: 0

So that's how you add a serial port.


Old cards and the information gap

This time I'll explore some of the issues relating to hacking on older hardware. I'll talk about expanding the work I did for the Olicom OC-2220 to the combo OC-2232 and the problems encountered.

In a previous edition, I talked about the Olicom OC-2220 card and getting it working. It works great, and in fact, I'm using it right now to make this blog entry. However, the next card I tried didn't fare so well. This is the Olicom OC-2232, which added a 33.6k modem to the same basic design as the OC-2220. It exposes the ethernet and modem such that I had to augment the PC Card system to access. I had to be able to specify the config entry to use to configure the resources for the card. However, when I started, FreeBSD's PC Card system lacked this feature.

I was able to augment FreeBSD's PC Card system to have a feature that's been requested infrequently. The ability for the driver to select the config entry to use. Right now, all of the FreeBSD PC Card drivers have been able to use the config entry that the system guesses is the right one. However, there are some combo cards that pre-date the PCMCIA multifunction standard that need to select a config entry.

So, after adding this, it was a simple matter to get the ex driver selecting the appropriate alternate config entry for the Olicom OC-2232 that I have. This card has the Intel 82595 and a 16550 compatible 33.6k modem on it. By default, FreeBSD will happen to pick the entry that corresponds to the modem only. However, with my hacks I have been able to make it select either the ethernet side only or both. FreeBSD needs a few changes to allow it to support both of these devices at the same time, but I'll write more about that at another time.

So the card comes up, and I'm able to attach to the ex driver. But there's a problem. dhclient doesn't finish. For the OC-2220, this returns immediately, so I know that the dongle cable is good, as is the port on the hub. The OC-2232 uses the same cables, as far as I can tell, but when I try to push packets through, I never get any interrupts, so dhclient never finishes. I've not instrumented the driver to see if adding a watchdog timeout would help make this work in the absence of interrupts or not.

This leads me think about some of these old cards that I have. It is impossible to get information on them. The best I've been able to find is binary only Windows and DOS drivers for them. These drivers don't work with the current version of Windows that I have on my laptop. This makes it hard to know if the problem I'm encountering is a hardware problem or a software problem. There's no support for this card in Linux (the base kernel doesn't support and 82595 based PC Cards, and it is nearly impossible to find a driver for the few cards that used this chip that wasn't incorporated into the kernel).

So assuming the card is good, there's no source available for it. I knew there was a similar card made by Silicom called the EtherSerial card. It has a real serial port in addition to the 82595 ethernet controller on it. Searching for it was difficult. Most likely there's a trick to forcing google to tell me "Where do I find the file silpmcica-1.02b.tar.gz?" with all the variant spellings and encodings (.tgz, tar.bz2, .tbz, .tbz2, etc), but I didn't see it. Altavista used to have this feature, and I'm sure that some sharp reader will tell me how to make google do it.

I was able to find, using the internet archive, the driver for the Silicom card. Well, kinda. I was able to discover the name of the file, and also discover that the internet archive didn't cache the files that people put on their FTP sites, so when I clicked on the driver link there, it tried to grab it from Silicom's current FTP server, which isn't setup for anonymous operation.

I was able to find the datasheets for this old part, however. I was lucky this part was popular enough that the various datasheet web sites have it available. There were three variants of the part, and only the FX variant appears to have been used in the PC Card devices.

So the resort of looking for data for this card was somewhat less successful than looking for data for the Crystal Semi based card that I had. There I was able to find everything I needed, but my needs were more meager. Now, I'm left wondering: do I have bad hardware? Do I need to prod some hidden register to turn on interrupts? Do I need to disassemble the drivers that I found to make further progress? These are all good questions, and I don't have the answers to any of them. All the questions that lead me to make progress involve a lot of time doing unfun tasks that really gain me no pleasure or knowledge.

Anyway, my trip down memory lane must end soon. I have other commitments in FreeBSD that I need to return to soon. This was a fun diversion (and hardware that's easy to carry), but I'm afraid this unsatisfying dead-end will likely be where this problem sits for a while as I have some processor porting work to do for people that have donated hardware to me. I've put that off long enough based on the fun I had one night with one PC Card. I'm afraid I'm going to have to put them back on the back burner unless new information surfaces. The other hardware is more relevant, and while it is fun to misbehave sometimes with something that may not be relevant for the fun of it, there's a different kind of fun to be had when doing things with more relevant hardware, and I think it is time I got back to that kind of fun in my spare time.


Good collection management software

Regular readers of this column know that I have a large collection of PC Cards. Some would say 'too large' and I'm not sure they'd be wrong. I was out in the garage last night looking for a specific card. I couldn't find it. I know it is there, somewhere, but don't know exactly where. Maybe I'll find it tonight when I look in a place that I remembered driving into Boulder today.

This got me to thinking: how can I manage all these cards. I need to figure out some way of recording generic information about the card. Where it lives, what dongles it needs, what driver it uses, etc. It would also be nice to know when I last tested it, how well it worked, etc. Maybe some notes about the card, like "This card has a blue label on it, and needs to have the dongle wiggled just so: .... for it to work." Oh, and it would also be nice to generate reports so that I can maintain a list of cards that I've tested and when on a web page automatically. I did this years ago, but stopped when it became too big a pita to keep current.

In the past, I've not seen anything that's good at doing all these things. I thought I'd ask my readers if they knew of anything that solves this problem? I know that there's many tools that could be used to build a solution, but many of them require a fair amount of customization to make into a workable solution. A quick google search doesn't turn up anything that's more sophisticated than a generic database. Does anybody know of something that's fairly close?


Olicom OC-2220 works

After applying John Bladwin's MPSAFE patches to the ex driver, the ex driver works with the Olicom OC-2220. If you are unfamiliar with this card, I'm not surprised. It was made in the mid 1990's. From a network perspective, it isn't that important. It is a slow 10BaseT card that doesn't seem to do full duplex.

However, from the PC Card perspective, there's some interesting things with ex. There's the Olicom OC-2232 that includes a modem. But it includes it in an interesting way that isn't quite standard. How do we pull in the serial port in this case? There's also some cards from Silicom that have a serial port bolted on as well, but in a different way. i've not seen good documentation for either of these cards, but at least there's a driver for the silicom available (or was once upon a time) for Linux. I sure hope that wasn't one of the things I lost in my disk crash...

So again, despite the age of the underlying chip, there's some interesting problems here. The trouble is that the problems are such that they can't easily be solved in an hour of hacking, so they may continue to linger....


Crystal Semiconductor Driver

Since I've been maintaining the PC Card layer in FreeBSD, I've accumulated a lot of PC Card hardware. Well over 100 different PC Card r2 (16-bit) and CardBus (32-bit) cards. Recently, Robert Watson started pushing to have all the network drivers in the tree be MPSAFE. John Bladwin posted some patches to the if_cs driver to bring it up to those standards. Since I had a soft spot in my heart for this driver for reasons I don't entirely understand, I took the IBM EtherJet PC Card that I had with me on a recent buisiness trip with the vague notion of testing out John's patches.

I discovered that the driver didn't work. It didn't work before the patches, nor after them. The breakage was minor and I likely wouldn't have noticed it except for the fact that I didn't have the Ethernet cable plugged in when I was doing the early testing. Since the breakage annoyed me, I went ahead and fixed it. I also noticed that the reading of the EEPROM was very slow, and caused me to drop characters when I inserted the card. I hate that. I discovered a number of DELAY statements in the EEPROM reading which were the cause of the problem. I thought "this is nuts" to myself, and went off to locate the datasheet for this part. After reading through it, I discovered the EEPROM busy bit that I polled in place of the hard coded 3ms DELAY. I went from having about 1.2s of DELAY and other busy waiting when I inserted the card to having on the order of 800us, a speedup of about 1500x.

This brings up a number of philosophical questions. Why did I bother with such an outdated chip? Why speed up a one time operation? Why spend any time at all on this after a busy day of meetings and crisis management?

Let's answer the last question first. I did it because I was absolutely exhausted by my meetings. While productive, and they helped to drive the problems of the project I was working on towards resolution, they were draining. By hacking on this driver I had a very safe area to make improvements. Unless I broke the build, nobody would notice the work, yet I'd have the satisfaction of a job well done. Since it is in an out-of-the way part of the kernel, I had the room to fail without throngs beating down my door. I had complete freedom to tinker and tidy as I saw fit, and doing so was very relaxing and invigorating after a long, hard day. Maybe I'm just weird, but sometimes a little bit of hacking to make something better is just what my brain needs to relax and unwind.

The reason I was spending any time at all on this was that this part made a resurgence in recent years inside embedded systems. There are several embedded designs that use this part when they don't have the ethernet on the SoC. More recent parts have all this built into the SoC, so the popularity has waned once again, but I knew some ARM boards used it, so in the back of my mind I had a justification for spending time on it based on my FreeBSD embedded hat that I wear from time to time. I was shocked to get email from someone who had one of these boards and wanted to know how to write a front end for this driver for that board within a day of my committing the cleanups. That was a nice bonus. Time will tell if he follows through, of course, but I was very amused by it.

Finally, why spend time optimizing an operation that happens only once at startup? I hate losing characters when I type. Since I didn't want to re-write the syscons keyboard driver to have a fast interrupt handler to read the keystrokes and queue them for later processing (the only thing that will interrupt a DELAY is a fast interrupt handler), I thought this was the easier path to solving my problem. I spend a lot of time at work making sure that the right priority calls are made, and it felt good to be "bad" and work on something that clearly is the wrong priority call in terms of everything else that's going on in FreeBSD.

I guess it all boils down to "I had an itch, and it felt good to scratch it." rather than any rational thought process. Sure, I justified it after the fact in many different ways, but it felt fundamentally good to just make something better for the sake of making it better and not have to worry about big picture this, or deadline that, or you broke my whatsit complaints. I had a well defined technical problem, I had to research solutions and hack a bit of code. It felt good being able to find the data I needed, fix the code, test it and see it working and passing packets again. I wish all problems that I faced in my technical life were so easy and rewarding.

Oh yea, and it turned out that I found a bug in John's patches and he was able to commit them to the tree, eliminating one more Giant Locked driver. I'm sure Robert will be happy. I'm sure there are others that would have been just as happy to have the impending removal of Giant Locked network drivers sweep it into the dustbin of history. Maybe I have that soft spot in my heart for it because it was one of the drivers that the Japanese Mobile community hacked years ago and seeing it the tree reminds me of happy trips to Japan, drinking way too much sake, and speaking bad Japanese as a result? Who knows....


Plat'Home provides OpenMicroServer

Plat'Home has generously shipped me an OpenMicroServer. Plat'Home has been doing Emebedded things for years in Japan. They used to have the coolest store to go visit in Akihabara, but that recently closed and now they are expanding their markets internationally through the web. I have fond memories of buying my first HappyHackingKeyboard there almost a decade ago...

So what is an OpenMicroServer? It is a ruggedized router with extra features to allow it to operate in a wider range of environments than just a router. It has DIO pins for control and monitoring. There's a console serial port, as well as an extra serial port. There's three multicolored LEDs as well. It operates over an extended temperature range. Inside there's a CF slot in case the built in flash is insufficient for your needs. Oh, and I almost overlooked the pair of USB 2.0 ports.

Under the hood there's an MIPS cpu inside the box, which is why they send it to me. I've started working on FreeBSD/mips support for it. There's a RMI Alchemy™ au1550 400MHz powering this box with 128MB RAM and 16MB Flash. It supports 3 ethernet ports. 1 10/100 port that also supports POE (to get power over the ethernet) and 2 that are 10/100/1000 gigE ports.

The only bad thing I can say about it is that it ships with Linux preinstalled... :-)

You can find more information about the specs here. Or general information about Plat'Home here.

Stay tuned for updates on how the port is going.


More mips support code committed

This weekend, I've committed more mips support code. Everything except for the tool chain is now in the tree. The tool chain will be pushed in over the next week or so. I have to verify that some changes I remember having to make to the tool chain are compatible with the tool chain that's in the FreeBSD repository. When everything has been pushed into the tree, I'll enable it as part of the make universe target.

FreeBSD/mips is starting to get attention from other FreeBSD developers now that it is in the tree. Alan Cox has started to audit the Mips pmap, for example. This should help FreeBSD/mips transition to the next level of support.

Many changes are still needed for the mips port. We need to audit the basic libc functions to make sure that we haven't stubbed anything out that's going to bite us in the future. We need to look to see if there's anything that can be refactored from the 3 different embedded platforms in the tree today (powerpc, arm and mips). Better documentation and porting to new chips/boards would help us to make things more portable.


FreeBSD/mips entering the tree

I've started committing FreeBSD/mips to the tree. It includes support for the ADM5120 SoC, a generic MIPS 4Kc in a Malta board, the IDT RC32434 (found on RB533) and preliminary support for the Broadcom Sentry 5 series of CPUS. It will likely be a few days before it is all in the tree and buildable. There's a number of issues that are cropping up as I'm pushing the code into the tree that weren't apparent until after the commits and merges back into p4. In addition, support for another platform is delayed pending approval to commit.

Look for more news, how-tos, etc in the days and weeks to come.


Tokyo AsiaBSDCon 2008 Dev Summit Day 1

Hello from Tokyo.

Today we had a developer summit at AsiaBSDCon 2008. We talked about a number of items. We talked about the FreeBSD/mips: it is booting multiuser. We'll be committing to FreeBSD soon.

We talked about ways to making it easier to have parts of FreeBSD be optional, with the default being 'on'.

There's this ugly hack which allows one to test the suspend/resume paths of drivers. Check it outthis patch.


D-LINK DIR-615 B2 hardware

If you go buy a D-LINK DIR-615, make sure that it is hardware revision A1. Hardware revision B2 has less flash (only 4MB) and RAM (16MB) and a completely different processor: Ubicom IP5090U cpu. This CPU uses a new instruction set (ubicom32) that isn't supported by any open source operating system that I could find. This is also the previous generation of the ubicom processor. The IP51xx is the latest generation of processor, and evidentially its only used on the DIR-655.

A good place to look for information about what processors and radios are in the different access points on sale now, including version information, can be found over at small net builder with information about the D-LINK DIR-615 B2.



The other day I saw that Target was selling the D-LINK DIR-615 draft N router for $50.00 each. Since it had been a while since I purchased a wireless router to hack, I bought one. It turns out that this was a wise choice.

This router chip has an 88F5180NB1 CPU. This is a Marvell Orion SoC. Support for this family of processors is coming into the tree shortly.

There's a FS28F640 flash chip on board. This is a 64Mb/8MB of memory. With compression, FreeBSD can fit into this size. There appears to be 32MB of RAM, which is also enough to run FreeBSD.

There's a 88E6061-LAJ1 PHY chip which should be relatively easy to program.

Finally, it has a mini-pci slot with a 802.11n card based on the 88W8361P-BEM1 chip. Maybe a driver for this chip will come along. I've not investigated the GPL tarball to see if there's a driver in source for this, or just a binary module.

There's a GPL tarball available at the D-Link web site.

Finally, there's two interesting connectors. One looks to be a JTAG connector, the other looks to be a serial port.

My next step is to look into what's coming out of the serial port and what's in the GPL tarball for hints while I'm waiting for the Orion support to come into the tree.


FreeBSD/arm on a Linksys NSLU2 (slug)

Thanks to some encouragement from Gavin Atkinson, I have been able to boot the AVILA kernel on my Linksys NSLU2 (slug). I have it running of NFS root at 266MHz. Not super fast, but not too bad. I need to clean up a bunch of stuff still, but at least I have the basics working.

I'll post more in a few days, once I get a chance to clean up what I have and submit it to CVS. But this is very exciting...


Buffalo LinkStation PC-L4PWAP

Today I'm writing about the Buffalo LinkStation PC-L4PWAP. It was on clearance at Circuit City, so I thought I'd take a chance and pick it up. At the very least, I'd have a new 'receiver' on my network to play tunes through at parties.

I cracked it open when I got it home. There's a Phillips PNX-1520E processor running at 300MHz inside. A quick web search turned up that it has a TM3260 CPU core with a lot of perripherals (I2C, PCI, IDE, etc). The TM3260 is a CPU from Phillips that is a VLWI processor. I had rather hoped when I saw pnx that it had one of their MIPS cores in it. But no such luck.

I didn't bother looking at the amount of memory or the amount of flash on the board once I discovered it wasn't MIPS based. I guess I'll have to content myself with listening to the music it is spooling off a uPNP server on my network... once I get one of them setup. I'll report back on how well it works.


Spot the Bug!

I was looking over some code for someone today. They were having problems with preemption in the write routine and couldn't understand why, since they said to take Giant for all devsw operations. In digging into the problem, I discovered the following code. Maybe you can spot the bug:

#define FOO_GIANT 0

(FOO_GIANT is used in the devsw data structure to paper over differences between 4.x and 6.x in this driver).

I think I know who did this change, but without cvs access to the code I can't be sure. Which is good, because I think it was me, but it might have been the person I was helping out. The change was made almost 4 years ago. This code has been in there that long and it wasn't until an especially demanding application came along on a faster CPU was it a problem.

Just goes to show you can never be too careful, or test too much...


Random Acts of Kindness

I went to my old house yesterday. Like many others, my old house hasn't sold in a while. There was a showing today, so I had to shovel the snow off the driveway. While I was there I discovered a most interesting package on my doorstep.

It was a nice, large calendar of African animals in the wild. I hadn't ordered the calendar, so I was very confused. It was from Cafe Press, so I thought it was a dividend from an item I'd designed and put up there. But after shoveling a little I realized that couldn't be it: I've just bought stuff from Cafe Press in the past. I hadn't designed anything for there. I'd thought about it, but never put my thoughts into actions.

After I finished shoveling, I took a closer look at the package. I found a card I'd overlooked before. Inside the card there was a nice note thanking me for the USB and other bits of FreeBSD work I'd done. It was anonymous, so I don't know who to thank for this bright spot in a busy day.

It is the little things like this that really make my involvement in the open source community enjoyable.

Thank you!


Building a big endian ufs image on a little endian system

Let's say you want to create a ram disk for a kernel, or a ufs image for an emulator. To make it interesting, the image needs to be in big endian format and you just have an intel x86 machine which is little endian. How do you proceed? If you were building a little endian image, the answer is simple: just newfs an md partition, mount it and copy. But that won't work for a big endian image. Fortunately, the answer is straight forward:
  1. create a tree of files you want in the image
  2. install the makefs port
  3. use makefs to create your image.
You'll need a /tmp file system of at least 2GB to follow these steps exactly. If you don't have one this big, then you'll need to use a different path below to use a different partition.

Create a tree of files

You'll need to create an image of what you want. Let's assume that it is a powerpc root disk for FreeBSD. For the sake of simplicity, I'm assuming that the kernel comes from elsewhere. If not, then you'll need to add the buildkernel/installkernel targets
  • setenv TARGET powerpc
  • setenv MAKEOBJDIRPREFIX /tmp/imp/obj
  • make buildworld
  • sudo make installworld DESTDIR=/tmp/imp/ppc-root
  • sudo make distrib-dirs DESTDIR=/tmp/imp/ppc-root
  • sudo make distribution DESTDIR=/tmp/imp/ppc-root
  • echo "hostname=ppc-qemu" > /tmp/imp/ppc-root/etc/rc.conf
  • echo ifconfig_DEFAULT=DHCP >> /tmp/imp/ppc-root/etc/rc.conf
  • echo /dev/ad0a / ufs rw 1 1 > /tmp/imp/ppc-root/etc/fstab
The above steps build the FreeBSD world, and create a directory that could be used as a root directory. It can be used via NFS, or placed on a flash or in a ram disk.

Installing the makefs port

NetBSD created a tool to create file systems. Colin Percival ported this to FreeBSD and make a FreeBSD port to boot. He's no longer maintaining the port, but I try to keep it compiling. Installing the port is done in the usual FreeBSD way:
  • cd /usr/ports/sysutils/makefs
  • make all
  • sudo make install
  • make clean
Making the image

Once you have makefs installed, creating the image is the next step. You'll need to figure out how big you wish to make the image. For me, I think that 500MB is a good size. The base system is about 250MB, and that leaves room left over for testing programs in the emulator.
  • makefs -B big -s 500m /tmp/imp/ppc-root-image /tmp/imp/ppc-root
The resulting file, /tmp/imp/ppc-root-image is going to be 500MB in size.