Powered by Squarespace

Updating the BIOS of a Thinkpad X220 using Linux

After spending a day trying to figure out various grub, syslinux and memdisk options, I retreated to googling and quickly found this page on the lenovo support forum.  I am going to copy the contents here to make sure I don't lose them in the future.  All props go to the original author:

1. Get the bios update iso (8duj10uc.iso here) from the lenovo support site.

2. Get 'geteltorito' and extract the boot image from the iso (isobar.c probably works too)

$ wget ''

$ perl 8duj10uc.iso > biosupdate.img

3. Copy the image to the usb thumdrive

$ sudo dd if=biosupdate.img of=/dev/usbthumdrive bs=512K

Here is a copy of the script for posterity:



use Getopt::Std;

# a bootimage extractor
# Script that will extract the first El Torito bootimage from a
# bootable CD image
# R. Krienke 08/2001
# License: GPL
# Get latest version from:
# Version 0.5
#    2009/06/22
#    A patch for harddisk emulation images from .
#    For BootMediaType=4 (harddisk emulation) SectorCount is always 1, and
#    returns just MBR. This patch guesses the correct bootimage size
#    from MBR (offset+size of the first partitition).
# Version 0.4
#    2007/02/01
#    A patch from Santiago Garcia  to use a virtual sector
#    size (vSecSize) of 512 bytes, as defined on "El Torito" specs and change
#    unpack of the sector count from n to v to get the correct sector count.
# Version 0.3
#    2006/02/21
#    A patch from  Ben Collins  to make the
#    utility work on PPC machines (change from 'L'-encoding in pack to 'V')
# Version 0.2
#    Several patches included from Nathan Stratton Treadway(
#    to adjust the platform output as well as fixes for other minor bugs
# Version 0.1
#    Initial release
# For information on El Torito see


# Read a particular sector from a file
# sector counting starts at 0, not 1
sub getSector{
   my ($secNum, $secCount, $file)=@_;
   my ($sec, $count);

   open(FILE, $file) || die "Cannot open \"$file\" \n";

   seek(FILE, $secNum*$secSize, 0);
   $count=read(FILE, $sec, $vSecSize*$secCount, 0) ;
   if( $count != $vSecSize*$secCount ){
       warn "Error reading from file \"$file\"\n";


# Write eltorito data into a file
sub writeOutputFile{

   open(OUT, ">".$name)|| die "$0: Cannot open outputfile \"$name\" for writing. Stop.";
   print OUT $value;

# Usage
sub usage{
        warn "\n$0 [-hv] [-o outputfilename] cd-image \n",
            "Script will try to extract an El Torito image from a \n",
            "bootable CD (or cd-image) given by  and write \n",
            "the data extracted to STDOUT or to a file.\n",
            "   -h:        This help. \n",
            "   -v:        Print version of script and exit.\n",
            "   -o : Write extracted data to file  instead of STDOUT.\n",
        exit 0;

# ---------------------------------------------------------------------

if( defined($opt_v) ){
        warn "Version: $utilVersion \n";
        exit 0;

if( defined($opt_h) || $#ARGV <0 ){

if( defined($opt_o) ){


if( ! -r $imageFile ){
        die "Cannot read image/device \"$imageFile\". Aborting\n";

# Read Sector 17 from CD which should contain a Boot Record Volume
# descriptor. This descriptor contains at its start the text ($isoIdent)
# CD001     and ($toritoSpec)
# see
# for details

$sector=getSector(17, 1, $imageFile );
($boot, $isoIdent, $version, $toritoSpec,
        $unUsed, $bootP)= unpack( "Ca5CA32A32V", $sector );

if( $isoIdent ne "CD001" || $toritoSpec ne "EL TORITO SPECIFICATION" ){
        die "This data image does not seem to be a bootable CD-image\n";

# Now fetch the sector of the booting catalog
$sector=getSector($bootP, 1, $imageFile );

print STDERR "Booting catalog starts at sector: $bootP \n";

# The first 32 bytes of this sector contains the validation entry for a
# boot. The first byte has to be 01, the next byte determines the
# architecture the image is designed for, where 00 is i86, 01 is PowerPC
# and 02 is Mac. More data give info about manufacturer, etc.  The
# final two bytes must contain 0x55 and 0xAA respectively (as
# defined by the El Torito standard).

$validateEntry=substr($sector, 0, 32);

($header, $platform, $unUsed, $manufact, $unUsed, $five, $aa)=
               unpack( "CCvA24vCC", $validateEntry);

if( $header != 1 || $five != 0x55 || $aa != 0xaa ){
        die "Invalid Validation Entry on image \n";

print STDERR "Manufacturer of CD: $manufact\n";
print STDERR "Image architecture: ";
print STDERR "x86" if( $platform == 0 );
print STDERR "PowerPC" if( $platform == 1 );
print STDERR "Mac" if( $platform == 2 );
print STDERR "unknown ($platform)" if( $platform > 2 );
print STDERR "\n";

# Now we examine the initial/defaultentry which follows the validate
# entry and has a size of 32 bytes.

$initialEntry=substr($sector, 32, 32);

($boot, $media, $loadSegment, $systemType, $unUsed,
       $sCount, $imgStart, $unUsed)=unpack( "CCvCCvVC", $initialEntry);

if( $boot != 0x88 ){
        die "Boot indicator in Initial/Default-Entry is not 0x88. CD is not bootable. \n";

print STDERR "Boot media type is: ";
if( $media == 0 ){
        print STDERR "no emulation";
if( $media == 1 ){
        print STDERR "1.2meg floppy";
if( $media == 2 ){
        print STDERR "1.44meg floppy";
if( $media == 3 ){
        print STDERR "2.88meg floppy";
if( $media == 4 ){
        print STDERR "harddisk";
        $MBR=getSector($imgStart, 1, $imageFile );
        $partition1=substr($MBR, 446, 16);
        ($unUsed, $firstSector, $partitionSize) = unpack( "A8VV", $partition1);
        $count=$firstSector + $partitionSize;
print STDERR "\n";

# Only use the internal sector counter if the real size is unknown
# ($count==0)

print STDERR "El Torito image starts at sector $imgStart and has $cnt sector(s) of $vSecSize Bytes\n";

# We are there:
# Now read the bootimage to stdout
$image=getSector($imgStart, $cnt, $imageFile);

if( length($outputFilename) ){
   writeOutputFile($outputFilename, $image);
   print STDERR "\nImage has been written to file \"$outputFilename\".\n";
   print "$image";
   print STDERR "Image has been written to stdout ....\n";

A Review of Grand River Rocks

I just got back from my first time climbing at Grand River Rocks, the new climbing gym in Kitchener-Waterloo.  This is going to be a short review from my first session, I'll post something longer once I get a better sense of the gym over the long term.  Tonight was also their first day open, so I'm not going to judge them entirely on my first experience.  Also, you should know that my regular gym is Climber's Rock in Burlington, however I've also climbed a little at the Guelph Grotto.

Grand River Rocks [GGR] seems good.  It is smaller than Climber's Rock, but the same or maybe bigger than Guelph Grotto (I'm not great at estimating the sizes.  Plus, as I am mostly a boulderer, I paid much more attention to the bouldering that the routes).  The bouldering is much better than at the Grotto.  The boulder walls, which fill the center of the gym, has a lot of angles and interesting shapes.  However as the walls are in the center of the gym, it feels a bit more cramped than Climber's Rock.   I found this especially true on the back side of the bouldering at the inside of the right angle of the L shaped feature.  How significant this is will totally depend on how crowded the gym gets.  It is all top-out bouldering which is nice.  The holds are currently very new and very rough, so expect to lose more skin that usual, I'm sure that will only take a few months to resolve.

Another difference between Climber's Rock and GRR is the the bouldering generally starts at a higher level.  Not that it is all hard, but Climber's Rock sets some easy intro problems for beginners.  We found that the lowest grade problem on the bouldering wall was definitely harder that the lowest grade at Climber's Rock.

The problems were generally interesting.  They seem to like low, sit down starts, which was ok for me, but caused some issues for some of my climbling companions.  I've been told that Climber's Rock sets some what easier that other gyms, however I was occasionally surprised at the choice of holds for some of the easier problems at GGR.  For example there was a "yellow" problem, which is their second easiest grade that was almost all two finger pockets.  That seemed a bit harsh for a relatively easy grade.

The route walls looked interesting, although I did not do any routes, so I'll save my opinion until later.  There was space for more routes, and it appears as though they did not have too many problems set that were sub 5.10, (which is what some of my friends are climbing).

I have a few constructive criticism for the GGR crew.  The tape colours for the bouldering problems are occasionally hard to differentiate.  Especially the orange/red and green/brown/black.  I would suggest getting brighter coloured tape as that would really help make them more distinguishable.  I also think this might make it easier to use ink on the tape to distinguish the holds for problems different problems of the same colour.  The floor had extra padding around the bouldering wall, however there were only two gym pads and one crash pad.  I really think they should have more pads.  Hopefully they are on order and simply have not arrived yet (the official grand opening is not until Sept 10).  The other thing that I would really like to know is if they are going to have a regular schedule for resetting the problems and routes.  At Climber's Rock they try to reset on section of the bouldering wall and a number of the routes each week.  This way you know when new problems will set.  I find this a really nice, and I hope GGR comes up with similar schedule (and posts it).  Regularly setting new problems is probably the biggest factor in deciding if I will buy a membership (note: I probably will).

In summary GGR seems to have most of the right pieces for it be a good local gym, the big question is how good their problems are going to be and how regularly they set new ones.  This is especially important as they don't have tons of bouldering, so it may not take too long to do all the problems at your level, and then be stuck with nothing to do.


Summer Food 2: BBQ Post mortem

Well, its the morning after.  If you saw my twitter stream, you'll know that things did not go as planned.  Instead of taking 4-6 hours to reach 190 degrees, it took about 10 hours to get to 180.  Ultimately the pulled pork tastes quite good, so that, at least was successful.  I also had problems getting the smoke generated properly.  I checked the smoke box after the cooking was over and I got less that half the wood smoldering. So my plan is to try and deduce what went wrong.  Of course I only have the one data point, so most of this is based on other experiences.

First, the smoke.  I think the smoke box did not start smoldering because I should have put it on earlier, when I was heating the barbecue, not once I had stabilied the temperature.  The fire was not high enough at that point to start the wood smoking.  If it was already smoking, I think it would have maintained generating the smoke, but it was too cold to start the fire.

Second.  The time.  The meat was still cold when it when on the bbq.  If you check the initial temperature when I put the meat on the bbq, it was still basically at fridge temperature in the center.  It took almost a full hour on the heat before the internal temperature was up to room temp.  Given that it only took an hour to get the internal temp to room temp, I'm not sure if that fully explains why it took basically twice the expected time to get to final temp.  Of course heat transfer is a complex process, so who knows.

Anyway, the recipe for the rub made more that I used for this experiment so I figure I should do another in a few weeks.

Another important note, running the bbq for 10 hours at lowest heat used about 1/4 of a tank of propane.

Here are photos of the meat, almost every hour (I missed a few).

Just starting 12 pm


1 pm.

2 pm.

3 pm.







12pm.  Post pulling.


Summer Food 2: Adventures in BBQ

As I write this I am a hour and thirty minutes into my first "proper" slow cooked bbq.  You can read the up to the minute goings on via my twitter feed.  However this longer post is going to be describing the tools I am using.

Meat, rub, mustard.  I am cooking a 4 lb pork butt roast.  A cut of shoulder meat.  Following the recipe here, I made a rub and then applied it by first applying a layer of mustard and then the rub.  This was yesterday at around 5pm.

Here is a run down of the tools I'm using.

My gymboss interval timer.  Usually this is used for, you know, exercise.  However the timer can go as high as 99 minutes, so I have has set it for 6 intervals of 60 minutes.  I've has also used this timer for grilling, 5 intervals of 2 minutes for cooking steak, and pork chops etc.

A grill thermometer.  I am using this to measure the temperature on the grill, as opposed to the temperature read by the thermometer integrated into the barbecue lid.  More accurate temperature monitoring means more accurate cooking.

This is my little smoke box.  You fill it full of wood chips.  The box is then placed in the bbq and heated until the wood starts to smolder.  This creates smoke that helps to flavour the meat.  Unfortunately, I messed this part up and did not heat the box high enough to get the wood smoldering.  So no smoke this time.  :(

The machine.  This is my Weber Genesis.  The cooking machine for today's little experiment.  1 burner on at lowest flame seems to maintain the internal temp at 225.

The meat as it just goes on, around 1pm.

The meat after the first hour.


Summer Food 1: Iced Tea

This summer I have been working on perfecting a recipe for iced tea.  It seems like it would be a pretty simple task, but there were a few things that need to be experimented with to balance the various flavours.  First, obviously is the tea.  How much?  Then the sweetener.  Sugar?  Honey?  How much?  Also this recipe is to make a cold tea, so steeping the tea in cold, not hot water.

Well, what I have learned in the first 5 or 6 attempts is the following: tea bags are inconsistent.  So the strength will vary quite a bit.  However my current mix is 4 tea bags to make around 2 litres of iced tea.  To help manage the variation in strength, I steep the four tea bags in 4 cups ( 1 litre ) of water in the fridge for 12 or more hours, once it has finished steeping I can add water to dilute to the appropriate strength.  There have been a few other issues with steeping tea bags this way.  Some tea bags float, even after soaking for hours.  This can keep them from steeping to full strength.  I have been trying to find a good way to weigh down the bags.

To sweeten I dissolve 1/4 cup of sugar in 1 cup of water and add that to the tea.  The easiest way to disolve the sugar is to mix the sugar and the water and then microwave for a minute.  This will make the sugar dissolve easily.  You can also do this with honey, although I prefer the cleaner taste of sugar.

As for teas, I've tried a couple types, a black and a couple of jasmine.  I'm mostly trying to use various teas that we had lying around, instead of buying teas specifically for making iced tea.

What I would like to do is start using loose leaf tea instead of tea bags.  That way I can measure the tea by weight, and hopefully get a more consistent strength.

So in summary:

  1. 4 tea bags steep overnight in 4 cups of water (in the fridge).  Try to make sure the bag sink.
  2. dissolve 1/4 cup of sugar in 1 cup of water and then add to the 4 cups of tea
  3. mix well and taste.  Add additional water as necessary.
  4. serve over ice.

I really want to start on some more interesting mixtures, but I need to nail down a consistent base recipe first.