Chinaunix首页 | 论坛 | 博客
  • 博客访问: 918269
  • 博文数量: 132
  • 博客积分: 9976
  • 博客等级: 中将
  • 技术积分: 1781
  • 用 户 组: 普通用户
  • 注册时间: 2007-08-30 20:40
文章分类

全部博文(132)

文章存档

2013年(1)

2011年(1)

2010年(15)

2009年(77)

2008年(36)

2007年(2)

我的朋友

分类:

2009-06-04 10:37:03

Installing GRUB on a Hard Disk Image File

================================================================================
from:

Page_white_text

article by on 24 January 2009, tagged as , , , and disk images

Introduction

is the GRand Unified Bootloader. For those unfamiliar, a bootloader is a critical piece of software used when a computer turns on. Its job is to load an operating system. The bootloader resides on a disk of some sort (floppy, hard) and is called by the BIOS, which is the real low-level program that runs on startup. GRUB is installed at a specific location on these devices.

Image files are byte-for-byte representations of block devices, such as a hard disk or floppy disk. They can be used for a variety of things, such as backup, offline investigation, or virtual machines. I was using the latter (specifically, and ). These programs act like a computer within a computer, and take an image file to be the disk for the virtual machine.

How do these come together? When building an image file from scratch, I wanted to install GRUB on it. There are a lot of about how to install GRUB on a floppy image or on a real HDD, but not on a HDD image. Perhaps this info is already out there, but since I didn’t find it, I figured I’d tell you all what klueska and I came up with.

Details

The following was done on a regular Linux box. Use root/sudo when you need to. Normally, I’ll explain what I’ll do, and then show the commands I used to do it.

Creating the Image

This will create an 8MB image. Use whatever size you want. These values will result in one cylinder (based on the old sector/cylinder/head sizing). Fdisk complained on smaller images, so YMMV. I have a folder called mnt/ in my current directory, which is where I store both the images and the image mount point.


dd if=/dev/zero of=mnt/hdd.img bs=512 count=16065

This creates a loopback device that connects to the image file. This helps some utilities that are expecting to work with a device instead of a file. For instance, fdisk was a little happier with this.


losetup /dev/loop1 mnt/hdd.img

Fdisk the image, just like it’s a regular block device. The easiest thing is to just create one Linux primary partition.


fdisk /dev/loop1

Okay, enough with the slow stuff; it’s time to put your “daddy pants” on. Here’s the problem. You need to make a file system on that partition, but you do not have a device that points to just that partition, like you would for a normal hard drive. You only have the loopback device, which points to the whole image. It’s like you only have /dev/hda, and not /dev/hda1. What to do? Create another loopback device, and have the device start from a certain offset within the image.

This determines the offset, in sectors, for the beginning of the partition. Then multiply the sector offset by 512, since losetup offsets by bytes.


fdisk -ul /dev/loop1

This will have us point loop2 to the partition on the disk (if there is only one partition), as explained in more detail . Then we simply make a filesystem on it.


losetup -o 32256 /dev/loop2 /dev/loop1
mkfs /dev/loop2

If you have multiple partitions, you will need to tell losetup how far to go into the target with the --sizelimit flag. By default, it will map all the way to the end of the target, which will clobber any following partitions. To figure out the size, look at the Blocks column output of fdisk -ul, and multiply that by 1024. Thanks to Anonymous for pointing this out in the comments below. Here’s an example (for about 400 cylinders):


losetup -o 32256 --sizelimit 3290079232 /dev/loop2 /dev/loop1
mkfs /dev/loop2

This will mount it so you can examine it and so you’re ready to install grub. Make sure you have mkdir’d mnt/hdd, yada yada yada.


mount /dev/loop2 mnt/hdd/

Installing GRUB

This creates the file structure on the image for GRUB and copies local copies of critical GRUB files to the appropriate folder. It also copies whatever kernel you want to load into the root of the image’s file system. Adjust files and paths to your liking.

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/

Don’t forget to edit the menu.lst file (a grub.conf) to suit your kernel. Mine looked something like this. Look elsewhere for more guidance.


default 0
timeout 10


title=LonnyOS
root (hd0,0)
kernel /the_kernel

Now install GRUB for real.


grub --device-map=/dev/null

This will open up a GRUB environment. Enter the following:


device (hd0) mnt/hdd.img
root (hd0,0)
setup (hd0)

Note that we set the device to the actual image file, and not the loopback device. GRUB can work with either. Normally, utilities work better with the device, but due to a in GRUB, it was flipping out (Error 22) when given the loopback device. It worked fine when installing on the hdd.img. For more details, look elsewhere (my references and google are decent starting points).

Using the Image

You can easily mount the image and use it, even while using the image directly for a virtual machine. I ran losetup -a to see which loopback devices I had, then the -d flag to delete whichever I don’t need. Now I’ll loopback directly into the image, and mount it. And then make sure my regular user account has all the access necessary. Also, be careful of any necessary sizelimits to losetup, as mentioned above.


losetup -o 32256 /dev/loop0 mnt/hdd.img
mount /dev/loop0 mnt/hdd
chown -R brho:brho mnt/hdd

As I muck around with the_kernel, I can just cp it into mnt/hdd/, and quickly run KVM or Bochs to test the new kernel.


kvm mnt/hdd.img
bochs -q 'ata0-master: type=disk, mode=flat, path="./mnt/hdd.img", cylinders=1, heads=255, spt=63'

One thing to note: after you copy the_kernel to mnt/hdd, the hdd.img is not actually updated instantly. This is because filesystems do not immediately flush their changes to disk, and the write() syscall will return early. If you want to immediately run your VM with your new image, simply sync your disks to make sure all writes are flushed.


sync

Conclusion

Hopefully this has helped you. If you hose your system, you’re on your own / standard disclaimers apply. But if not, perhaps you are the happy owner of a fresh GRUB hdd image. More importantly, you should know how to make one and (roughly) how the process worked.

References




Information This article was edited after publication by the author on 04 Feb 2009.

================================================================================
from: %20To%20Install%20GRUB%20into%20a%20disk%20image.pdf

How to install GRUB into a disk image
© 2008 Leon Woestenberg , Sidebranch


Disk and filesystem images

A disk image is an ordinary file that holds the exact contents and layout of a physical disk or any other block device. Similar a filesystem image is an exact copy of all the blocks that belong to a filesystem. Working with image files allows the developer to do much of the work without access to the target storage hardware, which is typically more expensive, slower, harder to access, and limited in numbers.
Many tools that work on block devices also work on image files. For example, an image file can be partitioned using sfdisk, and an image file can be formatted with a filesystem using mkfs.
Creating a block device image

To create a block device image file for a physical disk with a size of LBA logically addressable blocks of 512 bytes each (often called a sector), use dd as follows:

dd if=/dev/zero of=disk.img bs=512 count=${LBA}

If your host filesystem supports sparse files1 (files containing large chunks of zero data that do not occupy disk space), this is a faster and more space efficient alternative to the above:

dd if=/dev/zero of=disk.img bs=512 count=0 seek=${LBA}
Creating partitions

If you are targetting a IDE hard disk drive device on a x86 platform, or a device that behaves as such, we must take care of the Master Boot Record (MBR), the partition table and the partitions themselves. The first sector contains the MBR along with the partition table. Conventionally, the rest of the first track (this is the track on the first head of the first cylinder) is not used as partition space; the first partition starts at the second head of the first cylinder. Any subsequent partitions start on cylinder boundaries.

Suppose you want to partition the block device with two partitions laid out in a conventional way respecting the physical block device geometry. The geometry is assumed to be (cylinders, heads, sectors) = (C, H, S) here. The last partition is chosen to occupy the last L cylinders. With some math we end up with these offsets and sizes:

Disk Layout
--------------------------------------------------------
disk element......offset (sectors)......size (sectors)
MBR...............0.....................1
unused............1.....................(S-1)
partition 1.......S.....................((C-L)*H*S) - S
partition 2.......(C-L)*H*S.............L*H*S
--------------------------------------------------------

The sfdisk tool can be used to partition the disk in a scripted manner as follows:

sudo /sbin/sfdisk -C$C -H$H -S$S -uS -f -L --no-reread disk.img <$S,$($($C-$L)*$H*$S - $S),83,*
$($($C-$L)*$H*$S),$($L*$H*$S),83
EOF

We can create filesystems on the partitions inside the disk image directly, but this needs creating a loop device, as well as recent version of the loop device setup tool losetup that understands the size parameter. An easier alternative is to create partition images independent of the disk image, create filesystems on these, populate these and only as the final step before deployment, move the partition images inside the disk image. We use the latter approach:

dd if=/dev/zero of=part1.img bs=512 count=0 seek=$(($(($C-$L))*$H*$S - $S))
dd if=/dev/zero of=part2.img bs=512 count=0 seek=$(($L*$H*$S))

Creating filesystems
After creating the partition images, filesystems can be created on them as follows:
sudo /sbin/mke2fs -j -L”/” -F part1.img
sudo /sbin/mke2fs -j -L”etc” -F part2.img

For filesystems that are mounted read-only, disable the period filesystem check:
sudo /sbin/tune2fs -c0 -f part1.img
sudo /sbin/tune2fs -c0 -f part2.img

The partitions are now available to be populated with the intended content; executables, libraries etc. In the next step, we install GRUB onto it.
Mounting a filesystem image file
In order to populate a filesystem inside the image file, that filesystem must be mounted first. For the purpose of mounting these filesystems not associated with block devices, there exist loop devices. Using a loop device we can present our image file as a block device to the filesystem subsystem.
The resulting virtual block device is presented as a /dev/loop0 or /dev/loop/0 entry.
Installing GRUB into a filesystem image file
If you want to install a bootloader that uses a filesystem on disk such as GRUB, this can most easily be done now, while the seperate filesystem images are still available. By first mounting the partition’s filesystem we can copy the necessary GRUB files onto it afterwards:
mkdir -p /tmp/mnt/part1
sudo mount -o loop /tmp/part1.img /tmp/mnt/part1
Now, create a GRUB directory and copy the necessary stage 1.5 and stage 2 files onto it:
mkdir -p /tmp/mnt/part1/boot/grub
sudo cp /usr/share/lib/grub/i386-pc/* /tmp/mnt/part1/boot/grub/
sudo umount /tmp/mnt/part1
We still need to install the stage 1 itself. Installing the GRUB bootloader into a filesystem image file on the build host needs a bit of trickery to make GRUB believe it is installing itself onto a real block device. We setup a loop device for this:

sudo /sbin/losetup /dev/loop5 disk.img
Also, GRUB needs access to the filesystem where the stage 1.5 and stage 2 files are.
sudo mount -o loop,offset=$(($S*512)) disk.img /tmp/mnt/part1
We now trick GRUB into believing that the loop device is a hard disk device:
echo “(hd0) /dev/loop5” >/tmp/device.map
Finally, we execute GRUB to install itself on this device (image, but GRUB doesn’t know that).
sudo /tmp/grub-resumo/sbin/grub --batch --no-floppy --device-map=/tmp/device.map <device (hd0) /dev/loop5
geometry (hd0) ${C} ${H} ${S}
root (hd0,0)
setup --stage2=/tmp/mnt/part1/boot/grub/stage2 (hd0)
quit
EOF
Unmount the filesystem and drop the looped block device image:
sudo umount /tmp/mnt/part1
sudo /sbin/losetup -d /dev/loop5
Moving filesystems into a block device image
Earlier we have created a disk image on which we assembled a MBR in its first sector, containing a partition table for two partitions. For the partitions themselves we created seperate images and layed out a filesystem on each. Optionally, you added a bootloader or files to the filesystems. We now move these filesystem images onto the disk image, carefully respecting the offsets we have chosen earlier:
dd if=part1.img of=disk.img bs=512 seek=$S
dd if=part2.img of=disk.img bs=512 seek=$(($(($C-$L))*$H*$S))

================================================================================
from: http://www.gnu.org/software/hurd/hurd/running/gnu/create_an_image.html

Creating a bootable qemu image from a root filesystem and bootloader

  1. Create a hard disk image

    qemu-img create -f qcow  G
  2. Use a live CD (better to have a lighter OS like system rescue CD to make the process faster) and the image created to boot.

    qemu -cdrom /dev/cdrom -hda  -boot d
  3. Once system is booted use a partition editing tool (like fdisk, cfdisk, parted, gparted, qtparted ...) to partition the image.

    cfdisk

    create the necessary partitions (root and swap partitions boot, home ... if required)

  4. Create a file syatem for the root partiotion

    mke2fs /dev/hda1
  5. Mount the partition

    mkdir disk
    mount /dev/hda1 disk
  6. Copy the file system from the host machine to the mounted directory (use a compressed file system to make the copying faster)

    Grab the GNU spapshot from ams' site

    scp @: disk
  7. Uncompress the files

    cd disk
    tar -jxvf
  8. Unmount the mounted partition

    cd .. 
    umount disk
  9. power off the guest OS.

    poweroff
  10. To make the file syatem bootable download a grub floppy image

    <
  11. Run qemu to boot into your brand new system

    qemu -hda  -fda grub.img -boot a

Happy Hacking !!

Make your new system boot from the hard disk

  1. Mount your grub image

    mkdir floppy
    mount -t ext2 -o loop grub.img floppy
  2. Use previous steps 2 and 5 to boot from a liveCD and mount the partition

    cd disk/boot
    scp -r @:/boot/grub
  3. Poweroff the guest

    poweroff
  4. Boot new system using floppy image previous step 11

    use install to hard disk option if you used the above grub image

    or go to grub command line and type

    root (hd0,0)
    setup (hd0)

    Now you have a bootable system image. Enjoy Maadi !!

License:

GFDL 1.2+

Last edited 2009-05-18 16:16:38 UTC
================================================================================
from:


================================================================================
from:


================================================================================
from:




阅读(1214) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~