User Tools

Site Tools


howtocustomrestoreimage:pt2mkcustomimage

Part 2: HOWTO Make a Disk Image with a Custom Partition Table

Disclaimer: This part of the tutorial will require the use of hard disk manipulation tools. You should only follow this tutorial if you understand what you are doing. You are entirely responsible if something goes terribly wrong.

Source Material Let me begin by offering my humblest thanks to whomever is/are responsible for: http://wiki.edseek.com/guide:mount_loopback I love your work! Not just another guide on mount -o loop… covers partitions within disk images! It offers three methods… …below is the easy option believe it or not!

(Links back to: Intro and Part 1)

Creating the Disk Image

First let's get to know our eee-pc hard disk. On the eee-pc:

  • boot it up
  • [ctrl]-[alt]-[t] to get a terminal
  • become root & run fdisk -l
/home/user> sudo bash
eeepc-e:/home/user> fdisk -l /dev/sda
Disk /dev/sda: 4001 MB, 4001292288 bytes
255 heads, 63 sectors/track, 486 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
   Device Boot      Start         End      Blocks   Id  System
/dev/sda1               1         300     2409718+  83  Linux
/dev/sda2             301         484     1477980   83  Linux
/dev/sda3             485         485        8032+   c  W95 FAT32 (LBA)
/dev/sda4             486         486        8032+  ef  EFI (FAT-12/16/32)

Our eee-pc's disk contains 4001292288 bytes. Write this down. We'll use it down the track.

Don't be fooled by the 486 * 16065… …There's a little more disk than that. I'll explain shortly. Lets return to the working directory from Part 1. It should look something like this:

0x0065 working # ls
P701L.gz  usb.img

Lets do some maths with bc to understand how the eee-pc disk is. I've added some comments for clarity:

0x0065 working # bc
486*16065*512		# cylinders x blocks per cylinder x bytes per block
3997486080		# is less than the whole disk...
4001292288-3997486080
3806208			# ...so there's a little part cylinder on the end.
4001292288/512
7815024			# We have this many blocks of 512 on the disk
quit

So I say we make a disk image the size of the whole disk:

  • The Asus install key's initrd's rc script does some crazy ninja magic to the disk that saves them about 100MB on the compressed disk image… …I wont be doing any of that. It makes my head feel fuzzy just looking at their script and it assumes splitting the disk in half with at least one partition essentially being wiped & formatted. Not really what I want at all.
  • If you wish to adjust the disk image to put root on an encrypted loopback filesystem then you should take the fill data for the disk image from urandom or similar. I wont be looking at that today. Maybe if I do a gentoo version of this… (^_-) …on an eee-pc 1000 some day….
0x0065 working # dd bs=512 count=7815024 if=/dev/zero of=loop-eee
7815024+0 records in
7815024+0 records out
4001292288 bytes (4.0 GB) copied, 113.535 s, 35.2 MB/s

So we have a loopback disk with the same number of bytes as the EEE-PC hard disk, but it's full of zeros, so anything we don't use will compress really well.

Partitioning the Disk Image

PLEASE NOTE: You need to use the “u” command in fdisk before making the last partition or else your last partition will not reach the end of the device, but your filesystem will. (This is a problem… (^_^) …) This may not immediately occur to you. You'd definitely notice it when you try to fsck it though. (>_<)

0x0065 working # fdisk -C 486 loop-eee 
Device contains neither a valid DOS partition table, nor Sun, SGI or OSF
disklabel
Building a new DOS disklabel with disk identifier 0x785eb005.
Changes will remain in memory only, until you decide to write them.
After that, of course, the previous content won't be recoverable.

Warning: invalid flag 0x0000 of partition table 4 will be corrected by w(rite)

Command (m for help): p

Disk loop-eee: 0 MB, 0 bytes
255 heads, 63 sectors/track, 486 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Disk identifier: 0x785eb005

   Device Boot      Start         End      Blocks   Id  System

Do your stuff. I expect you know what you want or you wouldn't be doing this tutorial.

I'm not making a swap disk because constant little read-write cycles are reputedly bad for flash disks. (they apparently have a limited number of read-write cycles)

I'm making a 64MB 'BOOT' partition (a bit big I know. I used to make them 32 but I ran out once.) because if my 'ROOT' filesystem gets borked, I'd REALLY like to have a kernel, an initrd file and Grub on their own little self contained partition… …It's just good practice. Normally I'd leave this partition unmounted. I think I'll stick with that, as I intend to do a custom kernel image and changes to just about anything else under boot will likely bork our revised image. I'll be sending the laptop to a non-technical person, so it will be briefly mounted by Grub at boot but otherwise it will remain unmounted. If this isn't what you want, the solution lies in /etc/fstab.

The rest of my meagre disk will be a single ext2 'ROOT' partition. I'll be following the conventional wisdom than a non-journaling filesystem is better for flash disks as there is less 'jittery' read-write…

Command (m for help): u
...
   Device Boot      Start         End      Blocks   Id  System
loop-eee1              64      144584       72261   83  Linux
loop-eee2          144585     7815023     3835219+  83  Linux

Command (m for help): w 
...
WARNING: Re-reading the partition table failed with error 25:
Inappropriate ioctl for device. The kernel still uses the old table.
The new table will be used at the next reboot.
Syncing disks.

You can safely ignore the warning. We won't be asking the kernel to read the partition table today. We will need to feed our programs the correct offsets in bytes… (>_<)

Formatting the Disk Image

Let's find the offset for each partition in bytes. Again we do this with trusty old fdisk.

working # fdisk -l -u -C 486 loop-eee
Disk loop-eee: 0 MB, 0 bytes
255 heads, 63 sectors/track, 486 cylinders, total 0 sectors
Units = sectors of 1 * 512 = 512 bytes
Disk identifier: 0x9321416a
   Device Boot      Start         End      Blocks   Id  System
   loop-eee1              63      144584       72261   83  Linux
   loop-eee2          144585     7815023     3835219+  83  Linux

We need to multiply all this by 512 to get our offsets. Lets whip out bc:

0x0065 working # bc
63*512
32256		offset to the start of loop-eee1
144585*512
74027520	offset to the end of loop-eee1
74027520-32256
73995264	length of loop-eee1 in bytes
73995264/2048
36130		length of loop-eee1 in 2048 byte filesystem blocks
quit

If someone who knows about ext2 filesystem would like to suggest the most appropriate block size for a 64MB partition, I'm all ears. Until then, lets take the middle path & punt on a block size of 2048. Works for me…

First let's loop back to partition 1

0x0065 working # losetup --find --offset 32256 loop-eee 
0x0065 working # losetup -a
/dev/loop0: [0833]:17285128 (loop-eee), offset 32256 

VERY VERY IMPORTANT:

  • We need to specify the length of the filesystem we put on partition 1 or we'll just fill the remainder of the disk image… …that's the number after the loopback device file… …the man page explains it all fairly well.
  • At the time of writing the current version of Grub does not support the default inode size of the current version of e2fsprogs. Astounding, I know. You will want the -I option for anything that Grub needs to mount.
0x0065 working # mkfs.ext2 -I 128 -L BOOT -b 2048 /dev/loop0 36130
mke2fs 1.40.9 (27-Apr-2008)
Filesystem label=BOOT
OS type: Linux
Block size=2048 (log=1)
...
Maximum filesystem blocks=37748736
3 block groups
16384 blocks per group, 16384 fragments per group
...
This filesystem will be automatically checked every 22 mounts or
180 days, whichever comes first.  Use tune2fs -c or -i to override.

So that's partition 1 done. Let's do the easy one next. We just loop back to the correct offset in the file for partition 2 and then make a filesystem that covers the rest of the disk image:

0x0065 working # losetup -f -o 74027520 loop-eee
0x0065 working # losetup -a                      
/dev/loop0: [0833]:17285128 (loop-eee), offset 32256
/dev/loop1: [0833]:17285128 (loop-eee), offset 74027520
0x0065 working # mkfs.ext2 -L ROOT /dev/loop1      
mke2fs 1.40.9 (27-Apr-2008)
Warning: 256-byte inodes not usable on older systems
Filesystem label=ROOT
OS type: Linux
Block size=4096 (log=2)
...
Maximum filesystem blocks=985661440
...
This filesystem will be automatically checked every 33 mounts or
180 days, whichever comes first.  Use tune2fs -c or -i to override.

You'll note that it looks like the people who should know recommend 4096 for the bigger partition. Hmmmm…. OK. Open to suggestions.

Mounting our Disk Images Ready for Transfer

Making directories & mounting stuff…

0x0065 working # mkdir -p /mnt/key
0x0065 working # mount /dev/loop1 /mnt/key/
0x0065 working # mkdir -p /mnt/key/boot
0x0065 working # mount /dev/loop0 /mnt/key/boot/
0x0065 working # df
Filesystem           1K-blocks      Used Available Use% Mounted on
/dev/loop1             3774912      7516   3575636   1% /mnt/key
/dev/loop0               69978       160     66206   1% /mnt/key/boot

and it looks right. !(^-^)!

Next is transfering the Xandros image on.

howtocustomrestoreimage/pt2mkcustomimage.txt · Last modified: 2008/08/23 11:00 by 0x0065