iPAQ h2200 series installation
The h2200 series needs LAB to boot linux.

LAB stands for Linux As Bootloader. Its job is to load and execute kernels. The benefit of LAB is that we can leverage the power of Linux to make a more powerful bootloader than the stock bootloader. On h2200 we use it to boot from MMC/SD, CF, NFS, or even NFS-over-PPP-over-Bluetooth (if you really want to), plus erase and write to internal flash, copy files to filesystems over serial (like fixing a broken kernel), or download and boot a new kernel over serial.
The h2200 actually has three bootloaders:
- The 1st-stage bootloader: On power-up/reset, the first 16K of internal NAND flash (referred to here as the 1st-stage bootloader) is loaded and executed. It minimally initializes the iPAQ, and then loads either of the other two bootloaders depending on what buttons are pressed, or whether the 2nd-stage bootloader passes validity checks.
- The 2nd-stage bootloader: The 1st-stage bootloader loads 1.25M from flash and executes it. On a stock h2200, this code loads and starts PocketPC.
- The rescue bootloader: If Contacts-Power-Reset is pressed when the 1st-stage bootloader starts, it loads and executes the rescue bootloader (112K). The rescue bootloader can save and restore the contents of internal flash to and from CF.
To run Linux from flash instead of PocketPC, we merely replace the 2nd-stage bootloader with our own. It is possible to replace it with a zImage (as long as the zImage sets r1 to the proper machine type for h2200).
Notethat
as long as we don't touch the 1st-stage or rescue bootloaders, there is virtually no risk of bricking the iPAQ, as we can always restore Linux or PocketPC from a CF card. This page explains how to replace the stock 2nd-stage bootloader with LAB.
Step 1: Back up PocketPC and the 2nd-stage bootloader
First let's make a backup.
- Back up all your PocketPC data using iPAQ Backup.
- Insert a CF card (> 32M) that you don't mind erasing. The rescue bootloader overwrites whatever is on the card, including any partition table and filesystems.
- Hook up a serial or USB cable. You'll use this to talk to the rescue bootloader using a terminal program like tip, minicom, or HyperTerminal.
- Press Contacts-Power-Reset to get into the rescue bootloader. The iPAQ's screen should display some text, and your terminal program should display something like:
Manufacture Code=EC Device Code=75 SAMSUNG K9F5608U0A 32M NAND flash Memory found dwROMTotalSize = 2000000 wTotalChip = 1 HTC Integrated Re-Flash Utility for bootloader Version:1.18d GreatWall PVT ver 1.08 MainBoardID = 4 Built at: Mar 16 2003 11:05:12 Copyright (c) 1998-2002 High Tech Computer Corporation Turbo Mode Frequency = 398 MHz Run Mode Frequency = 398 MHz Memory Frequency = 100 MHz SDRAM Frequency = 100 MHz Main=0x90036118 awID[0]= 90 awID[1]= 90 SanDisk SDCFB-32 HAD 2.13 Model number : SanDisk SDCFB-32 Firware revision : HAD 2.13 Max Cylinder : 490, Max Head : 4, Max Sector : 32, Total space : 31360 KB Skip address transfer error: g_dwSkipLen=0 SER>
- Back up PocketPC by typing the following at the SER> or USB> prompt (the password is CPQHAMMER):
d2s
This takes a few minutes. Then store this CF card away, or dd the first 33M somewhere safe; I've copied mine onto my hard disk. If you have a card reader on a linux system and the CF card is /dev/hda, insert the CF card into your card reader and do this:dd if=/dev/hda of=pocketpc.rescue bs=1M count=33
- Back up the 2nd-stage bootloader by typing
d2s 28000 140000
Note that this overwrites whatever was on the CF card before, including what was written in step 5! So either insert another CF card, or copy the contents of the card as described in the previous step before doing this step. Then back up the first 1.25M of the CF card; if your CF card on your linux host is /dev/hda, insert the CF card into your card reader and do this:dd if=/dev/hda of=2ndstage.rescue bs=1K count=1280
Step 2: Replace PocketPC 2nd-stage bootloader with LAB
Now we'll replace the 2nd-stage bootloader with LAB. We can do this using the rescue bootloader or from linux. We'll use the rescue bootloader. Assuming that you have a card reader on /dev/hda in your host linux system (not the iPAQ):
- Get a LAB bootloader from here. Note that this file is not a plain zImage; it must have the HTC header, or the rescue bootloader will not recognize it.
- Insert a CF card in the card reader and copy the LAB 2nd-stage bootloader to the card:
dd if=zImage-LAB-20060222.htc of=/dev/hda
- Insert the CF card in the h2200 and enter the rescue bootloader by pressing Contacts-Power-Reset. It should scan the CF card and prompt you on the iPAQ's screen to "Press Power to flash". Note that on some large CF cards the scan can take a while.
- Press the iPAQ's power button. The rescue bootloader will copy the LAB from CF to flash and verify the checksum. A failed checksum is not necessarily bad; it may just mean that the correct checksum was not put in the header. This step should take 15-20 seconds.
- Reset the iPAQ. LAB should boot, showing its splash screen. If you're connected to the serial console, you should see LAB kernel messages as it boots, and then a command prompt. You may press a key to interrupt autobooting the target kernel.
When LAB autoboots, it looks for the file
/boot/labrunon the following devices in this order:
/dev/mmcblk0p1 ext2 /dev/mmcblk0p2 ext2 /dev/mmcblk0p3 ext2 /dev/mmcblk0p4 ext2 /dev/hda1 ext2 /dev/hda2 ext2 /dev/hda3 ext2 /dev/hda4 ext2 /dev/hda5 ext2 /dev/hda6 ext2 /dev/hda7 ext2 /dev/mtdblock3 jffs2
The rootfs must have a
/boot/labrun
file that loads the appropriate zImage and boots it with the right cmdline arguments. Here are some examples:
- rootfs on MMC/SD:
copy fs:/mnt/boot/zImage fs:/zImage umount /mnt armboot fs:/zImage "root=/dev/mmcblk0p1"
- rootfs on CF:
copy fs:/mnt/boot/zImage fs:/zImage umount /mnt armboot fs:/zImage "root=/dev/hda1 rootdelay=5"
- jffs2 rootfs on internal flash
copy fs:/mnt/boot/zImage fs:/zImage umount /mnt armboot fs:/zImage "rootfstype=jffs2 root=/dev/mtdblock3"
Add
console=ttyS0,115200n8to make the kernel use a serial console. Note that if /boot/zImage is symlinked, it must be a relative symlink; e.g. it must be symlinked to something like zImage-2.6.13-hh1-20060104, not /boot/zImage-2.6.13-hh1-20060104. For example:
# cd /mnt/boot # ls -l -rw-r--r-- 1 mreimer mreimer 856552 Jan 5 17:21 zImage-2.6.13-hh1+cvs20051221 # ln -s zImage-2.6.13-hh1+cvs20051221 zImage # ls -l /mnt/boot lrwxr-xr-x 1 mreimer mreimer 35 Jan 19 19:08 zImage -> zImage-2.6.13-hh1+cvs20051221 -rw-r--r-- 1 mreimer mreimer 856552 Jan 5 17:21 zImage-2.6.13-hh1+cvs20051221Note that previous versions of LAB just looked for /boot/zImage, so if you're upgrading from an older version of LAB, you'll need to create an appropriate /boot/labrun.
Step 3 (optional): Using internal flash for your rootfs
You can use the h2200's internal flash for your rootfs. Note that as long as you do not mistype/dev/mtd3or
erasemtd 3below, there is virtually no risk of bricking your h2200. First back up PocketPC as described above, download a jffs2 image, and then use one of the following methods:
Method 1: Flash a rootfs to internal flash using LAB (serial cable required)
- Copy the jffs2 rootfs image to a CF or MMC/SD card
- Boot into LAB.
- Mount the CF or MMC/SD card:
mount /dev/hda1 /mnt ext2 (for CF) mount /dev/mmcblk0p1 /mnt ext2 (for MMC/SD)
- Erase the internal flash:
erasemtd 3
- Write the rootfs to flash:
copy fs:/mnt/gpe-image.jffs2 nand:jffs2:3
- Unmount the card:
umount /mnt
- Reset your iPAQ and if your rootfs contains a proper /boot/labrun, it should load the kernel from the rootfs and boot it.
- If you use the GPE jffs2 package mentioned above, you can boot linux by typing the following into the lab boot prompt:
mount /dev/mtdblock3 /mnt copy fs:/mnt/boot/zImage-2.6.15-hh0 fs:/zImage umount /mnt armboot fs:/zImage "rootfstype=jffs2 root=/dev/mtdblock3 console=ttyS0,115200n8"
Method 2: Flash a rootfs to internal flash from linux
Boot linux on your iPAQ and do the following:modprobe mtdchar flash_eraseall -j /dev/mtd3 nandwrite /dev/mtd3 gpe-image.jffs2To make sure flashing was successful:
mount -t jffs2 /dev/mtdblock3 /mnt ls /mntWhen LAB boots, it will automatically look for
/boot/labrunand boot it. See above for examples of labrun files or take the one below if you use the GPE image:
copy fs:/mnt/boot/zImage-2.6.15-hh0 fs:/zImage umount /mnt armboot fs:/zImage "rootfstype=jffs2 root=/dev/mtdblock3 console=ttyS0,115200n8"Notes:
- Older rootfs images might not include mtd-utils, so you may have to install this yourself. You can download the ipk, put it somewhere linux can see it, and install it with
ipkg install /path/to/mtd-utils.ipk
- The first boot on a fresh rootfs can take a few minutes (5-10 minutes) while it does initial configuration.
- LAB first tries to boot from MMC/SD, then CF, then internal flash. So to boot from internal flash you may need to remove the CF or MMC/SD card if it has a rootfs + kernel.
Future LAB features
- Teach LAB to respond to button presses. Then we could do things like "Press Contacts to boot Linux from SD, Calendar to boot from CF" etc.
- LAB scripts: we could use LAB to install familiar/GPE/Opie, boot from various media, etc.
- Teach LAB to scan filesystems for zImages and present the user with a menu of options.

