Monday 30 August 2010

Looking at a PC's option ROMs

An Option ROM is firmware called by the BIOS, for example the Video BIOS or a SCSI controller card. The BIOS Boot Specification requires that option ROMs are aligned to 2K boundaries and must begin with bytes 0x55 0xaa. After Power On Self Test (POST) the BIOS scans for option ROMs and if it finds a correct header executes the initialisation code at byte offset 0x3.

The Option ROM header is as follows:

Byte 0: 0x55
Byte 1: 0xaa
Byte 2: size of ROM in 512 byte pages
Byte 3: Option ROM entry point

To dump out the option ROMs, use the ree utility:

sudo apt-get install ree

..and run as follows:

sudo ree

..this will dump out all the option ROMs in the form: hexaddress.rom where hexaddress is the memory segment where the ROM is located. e.g. for my Video BIOS ROM, I get the file c0000.rom.

To disassemble this use ndisasm:

sudo apt-get install nasm

ndisasm -k 0,3 c0000.rom | less

..or just use strings on the ROM image to get an idea what the Option ROM is, e.g.

strings c0000.rom
000000000000
00IBM VGA Compatible BIOS.
PCIR
(00`
*@0p
H?@0b
..

..in this case it is a VGA BIOS, and this makes sense as VGA BIOS ROMs normally start from segment c0000. On my Lenovo laptop I observe that the ROM contains the string "DECOMPILATION OR DISASSEMBLY PROHIBITED" which spoils our fun in finding out what the ROM is doing...

Anyhow, ree + ndisasm are useful tools for poking around your PCs option ROMs on Linux.

Wednesday 11 August 2010

loop devices, device mapper and kpartx

Recently I copied a hard disk image onto a backup drive using dd and later on needed to mount the third partition from this image. Usually I figure out the partition offset and mount using mount -oloop,offset=xxxx but I just could not be bothered this time around to figure out the offsets especially as I have several partitions in the image. Instead, I used the following runes:

1. Associate a loop device with the drive image:

losetup --show --find image-of-drive.img

..the --show option prints out the name of the loop device being used. In my case it was /dev/loop0

2. Create a device mapper device associated with the loop device:

echo "0 `blockdev --getsize /dev/loop0` linear /dev/loop0 0" | dmsetup create sdX

..this will create /dev/mapper/sdX

3. Use kpartx to create device maps from the partition tables on the mapper device:

kpartx -a /dev/mapper/sdX

4. And lo and behold this creates device maps over the detected partition segments. You can then mount the partitions as usual, e.g. partition #3:

mount /dev/mapper/sdX3 /mnt

..I should really put this now into a bash script for next time I need this...

Monday 9 August 2010

Firmware Test Suite: BIOS+ACPI health check

The FirmWare Test Suite (fwts) is a tool I've been working on to do automatic testing of a PC's firmware. There can be a lot of subtle or vexing Linux Kernel/firmware issues caused when firmware is buggy, so it's useful to have a tool that can automatically check for common BIOS and ACPI errors. Where possible the tool will give some form of advice on how to fix issues or workaround firmware issues.

It's packaged up and in Maverick universe, you can install it using:

sudo apt-get install fwts

To see the tests available in the tool use:

fwts --show-tests

There are over 30 tests and I hope to expand this every time I find new firmware issues which can be diagnosed automatically in a tool.

To run a test use, for example the ACPI AML syntax checking test use:

sudo fwts syntaxcheck

There are categories of tests, for example, by default fwts will run batch mode tests which run without the need of user intervention. Some tests, such as checking the laptop lid works or hotkeys requires user intervention - these are interactive tests and can be invoked using:

sudo fwts --interactive

By default the tool will append the test results into a log file called results.log. This logs the date/time the test was run, the name of the test and the test results and hopefully some useful advice if a test fails.

I suggest checking out the manual page to see some examples how to fully drive this tool.

Quite a lot of the tests have been picked up from the core of linuxfirmwarekit.org, but I've added a bunch more tests, and expanded the types of errors it checks for and the feedback advice it reports. I've targeted fwts to run with the Maverick 2.6.35 kernel but it should work fine on Lucid kernels too. I've written fwts with command line driven test framework to run the tests mainly to allow fwts to easily plug into more powerful test frameworks.

If you want to run the tool from a bootable USB flash key, then one can download a i386 or amd64 image and dd it to a USB flash key.

For example:

wget http://kernel.ubuntu.com/~kernel-ppa/testing/maverick-desktop-i386-fwts.img
sudo dd if=maverick-desktop-i386-fwts.img of=/dev/sdX

where /dev/sdX is the block device of your USB flash key

then boot off this USB flash key and let it run the tests. At the end it will automatically shutdown the PC and you can then remove the key. The key has a FAT formatted partition containing the results of the test in a directory named: fwts/ddmmyyyy/hhmm/results.log, where ddmmyyyy are the digits in the date and hhmm for the time the test was started.

The fwts PPA can be found in the Firmware Testing Team project and the source code is available in a git repository here.

I've also written a short OpenOffice presentation on the tool which also may prove instructive.