Click here to learn
about this Sponsor:
Home  |  News  |  Articles  |  Forum

  Home arrow Linux For Devices Articles arrow Introduction to Das U-Boot, the universal open source bootloader

Introduction to Das U-Boot, the universal open source bootloader
By Curt Brune

Rate This Article: Add This Article To:

Foreword: Das U-Boot is an open source bootloader available for a wide range of embedded processor architectures. This article gently introduces bootloader concepts, traces the origins of Das U-Boot, and offers technical details and tips on using Das U-Boot in embedded Linux devices.



Enjoy . . . !



Das U-Boot: The Universal Boot Loader

Exciting new embedded Linux devices are appearing at an astonishing rate. From tiny 3 inch "Gumstix" boards to PDAs and smart-phones embedded Linux is everywhere. Installing and booting Linux on these wildly varying boards is quite a chore. Without a good boot loader these machines are just complicated hunks of silicon with nothing to do. That's where Das U-Boot, a Free Software universal boot loader, steps in.

A boot loader, sometimes referred to as a boot monitor, is a small piece of software that executes soon after powering up a computer. On your desktop Linux PC you may be familiar with lilo or grub, which resides on the master boot record (MBR) of your hard drive. After the PC BIOS performs various system initializations it executes the boot loader located in the MBR. The boot loader then passes system information to the kernel and then executes the kernel. For instance, the boot loader tells the kernel which hard drive partition to mount as root.

In an embedded system the role of the boot loader is more complicated since these systems do not have a BIOS to perform the initial system configuration. The low level initialization of microprocessors, memory controllers, and other board specific hardware varies from board to board and CPU to CPU. These initializations must be performed before a Linux kernel image can execute.

At a minimum an embedded loader provides the following features:
  • Initializing the hardware, especially the memory controller.
  • Providing boot parameters for the Linux kernel.
  • Starting the Linux kernel
Additionally, most boot loaders also provide "convenience" features that simplify development:
  • Reading and writing arbitrary memory locations.
  • Uploading new binary images to the board's RAM via a serial line or Ethernet
  • Copying binary images from RAM to FLASH memory
Das U-Boot

Das U-Boot is a GPL'ed cross-platform boot loader shepherded by project leader Wolfgang Denk and backed by an active developer and user community. U-Boot provides out-of-the-box support for hundreds of embedded boards and a wide variety of CPUs including PowerPC, ARM, XScale, MIPS, Coldfire, NIOS, Microblaze, and x86. You can easily configure U-Boot to strike the right balance between a rich feature set and a small binary footprint.

U-Boot has its origins in the 8xxROM project, a boot loader for 8xx PowerPC systems by Magnus Damm. When bringing that project to Sourceforge in 2000, current project leader Wolfgang Denk renamed the project 'PPCBoot," since Sourceforge did not allow project names to begin with a digit.

The openness and utility of PPCBoot fanned the flames of its popularity, driving developers to port PPCBoot to new architectures. By September, 2002, PPCBoot supported four different ARM processors, and the name PPCBoot was becoming quaint. In November, 2002, the PPCBoot team retired the project, which led directly to the surfacing of "Das U-Boot."

The strength of the Free Software development process is clearly evident in the success of U-Boot. The four freedoms expressed by the FSF's Free Software Definition directly fuel U-Boot's impressive progress and wide spread deployment.

You can jump start your next embedded Linux project using U-Boot to take care of the low-level board initializations, allowing you to focus on the core of your embedded application. Downloading images and flashing kernels should be the least of your worries. If the need arises, however, you have the source code, and can add support for new hardware or add a special feature.

Prerequisites

Before building and installing U-Boot you need a cross-development tool chain for your target architecture. The term tool chain is a bit squishy, but generally means a C/C++ compiler, an assembler, a linker/loader, associated binary utilities and header files for a specific architecture, like PowerPC or ARM. Collectively these programs are called a tool chain.

You are probably familiar with the tool chain on your desktop Linux PC. That tool chain runs on an x86 platform and generates binaries for an x86 platform. A cross-development tool chain executes on one CPU architecture, but generates binaries for a different architecture. In my case the host architecture is x86 while the target architecture is ARM and PowerPC. Sometimes this process is also referred to as cross-compiling.

While it is possible to configure and build a tool chain from source it is time consuming and the myriad of configuration options makes it quite error prone. I highly recommend using a pre-built tool chain from a Linux vendor. The Embedded Linux Development Kit (ELDK), also by Wolfgang Denk, contains the tool chains used in this article.

Using cross-development tools makes it an absolute dream to develop embedded systems using Linux as the host development workstation. No need to maintain machines running other operating systems in order to run the compiler.

Configuring and Building

Building U-Boot for a supported platform is very straight forward, very similar to the familiar "untar, configure, make" method used by many software projects. To setup a default configuration for a particular board type this at the shell prompt after untarring the U-Boot tarball,
localhost:$ cd u-boot
localhost:$ make mrproper
localhost:$ make _config
where board> matches the board you want to build. This step setups the CPU architecture and board type.

You can fine tune the default configuration for your particular environment and board by editing the configuration file, "include/configs/board>.h". This file contains several C-preprocessor #define macros that you can modify for your needs. Some common options you might want to change are:
/* Serial port configuration */
#define CONFIG_BAUDRATE 19200
#define CFG_BAUDRATE_TABLE { 9600, 19200 }

/* Network configuration */
#define CONFIG_IPADDR 10.0.0.11
#define CONFIG_NETMASK 255.255.255.0
#define CONFIG_SERVERIP 10.0.0.1
These definitions are self explanatory, except for maybe CONFIG_SERVERIP, which is the IP address U-Boot uses for TFTP and NFS. Don't worry too much about these right now as you can change them later when U-Boot is running. For the complete list of configuration options see u-boot/README.

Now to build the binary image, u-boot.bin, type the following:
cd u-boot
make
You have several options for installing the binary image on your target board, and which option you select depends on your board and development environment. You might use a BDM/JTAG programmer, an existing vendor's boot loader or even an older version of U-Boot. While this step is crucial it is beyond the scope of this article to describe this procedure. From here on I will assume you have successfully installed U-Boot on your target board.

Getting Started

The next step is configuring your host workstation for serial communications with your target platform. On my system I have a DB9 serial cable connected to /dev/ttyS0. U-Boot expects the serial line to be set for 8 data bits, 1 stop bit, no parity and no handshake.

You can use your favorite serial communications program to connect to U-Boot. I prefer to use Kermit and a tiny Kermit script from within an emacs shell buffer. I put the following Kermit script into a file called "serial-term" and make the file executable:
#!/usr/bin/kermit
echo connecting /dev/ttyS0 .....
set line /dev/ttyS0
set FLOW AUTO
set speed 19200
set serial 8n1
SET CARRIER-WATCH OFF
connect
I like running serial-term from within an emacs shell because emacs keeps track of my command history, which the U-Boot shell does not support. Trust me, while developing you will be hitting the reset button on your board a lot and want to "up arrow" to the previous load command you just entered.

The user interface to U-Boot consists of a command line interrupter, much like a Linux shell prompt. When connected via a serial line you can interactively enter commands and see the results. After power on the initial u-boot prompt looks like this:
U-Boot 1.1.2 (Aug  3 2004 - 17:31:20)
RAM Configuration:
Bank #0: 00000000 8 MB
Flash: 2 MB
In: serial
Out: serial
Err: serial
u-boot #
This tells you that you have 8 megabytes of RAM starting at address 0x00000000, two megabytes of Flash and that the C-library file streams stdin, stdout and stderr are connected to the serial line.

You can receive more information about our board be issuing the board info command, bdinfo. In the folowing the commands typed by me appear in bold.

u-boot # bdinfo
DRAM bank = 0x00000000
-> start = 0x00000000
-> size = 0x00800000
ethaddr = 00:40:95:36:35:33
ip_addr = 10.0.0.11
baudrate = 19200 bps

Here you see the see the RAM configuration information again, the Ethernet MAC address, the IP address and serial port baud rate.

Environment Variables

Much like a traditional Linux shell the U-Boot shell uses environment variables to tailor its operation. The U-Boot commands to manipulate environment variables have the same names as the BASH shell. For instance printenv and setenv behave the same as their BASH shell counterparts.

In the following example you will dump the current environment variables using the "printenv" command and change the IP address of the TFTP server using the "setenv" command.

u-boot # printenv
baudrate=19200
ethaddr=00:40:95:36:35:33
netmask=255.255.255.0
ipaddr=10.0.0.11
serverip=10.0.0.1
stdin=serial
stdout=serial
stderr=serial
u-boot # setenv serverip 10.0.0.2
u-boot # printenv serverip
serverip=10.0.0.2

You can create short shell scripts by storing a sequence of U-Boot commands, separated by semicolons, in an environment variable. To execute the script use the "run" command followed by the variable name. This can be handy to automate repetitive tasks during development.

Network Commands

Having a network connection on your boot loader is very convenient during development. If your project requires several networked boards they can all download and boot the same kernel image from a centralized server. When you update the kernel you only need to update the single copy on the server and not each board individually.

U-Boot supports TFTP (Trivial FTP), a stripped down FTP that does not require user authentication, for downloading images into the board's RAM. The "tftp" command needs two pieces of information, the name of the file to download and where in memory to store the file as shown in the following example:

u-boot # tftp 8000 u-boot.bin
From server 10.0.0.1; our IP address is 10.0.0.11
Filename 'u-boot.bin'.
Load address: 0x8000
Loading: ###################
done
Bytes transferred = 95032 (17338 hex)

The size and location of the downloaded image are stored in the fileaddr and filesize environment variables for possible latter use by other shell commands and scripts.
U-Boot also supports NFS so you can download images from your existing NFS server as well.

Flash Commands

Some embedded projects only have access to a network while being programmed "in the factory". When deployed in the field the boards boot a kernel stored in the flash memory. The board can be updated in the field by reprogramming the flash memory with a new kernel. U-Boot offers several commands for programming, erasing and protecting the flash memory.

To see what type of flash memory your board has enter the flinfo command:

u-boot # flinfo
Bank # 1: AMD Am29LV160DB 16KB,2x8KB,32KB,31x64KB
Size: 2048 KB in 35 Sectors
Sector Start Addresses:
S00 @ 0x01000000 ! S01 @ 0x01004000 !
S02 @ 0x01006000 ! S03 @ 0x01008000 !
S04 @ 0x01010000 ! S05 @ 0x01020000 !
S06 @ 0x01030000 S07 @ 0x01040000
...
S32 @ 0x011D0000 S33 @ 0x011E0000
S34 @ 0x011F0000

The output carries quite a lot of information. Immediately you see the flash manufacturer, part number and sector layout. This particular part begins with a 16KB sector at address 0x01000000, followed by two 8KB sectors, a 32KB sector and 31 64KB sectors for a total of 2 megabytes in 35 sectors.

The exclamation points following sectors 0 through 5 indicate that those sectors are "protected". In this example sectors 0 through 4 contain the code for U-Boot itself, and sector 5 is used to store the environment variables. Any attempt to program these sectors without first unlocking them will fail. This offers some level of protection from "rm -rf /" type mistakes when programming the flash.

Continuing the TFTP example, let's assume the file you uploaded is a new version of U-Boot. You need to first unlock flash sectors 0 through 4 before programming the flash. Type "protect off 1:0-4", which instructs U-Boot to allow write access to flash bank 1, sectors 0 through 4.

u-boot # protect off 1:0-4
Un-Protect Flash Sectors 0-4 in Bank # 1

Next you must prepare the flash sectors for programming by erasing them. Enter "erase 1:0-4", which tells U-Boot to erase sectors 0 through 4 of flash bank 1.

u-boot # erase off 1:0-4
Erase Flash Sectors 0-4 in Bank # 1
Erasing Sector 0 @ 0x01000000 ... done
Erasing Sector 1 @ 0x01004000 ... done
Erasing Sector 2 @ 0x01006000 ... done
Erasing Sector 3 @ 0x01008000 ... done
Erasing Sector 4 @ 0x01010000 ... done
[end courier]


To program the flash memory you need to copy the image from RAM to the address of flash sector 0, 0x01000000, using the cp command. You will use the byte version of the command to copy the specified number of bytes. In this case you can use the fileaddr and filesize environment variables, which contains the RAM address and number of bytes loaded by the last TFTP command. Type cp.b ${fileaddr} 1000000 ${filesize} at the u-boot prompt.

u-boot # cp.b ${fileaddr} 1000000 ${filesize}
Copy to Flash... ................ done

Finally restore the write protection on flash sectors 0 through 4 by typing protect on 1:0-4 at the U-Boot prompt.

u-boot # protect on 1:0-4
Protect Flash Sectors 0-5 in Bank # 1

You have just updated the U-Boot code for you board. The next reboot will run the newly uploaded U-Boot code. Well done!

The final flash related command is the saveenv command, which like the name implies saves your current environment variables to a reserved flash sector. This allows your environment variables to persist across power cycles and reboots. You might want do this after updating the server IP address or when adding a new script. Type saveenv to save your environment.

u-boot # saveenv
Saving Environment to Flash...
Un-Protected 1 sectors
Erasing Flash...
Erasing Sector 5 @ 0x01020000 ... done
Erased 1 sectors
Writing to Flash... ................ done
Protected 1 sectors

As you can see the saveenv command bundles together the un-protect, erase, copy and protect steps you covered in the previous example.

Booting

OK, now you know how to load your image into RAM or flash. Next you want to run your kernel and boot into Linux. Most kernel images expect to start executing from a known location in memory, so you need to load your image into the correct place. The U-Boot distribution provides a nice utility for the host system called "mkimage" for just this purpose.

After creating your kernel image use mkimage to add a tiny header containing the load and execute address for the image, like this (all on one line):

localhost:$ mkimage -A arm -O linux -T kernel -C none -a 0x8000 -e 0x8000 -n "Linux 2.6.6" -d linux.bin uImage.bin

This command appends a small header containing the load and execute address 0x8000 to your kernel image and creates a new file called uImage.bin. The header also contains a CRC32 checksum, checked later during the image load. Remember the above command is run on your development workstation, not the embedded target.

You can now upload uImage.bin to your board and use the bootm command to boot your image. In the following example let's assume you stored uImage.bin at address 0x01030000 in the flash memory.

u-boot # bootm 1030000
## Booting image at 01030000 ...
Image Name: Linux 2.6.6
Image Type: ARM Linux Kernel Image
Data Size: 700256 Bytes = 683.8 kB
Load Address: 00008000
Entry Point: 00008000
Verifying Checksum ... OK
Starting kernel ...

And off you go! U-Boot uses the header information to copy your image to the correct location and then to start execution at the specified address. Notice that U-Boot also verifies the CRC32 checksum contained in the header before executing the kernel.

Conclusion

This introduction to the basic features gives you feel for the power and utility of "Das U-Boot". For the more advanced features consult the project README file and visit the U-Boot Wiki. I hope you consider using U-Boot on your next embedded project.



Acknowledgments

I would like to personally thank Wolfgang Denk and the other members of the U-Boot project for their mostly thankless efforts in creating, maintaining and extending "Das U-Boot" – open firmware today for an open tomorrow.



Resources

Das U-Boot project home page
http://sourceforge.net/projects/u-boot/

DENX U-Boot and Linux Guide
http://www.denx.de/twiki/bin/view/DULG/Manual

Free Software Foundation's "Free Software Definition" Page
http://www.fsf.org/philosophy/free-sw.html

TFTP
http://rfc.net/rfc1350.html


Copyright © 2004 by Curt Brune. Used with permission by LinuxDevices according to the terms of the Creative Commons License.


Talkback!


This article was originally published here by Cucy.net, which maintains a discussion thread for the article.



About the author: Curt Brune is an embedded systems consultant for Cucy Systems, based in Mountain View, California. When not championing Free Software he enjoys reading, being outdoors and spending time with his wife Lucy and son Owen.





Related Stories:


Discuss Introduction to Das U-Boot, the universal open source bootloader
 
>>> Be the FIRST to comment on this article!
 
 
 
>>> More Linux For Devices Articles Articles          >>> More By Curt Brune
 



FUEL Database on MontaVista Linux
Whether building a mobile handset, a car navigation system, a package tracking device, or a home entertainment console, developers need capable software systems, including an operating system, development tools, and supporting libraries, to gain maximum benefit from their hardware platform and to meet aggressive time-to-market goals.

Breaking New Ground: The Evolution of Linux Clustering
With a platform comprising a complete Linux distribution, enhanced for clustering, and tailored for HPC, Penguin Computing¿s Scyld Software provides the building blocks for organizations from enterprises to workgroups to deploy, manage, and maintain Linux clusters, regardless of their size.

Data Monitoring with NightStar LX
Unlike ordinary debuggers, NightStar LX doesn¿t leave you stranded in the dark. It¿s more than just a debugger, it¿s a whole suite of integrated diagnostic tools designed for time-critical Linux applications to reduce test time, increase productivity and lower costs. You can debug, monitor, analyze and tune with minimal intrusion, so you see real execution behavior. And that¿s positively illuminating.

Virtualizing Service Provider Networks with Vyatta
This paper highlights Vyatta's unique ability to virtualize networking functions using Vyatta's secure routing software in service provider environments.

High Availability Messaging Solution Using AXIGEN, Heartbeat and DRBD
This white paper discusses a high-availability messaging solution relying on the AXIGEN Mail Server, Heartbeat and DRBD. Solution architecture and implementation, as well as benefits of using AXIGEN for this setup are all presented in detail.

Understanding the Financial Benefits of Open Source
Will open source pay off? Open source is becoming standard within enterprises, often because of cost savings. Find out how much of a financial impact it can have on your organization. Get this methodology and calculator now, compliments of JBoss.

Embedded Hardware and OS Technology Empower PC-Based Platforms
The modern embedded computer is the jack of all trades appearing in many forms.

Data Management for Real-Time Distributed Systems
This paper provides an overview of the network-centric computing model, data distribution services, and distributed data management. It then describes how the SkyBoard integration and synchronization service, coupled with an implementation of the OMG¿s Data Distribution Service (DDS) standard, can be used to create an efficient data distribution, storage, and retrieval system.

7 Advantages of D2D Backup
For decades, tape has been the backup medium of choice. But, now, disk-to-disk (D2D) backup is gaining in favor. Learn why you should make the move in this whitepaper.

Got a HOT tip?   please tell us!
Free weekly newsletter
Enter your email...
Click for a profile of each sponsor:
SUPER-PLATINUM SPONSOR
MOBLIN NEWS & LINKS
Moblin Official Blog
Aigo to Go
Wind River's Moblin stack
Adobe AIR for devices
FEATURED VIDEO

Moblin v2 "Fastboot"
PLATINUM SPONSORS
GOLD SPONSORS
(Become a sponsor)

ADVERTISEMENT
(Advertise here)

Check out the latest Linux powered...

Mobile phones!

MIDs, UMPCs
& tablets

Mobile devices

Other cool
gadgets

Resource Library

• Unix, Linux Uptime and Reliability Increase: Patch Management Woes Plague Windows Yankee Group survey finds IBM AIX Unix is highest in ...
• Scalable, Fault-Tolerant NAS for Oracle - The Next Generation For several years NAS has been evolving as a storage ...
• Managing Software Intellectual Property in an Open Source World This whitepaper draws on the experiences of the Black Duck ...
• Open Source Security Myths Dispelled Is it risky to trust mission-critical infrastructure to open source ...
• Bringing IT Operations Management to Open Source & Beyond Download this IDC analyst report to learn how open source ...


BREAKING NEWS

• NAS system houses 2.5-inch drives for up to 6TB
• Atom SBC boasts special low-power mode
• Android leaps to rugged handheld, and more phones
• Simulator runs Android apps on Ubuntu
• Fanless industrial PC taps Atom
• Router platform runs OpenWRT Linux
• Feature-packed UMPC survives four-foot drops
• UMPC pioneer gives up the ghost
• Biodegradable, solar-powered netbook runs Linux
• Hypervisor rev'd for higher reliability
• Eurotech spins Atom development kits
• Home media server to demo on Intel Atom platform
• Atom boards feature fanless DC operation
• Low-cost pluggable NAS adds Linux support
• Taiwan open source conference sets agenda


Most popular stories -- past 90 days:
• Linux boots in 2.97 seconds
• Tiniest Linux system, yet?
• Linux powers "cloud" gaming console
• Report: T-Mobile sells out first 1.5 million G1s
• Open set-top box ships
• E17 adapted to Linux devices, demo'd on Treo650
• Android debuts
• First ALP Linux smartphone?
• Cortex-A8 gaming handheld runs Linux
• Ubuntu announces ARM port


DesktopLinux headlines:
• Simulator runs Android apps on Ubuntu
• Hypervisor rev'd for higher reliability
• Pluggable NAS now supports Linux desktops
• Moblin v2 beta targets netbooks
• Linux-ready netbook touted as "Student rugged"
• USB display technology heading for Linux
• Ubuntu One takes baby step to the cloud
• Game over for Linux netbooks?
• Linux Foundation relaunches Linux web site
• Dell spins lower-cost netbook


Also visit our sister site:


Sign up for LinuxForDevices.com's...

news feed


Or, follow us on Twitter...