Updates doc with new image file and instructions
[akaros.git] / Documentation / howtos / make-bootable-grub-hdd.txt
1 make-bootable-grub-hdd.txt
2 Barret Rhoden
3 2013-02-22
4
5 This document explains how to make a hard disk image file, install grub on the
6 image, and load your kernel (Akaros in the examples).
7
8
9 Initial Setup:
10 --------------------------
11 Commands that begin with # need root access.  Commands beginning with $ should
12 be done as your development user.
13
14 You need the loop module loaded with max_part=10 (or something more than the
15 number of partions you are making on an image file).
16
17 # modprobe loop max_part=10
18
19 If your loop device is compiled into the kernel, add the kernel parameter "loop.max_part=10"
20
21 For example, once you partition an image file and connect it to a loopback
22 device (e.g., loop1), you will see the following devices:
23
24 /dev/loop1
25 /dev/loop1p1
26 /dev/loop1p2
27 ..etc
28
29
30 Build your Image File:
31 --------------------------
32 This makes an image of size 268MB, which is 256MiB):
33
34 $ dd if=/dev/zero of=mnt/hdd.img bs=512 count=1 seek=524287
35
36 Connect to the image via a loopback device:
37
38 # losetup /dev/loop0 mnt/hdd.img 
39
40 Fdisk the device:
41
42 # fdisk /dev/loop0
43         Create a new linux partition
44         Note it has 524288 sectors (1 + the seek offset)
45         Also note the partition begins at 2048, not 512 like it used to (changes
46         to fdisk, probably to get away from 512 byte alignments)
47
48 Disconnect and reconnect the loopback device, so we now can see the
49 partitions:
50
51 # losetup -d /dev/loop0
52 # losetup /dev/loop0 mnt/hdd.img 
53 # ls /dev/loop0*
54 /dev/loop0  /dev/loop0p1
55
56 Make the filesystem:
57
58 # mkfs /dev/loop0p1
59
60 Create a mount point for your image file (as your user);
61
62 $ mkdir mnt/hdd/
63
64 Mount and chown.  The chown only needs to be done the first time you mount the
65 device.
66
67 # mount /dev/loop0p1 mnt/hdd/
68 # chown -R brho:brho mnt/hdd/
69
70
71 Install Grub on the Image file:
72 --------------------------
73
74 This assumes legacy grub:  for gentoo, emerge sys-boot/grub-static to get the
75 legacy grub.  I glanced at grub2, but don't particularly want to mess with
76 that.
77
78 Set up the grub1 files and directories (assuming you still have the image
79 mounted and have access to stage1 and stage2 files).
80
81 $ mkdir -p mnt/hdd/boot/grub
82 $ cp /boot/grub/stage1 /boot/grub/stage2 /boot/grub/menu.lst mnt/hdd/boot/grub/
83
84 Edit menu.lst.  Here's one similar to mine that works with Akaros:
85         default 0
86         timeout 5
87         serial --unit=0 --speed=115200 --word=8 --parity=no --stop=1
88         terminal --timeout=5 serial console
89         
90         title=Akaros
91         root (hd0,0)
92         kernel /kernel
93
94 Now put the kernel on the mounted image.  You can do this whenever, btw, and
95 you'll do this whenever you want to update the kernel (my Makelocal has a
96 target that does this).  So feel free to do this later.
97
98 $ cp obj/kern/kernel mnt/hdd/kernel
99
100 Actually install grub on the device.  Do this as a regular user (not root), to
101 limit damage in case you mess up (e.g., accidentally write to /dev/sda instead
102 of your image file)
103
104 $ /sbin/grub --device-map=/dev/null
105
106         Enter the commands at the grub> prompt.  I've included the output you
107         should see if things are going well:
108         
109         grub> device (hd0) mnt/hdd.img
110         device (hd0) mnt/hdd.img
111
112         grub> root (hd0,0)
113         root (hd0,0)
114          Filesystem type is ext2fs, partition type 0x83
115
116         grub> setup (hd0)
117         setup (hd0)
118          Checking if "/boot/grub/stage1" exists... yes
119          Checking if "/boot/grub/stage2" exists... yes
120          Checking if "/boot/grub/e2fs_stage1_5" exists... no
121          Running "install /boot/grub/stage1 (hd0) /boot/grub/stage2 p /boot/grub/menu.lst "... succeeded
122         Done.
123
124         grub> quit
125         quit
126
127
128 That's it.  Whenever you reboot, you'll need to recreate the loopback device
129 and remount the image at mnt/hdd/.  Check out my "kvm-up.sh" script for how I
130 do this (it's basically just losetup, sleep, and mount).
131
132 Whenever you update the kernel, cp it into mnt/hdd/kernel, and sync.  The sync
133 is necessary so the image file / backing store gets updated right away.  If
134 you don't do this, your VM might see the old version of kernel if you run the
135 VM right away (before the FS naturally syncs).  Check out my Makelocal target
136 for kvm for how to do this.
137
138
139 Old Stuff:
140 --------------------------
141 I originally wrote this back in 2009.  It works for older versions of fdisk
142 and has some acrobatics with loopback devices that will help if you can't use
143 the max_part parameter to the loop module.  Also, it has some examples with
144 using bochs
145
146
147 # make a 8MB image.  picked these values so there is 1 cyl (minimum, it seems)
148 dd if=/dev/zero of=mnt/hdd.img bs=512 count=16065
149 losetup /dev/loop1 mnt/hdd.img 
150 fdisk /dev/loop1
151 # determine the offset, in sectors
152 fdisk -ul /dev/loop1
153 # mult the sector offset by 512, since losetup offsets by bytes
154 # this will have us point loop2 to the partition on the disk
155 losetup -o 32256 /dev/loop2 /dev/loop1
156 mkfs /dev/loop2
157 mount /dev/loop2 mnt/hdd/
158 # copy over grub info
159 mkdir -p mnt/hdd/boot/grub
160 cp -r /boot/grub/stage1 /boot/grub/stage2 /boot/grub/menu.lst mnt/hdd/boot/grub
161 cp -r the_kernel mnt/hdd/
162 # edit accordingly
163 vi mnt/hdd/boot/grub/menu.lst 
164 grub --device-map=/dev/null 
165         # in here:
166         # important to not use the /dev/loop1, since there is a bug in grub
167         # use the image instead, since it bypasses whatever checks fail later
168         device (hd0) mnt/hdd.img
169         root (hd0,0)
170         setup (hd0) # make sure you don't do (hd0,0).  it'll still work, but not the way you want
171 kvm mnt/hdd.img
172 # or
173 bochs -q 'ata0-master: type=disk, mode=flat, path="./mnt/hdd.img", cylinders=1, heads=255, spt=63'
174 # to use a floppy image (made similarly)
175 bochs -q 'floppya: 1_44=mnt/floppy.img, status=inserted' 'boot:a'
176
177 # to easily edit, keep the hdd image mounted and just copy in your kernel or
178 # whatever
179 # list the loops, delete them with -d to keep things nice and clean
180 losetup -a 
181 losetup -o 32256 /dev/loop0 mnt/hdd.img 
182 mount /dev/loop0 mnt/hdd
183 chown -R brho:brho mnt/hdd
184
185 # you'll need to make sure changes to the mnt/hdd take effect immediately
186 # if you want to run a VM right away with the .img
187 sync
188
189
190 Notes:
191 --------------------------
192 http://www.linuxjournal.com/article/4622
193 http://sig9.com/bochs-grub
194 http://web2.clarkson.edu/projects/itl/honeypot/ddtutorial.txt
195 http://www.mail-archive.com/bug-grub@gnu.org/msg09648.html
196 http://www.omninerd.com/articles/Installing_GRUB_on_a_Hard_Disk_Image_File