The Mer Wiki now uses your Mer user account and password (create account on https://bugs.merproject.org/)


U-boot adaptation guide

From Mer Wiki
Revision as of 08:36, 1 February 2013 by Kjokinie (Talk | contribs)

Jump to: navigation, search

Contents

UNDER CONSRUCTION!

PAGE STILL UNDER CONSTRUCTION...

Basic assumptions / scope

  • This guide is meant for converting a working u-boot to boot to mer / nemo from SD card or internal eMMC.
    • "loadaddr" environment variable is defined
  • It is assumed that you have some way of accessing u-boot console (serial / adb / etc)
  • Mer / Nemo / etc image with separate FAT or Ext2 boot partition and a root partition on your boot media (SD or eMMC)
    • in case of device internal eMMC you need HW specific flashing tools to transfer the image to it
  • u-boot features needed:
    • working mmc/SD card driver for your board
    • "fat load" or ext2load support (CONFIG_CMD_FAT, CONFIG_CMD_EXT2)
    • hush shell support (CONFIG_SYS_HUSH_PARSER)

Minimum path to boot

What are the absolute minimum things to get u-boot boot a linux-kernel from a SD card or eMMC for mer/nemo?

Here is the list:

  • load the kernel uImage from a disk to memory
    • fat load / ext2load / mmc load
  • start the kernel
    • bootm ${loadaddr}
  • pass right parameters to kernel in "bootargs" environment variable
    • parameters specific for the HW (typically just re-use what is there already in bootargs)
    • Mer/Nemo root FS location
    • systemd.unit=start.getty

Quick & generic SD card boot (Hacker's view)

Device Setup

  • Insert SD card with nemo image (uImage on ext2 or vfat boot partition, and rootfs on second partition)
  • Boot the device to u-boot console

u-boot environment

Then we need to setup the above minimum things in u-boot environment in place. Start with running "printenv"

$ printenv
bootcmd=run emmcboot
bootdelay=1
baudrate=115200
verify=n
rdinit=init
loadaddr=0x00100000
console=ttyAMA2,115200n8
...
<clip><clip>


Now you see what is the current environment, it's good idea to copy-paste this somewhere safe just in case you make a mess of it ;)

Generic u-boot script for booting

Now then, the steps to success were to load the kernel and boot it, so we set up a generic script to do that (copy paste below command to u-boot prompt):

setenv nemo_bootcmd 'for j in 2 1 0; do \
	echo stepj $j; \
		mmc rescan $j;
		for i in 0 1 2 3 4 5 6 7 8 9 a b c d e f 10 11 12 13 14 15 16 17 18 19; do \
			mmc rescan $j; \
			if fat load mmc $j:$i ${loadaddr} /uImage; then \
				bootm ${loadaddr}; \
			fi; \
			if fat load mmc $j:$i ${loadaddr} /boot/uImage; then \
				bootm ${loadaddr}; \
			fi; \
			if ext2load mmc $j:$i ${loadaddr} /uImage; then \
				bootm ${loadaddr}; \
			fi; \
			if ext2load mmc $j:$i ${loadaddr} /boot/uImage; then \
				bootm ${loadaddr}; \
			fi; \
			echo no device found in mmc $j partition $i; \
		done; \
	done'

The command above sets up a new environment variable "nemo_bootcmd", that, if run, goes through mmc devices 2, 1, and 0 and tries loading uImage from partitions 1 to 25 on each of those devices. It tries to load the kernel uImage with fat load (in case it's a FAT partition) and ext2load (in case it's ext2 partition) from / and /boot/ folders (the most likely locations). If a image is found and loaded successfully it is started with the bootm command.

Setting up boot arguments for kernel

Next, before we boot, we need to make sure kernel gets right bootargs passed so it knows where the root filesystem is. On my SD card the boot partition is partition 1 and root fs partition is 2. Check what does is set for bootargs when you run "printenv". Let's say the bootargs looks like this:

bootargs=cachepolicy=writealloc noinitrd hwtoolonuart= rdinit=init init=init board_id=1 crashkernel=crashkernel=1M@0x5600000 logo.nologo startup_graphics=1 root=/dev/mmcblk2p2 console=ttyAMA2,115200n8

Now there already is a "root" parameter there (root=/dev/mmcblk2p2), but it's pointing to mmc dev 2 (mmcblk2), the partition is correct (p2). With mmcinfo command I find out that my 8GB SD card is in mmc dev 1, like this

$ mmc list
EMMC: 0
 MMC: 1
$ mmcinfo 1
Device: MMC
Manufacturer ID: 2
OEM: 544d
Name: SA08G 
Tran Speed: 25000000
Rd Block Len: 512
SD version 2.0
High Capacity: Yes
Capacity: 7973371904
Bus Width: 4-bit

So we need to change the kernel arguments to match that. Also SD cards often wakes up slowly, so additional "rootwait" parameter is needed so that kernel will wait for the SD card to appear. For systemd we also need this parameter "systemd.unit=start.getty".

So let's redefine the boot arguments with following:

setenv bootargs 'cachepolicy=writealloc noinitrd hwtoolonuart= rdinit=init init=init board_id=1 \
crashkernel=crashkernel=1M@0x5600000 logo.nologo startup_graphics=1 root=/dev/mmcblk1p2 rootwait \
console=ttyAMA2,115200n8 systemd.unit=start.getty'

Boot the kernel!

Now then, everything should be set up for successfull boot. Let's try running our script:

$ run nemo_bootcmd
U8500 $ run nemo_bootcmd
Writing partition block (if needed)...
 eMMC partition block exists now
MMC Device 2 not found
MMC Device 2 not found

** Invalid boot device **
MMC Device 2 not found

** Invalid boot device **
MMC Device 2 not found
** Block device mmc 2 not supported
MMC Device 2 not found
** Block device mmc 2 not supported
no device found in mmc 2 partition 0

<clip-clip>
....
<clip-clip\>

** Invalid boot device **
MMC Device 2 not found
** Block device mmc 2 not supported
MMC Device 2 not found
** Block device mmc 2 not supported
no device found in mmc 2 partition 19
** Partition 0 not valid on device 1 **

** Unable to use mmc 1:0 for fatload **
** Partition 0 not valid on device 1 **

** Unable to use mmc 1:0 for fatload **
Loading file "/uImage" from mmc device 1
Failed to mount ext2 filesystem...
** Bad ext2 partition or disk - mmc 1:0 **
Loading file "/boot/uImage" from mmc device 1
Failed to mount ext2 filesystem...
** Bad ext2 partition or disk - mmc 1:0 **
no device found in mmc 1 partition 0
Reading /uImage

4764960 bytes read
## Booting kernel from Legacy Image at 00100000 ...
   Image Name:   Linux-3.0.8.20121218.2
   Image Type:   ARM Linux Kernel Image (uncompressed)
   Data Size:    4764896 Bytes =  4.5 MB
   Load Address: 00008000
   Entry Point:  00008000
   Loading Kernel Image ... OK
OK

Starting kernel ...  arch 3293

Uncompressing Linux... done, booting the kernel.

So now the kernel was found and booted from partition 1 of mmc dev 1 (which was my SD card). Nice!

Making it automatic for your device

The above steps were nice to get Nemo booted once, but how to make it automatic so you don't need to type in the changes above on every boot.

  • Run the steps above again, except do not run the nemo_bootcmd.

If you don't stop u-boot to command prompt during normal boot, u-boot will automatically execute the environment variable "bootcmd". Let's see what is in bootcmd now:

$ printenv
...
bootcmd=run emmcboot
...

On my device the default bootcmd runs another script that boots a kernel from eMMC. Let's edit this a bit to add our boot there as well:

setenv bootcmd 'run nemo_bootcmd; run emmcboot'

Now our "nemo_bootcmd" boot script will be run first. In case our boot script does not find anything to boot, the old boot command will still get executed as backup.

Lastly and most importantly, you must save the changes to flash in order for this to work automatically.

$ saveenv
Saving Environment to EMMC...
Writing to EMMC... done

Now reboot your device and do not interrupt u-boot for console. Congratulations, you have automatic boot setup!

Maintainers way

Personal tools