Flashrom, Alix 1.C and FreeBSD

I’m quite surprised that flashrom works pretty much out of the box on FreeBSD running on my Alix 1.C board. All I needed to do was comment out the code in the enable_flash_cs5536() function part of the chipset_enable.c file. Then, this simple command let me read out the BIOS image:

$ flashrom -f -r -c "SST49LF040" bios.bin

Avnet Spartan-3A Eval Board

So I got this Xilinx Spartan-3A Board by Avnet recently. I bought it because it features a fairly large parallel flash chip (32 MBit) and an even larger SPI flash (128 Mbit).

The board also features three clocks. One 16MHz clock is driven by an on-board oscillator while the other two (12 MHz and 32 kHz) are derived from a small controller.

For the last few evenings, I tried to get the parallel flash to work. Since a single cycle of the slow 32 kHz clock meets the timing requirements of the parallel flash chip, I thought I’d try to use that before enhancing the design to also work w/ the faster clock(s).

Unfortunately, that didn’t work. When using the slow clock, mapping a signal directly to an output (LED) worked just fine, but routing the signal through more than few flip-flops didn’t work at all. Apparently, the FPGA didn’t like the slow clock too much.

Bottom line: Took me three days to figure out that the board doesn’t work with the slow 32 kHz clock. Oh well, at least I learned something new…

SSH Tricks

My shell scripting skills suck. So it comes naturally that I learn a lot every time I need to write a script. The trick I’m about to describe is so neat that I want to share it.

Assume for a second that you need to execute a series of commands on a remote machine, but you can’t pass them to SSH at once. Or consider that you might need to transfer a file over to a remote host and then extract it there. Normally, you’d need to create several SSH connections for this. In the “transfer, then extract” scenario, you need one connection for scp(1) and another one to extract the file on the remote host. Unless you have your public key in the remote host’s ~/.ssh/authorized_keys file, you need to enter your password for the remote host twice. It’s probably not a big deal for most, but it’s annoying at times.

It might be obvious for some, but I recently found out that ssh(1) offers a solution for the problem described above. It allows you to open one connection in "master" mode to which other SSH processes can connect through a socket. The options for the "master" connection are:

$ ssh -M -S /path/to/socket user@rhost

Alternatively, the ControlPath and ControlMaster options can be set in the appropriate SSH configuration files. Other SSH processes that want to connect to the "master" connection only need to use the -S option. The authentication of the "master" connection will be re-used for all other connections that go through the socket. I’m not sure if SSH even opens a separate TCP connection.

Going further, this can be used in scripts to save the user a lot of password typing, especially if the execution flow switches between local and remote commands a lot. At the beginning of the script, simply create a &qout;master" connection like this:

$ ssh -M -S /path/to/socket -f user@rhost 
    "while true ; do sleep 3600 ; done"

It should be noted that the path to the socket can be made unique by using a combination of the placeholders %l, %h, %p, %r for the local host, remote host, port and remote username, respectively. The -f parameter makes SSH go into the background just before command execution. However, it requires that a command is specified, hence an endless loop of sleep(1) calls is added to the command line. Other SSH connections can be opened like this, not requiring any further user input (for authentication):

$ ssh -S /path/to/socket user@rhost

This leaves the problem of how the "master" process can be terminated when the script has finished. Some versions of SSH offer the -O parameter which can be used to check if the "master" is still running and, more importantly, to tell the "master" to exit. Note that in addition to the socket, the remote user and host need to be specified.

$ ssh -S /path/to/socket -O check user@rhost
$ ssh -S /path/to/socket -O exit user@rhost

However, there are still two problems to be solved. First, when the "master" quits, the dummy sleep loop continues to run. And second, how can the "master" be terminated if the given SSH version doesn’t offer the -O parameter (short of killing the process by its PID)?

hexdump(1) lies!

This week I found out that hexdump(1) on Linux doesn’t seem to work with bytes but with half-words. I found out because I compared a byte-by-byte binary dump (output of a separate program) to the output of hexdump(1) (dumping the same data) and noticed that hexdump(1)‘s output always swapped two adjacent bytes.

Maybe I haven’t found the right parameters, though.

An Encrypted File-backed File System on FreeBSD

The following is a compilation of information, largely based on the FreeBSD Handbook, Section 18.13 and Section 18.16. This post describes how a file-backed, encrypted file system can be built and used on FreeBSD.

Prerequisites

In order to follow the steps below, the following prerequisites must be met:

  • md(4) in the Kernel
  • gbde(4) in the Kernel, i.e. kldload geom_bde
  • The /etc/gbde directory must exist

First time installation

After those requirements are fullfilled, it’s time to take the first step which is creating a file that will serve as the basis for the file system. There is no support for growing images so you need to allocate all space now. This command creates a 128 MByte file filled with zeros:

$ dd if=/dev/zero of=encrypted.img bs=4k count=32768

Next, create a memory disk which is based on the the image file created above. As root, do:

# mdconfig -a -t vnode -f encrypted.img -u <unit>

In the example above, the parametr -u <unit> is optional and specifies a number which determines the number of the md(4) device. For example, if you use 4, then md4 will be created.

Now create a partition table which, e.g. one with an automatic layout:

# bsdlabel -w md<unit> auto

At this point, you have the equivalent of a hard disk w/ one or more FreeBSD partitions on it. Note that there is no filesystem, yet. In order to create an encrypted file system, an initialization step must be performed:

# gbde init /dev/md0c -i -L /etc/gbde/encrypted.lock

The initialization step opens an editor where the user is asked to enter a few parameters. Most notably it is probably sensible to change the sector_size to 4096, i.e. the page size on i386. When the editor is closed, the gbde(8) program asks for a password. This password will be used to encrypt the disk, so do not lose it. Note that the /dev/md0c parameter corresponds to the md(4) device which was previously created. The file of the lock name can be arbitrarily named as long as its ending is .lock. Also note that the lock file must be backed up as the file system cannot be easily accessed without the file.

Now the encrypted device can be attached by running

# gbde attach /dev/md0c -l /etc/gbde/encrypted.lock

You’ll be prompted for the password set in the previous step. If the password is accepted, you’ll end up with a new disk device at /dev/md0c.bde on which you can operate the same way as on a regular disk. That means you’ll need to create a file system, first.

# newfs -U -O2 /dev/md0c.bde

Make sure you use the .bde device node and not the raw memory disk as you’d end up without encryption. When you’re done, it’s time to mount the file system:

# mkdir /encrypted
# mount /dev/md0c.bde /encrypted

Unmounting the encrypted file system

Unmounting the file system is easy, but the gbde(4) device needs to be detached before the md(4) device can be destroyed.

# umount /encrypted
# gbde detach /dev/md0c
# mdconfig -d -u 0

Re-mounting an encrypted file system

Re-mounting is simple, but note that the FreeBSD handbook suggests that the file system be checked for errors before mounting:

# mdconfig -a -t vnode -f encrypted.img
md0
# gbde attach /dev/md0c -l /etc/gbde/encrypted.lock
# fsck -p -t ffs /dev/md0c.bde
# mount /dev/md0c.bde encrypted

Generating random passwords

Here are a couple of ways of generating random passwords without using a “password generator”. First, generate a random string like this:

$ dd if=/dev/urandom count=500 bs=1 | tr "n" " " | sed 's/[^a-zA-Z0-9]//g'

or like this

$ dd if=/dev/urandom count=500 bs=1 | md5

Then adjust the length by piping the output through cut(1):

... | cut -c-8

While the first option is more to type, it generates lower and upper case letters. The second option is easier to type but only generates lower-case passwords.

Update (Dec 12th, 2008): Fixed error. cut(1) must be used, not cat(1).

The new GenFw Tool

I’ve re-written the GenFw tool part of the TianoCore BaseTools project. The source code can be found here. In order to use the tool, the file Source/C/GenFw/GenFw.c must be replaced with the re-written one. Then, the base tools must be re-built. After that, the EDK2 build process can be started. It will automatically pick up the new tool which will brand an ELF file with an UEFI file type.

Currently, the re-written tool will not compile on Linux. The reason is that Linux lacks implementations of err(3), errx(3), warn(3), etc. library functions which the BSDs have. It should be easy to add some compatibility macros using a combination of fprintf(3), strerror(3) and exit(3). I might add those should the need arise.

Update (Dec 3rd, 2008): I’ve added the compatibility macros for Linux. An updated version of the source code can be downloaded here.

More on TianoCore for coreboot

It’s been a while since I last worked on combining TianoCore and coreboot. Tonight I had some spare time and tried to pursue the project.

The previously mentioned build failure does indeed stem from the fact that the build tools cannot cope with ELF binaries. Especially problematic is the GenFw tool which is supposed to convert the binary file into an UEFI firmware volume file. In order to do that, it parses the header information of the input binary executable file and encodes the type of file (in UEFI terms) in a spare header field. The tool expects to work on PE32 files but the TianoCore developers have added code which converts an ELF image into a PE32 image internally if the tool is pointed at an ELF file. However, this facility is only compiled in if #defined(Linux) is true. Of course, that won’t work on FreeBSD but changing the relevant pre-processor condition allowed me to produce an UEFI firmware volume without any further changes to the code.

However, this shortcut will only work on x86 and only if the target platform is x86, too. The real solution is to avoid the conversion and instead encode the UEFI file type directly into the ELF header. I’ve already done this for my thesis project (*) and back then it seemed that re-writing the GenFw tool was easier than fixing the existing implementation. Well, here’s the next item on the ToDo list…

(*) I used the Java-based tools for the thesis project which means that a different tool with essentially the same functionality was the culprit.