Optimizing Arch Linux image installation on the Raspberry Pi

In this post I will show step by step how to optimize the Arch Linux image installation for the Raspberry Pi on a SD card.

Before you continue reading, start downloading the Arch Linux ARM image (torrent, direct) from the Raspberry Pi download page.

As you already know, SD cards (flash memories in general) work a bit different than regular (magnetic) hard disks and extra care has to be taken if we want full performance. The most important is to obtain the Erase Block size (EBS) and the Page size (PS), because we should align the partitions to the EBS and also it’d be better to inform the filesystem about the best way to access the underlying memory.

This is our road map:

  1. Get the information.
    • Obtain the EBS and PS of the SD card.
    • Retrieve the partition layout of the Arch Linux image.
  2. Create the new filesystem on the SD card.
    • Replicate the partition layout.
    • Format the partitions.
  3. Copy the contents from the image to the SD.
    • Clone the MB.
    • Copy the files.

Get the information.

We start by “guessing” the EBS and the PS of the flash memory. In my system, the 8 GB SD memory card is assigned to the device /dev/sdb

$ git clone git://git.linaro.org/people/arnd/flashbench.git
$ cd flashbench
$ make
$ sudo ./flashbench -a /dev/sdb --blocksize=1024
align 2147483648        pre 1.29ms      on 1.57ms       post 1.34ms     diff 251µs
align 1073741824        pre 1.3ms       on 1.62ms       post 1.32ms     diff 306µs
align 536870912 pre 1.31ms      on 1.61ms       post 1.32ms     diff 296µs
align 268435456 pre 1.44ms      on 1.8ms        post 1.51ms     diff 319µs
align 134217728 pre 1.33ms      on 1.77ms       post 1.25ms     diff 487µs
align 67108864  pre 1.48ms      on 1.8ms        post 1.51ms     diff 306µs
align 33554432  pre 1.38ms      on 1.77ms       post 1.47ms     diff 353µs
align 16777216  pre 1.32ms      on 1.67ms       post 1.41ms     diff 304µs
align 8388608   pre 1.28ms      on 1.69ms       post 1.37ms     diff 365µs
align 4194304   pre 1.36ms      on 1.65ms       post 1.39ms     diff 271µs
align 2097152   pre 1.38ms      on 1.41ms       post 1.39ms     diff 22.3µs
align 1048576   pre 1.37ms      on 1.43ms       post 1.36ms     diff 62µs
align 524288    pre 1.39ms      on 1.4ms        post 1.38ms     diff 18.6µs
align 262144    pre 1.38ms      on 1.4ms        post 1.39ms     diff 17.3µs
align 131072    pre 1.39ms      on 1.41ms       post 1.39ms     diff 15.8µs
align 65536     pre 1.39ms      on 1.4ms        post 1.39ms     diff 13.6µs
align 32768     pre 1.39ms      on 1.4ms        post 1.37ms     diff 24.3µs
align 16384     pre 1.39ms      on 1.39ms       post 1.38ms     diff 1.7µs
align 8192      pre 1.38ms      on 1.39ms       post 1.38ms     diff 12.2µs
align 4096      pre 1.41ms      on 1.4ms        post 1.38ms     diff 5.74µs
align 2048      pre 1.39ms      on 1.39ms       post 1.39ms     diff 8.7µs

Focusing on the last column we look for the “big gaps”, the first will likely be the EBS and the second the page size (if this sounds all Greek to you then read this excellent post, the flashbench tool README or my previous entry). From the above data we may conclude that:

  • Erase Block size = 4194304 = 4 MB
  • Page size = 32768 = 32 kB

The other information we need is the partition layout, for that we will inspect the downloaded Arch Linux image.
Check the sha1 of the download file:
$ echo "1d2508908e7d8c899f4a5284e855cb27c17645dc archlinux-hf-2013-02-11.zip" | sha1sum -c -
archlinux-hf-2013-02-11.zip: OK

Extract the image somewhere:
$ cd /tmp
$ unzip /path/to/archlinux-hf-2013-02-11.zip

Inspect the image:

$ fdisk -lu /tmp/archlinux-hf-2013-02-11.img

Disk /tmp/archlinux-hf-2013-02-11.img: 1939 MB, 1939865600 bytes, 3788800 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk label type: dos
Disk identifier: 0x0004f23a

                           Device Boot      Start         End      Blocks   Id  System
/tmp/archlinux-hf-2013-02-11.img1   *        2048      186367       92160    c  W95 FAT32 (LBA)
/tmp/archlinux-hf-2013-02-11.img2          186368     3667967     1740800   83  Linux

We can see that the total size is around 2 GB (1939 MB) and that there are two partitions one starting at sector 2048 and another starting at 186368. In fdisk each sector is 512 bytes and each block is 1 kB, therefore the first partition is (92160 blocks x 1 kB =) 90 MB and starts at (2048 x 512 bytes=) 1 MB; the second starts at 91 MB and is 1700 MB large. If you know a bit about the Raspberry Pi, it is easy to establish that the first partition (the FAT32) is the boot partition and the second is the system partition.
For our SD we want the same layout but having the partitions aligned to the EBS, 4 MB in my case, and using the whole memory and not only 2 GB.

Create the new filesystem on the SD card.

From the previous step we know that we need two partitions, a FAT32 partition (type ‘c’) of around 100 MB and a Linux partition (type ’83’) using the remaining space. The first partition should start at 4 MB (the EBS) and the second at a multiple of 4 MB, 100 MB sounds a good number to me.

  • First partition
    • Starts at: 4 MB
    • Size: 96 MB (= 100 MB – 4 MB)
    • FAT32 LBA
    • Boot flag on
  • Second partition
    • Starts at: 100 MB
    • Type ext4

Using the graphical (boring) GParted

GParted is an excellent tool and you should use it whenever suits the task, like this one. “Boring” is preferable to “I fucked up my computer because I wanted to be cool using the command line”. So hands on.
Select the SD card device, exercise extreme care, and create a new partition table. In my case the SD card is /dev/sdb
Gparted New Table
Create the first partition starting at the EBS (4 MB), size 96 MB and type FAT32; make sure that the field “Aligned to” shows MiB.
Boot Partition
Create the second partition starting at 100 MB, type ext4 and using the rest of the free space.
Create Root Partition
Apply the changes.
Set the boot and LBA flags to the first partition, for that, right click on it and go to “Manage Flags”.
Manage FlagsBoot Partition Flags
And this is how it should look at the endSD card partition
Optionally you can right click on the boot partition and format it as FAT32.

fdisk, pain does not exist

Do you want to go all old fashion and do it in fdisk? Yeah!!! Let’s be masochists. Let’s present again the layout to have it fresh:

  • First partition
    • Starts at: 4 MB -> 4194304 bytes ÷ 512 bytes/sector = 8192 sector
    • Type ‘c’: FAT32 LBA
    • boot flag on
  • Second partition
    • Starts at: 100 MB -> 104,857,600 bytes ÷ 512 bytes/sector = 204,800 sector
    • Type ’83’: linux

Obviously the first partition will end at (204800-1)=204799 and the second will use all the remaining free space.
Start fdisk on the device and go through the menus.

Once we have the partitions we have to format them. The boot FAT32 partition can be formatted with Gparted if you like but the system ext4 partition is better to be done through the command line. These will be the ext4 parameters to use (consult the magic soup recipe):

  • Filesystem block = 4 kB
  • Stride = Page size / Filesystem block = 32 kB / 4 kB = 8
  • Stripe-width = Erase Block size / Filesystem block = 4 MB / 4 kB = 1024
  • No journal.

# mkfs.vfat -F 32 -n BOOT /dev/sdb1
# mkfs.ext4 -b 4096 -O ^has_journal -E stride=8,stripe-width=1024 -L ROOT /dev/sdb2

Copy the contents from the image to the SD.

The SD is ready, the partitions have been created and formatted, what is left is copying the contents from the downloaded Arch Linux image to the SD card including the MBR. For the data, we will have to mount the Arch Linux image, mount the SD partitions and copy from one to another, easy peasy.

Copy the MBR.
Note that the MBR is 512 bytes but we only have to copy the first 446 bytes, the rest of the bytes describe the partition table.
# dd if=archlinux-hf-2013-02-11.img of=/dev/sdb bs=446 count=1

Mount the SD card partitions.
The order is important because the boot partition has to be mounted inside the root partition, therefore first we have to mount the root (sdb2) and the boot (sdb1). Note that the mount points do not exist and we also have to create them.
# mkdir /mnt/sd
# mount /dev/sdb2 /mnt/sd
# mkdir /mnt/sd/boot
# mount /dev/sdb1 /mnt/sd/boot

Mount the Arch Linux image.
We will use the tool kpartx to load all the partitions contained in the image into the mapper.
List the partitions:
# kpartx -l archlinux-hf-2013-02-11.img
loop0p1 : 0 184320 /dev/loop0 2048
loop0p2 : 0 3481600 /dev/loop0 186368
loop deleted : /dev/loop0

Map the partitions:
# kpartx -va archlinux-hf-2013-02-11.img
add map loop0p1 (254:6): 0 184320 linear /dev/loop0 2048
add map loop0p2 (254:7): 0 3481600 linear /dev/loop0 186368

Verify they new mappings have been set:
#ls -l /dev/mapper/
total 0
crw------- 1 root root 10, 236 May 15 12:54 control
lrwxrwxrwx 1 root root 7 May 15 12:54 cryptlvm -> ../dm-0
brw-r--r-- 1 elhorzo users 254, 6 May 16 21:11 loop0p1
brw-r--r-- 1 elhorzo users 254, 7 May 16 21:11 loop0p2

Create the mount point and mount the root and the boot partitions (in that order):
# mkdir /mnt/archimage
# mount /dev/mapper/loop0p2 /mnt/archimage
# mount /dev/mapper/loop0p1 /mnt/archimage/boot

Copy the contents.
We will use the 'archive' option in order to preserve the permissions, ownership and links, also the 'archive' includes the 'recursive' option.
# cp -av /mnt/archimage/. /mnt/sd/
It is very important the dot ‘.‘ in the copy command, without the dot a new directory called ‘archmiage’ would be created in /mnt/sd instead of copying the contents.

Clean up.
Flush the buffers and unmount everything:
# sync
# umount /mnt/sd/{boot,}
# umount /mnt/archimage/{boot,}

And that’s all. You can plug the SD card into the Raspberry Pi and boot. If you have a headless Pi you can read my previous post about how to easily find out its IP address in order to SSH to it.

This entry was posted in Raspberry Pi and tagged , , , , , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s