| make-bootable-grub-hdd.txt |
| Barret Rhoden |
| 2013-02-22 |
| |
| This document explains how to make a hard disk image file, install grub on the |
| image, and load your kernel (Akaros in the examples). |
| |
| |
| Initial Setup: |
| -------------------------- |
| Commands that begin with # need root access. Commands beginning with $ should |
| be done as your development user. |
| |
| You need the loop module loaded with max_part=10 (or something more than the |
| number of partions you are making on an image file). |
| |
| # modprobe loop max_part=10 |
| |
| If your loop device is compiled into the kernel, add the kernel parameter "loop.max_part=10" |
| |
| For example, once you partition an image file and connect it to a loopback |
| device (e.g., loop1), you will see the following devices: |
| |
| /dev/loop1 |
| /dev/loop1p1 |
| /dev/loop1p2 |
| ..etc |
| |
| |
| Build your Image File: |
| -------------------------- |
| This makes an image of size 268MB, which is 256MiB): |
| |
| $ dd if=/dev/zero of=mnt/hdd.img bs=512 count=1 seek=524287 |
| |
| Connect to the image via a loopback device: |
| |
| # losetup /dev/loop0 mnt/hdd.img |
| |
| Fdisk the device: |
| |
| # fdisk /dev/loop0 |
| Create a new linux partition |
| Note it has 524288 sectors (1 + the seek offset) |
| Also note the partition begins at 2048, not 512 like it used to (changes |
| to fdisk, probably to get away from 512 byte alignments) |
| |
| Disconnect and reconnect the loopback device, so we now can see the |
| partitions: |
| |
| # losetup -d /dev/loop0 |
| # losetup /dev/loop0 mnt/hdd.img |
| # ls /dev/loop0* |
| /dev/loop0 /dev/loop0p1 |
| |
| Make the filesystem: |
| |
| # mkfs /dev/loop0p1 |
| |
| Create a mount point for your image file (as your user); |
| |
| $ mkdir mnt/hdd/ |
| |
| Mount and chown. The chown only needs to be done the first time you mount the |
| device. |
| |
| # mount /dev/loop0p1 mnt/hdd/ |
| # chown -R brho:brho mnt/hdd/ |
| |
| |
| Install Grub on the Image file: |
| -------------------------- |
| |
| This assumes legacy grub: for gentoo, emerge sys-boot/grub-static to get the |
| legacy grub. I glanced at grub2, but don't particularly want to mess with |
| that. |
| |
| Set up the grub1 files and directories (assuming you still have the image |
| mounted and have access to stage1 and stage2 files). |
| |
| $ mkdir -p mnt/hdd/boot/grub |
| $ cp /boot/grub/stage1 /boot/grub/stage2 /boot/grub/menu.lst mnt/hdd/boot/grub/ |
| |
| Edit menu.lst. Here's one similar to mine that works with Akaros: |
| default 0 |
| timeout 5 |
| serial --unit=0 --speed=115200 --word=8 --parity=no --stop=1 |
| terminal --timeout=5 serial console |
| |
| title=Akaros |
| root (hd0,0) |
| kernel /kernel |
| |
| Now put the kernel on the mounted image. You can do this whenever, btw, and |
| you'll do this whenever you want to update the kernel (my Makelocal has a |
| target that does this). So feel free to do this later. |
| |
| $ cp obj/kern/kernel mnt/hdd/kernel |
| |
| Actually install grub on the device. Do this as a regular user (not root), to |
| limit damage in case you mess up (e.g., accidentally write to /dev/sda instead |
| of your image file) |
| |
| $ /sbin/grub --device-map=/dev/null |
| |
| Enter the commands at the grub> prompt. I've included the output you |
| should see if things are going well: |
| |
| grub> device (hd0) mnt/hdd.img |
| device (hd0) mnt/hdd.img |
| |
| grub> root (hd0,0) |
| root (hd0,0) |
| Filesystem type is ext2fs, partition type 0x83 |
| |
| grub> setup (hd0) |
| setup (hd0) |
| Checking if "/boot/grub/stage1" exists... yes |
| Checking if "/boot/grub/stage2" exists... yes |
| Checking if "/boot/grub/e2fs_stage1_5" exists... no |
| Running "install /boot/grub/stage1 (hd0) /boot/grub/stage2 p /boot/grub/menu.lst "... succeeded |
| Done. |
| |
| grub> quit |
| quit |
| |
| |
| That's it. Whenever you reboot, you'll need to recreate the loopback device |
| and remount the image at mnt/hdd/. Check out my "kvm-up.sh" script for how I |
| do this (it's basically just losetup, sleep, and mount). |
| |
| Whenever you update the kernel, cp it into mnt/hdd/kernel, and sync. The sync |
| is necessary so the image file / backing store gets updated right away. If |
| you don't do this, your VM might see the old version of kernel if you run the |
| VM right away (before the FS naturally syncs). Check out my Makelocal target |
| for kvm for how to do this. |
| |
| |
| Old Stuff: |
| -------------------------- |
| I originally wrote this back in 2009. It works for older versions of fdisk |
| and has some acrobatics with loopback devices that will help if you can't use |
| the max_part parameter to the loop module. Also, it has some examples with |
| using bochs |
| |
| |
| # make a 8MB image. picked these values so there is 1 cyl (minimum, it seems) |
| dd if=/dev/zero of=mnt/hdd.img bs=512 count=16065 |
| losetup /dev/loop1 mnt/hdd.img |
| fdisk /dev/loop1 |
| # determine the offset, in sectors |
| fdisk -ul /dev/loop1 |
| # mult the sector offset by 512, since losetup offsets by bytes |
| # this will have us point loop2 to the partition on the disk |
| losetup -o 32256 /dev/loop2 /dev/loop1 |
| mkfs /dev/loop2 |
| mount /dev/loop2 mnt/hdd/ |
| # copy over grub info |
| mkdir -p mnt/hdd/boot/grub |
| cp -r /boot/grub/stage1 /boot/grub/stage2 /boot/grub/menu.lst mnt/hdd/boot/grub |
| cp -r the_kernel mnt/hdd/ |
| # edit accordingly |
| vi mnt/hdd/boot/grub/menu.lst |
| grub --device-map=/dev/null |
| # in here: |
| # important to not use the /dev/loop1, since there is a bug in grub |
| # use the image instead, since it bypasses whatever checks fail later |
| device (hd0) mnt/hdd.img |
| root (hd0,0) |
| setup (hd0) # make sure you don't do (hd0,0). it'll still work, but not the way you want |
| kvm mnt/hdd.img |
| # or |
| bochs -q 'ata0-master: type=disk, mode=flat, path="./mnt/hdd.img", cylinders=1, heads=255, spt=63' |
| # to use a floppy image (made similarly) |
| bochs -q 'floppya: 1_44=mnt/floppy.img, status=inserted' 'boot:a' |
| |
| # to easily edit, keep the hdd image mounted and just copy in your kernel or |
| # whatever |
| # list the loops, delete them with -d to keep things nice and clean |
| losetup -a |
| losetup -o 32256 /dev/loop0 mnt/hdd.img |
| mount /dev/loop0 mnt/hdd |
| chown -R brho:brho mnt/hdd |
| |
| # you'll need to make sure changes to the mnt/hdd take effect immediately |
| # if you want to run a VM right away with the .img |
| sync |
| |
| |
| Notes: |
| -------------------------- |
| http://www.linuxjournal.com/article/4622 |
| http://sig9.com/bochs-grub |
| http://web2.clarkson.edu/projects/itl/honeypot/ddtutorial.txt |
| http://www.mail-archive.com/bug-grub@gnu.org/msg09648.html |
| http://www.omninerd.com/articles/Installing_GRUB_on_a_Hard_Disk_Image_File |