Booting the Neo FreeRunner from SD via U-Boot

From Openmoko

Revision as of 07:20, 23 July 2008 by Mmontour (Talk | contribs)

Jump to: navigation, search

Here are the steps described to boot your system from an SD card. The SD card shares a bus with the GPU, so it may not perform as well, but it is another option.

Some versions of u-boot (including the one shipped on the first batch of Freerunners) don't work properly for booting from SD card. Daily images on buildhost with a timestamp of "20080723" or newer should be OK.

Be careful when flashing a new u-boot to a Neo1973 as there is a risk of bricking your device. This is not a concern for a Freerunner as it contains a backup copy of u-boot in NOR Flash.


Contents

Change your kernel settings

Note: Since 2008-07-17 the kernel includes support for ext3 and ext2 filesystems. ext2 is recommended because of the finite write life of flash storage. Prior to 2008-07-17, the kernel only came configured with support for ext3. You can check the available filesystems with

less /proc/filesystems


Kernel building is supposed to be done through OpenEmbedded. If you use the MokoMakefile open up $OMDIR/openmoko/trunk/oe/packages/linux/linux-gta01/defconfig-2.6.21.6-fic-gta01. If you are building OM-2007.2 open $OEDIR/openembedded/packages/linux/linux-openmoko/defconfig-2.6.22.5-fic-gta01.

Note: That kernel version may change in future releases.

Now find the line saying:

CONFIG_MMC_S3C=m

and change it to:

CONFIG_MMC_S3C=y

If you want to use an ext2 file system on the SD, also find the line saying:

CONFIG_EXT2_FS=m

and change it to:

CONFIG_EXT2_FS=y

If you're using MokoMakfile, you can clean out your last kernel build (forcing a new build) by running:

make clean-package-linux-openmoko

Acquiring a tarfile rootfs

There are two ways of acquiring an rootfs image as a tar archive. You can either build it on your own using the OpenEmbedded Distribution. Or download it from the openmoko buildhost.


Possibility 1: Downloading the rootfs/kernel tar from the Openmoko buildhost

Choose and find the rootfs/kernel combo you would like to install at Latest Images.

Possibility 2: Building a tarfile distribution using OpenEmbedded

Another possibility to get a tar archive of your rootfs is to build it on your own with the OpenEmbedded environment.

To build OM-2007.2 you need to add "tar" to the image types in your local.conf:

IMAGE_FSTYPES = "jffs2 tar"

After that build a new image by issuing:

bitbake openmoko-devel-image

or if you are using the MokoMakefile:

make openmoko-devel-image

After the process finished there will be a OpenMoko-....tar in the deploy directory, which is your newly created rootfs archive


Prepare the SD card

Partioning the SD card

Unfortunately the uboot loader can only read from FAT partitions. Therefore the kernel needs to be stored in a partition with this filesystem. Nevertheless we want to store our rootfs in an ext3 (or ext2) filesystem. To acomplish this the sd-card needs to be partitioned into to different parts. This example shows how to do this using the fdisk utility. Feel free to use the partitioning utility of your liking for this task.

fdisk /dev/mmcblk0

Note: The device file might differ on your system. If you are not sure about it, you may check your kernel message log by calling dmesg to find the correct device.

We will now create a 8 mb partition for our kernel and another one for the rootfs which will take up all the remaining space.

  Command (m for help): d
  Selected partition 1
  Command (m for help): n
  Command action
     e   extended
     p   primary partition (1-4)
  p
  Partition number (1-4): 1
  First cylinder (1-983, default 1):
  Using default value 1
  Last cylinder or +size or +sizeM or +sizeK (1-983, default 983): +8M
  Command (m for help): n
  Command action
     e   extended
     p   primary partition (1-4)
  p
  Partition number (1-4): 2
  First cylinder (18-983, default 18):
  Using default value 18
  Last cylinder or +size or +sizeM or +sizeK (18-983, default 983):
  Using default value 983
  Command (m for help): w
  The partition table has been altered!
  Calling ioctl() to re-read partition table.
  Syncing disks.

Formatting the SD card

As already mentioned we need the first partition to be formatted with the FAT filesystem. Just issue the following command to create this fs:

mkfs.vfat /dev/mmcblk0p1

The second partition is about to be formatted with ext3 (For ext2 to work you need to make sure you compiled the kernel with the correct configuration):

mkfs.ext3 /dev/mmcblk0p2


Populate SD card

Your sd card is now ready to be filled up with the rootfs and the needed kernel to boot.

Mount the second partition of your SD card somewhere and put the image on it:

mount /dev/mmcblk0p2 /mnt/moko
tar -C /mnt/moko/ -xzvf openmoko-devel-image-fic-gta01-20070313022035.rootfs.tar.gz

Note: As always in this guide the device name as well as the rootfs name needs to be adjusted to your device and filename structure

The next step is to mount the first partition of the sd card and install the kernel on it.

mount /dev/mmcblk0p1 /mnt/mokokernel
cp uImage-fic-gta01-latest.bin /mnt/mokokernel/uImage.bin

Make sure your kernel is called uImage.bin after copying it to the card.

Unmount both the rootfs partition and the kernel partition and make sure all remaining buffers are written to it:

umount /mnt/moko
umount /mnt/mokokernel
sync

Add uboot boot entry

Dependent on the revision of the phone and the partition type (ext2/ext3) you are using it might be necessary to add an entry to the bootmenu, to be able to boot the system of your sd card. If you are using a Freerunner and have created an ext2 partition you should be able to boot from the card right out of the box, because a boot menu entry for this should already exist in the NAND boot menu. In any other case you should at least make sure the needed entry exists in your menu before proceeding. You will need to enter the uboot shell of the NAND boot menu for this. A description on how to connect to the uboot loader shell can be found in this article: Uboot#Bootloader_prompt. Details on howto get into the NAND boot menu can be found here.

After you read these two references you should be connected to your NAND uboot shell right now. The first thing to do is to set the boot menu timeout to a really high value. Unfortunately if you don't do this, the boot loader will continue booting after the default timeout (60 seconds) even if you are connected to the uboot shell. Just enter the following command to the menu prompt:

setenv boot_menu_timeout 99999

This will set the timeout to 99999 seconds which should definitely enough time for us finish whatever work we want accomplish in the boot loader shell.

Now we will make sure a appropriate menu item for booting from sd exists, or create it otherwise. You can print the defined boot loader environment by issuing the command:

printenv

If it shows a line beginning with menu_ followed by the commands which are just to follow in this guide, you do not need to create a new menu entry. In any other case please proceed with the following.

It is important to distinguish between ext2 and ext3 root partitions at this point. Please make sure you are using the correct configuration based on the decisions you made earlier.


Boot entry for ext3 partitions:

setenv menu_9 Boot from microSD (FAT+ext3): setenv bootargs \${bootargs_base} rootfstype=ext3 root=/dev/mmcblk0p2 rootdelay=5 \${mtdparts} ro\; mmcinit\; fatload mmc 1 0x32000000 \${sd_image_name}\; bootm 0x32000000

Boot entry for ext2 partitions:

setenv menu_9 Boot from microSD (FAT+ext2): setenv bootargs \${bootargs_base} rootfstype=ext2 root=/dev/mmcblk0p2 rootdelay=5 \${mtdparts} ro\; mmcinit\; fatload mmc 1 0x32000000 \${sd_image_name}\; bootm 0x32000000

Note: The backslashes (\) are important for uboot to set the command as new environment variable (menu_9) instead of just executing them as soon as enter is pressed

Note: Copy and paste may not work. At least it did not work for me as I tried. You will have to type in the commandline manually.

You are nearly done. Just issue a

printenv

and verify that your newly created entry is correctly displayed (This time the backslashes are not displayed anyone).

If everything looks fine enter

saveenv

into the prompt and press enter. The new configuration should now be saved to the NAND.

Shutdown your neo with the following command:

neo1973 power-off

After you restarted the Neo and got back to the NAND boot menu you should be able to select your newly created menu entry and successfully boot into the rootfs from your sd card.

Appendix

Boot from SDHC

As SDHC is currently not supported in u-boot you can't use the Booting from SD guide. But there's a kind of workaround that is a good option to have at least your rootfs on the microSDHC:

First you can follow Step 1 to get an kernel-image with mmc- and ext2-support. But instead of copying the image to the rootfs you will have to flash it to the Neo's internal NAND-Flash (using Dfu-util). Now you can continue with Step 2 (like mentioned before you do not have to copy your uImage to the rootfs) and follow the instructions to Step 3. Instead of the setenv commands in Step 3 you have to enter the following:

GTA01Bv4 # setenv menu_5 Boot from SDHC: setenv  bootargs root=/dev/mmcblk0p1 console=tty0 rootdelay=5 neo1973-nand:0x00040000(u-boot),0x00004000(u-boot_env),0x00200000(kernel),0x000a0000(splash)\; nand read.e 0x32000000 kernel\; bootm 0x32000000
GTA01Bv4 # saveenv

And that's it! Now you can use the newly created menu option "Boot from SDHC" to boot the internal kernel, using the root-filesystem on the microSDHC.


Autoboot from SDHC

Maybe you want to Boot automatically from SDHC: Set a new Bootmenu Entry for booting from NAND first

GTA01Bv4 # setenv menu_6 Boot from NAND: setenv bootargs \${bootargs_base} \${mtdparts}\; nand read.e 0x32000000 kernel\; bootm 0x32000000
GTA01Bv4 # saveenv

then Power-off, and enter the Bootmenu to test the new Entry.If you can boot from NAND, shutdown, enter Boot menu, connect to bootloader and set the (auto)bootcmd for boot from SDHC:

GTA01Bv4 # setenv bootcmd setenv bootargs root=/dev/mmcblk0p1 rootdelay=10 console=tty0 neo1973-nand:0x00040000(u-boot),0x00004000(u-boot_env),0x00200000(kernel),0x000a0000(splash)\; nand read.e 0x32000000 kernel\; bootm 0x32000000 
GTA01Bv4 # saveenv

Now you boot from SDHC everytime you press the Power-Button or reboot and if you like to boot from NAND -just use the bootmenu.


Fixing udev automount

Udev automatically mounts the SD Card in /media/mmcblk0p1/ you can disable this with

echo /dev/mmcblk >> /etc/udev/mount.blacklist

Remarks on Kernel Parameters

loglevel

Some people suggested adding:

loglevel=8

to the kernel command line. This makes the boot process extremely slow because the framebuffer (the neo display in text mode) has to print out tons of lines of debug messages like:

s3c2410-sdi s3c2410-sdi: ......
mmc0: ....
Personal tools

Here are the steps described to boot your system from an SD card. The SD card shares a bus with the GPU, so it may not perform as well, but it is another option.

Some versions of u-boot (including the one shipped on the first batch of Freerunners) don't work properly for booting from SD card. Daily images on buildhost with a timestamp of "20080723" or newer should be OK.

Be careful when flashing a new u-boot to a Neo1973 as there is a risk of bricking your device. This is not a concern for a Freerunner as it contains a backup copy of u-boot in NOR Flash.


Change your kernel settings

Note: Since 2008-07-17 the kernel includes support for ext3 and ext2 filesystems. ext2 is recommended because of the finite write life of flash storage. Prior to 2008-07-17, the kernel only came configured with support for ext3. You can check the available filesystems with

less /proc/filesystems


Kernel building is supposed to be done through OpenEmbedded. If you use the MokoMakefile open up $OMDIR/openmoko/trunk/oe/packages/linux/linux-gta01/defconfig-2.6.21.6-fic-gta01. If you are building OM-2007.2 open $OEDIR/openembedded/packages/linux/linux-openmoko/defconfig-2.6.22.5-fic-gta01.

Note: That kernel version may change in future releases.

Now find the line saying:

CONFIG_MMC_S3C=m

and change it to:

CONFIG_MMC_S3C=y

If you want to use an ext2 file system on the SD, also find the line saying:

CONFIG_EXT2_FS=m

and change it to:

CONFIG_EXT2_FS=y

If you're using MokoMakfile, you can clean out your last kernel build (forcing a new build) by running:

make clean-package-linux-openmoko

Acquiring a tarfile rootfs

There are two ways of acquiring an rootfs image as a tar archive. You can either build it on your own using the OpenEmbedded Distribution. Or download it from the openmoko buildhost.


Possibility 1: Downloading the rootfs/kernel tar from the Openmoko buildhost

Choose and find the rootfs/kernel combo you would like to install at Latest Images.

Possibility 2: Building a tarfile distribution using OpenEmbedded

Another possibility to get a tar archive of your rootfs is to build it on your own with the OpenEmbedded environment.

To build OM-2007.2 you need to add "tar" to the image types in your local.conf:

IMAGE_FSTYPES = "jffs2 tar"

After that build a new image by issuing:

bitbake openmoko-devel-image

or if you are using the MokoMakefile:

make openmoko-devel-image

After the process finished there will be a OpenMoko-....tar in the deploy directory, which is your newly created rootfs archive


Prepare the SD card

Partioning the SD card

Unfortunately the uboot loader can only read from FAT partitions. Therefore the kernel needs to be stored in a partition with this filesystem. Nevertheless we want to store our rootfs in an ext3 (or ext2) filesystem. To acomplish this the sd-card needs to be partitioned into to different parts. This example shows how to do this using the fdisk utility. Feel free to use the partitioning utility of your liking for this task.

fdisk /dev/mmcblk0

Note: The device file might differ on your system. If you are not sure about it, you may check your kernel message log by calling dmesg to find the correct device.

We will now create a 8 mb partition for our kernel and another one for the rootfs which will take up all the remaining space.

  Command (m for help): d
  Selected partition 1
  Command (m for help): n
  Command action
     e   extended
     p   primary partition (1-4)
  p
  Partition number (1-4): 1
  First cylinder (1-983, default 1):
  Using default value 1
  Last cylinder or +size or +sizeM or +sizeK (1-983, default 983): +8M
  Command (m for help): n
  Command action
     e   extended
     p   primary partition (1-4)
  p
  Partition number (1-4): 2
  First cylinder (18-983, default 18):
  Using default value 18
  Last cylinder or +size or +sizeM or +sizeK (18-983, default 983):
  Using default value 983
  Command (m for help): w
  The partition table has been altered!
  Calling ioctl() to re-read partition table.
  Syncing disks.

Formatting the SD card

As already mentioned we need the first partition to be formatted with the FAT filesystem. Just issue the following command to create this fs:

mkfs.vfat /dev/mmcblk0p1

The second partition is about to be formatted with ext3 (For ext2 to work you need to make sure you compiled the kernel with the correct configuration):

mkfs.ext3 /dev/mmcblk0p2


Populate SD card

Your sd card is now ready to be filled up with the rootfs and the needed kernel to boot.

Mount the second partition of your SD card somewhere and put the image on it:

mount /dev/mmcblk0p2 /mnt/moko
tar -C /mnt/moko/ -xzvf openmoko-devel-image-fic-gta01-20070313022035.rootfs.tar.gz

Note: As always in this guide the device name as well as the rootfs name needs to be adjusted to your device and filename structure

The next step is to mount the first partition of the sd card and install the kernel on it.

mount /dev/mmcblk0p1 /mnt/mokokernel
cp uImage-fic-gta01-latest.bin /mnt/mokokernel/uImage.bin

Make sure your kernel is called uImage.bin after copying it to the card.

Unmount both the rootfs partition and the kernel partition and make sure all remaining buffers are written to it:

umount /mnt/moko
umount /mnt/mokokernel
sync

Add uboot boot entry

Dependent on the revision of the phone and the partition type (ext2/ext3) you are using it might be necessary to add an entry to the bootmenu, to be able to boot the system of your sd card. If you are using a Freerunner and have created an ext2 partition you should be able to boot from the card right out of the box, because a boot menu entry for this should already exist in the NAND boot menu. In any other case you should at least make sure the needed entry exists in your menu before proceeding. You will need to enter the uboot shell of the NAND boot menu for this. A description on how to connect to the uboot loader shell can be found in this article: Uboot#Bootloader_prompt. Details on howto get into the NAND boot menu can be found here.

After you read these two references you should be connected to your NAND uboot shell right now. The first thing to do is to set the boot menu timeout to a really high value. Unfortunately if you don't do this, the boot loader will continue booting after the default timeout (60 seconds) even if you are connected to the uboot shell. Just enter the following command to the menu prompt:

setenv boot_menu_timeout 99999

This will set the timeout to 99999 seconds which should definitely enough time for us finish whatever work we want accomplish in the boot loader shell.

Now we will make sure a appropriate menu item for booting from sd exists, or create it otherwise. You can print the defined boot loader environment by issuing the command:

printenv

If it shows a line beginning with menu_ followed by the commands which are just to follow in this guide, you do not need to create a new menu entry. In any other case please proceed with the following.

It is important to distinguish between ext2 and ext3 root partitions at this point. Please make sure you are using the correct configuration based on the decisions you made earlier.


Boot entry for ext3 partitions:

setenv menu_9 Boot from microSD (FAT+ext3): setenv bootargs \${bootargs_base} rootfstype=ext3 root=/dev/mmcblk0p2 rootdelay=5 \${mtdparts} ro\; mmcinit\; fatload mmc 1 0x32000000 \${sd_image_name}\; bootm 0x32000000

Boot entry for ext2 partitions:

setenv menu_9 Boot from microSD (FAT+ext2): setenv bootargs \${bootargs_base} rootfstype=ext2 root=/dev/mmcblk0p2 rootdelay=5 \${mtdparts} ro\; mmcinit\; fatload mmc 1 0x32000000 \${sd_image_name}\; bootm 0x32000000

Note: The backslashes (\) are important for uboot to set the command as new environment variable (menu_9) instead of just executing them as soon as enter is pressed

Note: Copy and paste may not work. At least it did not work for me as I tried. You will have to type in the commandline manually.

You are nearly done. Just issue a

printenv

and verify that your newly created entry is correctly displayed (This time the backslashes are not displayed anyone).

If everything looks fine enter

saveenv

into the prompt and press enter. The new configuration should now be saved to the NAND.

Shutdown your neo with the following command:

neo1973 power-off

After you restarted the Neo and got back to the NAND boot menu you should be able to select your newly created menu entry and successfully boot into the rootfs from your sd card.

Appendix

Boot from SDHC

As SDHC is currently not supported in u-boot you can't use the Booting from SD guide. But there's a kind of workaround that is a good option to have at least your rootfs on the microSDHC:

First you can follow Step 1 to get an kernel-image with mmc- and ext2-support. But instead of copying the image to the rootfs you will have to flash it to the Neo's internal NAND-Flash (using Dfu-util). Now you can continue with Step 2 (like mentioned before you do not have to copy your uImage to the rootfs) and follow the instructions to Step 3. Instead of the setenv commands in Step 3 you have to enter the following:

GTA01Bv4 # setenv menu_5 Boot from SDHC: setenv  bootargs root=/dev/mmcblk0p1 console=tty0 rootdelay=5 neo1973-nand:0x00040000(u-boot),0x00004000(u-boot_env),0x00200000(kernel),0x000a0000(splash)\; nand read.e 0x32000000 kernel\; bootm 0x32000000
GTA01Bv4 # saveenv

And that's it! Now you can use the newly created menu option "Boot from SDHC" to boot the internal kernel, using the root-filesystem on the microSDHC.


Autoboot from SDHC

Maybe you want to Boot automatically from SDHC: Set a new Bootmenu Entry for booting from NAND first

GTA01Bv4 # setenv menu_6 Boot from NAND: setenv bootargs \${bootargs_base} \${mtdparts}\; nand read.e 0x32000000 kernel\; bootm 0x32000000
GTA01Bv4 # saveenv

then Power-off, and enter the Bootmenu to test the new Entry.If you can boot from NAND, shutdown, enter Boot menu, connect to bootloader and set the (auto)bootcmd for boot from SDHC:

GTA01Bv4 # setenv bootcmd setenv bootargs root=/dev/mmcblk0p1 rootdelay=10 console=tty0 neo1973-nand:0x00040000(u-boot),0x00004000(u-boot_env),0x00200000(kernel),0x000a0000(splash)\; nand read.e 0x32000000 kernel\; bootm 0x32000000 
GTA01Bv4 # saveenv

Now you boot from SDHC everytime you press the Power-Button or reboot and if you like to boot from NAND -just use the bootmenu.


Fixing udev automount

Udev automatically mounts the SD Card in /media/mmcblk0p1/ you can disable this with

echo /dev/mmcblk >> /etc/udev/mount.blacklist

Remarks on Kernel Parameters

loglevel

Some people suggested adding:

loglevel=8

to the kernel command line. This makes the boot process extremely slow because the framebuffer (the neo display in text mode) has to print out tons of lines of debug messages like:

s3c2410-sdi s3c2410-sdi: ......
mmc0: ....