Joe Pfeiffer -- pfeiffer@cs.nmsu.edu
I recently spent several weeks getting a Technologic Systems TS-5500 486-based single board computer to boot OpenEmbedded from a compact flash card. The following notes describe the sequence of operations that finally succeeded. Hopefully, they will be helpful to others trying to get openembedded running on other, similar SBCs.
Disclaimer: this information is the result of my own experience, and is released with the hope that it is useful. However, I make no warranty that it will also work on your system, and explicitly disclaim all liability for your results. Installing boot loaders is an inherently risky business; it's easy to imagine missing a step or mis-typing something resulting in corrupting the MBR on your workstation. That could turn into a Really Bad Day.
Note on device names:
On my workstation, the CF drive appears as/dev/sda
and its
first partition as /dev/sda1
. Everything I say here will
have to be modified to reflect your setup.
The most important changes will be to make sure the major and minor device numbers you set up in step 8 correspond to the actual CF card.
- /dev/sda and /dev/sda1:
$ mknod /dev/sda b 8 0
$ mknod /dev/sda1 b 8 1
- /dev/sdb and /dev/sdb1:
$ mknod /dev/sdb b 8 16
$ mknod /dev/sdb1 b 8 17
- /dev/sdc and /dev/sdc1:
$ mknod /dev/sdc b 8 32
$ mknod /dev/sdc1 b 8 33
- /dev/sdd and /dev/sdd1:
$ mknod /dev/sdd b 8 48
$ mknod /dev/sdd1 b 8 49
After that, of course, you need to subsitute the actual name of the device for /dev/sda and /dev/sda1 as appropriate.
New! I had a request for my CF image -- so I bzip2ed it, and here it is! You can put this on your CF card with the command
# bzcat cf.dd.bz2 | dd of=/dev/sda
(note: this is an image of a 512MB filesystem. If your CF card is
too small, you'll get an error saying dd: writing to `/dev/sda':
No space left on device
and grub won't be able to boot your machine)
Of course, this approach only installs exactly my image on your board. I suppose that's useful for making sure it all really works... If you're going to create your own image and install it, you'll need to go down to the next section.
Prerequisites: it is assumed that you've successfully installed openembedded, and have created a bootstrap-image for use with your SBC. Also, you'll need a CF adapter for your workstation.
On with the show:
Partition CF with
# cfdisk /dev/sda
I created a single partition, with FS type 83 (Linux), marked as bootable.
Copy openembedded bootable image to CF partition with
# zcat openembedded/tmp/deploy/images/bootstrap-image-ts5500-20070306233119.rootfs.ext2.gz > /dev/sda1
(of course, this will have to be modified to reflect the actual name
of the bootstrap-image you will be installing. The important thing
is that you will need to use the *.ext2.gz
image).
This may happen suspiciously quickly, for the reason to be
noted in the next step:
Important! Since /dev/sda1 is a block device, writes to it are cached.
# sync
This will take a while, as the writes from the last step actually take place now. note: the speed of these two steps seems to vary with the CF adapter used. At any rate, I've sometimes seen the zcat command finish in virtually no time while the sync takes several minutes, and I've seen it the other way around. Just do both!
Mount the CF partition containing the openembedded filesystem with
# mount /dev/sda1 /mnt
Note: the disk must not be mounted noexec
. in the procedure
being described here, it isn't necessary to have grub installed
on
your workstation to get it on the CF -- we'll use the version on
the CF itself. It would also be possible to install from the
workstation's disk with minimal changes.
Switch to execution from the CF. There is no bash
shell in the openembedded bootstrap image I built, so I had to specify the shell.
# chroot /mnt sh
You are now executing commands from a "chroot
jail"
(note the change in prompt)
Both Debian (the system I use on my workstation) and openembedded leave the files for grub in /usr/lib/grub/i386-pc/ but grub expects to find them in /boot/grub (I suppose it's to allow for people who have /boot on a separate partition). While it's possible to set it up from the former, life is much easier if we follow the installation instructions and copy the files we need.
$ mkdir /boot/grub $ cp /usr/lib/grub/i386-pc/stage1 /boot/grub $ cp /usr/lib/grub/i386-pc/e2fs_stage1_5 /boot/grub $ cp /usr/lib/grub/i386-pc/stage2 /boot/grub
Create a boot configuration file. Note: I'm sure I'm doing something wrong, but I can't get the vt100 emulation to work. I get invalid escape sequences (in particular, double-semicolons in the middle of cursor positioning). Consequently, I need to use the dumb terminal option to get things to work. Comments are in the file.
$ cat > /boot/grub/menu.lst # use the serial terminal for the console. The --unit is specifying # that it should use /dev/ttyS1, the speed is 115200 serial --unit=1 --speed=115200 # it's a dumb terminal. terminal --dumb serial # by default, boot menu entry 0. There's no timeout, so we'll sit at # the prompt until the user hits "enter" default 0 # start menu entry with title title openembedded GNU/linux # tell grub to find the kernel on /dev/hda1 root (hd0,0) # the kernel needs to use ttyS1, same speed as grub. Also, we need to # tell the kernel where to find its root filesystem. Note the # different syntax for specifying the console and specifying the root. kernel /boot/bzImage console=ttyS1,115200 root=/dev/hda1 EOT
In order to have access to the CF as a device, we need to create a special file for it on the CF itself. Note that the major and minor numbers must correspond to the major and minor numbers for the CFdisk on your workstation.
$ mknod /dev/sda b 8 0 $ mknod /dev/sda1 b 8 1
When you're all done, you can delete these if you want. I didn't bother.
Execute grub
$ grub
The following commands are executed from within grub (note the change in prompt)
Map grub's internal idea of the first hard drive to /dev/sda
. Now
it'll use /dev/sda
when installing the bootloader (but it'll still
go to the onboard IDE interface at boot time)
grub> device (hd0) /dev/sda
Grub should respond with
device (hd0) /dev/sda
Tell grub it'll be booting from the first partition on the drive.
grub> root (hd0,0)
Grub should respond with
root (hd0,0) Filesystem type is ext2fs, partition type 0x83
Now install the bootloader
grub> setup (hd0)
Grub should respond with
Checking if "/boot/grub/stage1" exists... yes Checking if "/boot/grub/stage2" exists... yes Checking if "/boot/grub/e2fs_stage1_5" exists... yes Running "embed /boot/grub/e2fs_stage1_5 (hd0)"... 17 sectors are embedded. succeeded Running "install /boot/grub/stage1 (hd0) (hd0)1+17 p (hd0,0)/boot/grub/stage2 /boot/grub/menu.lst"... succeeded Done.
Exit grub
grub> quit
On my system, grub segfaults at this point. I imagine this is something Somebody should look into... or maybe some helpful soul will show me something I'm doing wrong.
Get out of chroot
jail.
$ exit
Note the change in prompt
# umount /mnt
Next step is to make sure the SBC's BIOS is set up correctly.
It must be configured to boot from the CF drive (on the TS-5500
BIOS this is seen as drive C:), using AUTOCONFIG, LBA
.
I spent several days discoving this fact. My BIOS was initially
set up using AUTOCONFIG, PHYSICAL
(which I assume
to mean CHS); the
symptom was that when I tried to boot I saw GRUB GRUB
GRUB GRUB
repeated forever on my terminal emulator screen.