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!
First let's get to know our eee-pc hard disk. On the eee-pc:
/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:
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.
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… (>_<)
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: :17285128 (loop-eee), offset 32256
VERY VERY IMPORTANT:
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: :17285128 (loop-eee), offset 32256 /dev/loop1: :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.
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. !(^-^)!