Sunday, March 21, 2010

Creating a bootable microSD card

In my mind one of the nicer features of the Overo COM computer is it will boot directly from a properly prepared microSD card.  The 'advantage' to having the Overo COM computer boot up from the microSD card first is you do not have to make any modifications to the onboard NAND image - if you trash the installed Operating System on the microSD card you can just remove the card and the Overo COM computer will bootup off the NAND rom code instead - I can think of several situations where this could be a handy feature!

The Overo boot rom sequence checks the microSD slot first to see if there is a device and if one is found it checks to see if there is a boot sector prior to checking the onboard NAND Rom.  If a boot sector is found on an installed microSD card the boot loader will attempt to load and execute the boot sector information.  In order to create a bootable microSD compatible with the OMAP3 boot ROM, you must set the geometry of the microSD card correctly otherwise the boot rom will not recognize the microSD card as a bootable device and pass control on to the code loaded in the NAND memory onboard the Overo COM.

The following instructions are performed on your development system - they are performed in a Linux environment and since your Overo development system is a Linux environment that seems like the logical machine to use (grin).  In order to configure the microSD card for the proper device geometry you use the fdisk "Expert mode".  The following instructions outline how to partition and format a bootable microSD card.

The following information describes the steps for setting up a brand new 2GB microSD card.  Since there are several different sizes of microSD cards I have included the instructions to setup the different sized cards.  The majority of the difference is in the calculation of the number of 'sectors' that you will need to enter when setting up the geometry of the microSD card.

One thing you will need is a flash card reader that is capable of working with microSD HC cards as well as microSD cards.  If the flash card reader cannot read (and write) to microSDHC cards then you will be limited to a maximum of 2-gig microSD card size (maximum size of microSD card - the HC specifications allow for up to 32-Gigs of storage).  If your machine has a SD Card slot check to see if the machine is capable of reading (and writing) to SDHC cards - if not obtain an external USB 2.0 card reader that does.  You will be much happier with the additional storage capacity of the SDHC cards.

Here is one type of microSD card reader that is USB 2.0 capable - it can be found here at Amazon.com - It is a great deal for the price!


Insert the microSD card into the development machine's flash card slot (or the external card reader). You may need to use a microSD to SD card adaptor to fit your slot.  On my Ubuntu 8.04 machine, the newly inserted card shows up as /dev/sdc and that is the device name that I will use for the following instructions. You will need to substitute the proper device name for your machine as I am sure our two machines are not configured the same (grin). You can use 'mount' or 'df' to see where the card mounts on your machine.  If you type 'mount' without anything else it will show you what is mounted where - df, which stands for 'disk files', shows you the information about the different partitions on your machine along with the device names and mount points.

Since your development system probably is configured to 'auto-mount' mountable devices and the microSD cards come formatted with Windows filesystems (seems to be the pervasive standard) the microSD card was most likely mounted to the filesystem automatically.  We do NOT need the card to be mounted at this time as we need to change the storage geometry of the card.  Let's unmount the device's existing file system before we get started with fdisk (type the command listed in blue then press ENTER):

 sudo umount /dev/sdc1

NOTE: Substitute the device name for your microSD card in place of the 'sdc1' listed above.

Partitioning the card

To perform the partitioning steps we need to launch the fdisk application and create an empty partition table on the microSD card. Note that the argument for fdisk is the entire device (/dev/sdc) not just a single partition (i.e. /dev/sdc1):
 sudo fdisk /dev/sdc      <--- be sure to specify your device for the microSD card here

Command (m for help): o

Building a new DOS disklabel. 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)

Let's first look at the current card information:

Command (m for help): p

Disk /dev/sdc: 2032 MB, 2032664576 bytes
64 heads, 63 sectors/track, 984 cylinders
Units = cylinders of 4032 * 512 = 2064384 bytes
Disk identifier: 0x00aa8e5c
Device Boot Start End Blocks Id System

Note the card size in bytes - I have it listed in RED above but it displays the same as the rest of the information on your development system. Write the information down as we will need it later in the process.  This is also one of the differences I mentioned earlier for creating bootable microSDHC cards.

Now go into fdisk "Expert" mode:

Command (m for help): x

Next we will set the geometry to 255 heads, 63 sectors and a calculated value for the number of cylinders required for the particular microSD card.  The 'calculated number of cylinders' is the difference for the different sized cards and is calculated the same across microSD cards.

There are a couple of methods we can use to calculate the number of cylinders for a specific microSD card:

1.  We can do it the hard way - To calculate the number of cylinders, we take the 2032664576 bytes reported above by fdisk divided by 255 heads, 63 sectors and 512 bytes per sector:
2032664576 / 255 / 63 / 512 = 247.12 which we round down to 247 cylinders.

***OR***

2.  The easy way - divide the size in bytes by 8225280 (which is 255 * 63 * 512) to get the number of whole cylinders (drop the fractional part which is also done in the "hard way" method).
2032664576 / 8225280 = 247.12, drop the fractional part to yield 247 cylinders.

Personally - I prefer the easy way myself!

Now that we have the number of cylinders we need for the specific geometry we are setting up on the microSD card we can proceed to do precisely that:

Expert command (m for help): h

Number of heads (1-256, default 4): 255

Expert command (m for help): s

Number of sectors (1-63, default 62): 63

Warning: setting sector offset for DOS compatiblity

Expert command (m for help): c

Number of cylinders (1-1048576, default 984): 247  <--- our calculated cylinder count

At this point we have configured the settings for the geometry of the microSD card and are finished with the 'expert' mode in fdisk - we need to return to the main mode to finish up the configuration of our microSD card and create a new 32 MB FAT partition to allow the Overo COM boot rom to recognize our boot partition:

Expert command (m for help): r

Command (m for help): n

Command action
e extended
p primary partition (1-4)

p

Partition number (1-4): 1

First cylinder (1-247, default 1): 1

Last cylinder or +size or +sizeM or +sizeK (1-247, default 15): +32M

Change the partition type to FAT32:

Command (m for help): t

Selected partition 1

Hex code (type L to list codes): c

Changed system type of partition 1 to c (W95 FAT32 (LBA))

And mark it bootable:

Command (m for help): a

Partition number (1-4): 1

Next we create an ext3 partition for the rootfs - the 'boot' partition we created is just to allow boot-up of the system - the next partition is where our operating system and filesystem will live:

Command (m for help): n
Command action
e extended
p primary partition (1-4)
p

Partition number (1-4): 2

First cylinder (6-247, default 6): 6

Last cylinder or +size or +sizeM or +sizeK (6-247, default 247): 247

To verify our work, let's print the partition info:

Command (m for help): p

Disk /dev/sdc: 2032 MB, 2032664576 bytes

255 heads, 63 sectors/track, 247 cylinders

Units = cylinders of 16065 * 512 = 8225280 bytes

Disk identifier: 0x00aa8e5c

Device       Boot     Start     End       Blocks       Id         System

/dev/sdc1     *           1         5        40131        c         W95 FAT32 (LBA)
/dev/sdc2                 6      247    1943865       83         Linux

Up to this point no changes have been made to the card itself - all of the changes exist in the partition table located in memory, so our final step is to write the new partition table to the card and then exit:

Command (m for help): w

The partition table has been altered!

Calling ioctl() to re-read partition table.

WARNING: If you have created or modified any DOS 6.x
partitions, please see the fdisk manual page for additional
information.

Syncing disks.

At this point we have exited the fdisk program after it altered the partition table of the microSD card.  We still have some things to do to the microSD card before we can use it with the Overo COM machines...

Formatting the new partitions

As you recall - we created two distinct partitions on the microSD card after we changed its geometry - one partition was a FAT-32 partition of about 23-megs in size and the second partition was a Linux ext3 partition comprised of the rest of the remaining microSD card storage space.

We format the first partition as a FAT file system (the -n parameter gives it a label of FAT, you can change or omit this if you like):

 sudo mkfs.vfat -F 32 /dev/sdc1 -n FAT

mkfs.vfat 2.11 (12 Mar 2005)

NOTE:  If you run into the issue where your development system does not recognize the mkfs.vfat command you need to install the mkfs.vfat application.  Some Linux versions do not install the DOS format program normally as part of their installations.

We format the second partition as an ext3 file system:

 sudo mkfs.ext3 /dev/sdc2

mke2fs 1.40.8 (13-Mar-2008)

Filesystem label=
OS type: Linux
Block size=4096 (log=2)
Fragment size=4096 (log=2)
121920 inodes, 485966 blocks

24298 blocks (5.00%) reserved for the super user

First data block=0
Maximum filesystem blocks=499122176
15 block groups
32768 blocks per group, 32768 fragments per group
8128 inodes per group

Superblock backups stored on blocks:
32768, 98304, 163840, 229376, 294912

Writing inode tables: done

Creating journal (8192 blocks): done

Writing superblocks and filesystem accounting information: done

This filesystem will be automatically checked every 36 mounts or
180 days, whichever comes first. Use tune2fs -c or -i to override.

At this point in the process we now have a microSD card with the proper storage geometry and properly formatted partitions.  Our next objective is to load a bootable operating system on the microSD card.

Installing the boot files

There are three files required on the first (FAT) partition to boot your Overo:

1.  MLO :

The boot-loader loader - this small program is loaded into the OMAP3 processor's static RAM.  It does some minimal configuration of system memory and io pins and then loads the second file.

2.  u-boot.bin :

The boot loader - This low-level application performs so housekeeping and loads the Linux kernel, then transfers control to the Linux kernel.  Probably would be considered the 'grub' of the Overo system.

3.  uImage:

The linux kernel - the actual kernel that will control the operating system operations.

You can build these components of the boot partition yourself or download pre-built images.  The uImage kernel is the one created during the Bitbake/Openembedded build process so would need to be loaded into the boot partition so it matches the rootfs installed in the second partition.  Failure to do this can (and usually does) result in different types of runtime issues from wrong kernel drivers (modules) all the way to kernel panics.  One advantage of building the different components yourself is you know what exactly is in them - if you actually study the source code that is (grin)...  Since the MLO initially configures the Omap processor pin configurations you will NEED to build this file if you need to change the default configurations.

It is very important that these three files have precisely these names and are loaded into the boot partition in a very specific order.  The Overo boot loader does not use the names per-se but instead loads the FIRST installed file on the boot partition (MLO) which does look for specific name 'u-boot.bin' when it is time to load the boot loader.  The boot loader also looks for the specific name uImage to load the Linux kernel.

Given the above information it becomes apparent why the names of the file must match and also the sequence used to load the specific files into the bootable partition on the microSD card.

It is beyond the scope of this posting on "how" to create the above listed files - this is an exercise left up to you (and a later posting - grin).   Once you have completed building or downloading these files, mount the FAT partition of your microSD card. This example will assume that you have mounted it at /media/card:

NOTE: If there is not a /media/card mount-point you will need to create it using the following command:

sudo  mkdir  -p   /media/card

Now mount the microSD card filesystem to the development system's filesystem:
sudo  mount  /dev/sdc1  /media/card  <--- remember to use your device specification here
Due to constraints of the mask boot ROM in the OMAP processor, MLO MUST be written first:
({directory-path} is the directory path to where the MLO-overo file is located on your system)

sudo  cp  {directory-path}/MLO-overo  /media/card/MLO

Then copy u-boot and the linux kernel to the card:
(The order of the copy commands is not important here - just that MLO was copied to the boot partition FIRST)
sudo  cp  {directory-path}/u-boot-overo.bin   /media/card/u-boot.bin

sudo  cp  {directory-path}/uImage-overo.bin   /media/card/uImage

We are done with the construction of the boot partition on the microSD card so you can now unmount the FAT partition:

sudo umount /dev/sdc1

At this point you have a bootable FAT partition.  Pat yourself on the back - grab a beer (if of legal age!) and enjoy!!!  You have accomplished something here today!

We still have one final task to complete in order to have a full-fledged bootable operating system on the microSD card - The final step is to untar your desired rootfs onto the ext3 partition that you created above.  It is outside the scope of these instructions - the rootfs file referenced here is created as part of the build process performed by the Bitbake/Openembedded development system for the Overo COM.  You can download pre-compiled versions from the Overo Development site or create your own using the Bitbake/Openembedded development system.

Note that this step can be dangerous. You do not want to untar your Overo rootfs onto your development machine - be careful!

This example will assume that you have mounted it at /media/card - following step performs this task:

sudo mount /dev/sdc /media/card

Now untar your desired rootfs - very important, you want to be in the partition on the microSD card to perform the untar operation!  Perform the following step!

cd /media/card

VERY IMPORTANT - Be sure to list the full path to the rootfs file in the following instruction...
sudo tar -xvjf   /path/to/omap3-console-image-overo.tar.bz2

Once the system has finished installation of the root filesystem on the second partition of the microSD card you can check it out using the ls command to see the content.  You can also use the df command to see how much of the second partition is used and how much free space there in the microSD card.  Once you are satisfied things look correct you can unmount the microSD second ext3 partition from your development system:

sudo umount /dev/sdc2

Congratulations!!!!!  You have reached that thrilling moment of truth!

You are now the proud owner of a microSD card with a bootable Overo operating system in it. 

If you have done everything correctly and you have a viable MLO, u-boot.bin, uImage and rootfs system installed on the microSD card and the uImage and rootfs cross-compiled correctly (a lot of if's I know!) you should be able to boot up the Overo from the microSD card simply by inserting the microSD card into the Overo microSD card socket and applying power to the Overo COM machine.  Watch the information displayed from the console output of the Overo during bootup to verify it is indeed booting from the microSD card.

Let me know how it goes for you!  Good, bad or indifferent I want to hear from you!!!

A couple of notable items:

1.  You want to use microSD cards that are rated as Class-6 cards.  There are several Class ratings and the lower numbers are slower microSD cards.

2.  You get what you pay for in microSD Cards - if you use a cheap card then you most likely will have issues later - I did not say inexpensive cards as there are some good inexpensive cards out there - I am referring to "cheap" inferior cards that use old flash rom technologies.

3.  If there is an interest I will build pre-configured microSD Cards for a small fee - you supply the cards and I will reset the geometries and perform the partitioning and formatting operations - let me know if this is something of interest to my readers (grin).  For an additional small fee I will load the cards as well with the boot partition and root filesystem.  Contact me here if interested (leave me a comment)...

A second item - I have listed several hardware sites where you can get really good pricing and I make a very small commission from the sale - I realize this seems tacky but I have to do something given the current financial hole I find myself in at the moment.  

Thanks for understanding and a Special Thanks to those who help out!

No comments:

Post a Comment