20080816

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...

20080809

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 :-) ]]

20080807

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:
Log:
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...

20080806

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.

20080803

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 MAKEOBJDIRPREFIX /tmp/$USER/obj
setenv TARGET_BIG_ENDIAN t
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;
fixed-address 10.0.0.221;
next-server 10.0.0.251;
filename "kernel-slug.nfs";
option root-path "10.0.0.251:/data/freebsd/roots/slug";
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 10.0.0.251 -l 10.0.0.1
IP: 10.0.0.1/255.255.255.0 Gateway: 0.0.0.0
Default server: 10.0.0.251
RedBoot> load -b 0x200000 kernel-avila.nfs
Using default protocol (TFTP)
Address offset = 0x40000000
Entry point: 0x00200100, address range: 0x00200000-0x004db2d4
RedBoot> go


dmesg
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: 192.168.0.1/255.255.255.0, Gateway: 192.168.0.1
Default server: 0.0.0.0, DNS server IP: 0.0.0.0

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
^C
RedBoot> ip -l 10.0.0.12 -h 10.0.0.8
IP: 10.0.0.12/255.255.255.0, Gateway: 192.168.0.1
Default server: 10.0.0.8, DNS server IP: 0.0.0.0
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
imp@lighthouse:/tmp/imp/obj/arm/cache/svn/head/sys/NSLU
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: [GIANT-LOCKED]
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: [GIANT-LOCKED]
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: [GIANT-LOCKED]
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 0.0.0.0 (accepted) (no root path)
Sending DHCP Request packet from interface npe0 (00:14:bf:68:47:ba)
Received DHCP Ack packet on npe0 from 0.0.0.0 (accepted) (got root path)
npe0 at 10.0.0.12 server 0.0.0.0 boot file kernel.slug
subnet mask 255.255.255.0 router 10.0.0.1 rootfs 10.0.0.8:/pe/slug rootopts nolockd
Adjusted interface npe0
Trying to mount root from nfs:
NFS ROOT: 10.0.0.8:/pe/slug
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 10.0.0.12 Broadcast 10.0.0.255
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 10.0.0.8:/pe/slug
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 255.255.255.255 port 67
ip length 328 disagrees with bytes received 332.
accepting packet with data after udp payload.
DHCPACK from 10.0.0.1
bound to 10.0.0.12 -- renewal in 900 seconds.
lo0: flags=8049 metric 0 mtu 16384
inet6 fe80::1%lo0 prefixlen 64 scopeid 0x2
inet6 ::1 prefixlen 128
inet 127.0.0.1 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 10.0.0.12 netmask 0xffffff00 broadcast 10.0.0.255
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 10.0.0.6 offset 1217746845.716155 sec
slug# date
Sun Aug 3 07:04:19 UTC 2008
slug# df
Filesystem 1K-blocks Used Avail Capacity Mounted on
10.0.0.8:/pe/slug 55871592 49741636 1660230 97% /
devfs 1 1 0 100% /dev
10.0.0.8:/pe 55871592 49741636 1660230 97% /pe

20080801

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 :-)

20080729

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.

20080726

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...

20080722

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.

20080715

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.

devd_enable=YES
ifconfig_wlan0="inet 10.0.0.1/24"
wlans_ath0="wlan0"
create_args_wlan0="wlanmode hostap mode 11g"
hostapd_enable=YES


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:

interface=wlan0
hw_mode=g
macaddr_acl=0
auth_algs=1
ctrl_interface=/var/run/hostapd
ctrl_interface_group=wheel
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.

20080706

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.

20080627

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: 1.3.0.0

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
Marvell>>

So that's how you add a serial port.

20080623

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.

20080616

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?

20080613

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....

20080612

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....

20080531

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.

20080426

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.

20080414

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.

20080327

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.

20080320

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.

20080318

D-LINK DIR-615

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.

20080316

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...

20080312

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.

20080110

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:

#ifdef D_NEED_GIANT
#define FOO_GIANT D_NEEDGIANT
#else
#define FOO_GIANT 0
#endif

(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...

20080105

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!

20080103

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.

20071229

An old-school hack remembered

Way back in the days of yore, when Turbo C++ had just came out, I was using a DEC Rainbow 100B+. For those not old enough to recall, this was a machine that came out in 1985 with software that came out in about 1990. Boreland had done a good job of not using all the IBM BIOS calls, so its compilers and such were useful on the Rainbow. The Rainbow had an 8088 processor in it, but wasn't IBM Compatible (being released at about the same time the IBM PC was). The Rainbow was better in a lot of ways, which is how I wound up with it, but worse in other ways...

However, Boreland hadn't done a perfect job. They had used an unused software interrupt (INT 18h) for memory management of the compiler. Early versions of the Turbo C++ used it in only a few places. Patches quickly appeared in the Rainbow community to allow one to run TurboC++ on the Rainbow. These patches were about a hundred lines of code and just patched the offending INT calls to use a different vector (one that was unused on the Rainbow).

I had seen these patches, and when my job was using C++, I thought it would be cool to be able to compile code for it at home. I went out and bought Turbo C++, only to discover it was a newer version of the compiler than the one the patches were for. They just didn't work. So I wrote the author of the patches, who seemed a little put out with me for asking so soon after the compiler was released. Feeling a little bad for not having given more to the online Rainbow community that had given me so much cool software, I resolved to create patches myself and post them.

To make a long story short, I failed. The code was too complicated in the new version for someone of my meager skills (at the time) to produce patches. The calls were all over the code, and the sequence of bytes that invoked INT 18h were in many places that turned out to be data.

Being young, and still struggling to make ends meet, I wasn't about to let this get in my way. I didn't want to have wasted that $80 on software I couldn't use and now couldn't return. Buying a new machine was out of the budget at the time. So I came up with a clever hack, which I'll describe now.

On the DEC Rainbow, INT 18 was used for video output. So when the compiler ran, it would call INT18, which would then dive into the BIOS with loco registers crashing the machine, or just not working. The trick turned out to be simple. I used a TSR to fake things out. The TSR would load at an address that could be known at run time. This TSR hooked into the MS-DOS interrupt vector which was used to set interrupt vectors and into the interrupt vector that was called when a progam terminated. I also hooked into the INT 18h interrupt vector to vector calls to it through my code. When a normal program would run, it would get the system's INT 18h call, and all the video would work. This let me run my editors, terminal emulators and games without rebooting. When Turbo C++ would run, it would install its own INT 18 handler to do its thing. My program intercepted this call and just saved the target for later use rather than writing it into low memory to give it effect. Later, when an INT 18 call happened, I'd check the calling address. If it was at or below my TSR or in the ROM BIOS, then I know it was something in the system making the call and I called the original INT 18 handler. If it was above my address, I knew it was boreland's compiler and would call the address it had tried to install earlier. When the turbo C++ terminated, I'd reset things to the initial state.

I did this trick almost 18 years ago now, yet it still strikes me as a clever way around a problem. The program took me an afternoon to write and debug, yet provided me with years of useful service until I retired the Rainbow...

20071212

Building a bootable ARM SD

A few weeks ago, I wrote up how to make a bootable i386 image. People have been asking me to extend it for my ARM platform.

Here are the instructions for a hypothetical box that has a boot loader that can load an image from a FAT partition of a SD card, and FreeBSD runs off of a ufs partition on the SD card. This will be for a big endian ARM target, based on the AVILA kernel. I'm also assuming that this platform doesn't use FreeBSD's normal /boot/loader.
  1. setenv MAKEOBJDIRPREFIX /blah
  2. setenv TARGET arm
  3. setenv TARGET_ARCH arm
  4. setenv TARGET_CPU xscale
  5. make buildworld
  6. make buildkernel KERNCONF=AVILA
  7. fdisk -I da0
  8. fdisk -f disk-partitions da1
  9. newfs -t msdos /dev/da0s1
  10. bsdlabel -w da0s2 auto
  11. newfs /dev/da0s2a
  12. mount /dev/da0s2a /mnt
  13. make installworld DESTDIR=/mnt
  14. make installkernel DESTDIR=/mnt KERNCONF=AVILA INSTALL_NODEBUG=t
  15. make distrib-dirs DESTDIR=/mnt
  16. make distribution DESTDIR=/mnt
  17. echo /dev/da0s2a / ufs rw 1 1 > /mnt/etc/fstab
  18. echo ifconfig_DEFAULT=DHCP > /mnt/etc/rc.conf
  19. echo hostname=demo >> /mnt/etc/rc.conf
  20. cp /mnt/boot/kernel/kernel /tmp
  21. umount /mnt
  22. mount -t msdos /dev/da0s1 /mnt
  23. cp /tmp/kernel /mnt
  24. umount /mnt
In step 8, one needs to have a special file. Here's what I use, but one needs to automate it a little more. Here's a hand-tuned one that I used for a 1GB SD card I had laying around.

# partition table
g c940 h32 s63
p 1 6 63 201537
p 2 165 201600 1780128

Clearly, one needs to tune the above for their specific part. NanoBSD tries to automate this process, but that is beyond the scope of this posting.

Update: fixed step 17.

20071211

Article about my past life

Wired has a great article about the high precision hobbyist timing community. These folks are less fanatical about timing than the professionals, but not by much. You know you are a true time geek when you understand the joke in Tom's quote from the article about his trip to a tall mountain near his home "It was the best extra 22 nanoseconds I've ever spent with the kids." Check it out here.

20071210

Cisco and Observations of a new Mac user.

Last week I started at Cisco. The entire week I tried to figure out how to drink from a fire hose without getting hurt. This week, I'll be learning where to go for help with fire hose related injuries. :-).

Seriously, I've joined a very dynamic and energetic group here at Cisco. The job so far has been a blast, and I'm really enjoying the work. We're at the early stages of many things in my group, so it would be a little premature to talk about them right now. since Cisco hires a lot of people, they have managed to optimize the typical new-hire HR madness enough that I was able to get something accomplished last week.

And I even found time to tweak the new MacBook Pro that showed up on my doorstep. This is the first employer provided laptop that I've had in at least 15 years. The last one was a Tadpole Sparcstation II class machine... I knew that Apple had done a great job on the GUI, but when I was able to setup printers and get onto my Samba shares without doing more than a few key clicks to accept automatically discovered items, I was hooked. On my Windows box that I keep around for the rest of the family, these two activities took me a couple of days of hacking to get barely working some of the time. OS X Leopard just works, and I have all the unix tools I know and love.

20071128

A quick thumbnail to cross debugging core files

This is just a quick thumbnail about how to take a core file from a FreeBSD/arm box and debug it on a FreeBSD/i386 box you cross compiled the FreeBSD/arm image on.

For normal gdb, one would just type:
  • gdb prog prog.core
and be done with it. However, without careful setup, this won't work when cross debugging. If you do the above, you'll get a number of warnings or errors from gdb when it tries to load the i386 libraries with the arm binary.

There is a simple trick, however, that gets around these problems. It can be used both when debugging cross architecture and when debugging different a core from one release on a newer/older release of FreeBSD. This example, I use 'gdb-arm' which is the debugger I use for cross debugging.
  • # gdb-arm
  • (gdb) set solib-absolute-prefix /path/to/built/image
  • (gdb) file prog
  • (gdb) core-file prog.core
  • (gdb)
By setting solib-absolute-prefix, you are instructing gdb to use that path as a prefix for all files it has to look up. So rather than /lib/libc.so.7, it will look in /path/to/built/image/lib/libc.so.7. Now that you have all the libraries that you need for debugging, you'll be able to track down the problems in no time.

This is just the barest of sketches for what to do. There are many other ways to make debugging easier in a cross debugging environment, and gdb can do more than just look at core files. But those topics will have to wait for another day. The curious are invited to read through the gdb info files. They are very complete, and well indexed by google or other search engines.

20071018

SDHC purchased

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

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

I'll keep everybody posted.

20071016

Building bootable FreeBSD/i386 images

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

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

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

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

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

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

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

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

Cross debugger

GDB Cross building on FreeBSD

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

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

Running the debugger

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

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

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

The cross-gdb port

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

20070929

FreeBSD/arm on a new SoC

Today I started work on porting FreeBSD/arm to a new SoC. I'm taking very detailed notes on this process, as well as attempting to learn from my atmel port how best to organize the port. I'll keep everybody posted and once I get far enough into it, I'll summarize the notes in a series of articles here. Hopefully this will help speed adoption of FreeBSD/arm on new hardware.

Speaking of new hardware, there's people working on a FreeBSD port to the NEO1973. Andrew Turner's email on the latest snapshot can be found here.

20070707

Merging *BSD's usbdevs

Once upon a time, all the BSD's got their USB stack from NetBSD. With it came a usbdevs file. This file has grown and mutated on the different BSDs for some time. The time has come to merge them all back together. This sounds simple in theory, but in practice it is a lot more complicated. Different BSDs use different names for some vendors and some devices. Sometimes one is more correct than the other. Other times, they are merely both wrong. Still other times the names are the same, but the descriptions of the device are different. There's about ~2k lines in each of the files, and the merged file is closer to ~3k lines long.

I can do basically whatever I want to the FreeBSD usbdevs file to make this happen. The tricky part is justifying all the changes to a skeptical audience for the other projects. The other tricky part in merging is making sure that nothing breaks. Of course the final tricky part is getting the leg work done and the files committed quickly enough that they do not become stale. That's going to likely be the hardest part of all.

20070623

USB update

I've finished much of the work on improving the in-tree USB stack, apart from adding device IDs. This is just the initial round. Now that all the cruft has been removed from the in-tree USB stack, we'll be able to support it better in RELENG_7. I plan on merging most of the client drivers into RELENG_6 after a couple of weeks, depending on how testing goes. So far, so good. I've added about 30 new devices. In fact, I've added so many that I've had no time to update the manual pages. If there are any doc people that can help synchronize the man pages to what we now support, that would be great.

After removing the obfuscating macros from the code, it is clear to me that adding some primitive locking to the USB stack might be possible now. It isn't going to happen for 7.0, however.

20070610

ooo builds!

After the shared library version bump, the xorg 7.2 transition and the new gcc compiler in the base, I started to rebuild everything. After some snafu deleted all my +CONTENTS files, I've finally managed to rebuild everything (I think). The last major thing was ooo. After my laptop would shut down for being too hot a dozen times, and having to play whack-a-mole to remove all the extra bogus junk that's accumulated in /tmp, I've finally been able to do a build.

The biggest lesson learned, apart from how fragile java can be on amd64, is that ooo itself takes 8G of disk to build. That's /usr/ports/editors/openoffice.org-2/work only, not counting the dozens of packages it depends on. I thought I was being insanely pessimistic when I installed /tmp with 10G and put my ports tree there. Now I see that I'm right up on the edge. I'll have to repartition my disk, or get a bigger one.

Now, if only kino worked on FreeBSD/amd64 and current. It isn't even compiling for me these days :-(.

20070609

Minor USB cleanup

I did a quick pass through the tree tonight eliminating all the devinfo stuff. This code had been implemented in uhub a while ago, but the client drivers were never updated to remove the bloat. We set the device name to usbd_get_devinfo in uhub, but then in the client drivers, we computed it again, and printed it, so the data would appear twice.

So far the only wrinkle is that kldunload/kldload doesn't set the description, but there are bigger problems there.

I hope to investigate a few of the bigger usb problems before 7.0 branches and get them fixed.

20070605

CardBus and USB minor improvements

I've started working on some minor improvements to CardBus and USB. I'd like to see each of them using filters. CardBus and PC Card necessarily share interrupts between the bridge and the client devices. There's only one interrupt pin. Having to schedule an ithread just to check on the status of the card (for eject events) or power (for the interrupt driven power-up sequence) imposes a large overhead on the system. In addition, it may interfere with CardBus drivers that use filter. The current ISR isn't written to be a filter (what used to be known as a fast interrupt), so some work is needed to migrate it to such an interrupt.

For USB the problem is different. There's no interrupt sharing inside of USB, per se, since all the work goes through the pci<->usb host controller. However, on many systems the designers cheaped out and forced usb and the network to share interrupts. Since usb is still Giant locked, this causes a lot of extra Giant contention. The idea hear is to introduce a filter that turns off the interrupt bits and requests that the ISR run. The ISR would be exactly like we have today, with the addition of code to turn the interrupt sources back on. The theory here is that network inspired interrupts don't have to take out Giant at all since usb can schedule its ithread only when there's real work to do. If the ithread isn't scheduled, then Giant isn't taken out.

Since the freeze is coming up soon, I need to get this done in the next two weeks.

20070525

Found cheap SDIO 802.11b card

At CompUSA today I found a cheap 802.11b SDIO card. This card is labeled as a Kodak Camera wireless card, but has a Marvell 8686 lurking under the hood. I've seen this card before, but it was $100. Today it was $20, which was cheap enough to take a flier on. This card should come in handy when I get around to implementing an SDIO stack for the SD/MMC stack that is in FreeBSD right now. I don't know if there's any information available for this card, and I've seen indications that there might not be, but at the very least I have a card that I can parse the CIS from and do other things in preparation. OpenBSD has a partially reverse engineered driver for a PCI cousin of this card that might have some clues, but I doubt I'll find anything useful for it.

But playing with this card will have to wait until I can get the simple memory cards working with the sdh driver, or the sdmmc stuff. I need to get the ZyDas ZD1211 driver going first.

I also found a TRENDnet wireless card based on the RTL8187B chipset. Linux driver, a couple of different ones, are available. But it uses some non-standard 802.11 code, so decoding it might be interesting. It is way down in the queue at the moment, since I have no documentation for it and no known working driver. At least with the ZD1211, I have two known working drivers from which to crib.

20070524

SD/MMC

There's another SD/MMC stack for FreeBSD that's been posted. It was written by Akihiko GOTANDA-san using the SD simplified specifications. It works well for the Ricoh based parts, but fails to attach to my TI based parts. It doesn't have the hacks necessary to put the TI parts into standards conforming mode either, but even with those added there are some problems. This driver was recently announced in the mobile@ mailing list.

This joins my SD/MMC stack that I wrote for the Atmel AT91RM9200 port. Andrea Bittau also has written a 'sdh' driver that plugs into my stack. It works with Ricoh parts, but not TI parts either, but it gets closer than Gotanda-san's driver. It was announced a while ago in the mobile@ mailing list.

And there was much interest in my SD/MMC card talk at BSDcan! I'm glad to see more interest here.

ZyDas usb stick update

After my last entry, I noticed that Linux, OpenBSD and hps' new stack all have ZyDas drivers, at least for the ZD1211 and ZD1211B. hps' zyd driver appears to be a relatively recent port to his new stack.

I have the OpenBSD one builing on FreeBSD's current USB stack. I still need it for other reasons, and a MFC of HPS' stack will never happen, so if we want to support it in 6.x, we'll need one for the old stack.

I get to the part where the driver tires to setup the MAC with the RF specific register values when I get a panic. I've not had the time to debug it further, but hope to find that time soon.

My experiences with BSDcan showed that I needed both USB and CardBus wireless working...

20070523

Ativa Wireless G Network Adapter

I stopped by Office Depot today to buy a wireless usb card. I wound up getting the rather generic sounding Ativa Wireless G USB network card. This turns out to be a rebadged Belkin F5D7050 v4000 wireless card. This has the ZyDas ZD1211 chipset in it. This is a fairly popular chipset to judge by ebay (where it is just about the only chipset advertised).

There's a Linux driver. Well, there are two. One that was basically binary only that was written by ZyDas, and another that was a rewrite by the community. I'll have to see if there's one for FreeBSD :-)

20070522

eHome Cardbus card

Looks like my run of luck with CardBus cards has reached an end.

I came home with an eHome card, but it is a Marvel part for which little documentation can be found on the web. Of course, if you have info on the 88W8310 part used in this CardBus card, please let me know. This is H/W REV A1, in case they have multiple versions of the EH101.

20070519

BSDcan 2007

I had an absolute blast at BSDcan 2007.

There's more buzz this year about embedding FreeBSD than there has been in prior years. I believe that we're building momentum in this space.

There were a number of cool talks about developments in FreeBSD, which you can see at the bsdcan web site.

My talk on SD/MMC cards was well recieved. The slides are available now. This contains an overview of the various flavors of SD/MMC card.

My talk on the Atmel AT91RM9200 slides are also available, as are my 2000 talk on NEWCARD as a paper or as MagicPoint slides, and the follow on paper on ISA vs PCI interrupt dispatch in the PC Card code I gave in 2002.

I've had a chance to also hack on the cardbus resource allocation code a bit while here. There's still something screwy going on with it, but I'm having trouble locating the oddness.

I had hoped to collect some of the older SD/MMC cards while at this conference. However, nobody had any cards that I was able to take with me. I did have a few of them that I was able to try out on my Atmel AT91RM9200 board and fix minor timing issues with the stack (the older ones are a little slower and needed slightly longer timeouts).

The best part is seeing everybody again from past years. It is good to see the community growing. It is also good to see many people form companies that have been designing in FreeBSD into their products for years. These companies have also started to fund the chances necessary for them to run FreeBSD in different embedded platforms (both i386 based, as well as powerpc and mips based hardware was talked about).

There's also been some buzz about creating a FreeBSD community summit to complement the FreeBSD developers summit. A place where developers, engineers from companies using the products and users could get together and discuss how to drive FreeBSD development as well as ways to facilitate integration of changes that companies have developed for FreeBSD that they desire to give back to the FreeBSD project.

It was also good to see developers from the sister BSD projects. Renewing the personal ties to the people in these sister projects is good for the BSD ecosystem, and we need to do more of them.

That's all for now. I hope to post links to videos from my talks shortly (or find some way to put them on you tube, if they are short enough).

see everybody next year!

All in all, a very exciting BSDcan.

20070513

FreeBSD SD/MMC stack talk

My talk for BSDCan 2007 on the FreeBSD SD/MMC stack is going nicely. The basics are done, and now I'm into the hard part of the talk: actually documenting the dataflow and interfaces between layers. This is the part of the talk that will be the call to arms: more work needs to be done to add support for all the latest SD/MMC goodies.

I'll post a pointer here once I've finished the talk to my slides with notes. Maybe people here can find any silly errors in them before the question and answer session of my talk brings them up. I'll also report on the status of the Standard SD Host Adapter driver that's been written, but not yet committed to current yet. The talk also gives a lot of background for these devices, and has a number of pointers to publicly available documents that thankfully nearly totally document all aspects of SD/MMC. The exceptions being mainly the DRM features of SD and the secure MMC extensions.

20070508

FreeBSD wireless picture frame

Tonight I finished a present for my wife. A wireless picture frame based on FreeBSD.

The frame is running on an old Sony VAIO PCG-505TS that I had from many years ago. Its battery is nearly shot, good only now for powering the BIOS battery. However, I put in a solid state disk and a subset of FreeBSD. It now displays pictures from a directory on our home network in rotation.

The hardest part turned out to be how to securely mount the laptop into the picture frame.

I'll describe the software that I used in the coming days. For now, just this little teaser.

20070425

Catching up

Things at my day job are finally starting to slow down a little, so I've been trying to catch up with a bunch of changes that I made at a breakneck pace over the past several months. These should be trickling into the FreeBSD tree over the next few days and weeks.

I've setup three different Atmel boards for testing this latest batch of changes. The first board is one that my company makes. The second is a Kwikbyte KB9202A (modified to have a 32kb iic eeprom, since I burned out the first one). The third is a new eval board that I'm going to try to get running FreeBSD/arm. It has uBoot on it, so will be a departure from what I've done in the past.

I've also setup my Gateworks boards finally, so I can get FreeBSD/arm on there for testing purposes.

I also have new hardware from Atmel that should be setup soon. As well as a cute little Atmel AT91Rm9200 based smart terminal that needs to find some time to get on my dance card.

I've managed to get the necessary infrastructure into place. I have a usb hub and a bunch of serial to usb dongles to create a makeshift terminal server. I'll be transitioning this to one of the atmel boards so I can at least put it to good use.

Anyway, now that it is looking like I'll have some more time I should be writing these more often as well.

20070305

FreeBSD ExpressCard Support

I was browsing the support for ExpressCard in Linux. I couldn't find any explicit support for it at all, not matter where I looked. I found usb support and pci express support, as well as hot plug versions of the latter. This puzzled me a bit, since I'd read that Linux supported ExpressCard cards. Maybe no special software support is required at all...

So, I thought I'd get a couple of ExpressCards and take them for a test spin. It turns out that FreeBSD versions back to 4.x that can boot on modern machines with ExpressCard slots will support one important class of cards (assuming the drivers are in the version of FreeBSD that you try).

The ExpressCard standard specifies two types of cards, from an electrical point of view (not to be confused with the two width form-factors offered: 34mm and 54mm). The first kind is card that contains a USB 2.0 device in it. In this configuration, the host bridge connects it up to power and a standard usb hub. The second kind of card is a single channel PCI Express card, used for applications where greater bandwidth is required between the CPU and the hardware on the card.

The USB versions just work. I plugged in a Delkin Devices eFilm ExpressCard that I was recently able to purchase due to the generosity of a someone who sent me money to buy toys with. This device supports SD, SDHC, MMC, MS, MSpro and xD cards. Since I also wanted to enhance the SD/MMC stack to support SDHC cards, I thought this would be a good choice (since the price was right) for me to test things out on.

The PCIe versions will need PCIe hot-plug support added to pcib (or a subclass). I've had trouble finding cards that are PCIe for sure, so if you know of one, please let me know. I'm guessing that the eSATA cards are a good choice for that, but confirmation would be great.

So the good news is: FreeBSD has supported at least some of the ExpressCard cards since before the ExpressCard standard was published.

20070303

Followup Atmel AT91 family work

After receiving an evaluation board from Atmel with an AT91SAM9260 onboard, I've started updating the Atmel support for FreeBSD in the p4 repository.

This chip is basically the same as the AT91RM9200, but with a few twists. First, it uses a ARM926EJS core rather than a ARM910T core. This means that it has an arm9e core in it (half way between an arm9 and an arm10 core). Fortunately, the NetBSD support for these CPUs was easy to port, and has been nearly a drop in (I'm sure I botched something it went so smoothly).

Next, there are three classes of devices on the AT91SAM926x parts that need addressing. The first class of parts are those that have FreeBSD drivers that utilize the AT91RM9200 errata to produce proper function. Many of these bugs in silicon have been fixed, so the kernel needs to cope in some manner. The MCI device is the most prominent here, as it needed to have byte swapping done in and outbound to be interoperable with other systems. There were structural changes that severely affected performance that will need to be ifdef'd for the old part. There are a number of other minor tweaks that may be necessary.

Next, we have those devices that were present in the RM9200, but have been augmented for the SAM9 series. These include enhanced support for SDIO cards in the MCI device, as well as a number of minor additions to the TWI, SPI and USART devices (or so my first reading would suggest... some are so minor that they could just be clearer documentation).

Finally, we have those devices that aren't present at all on the RM9200, but are in the SAM9 devices. There's an LCD controller and a cool image processing whatsit that fall into this category. The EMAC from the RM9200 has been removed, replaced by a newer 10/100 part that has more buffers for transmit, so the bottlenecks seen on the RM9200's network performance can be corrected. This will take a little time, but since the SD card boot should just work, or nearly should, the pressure to have this falls from 'critical' down to 'necessary for basic support.'

The eval board I received also has some neat audio hardware attached to the SSC bus (think McASP-like bus, if you are familiar with TI's DSPs). Back of the envelope calculations suggest that I could use this device as my 'audio server'. It is small enough to slip into the rack of audio/video gear I have upstairs and fast enough to play skipless audio. This is a ways off, but time will tell.

The devices are located at different addresses than the RM9200. Initially, I'll augment the hint structure we have to cope. It should be nearly complete as it is. Eventually, however, it might be nice to have 'super kernels' that can run on any member of the Atmel family of processors that FreeBSD supports. To do that, hints will need to have some way of selecting which subset to use.

The boot loader that I carefully optimized for the RM9200 is likely too big for the SAM9. There's 16kB of SRAM on the RM9200, 12kB of which is useful for the first stage of a loader. The SAM9 has only 4kB, but a much augmented boot ROM code that may be able to help. The bootspi boot loader is about 9k with all the bells and whistles, and could be chopped to about 5k w/o much effort. I'm unsure if I should do anything here, or just have the redboot that's on the board load the kernel (or a special boot2 that runs in SDRAM rather than SRAM).

I'm sure I'm missing some other issues that will come up during the port. But so far it has been an uneventful few hours. Time, alas, conspires against me. I find I have only a few hours here or there to work on it. Although I've been working on it for weeks, I have only put 3 hours of actual grunt time into the port...

20070203

General cleanups in the newbus area

From time to time I notice things, or others do, in newbus that need to be cleaned up. These things aren't all that hard to do, usually, but finding all the places that need to do them can be a daunting task.

So I'll just report a couple that I've noticed in the past couple days, along with one from Hans Petter Selasky.

Callers of device_get_children do not check the return value. It can only fail when memory is low and the allocation fails for the children. However, it should still be checked. Going through the tree and doing sane things when it does would take some doing. This is the problem that Hans found, and many places in his usb tree he just made sure that nothing bad happened, but there might be other things necessary in some cases.

Next, not busses free up their ivars. Some just need to have a simple free(ivar) call, while others need more complicated freeing. One pass would be to audit all busses to make sure they do the right thing. This is complicated by the fact that almost all network drivers are now bus drivers too because they add mii bus to the mix.

Perhaps an idea might be to combine these two issues. device_delete_child, which would delete all the children automatically. Busses could register a bus_child_about_to_be_deleted callback which could cleanup the ivars. The default should be to just free device_get_ivar of the child deleted. Coding this up shouldn't take long, but modifying busses to use this, as well as making sure it is sufficiently general might be a bit if a challenge.

I've also done some work in p4 to create an obio concept. In this concept, all the busses in things like SoC that need help with enumeration would derive from obio (or maybe just use obio routines) which should help cut down on the large amounts of duplicated code currently present in the system. OK, small amounts, but each done almost right, but with niggling little (or large) hacks that a more regular system would solve.

I'm sure other people can suggest improvements for other problems they have noticed. Leave comments if you've seen something specific in FreeBSD and I'll update this article, or do a followup, as necessary.