U-Boot
From GumstixDocsWiki
As of 2010, all Gumstix customers should be using Gumstix OpenEmbedded, not Buildroot.
The Gumstix Developer's website is www.gumstix.net
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
For legacy customers still requiring buildroot:
The Gumstix uses the U-Boot bootloader to do the first-pass initialization of the hardware, and then load and jump to the Linux kernel. U-Boot provides a low-level way of accessing various devices on the gumstix before the full operating system is loaded. This page provides a very brief overview of some useful u-boot commands. A more complete description of U-Boot is available from the U-Boot project itself at sourceforge.
Linux Devices has a good article titled "Introduction to Das U-Boot, the universal open source bootloader".
An overview of U-Boot
U-boot is not an operating system; it's a bootloader. It includes some bare-bones read-only methods for accessing various devices, like MMC, CF, ethernet, but does not include any code to allow writing to most devices.
The idea is that u-boot is really supposed to be just enough to load & execute an OS kernel. The OS is where a programmer should generally be doing peripheral I/O beyond that needed to bootstrap the OS itself.
The U-boot command line is accessible from the Gumstix serial port (ttyS0 - 115200/8/1/N). To gain access to the U-boot prompt, power on the Gumstix and press any key within the first three seconds. The prompt will look like: GUM>
An overview of flash
Flash on the gumstix is divided from U-Boot's point of view into 3 chunks: sector 1:0, which runs from memory address 0x0 to 0x20000, contains the u-boot code. sector 1:1, running from 0x20000 to 0x40000, is used by u-boot to save its environment variables. This is a bit of a waste of space, and will likely be changed in the future, as the u-boot environment is typically a few hundred bytes at most, not nearly 128Kb. The third chunk of flash from U-Boot's perspective, stores a JFFS2 filesystem, which is the root partition for the linux operating system. This filesystem includes the kernel itself as well as the basic linux operating environment. u-boot includes a built-in software protection for sectors 0 and 1, to make it harder to accidentally nuke u-boot itself. To remove this protection if you do in fact want to overwrite u-boot, you'll want to use the
protect off all
command.
An overview of RAM
RAM starts at 0xa0000000 and runs to 0xa3f00000 -- above this address is where the running u-boot is loaded. It's generally a bad idea to overwrite the running u-boot in RAM.
The JFFS2 filesystem
You can read from the JFFS2 filesystem using the commands
ls fsload
The MMC card
After initializing the MMC system using the command
mmcinit
you can then access an MS-DOS filesystem on the MMC card using the commands
fatls mmc 1 fatload mmc 1 address filename
where address is the address that you wish to load the file to. Normally, you would load into RAM, which is located at a2000000.
The CF card
U-Boot 1.1.4-r1066 supports CF cards.
After initializing the CF system using the command
pinit on
you can then access an MS-DOS filesystem on the CF card using the commands
fatls ide 0 fatload ide 0 address filename
where address is the address that you wish to load the file to. Normally, you would load into RAM, which is located at a2000000.
U-Boot command line
You talk to u-boot through its basic command line interface. The most useful command is
help
which will dump a list of the available commands.
help command
will give you a display of the syntax for that command. You can use some basic environment variables in U-Boot. You can get a listing of the predefined ones using the
printenv
command. The bootcmd environment variable is run by u-boot to boot Linux. The default bootcmd on a Gumstix checks for a MMC card that contains a file named gumstix-factory.script and runs that script if it exists. To reference an environment variable in a command line, use the syntax
${variable}
or, for older versions of U-boot
$(variable)
To execute the value of an environment variable as a command, use
run ${variable}
You can enter multiple commands on a line by separating them with semi-colons:
command 1;command 2
Gumstix-factory.script
U-Boot scripts are just U-Boot commands that have a header for U-Boot. mkimage is the tool that is used to add the header. mkimage is in gumstix-buildroot/build_arm_nofpu/staging_dir/bin/. You can create your own bootcmd script. For example, to run a kernel on a MMC cardecho "Booting Development System..." set workedok Failed if mmcinit; then if fatload mmc 0 a2000000 uImage-2.6.17; then set workedok Success fi fi bootm a2000000
If you call this script my-gumstix-factory.script
mkimage -A arm -O linux -T script -C none -a 0 -e 0 -n gumstix-factory.script -d my-gumstix-factory.script gumstix-factory.script
will produce a U-Boot image that will be run if you place it on a MMC card with a kernel uImage named uImage-2.6.17.
Loading new stuff to flash
The two things you generally might want to load to flash are a new JFFS2 filesystem image (eg the output of the buildroot), or a new U-Boot. Before you copy either of these to flash, you'll have to load them to RAM. You currently cannot load directly to flash; in fact this tends to hose flash pretty badly -- if you unrecoverably write to your flash, and it's no longer erasable or writable by u-boot, we can provide a tool which will generally recover the flash, but it involves completely wiping all the data off the gumstix and starting over from scratch. Please contact customer support if you need this tool. To load the contents of a file to RAM, you'll first have to put the file somewhere it's accessible to the gumstix. The 2 easiest options are on the MMC card, or on the other end of a kermit-enabled serial line. The former of these will be a lot faster than the latter for large files like a JFFS2 image. You can load the file into RAM using, eg:
fatload mmc 1 a2000000 root_fs_arm
which will load the file root_fs_arm from the mmc card to start address a2000000. A nice side-effect of the load is that it stores the size of the thing it just loaded into the environment variable filesize. This can then be used later... If you're loading over a serial line using kermit, enter
loadb a2000000
and then initiate the kermit send (if it doesn't work, try the "robust"-mode of kermit). Again, u-boot will automatically set the filesize variable for you.
Now that the file has been loaded into flash, it would be a good idea to determine the 32-bit CRC of the file, and compare that to the 32-bit CRC of the file as it exists your build machine. In u-boot use:
crc32 a2000000 ${filesize}
To calculate the 32-bit CRC on your build machine see the Calculating 32 bit CRCs page.
Once the data you want to flash is loaded in RAM, you'll need to prepare the flash to be written. Flash has 2 main writing modes -- "turn bit off" for any addressable bit, and "erase sector" which resets all of the bits in that sector to 0xFF (ie turns all the bits on). Generally before you write data to flash, you'll first need to erase the sectors you're going to be writing to. In this example, we'll erase the JFFS2 filesystem portion of the flash (replace 31 below with 127 if you have the xm board):
era 1:2-31
or you can use
protect on 1:0-1 && erase all
which will work regardless of the flash size that you have.
That will chug away one sector at a time, erasing everything (setting all bytes to 0xFF). Once it's done, we can now copy the filesystem image from RAM to flash:
cp.b a2000000 40000 ${filesize}
Note how we're using cp.b, and how we're making use of the filesize (reminder: old versions use the "$(filesize)"-syntax) which was stored for us by U-Boot. Once the cp command is done, the flash is written. There's no sync or equivalent -- writes to flash are fully synchronous in U-Boot. Have a look at the Replacing the filesystem image page for a complete walk-through.
If you want to replace u-boot itself, almost the same commands are used, but you erase different sectors and copy to a different location:
mmcinit
fatload mmc 1 a2000000 u-boot.bin
protect off 1:0-1
era 1:0-1
cp.b a2000000 0 ${filesize}
reset
Note that the destination address used in the cp.b is 0 when updating u-boot and 40000 when updating the jffs2
or by serial (kermit):
GUM>loadb a2000000
kermit>send u-boot.bin
kermit>connect
GUM>protect off 1:0-1
GUM>era 1:0-1
GUM>cp.b a2000000 0 ${filesize}
GUM>reset
This will reboot the gumstix with the new u-boot now running. DO NOT USE SAVEENV BEFORE REBOOTING savenev before rebooting will cause the old u-boot to attempt to write the environment to *its* prefered location for that stuff to be saved, which is likely *not* the same place as the new u-boot wants it to be. It will quite likely trash some critical piece of new u-boot code in flash if you use old u-boot's saveenv to overwrite new u-boot. Note: After flashing u-boot no evnironment will be set, so on the next boot you will be told that CRC has failed and a default environment will be used. To fix this simply use the u-boot command "saveenv" to save the current environment. Remember you can check the environment with "printenv" end change variables with "setenv".
WARNING: It is important that you NOT call saveenv until AFTER rebooting with the new u-boot. If you call saveenv PRIOR to rebooting, then you will be attempthing to modify the environment of the new u-boot using the old u-boot, which may leave you with a completely hosed u-boot.
Loading via TFTP
If you have a network card for your gumstix, you can use TFTP to load files. You need to set the serverip variable to be the IP address of your TFTP server, and the ipaddr variable to IP address that you wish to assign to the gumstix. The IP addresses shown below are typical, you may need to adjust them for your network.
setenv serverip 192.168.1.1 setenv ipaddr 192.168.1.20 saveenv tftp a2000000 root_fs_arm.r734^
and then erase flash and copy into flash as above.
Under Windows, the following free TFTP servers have been used successfully: tftpd32 and uCon (about half way down the page).
Booting the kernel
The primary purpose of u-boot is to boot the linux kernel. It will do this by default by running the commands:
fsload a2000000 boot/uImage bootm a2000000
with appropriate bootargs.
To change the arguments provided to the kernel at boot time, specify them by setting a u-boot variable. The 2.6.10gum kernel uses:
setenv bootargs console=ttyS0,115200n8 root=1f02 rootfstype=jffs2 reboot=cold,hard
while the 2.6.13gum and later kernel uses a different numbering scheme to identify its flash partitions:
setenv bootargs console=ttyS0,115200n8 root=1f01 rootfstype=jffs2 reboot=cold,hard
Use printenv to print the environment variables, and saveenv to store them to flash, once you are satisfied that they are correct.
For more information on booting the kernel, specifying different kernel command line options, etc. please see the official U-Boot project site.
Recovering from screwed up boot files
If you happen to edit some of the boot files (like /etc/inittab or something else) and your kernel boots, but the user-mode stuff doesn't, you may be able to recover by changing the init program. You can tell the kernel the name of the init program to use using the init= option on the kernel command line. By default, the kernel runs /sbin/init which kicks off a number of other processes.
If you add init=/bin/sh to the kernel command line (u-boot bootargs variable) then the kernel will launch the shell directly. You can then recover the bad file using your backup (you did create a backup didn't you?) Or perhaps you can edit the offending file and fix it.
Remember that you need to keep all of the other arguments being passed into bootargs as well as adding init=. The simplest way to add the init= option to the end of bootargs is to do this:
setenv bootargs $bootargs init=/bin/sh boot
You can test your new boot files by executing:
exec init
from the shell. You need to use exec so that the init process takes over the shell. Init needs to have a process id of 1.
Once you're happy with everything, you can remove the init= option from bootargs and re-save the environment.
Note: This technique can also be used to change the root password (if you've changed it and forgotten).
Debugging
To debug u-boot, you'll need to use the JTAG connector.
List of U-Boot Commands
This is the output from U-Boot 1.2.0 on a verdex when turning the gumstix on, and typing "help".
U-Boot 1.2.0 (May 22 2007 - 20:41:35) - PXA270@600 MHz - 1352:1412 *** Welcome to Gumstix *** DRAM: 128 MB Flash: 32 MB Using default environment SMC91C1111-0 Net: SMC91C1111-0 Hit any key to stop autoboot: 0 GUM> help ? - alias for 'help' askenv - get environment variables from stdin autoscr - run script from memory base - print or set address offset bdinfo - print Board Info structure boot - boot default, i.e., run 'bootcmd' bootd - boot default, i.e., run 'bootcmd' bootelf - Boot from an ELF image in memory bootm - boot application image from memory bootp - boot image via network using BootP/TFTP protocol bootvx - Boot vxWorks from an ELF image cmp - memory compare coninfo - print console devices and information cp - memory copy crc32 - checksum calculation dcache - enable or disable data cache dhcp - invoke DHCP client to obtain IP/boot params diskboot- boot from IDE device echo - echo args to console erase - erase FLASH memory exit - exit script fatinfo - print information about filesystem fatload - load binary file from a dos filesystem fatls - list files in a directory (default /) flinfo - print FLASH memory information fsinfo - print information about filesystems fsload - load binary file from a filesystem image go - start application at address 'addr' help - print online help icache - enable or disable instruction cache ide - IDE sub-system iminfo - print header information for application image itest - return true/false on integer compare jerase - erase FLASH memory for JFFS2 katinstall - Load kernel to RAM from offset at top of flash katload - Load kernel to RAM from offset at top of flash loadb - load binary file over serial line (kermit mode) loads - load S-Record file over serial line loady - load binary file over serial line (ymodem mode) loop - infinite loop on address range loopw - infinite write loop on address range ls - list files in a directory (default /) md - memory display mdc - memory display cyclic mm - memory modify (auto-incrementing) mmcinit - init mmc card mtest - simple RAM test mw - memory write (fill) mwc - memory write cyclic nfs - boot image via network using NFS protocol nm - memory modify (constant address) ping - send ICMP ECHO_REQUEST to network host pinit - PCMCIA sub-system printenv- print environment variables protect - enable or disable FLASH write protection rarpboot- boot image via network using RARP/TFTP protocol reset - Perform RESET of the CPU run - run commands in an environment variable saveenv - save environment variables to persistent storage saves - save S-Record file over serial line setenv - set environment variables sleep - delay execution for some time test - minimal test like /bin/sh tftpboot- boot image via network using TFTP protocol version - print monitor version GUM>

