Bochs is a free software simulator for PC compatibles available from http://bochs.sourceforge.net. This page captures the instructions and setup information for Bochs and RTEMS.
TBD: Using Bochs Network Driver with RTEMS TBD: MicroWindows under Bochs
I used an old Grub floppy image from the 4.5.0 release series. It was obtained by using dd_ to read the raw contents of a 1.44 megabyte floppy disk.
Hard Disk Image
Setting up a new Image
Anthony Richards was nice enough to post the following instructions to the RTEMS Users mailing list on how to create a file that is a hard disk image for use from Bochs. See http://www.rtems.com/ml/rtems-users/2004/october/msg00064.html for the original post.
The following instructions describe how to make a disk image of arbitrary size. For the 10 megabyte example given, the corresponding bochs lines are:
ata0: enabled=1, ioaddr1=0x1f0, ioaddr2=0x3f0, irq=14 ata0-master: type=disk, path="harddisk.img", cylinders=20, heads=16, spt=63, translation=auto, biosdetect=auto, model="Generic 1234"
Hard disks have a particular logical geometry that is specified in terms of cylinders/head/sectors or CHS. Visualize a stack of CD-ROM disks all turning on a common spindle. The number of CD-ROM disks would correspond to the number of heads in a hard disk drive. Each CD-ROM has a certain number of tracks (or cylinders) and each track has a certain number of disk sectors. On a hard disk a sector is 512 bytes. We can figure out the total disk capacity (in bytes) from: CHS512. The maximum allow value for H is 255 and that for S is 63. The maximum allowed value of C is 1024. The largest allowable hard disk size is therefore 102425563512 or about 8.4 GB. (Note: Newer PC BIOSes use a different geometry scheme know as LBA that allows for much larger drives, but for a long time PCs could get by using CHS addressing because no one could dream of drives ever exceeding the 8.4 GB size limit. I'm not sure if Bochs and/or FreeDOS support LBA, but that doesn't really matter to us. We will normally work with 10 MB hard disk images, not GB disk images.) Assuming S=63 and H=16, we can figure out how many cylinder we need for a 10 MB drive: C = (10x1024x1024)/(63x16x512) = 20.317. We need an integer value for C so a value of C = 20 will give us about a 10 MB hard disk image. Create the image as follows (CHS </tt> 201663 = 20160):
dd if=/dev/zero of=harddisk.img bs=512 count=20160
Formatting the Hard Disk Image using FreeDOS
Unfortunately, there is not an mtools utility for partitioning a hard disk image and writing a boot manager to the MBR. We will need to use FreeDOS for that. So change the bochsrc.txt file so that harddisk.img is now the AT0 slave drive. (You still need the AT0 master drive because it contains the FreeDOS operating system.) Boot FreeDOS, use fdisk to create a single primary partition on the new disk drive (make sure you are partitioning the new slave drive and not the original master drive). fdisk writes a boot loader and partition table to the MBR of the drive. You will probably need to reboot FreeDOS after running fdisk, do so, and then use format to format the new partition (it should be the D: partition.) (All of this seems complicated, but I wish adding a new disk drive to a real PC were this easy.) Now create files and/or directories on your new D: partition.
Configure mtools to access the new partition. Since the partition is already formatted, just mtsetup harddisk.img should do it. Verify that you can copy files to/from the partition using the mtools utilities. Note: The partition is configured as the mtools C: drive, while under FreeDOS it is the D: drive.
Formatting the Hard Disk Image using Linux
Now we attach the hard disk image file harddisk.img to a loopback device. This lets us treat the file as though it were a physical disk.
Note: Under a normal Linux setup you will need to be root to use the losetup command (The same applies to most commands we'll be using).
#losetup /dev/loop0 /path/to/harddisk.img
Now to create the MBR and partition table on the disk image (Usually you need to be root).
#fdisk -u -C20 -S63 -H16 /dev/loop0
Within fdisk use the following commands:
o - Create a new empty DOS partition table.
n - Create a new partition (For simplicity just make 1 primary partition covering the whole disk).
a - Toggle the bootable flag.
t - change a partition's system id to b = FAT32 (not LBA)
p - Print the partition table.
You should end up with a screen that looks something like this:
Disk /dev/loop0: 10 MB, 10321920 bytes 16 heads, 63 sectors/track, 20 cylinders, total 20160 sectors Units <tt> sectors of 1 * 512 </tt> 512 bytes Device Boot Start End Blocks Id System /dev/loop0p1 * 63 20159 10048+ 6 W95 FAT32
w - Write partition table to our 'disk' and exit.
Please note the number of blocks is 10048. We need it later.
Now, remember to detach the disk image from the loopback device before formatting the Hard Disk image.
#losetup -d /dev/loop0
Ok, now we attach the file to the loopback device again, but in such a way that we skip everything before the start of our partition. Since each sector is 512 bytes long we therefore know the starting byte of the partition is 32256 (63*512) bytes into the file.
#losetup -o32256 /dev/loop0 /path/to/harddisk.img
We now have a device (/dev/loop0) which we can use in a similar fashion to a normal one for a partition (eg /dev/hda1).
To format a FAT32 DOS filesystem use (now we need the number of blocks from above):
#mkdosfs -F32 /dev/loop0 10048
Remember to detach the disk image from the loopback device again.
#losetup -d /dev/loop0
Now mount the hard disk image on the loopback device. This enables us to copy file the the newly create filesystem.
#mount -t vfat -oloop<tt>/dev/loop0,offset</tt>32256 /path/to/harddisk.img /mnt/wherever
Create a directory for the grub boot loader files:
Now copy the following three files from your grub installation stage1, fatstage15 and stage2 to the hard disk image.
#cd /boot/grub && cp stage1 fat''stage1''5 stage2 /mnt/wherever/boot/grub
Then create a menu.lst file in /mnt/wherever/boot/grub containing the kernels you are going to boot. An example menu.lst could be:
color cyan/blue white/blue title= Hello World Test kernel= (hd0,0)/hello.exe
All we need now is to install grub in the MBR for the hard disk image. This is done by booting a grub floppy image in bochs. The boot floppy image is create by concatenating the grub boot stage image files into one floppy image:
#cat stage1 stage2 > grubboot.img
and add the following to your .bochsrc:
boot: floppy floppya: 1_44<tt>/path/to/grubboot.img , status</tt>inserted
Make sure you also have the newly created hard disk image in your .bochsrc as well:
ata0: enabled<tt>1, ioaddr1</tt>0x1f0, ioaddr2<tt>0x3f0, irq</tt>14 ata0-master: type<tt>disk, path</tt>"harddisk.img", cylinders<tt>20, heads</tt>16, spt<tt>63, translation</tt>auto, biosdetect<tt>auto, model</tt>"Generic 1234"
Now boot into the grub menu and do the following two commands:
grub> root (hd0,0) grub> setup (hd0)
The result should look something like this:
GNU GRUB version 0.93 (639K lower / 7168K upper memory) [ Minimal BASH-like line editing is supported. For the first word, TAB lists possible command completions. Anywhere else TAB lists the possible completions of a device/filename. ] grub> root (hd0,0) Filesystem type is fat, partition type 0xb grub> setup (hd0) Checking if "/boot/grub/stage1" exists... yes Checking if "/boot/grub/stage2" exists... yes Checking if "/boot/grub/fat''stage1''5" exists... yes Running "embed /boot/grub/fat''stage1''5 (hd0)"... 15 sectors are embedded. succeeded Running "install /boot/grub/stage1 (hd0) (hd0)1+15 p (hd0,0)/boot/grub/stage2 /boot/grub/menu.lst"... succeeded Done.
Now power down bochs and try the new harddisk image by changing the boot device in your .bochsrc:
The following configuration file is what JoelSherrill used to boot from a floppy image:
#configuration file for Bochs to boot RTEMS Grub floppy config_interface: textconfig display_library: x megs: 8 romimage: file<tt>/usr/share/bochs/BIOS-bochs-latest, address</tt>0xf0000 vgaromimage: /usr/share/bochs/VGABIOS-elpin-2.40 boot: floppy floppya: 1_44<tt>/home/joel/bochs/grub144 , status</tt>inserted #no floppyb ata0: enabled<tt>1, ioaddr1</tt>0x1f0, ioaddr2<tt>0x3f0, irq</tt>14 ata1: enabled=0 ata2: enabled=0 ata3: enabled=0 parport1: enabled<tt>1, file</tt>"" com1: enabled<tt>1, dev</tt>"" usb1: enabled<tt>1, ioaddr</tt>0xff80, irq=10 #no sb16 floppy''bootsig''check: disabled=0 vga''update''interval: 30000 keyboard''serial''delay: 20000 keyboard''paste''delay: 100000 floppy''command''delay: 50000 ips: 500000 text''snapshot''check: 0 mouse: enabled=0 private_colormap: enabled=0 i440fxsupport: enabled=0 clock: sync<tt>none, time0</tt>local #no ne2k newharddrivesupport: enabled=1 #no loader log: - logprefix: %t%e%d debugger_log: - panic: action=fatal error: action=report info: action=report debug: action=ignore pass: action=fatal keyboard_mapping: enabled<tt>0, map</tt> keyboard_type: mf user_shortcut: keys=none #no cmosimage
Bochs appears to hang
From http://www.rtems.com/ml/rtems-users/2004/october/msg00304.html in an exchange between Erwin Rol and Anthony Richardson.
> I saw that problem too, it seems to hang in the timer calibration > routines. Could you try if the following line in yer bochs config file > helps. > > clock: syncnone, time0local > > - Erwin
Although, this didn't help in my particular case it led me to try different Bochs related timer/clock parameters. Changing the value of ips from 900000 to 1000000 caused the problem to go away. Values of ips of 900000 or lower cause the latest RTEMS executables to lock up. Older RTEMS executables (from the contrib grub floppy) work fine with lower value of ips.