17.01.2015 Views

The DENX U-Boot and Linux Guide (DULG) for canyonlands - Lysator

The DENX U-Boot and Linux Guide (DULG) for canyonlands - Lysator

The DENX U-Boot and Linux Guide (DULG) for canyonlands - Lysator

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

<strong>The</strong> <strong>DENX</strong> U-<strong>Boot</strong> <strong>and</strong> <strong>Linux</strong> <strong>Guide</strong> (<strong>DULG</strong>) <strong>for</strong><br />

canyonl<strong>and</strong>s<br />

Table of contents:<br />

• 1. Abstract<br />

• 2. Introduction<br />

♦ 2.1. Copyright<br />

♦ 2.2. Disclaimer<br />

♦ 2.3. Availability<br />

♦ 2.4. Credits<br />

♦ 2.5. Translations<br />

♦ 2.6. Feedback<br />

♦ 2.7. Conventions<br />

• 3. Embedded <strong>Linux</strong> Development Kit<br />

♦ 3.1. ELDK Availability<br />

♦ 3.2. ELDK Getting Help<br />

♦ 3.3. Supported Host Systems<br />

♦ 3.4. Supported Target Architectures<br />

♦ 3.5. Installation<br />

◊ 3.5.1. Product Packaging<br />

◊ 3.5.2. Downloading the ELDK<br />

◊ 3.5.3. Initial Installation<br />

◊ 3.5.4. Installation <strong>and</strong> Removal of Individual Packages<br />

◊ 3.5.5. Removal of the Entire Installation<br />

♦ 3.6. Working with ELDK<br />

◊ 3.6.1. Switching Between Multiple Installations<br />

♦ 3.7. Mounting Target Components via NFS<br />

♦ 3.8. Rebuilding ELDK Components<br />

◊ 3.8.1. ELDK Source Distribution<br />

◊ 3.8.2. Rebuilding Target Packages<br />

◊ 3.8.3. Rebuilding ELDT Packages<br />

♦ 3.9. ELDK Packages<br />

◊ 3.9.1. List of ELDT Packages<br />

◊ 3.9.2. List of Target Packages<br />

♦ 3.10. Rebuilding the ELDK from Scratch<br />

◊ 3.10.1. ELDK Build Process Overview<br />

◊ 3.10.2. Setting Up ELDK Build Environment<br />

◊ 3.10.3. build.sh Usage<br />

◊ 3.10.4. Format of the cpkgs.lst <strong>and</strong> tpkgs.lst Files<br />

♦ 3.11. Notes <strong>for</strong> Solaris 2.x Host Environment<br />

• 4. System Setup<br />

♦ 4.1. Serial Console Access<br />

♦ 4.2. Configuring the "cu" comm<strong>and</strong><br />

♦ 4.3. Configuring the "kermit" comm<strong>and</strong><br />

♦ 4.4. Using the "minicom" program<br />

♦ 4.5. Permission Denied Problems<br />

♦ 4.6. Configuration of a TFTP Server<br />

♦ 4.7. Configuration of a BOOTP / DHCP Server<br />

♦ 4.8. Configuring a NFS Server<br />

• 5. Das U-<strong>Boot</strong><br />

♦ 5.1. Current Versions<br />

♦ 5.2. Unpacking the Source Code<br />

<strong>The</strong> <strong>DENX</strong> U-<strong>Boot</strong> <strong>and</strong> <strong>Linux</strong> <strong>Guide</strong> (<strong>DULG</strong>) <strong>for</strong> canyonl<strong>and</strong>s 1


♦ 5.3. Configuration<br />

♦ 5.4. Installation<br />

◊ 5.4.1. Be<strong>for</strong>e You Begin<br />

⋅ 5.4.1.1. Installation Requirements<br />

⋅ 5.4.1.2. Board Identification Data<br />

◊ 5.4.2. Installation Using a BDM/JTAG Debugger<br />

◊ 5.4.3. Installation using U-<strong>Boot</strong><br />

♦ 5.5. Tool Installation<br />

♦ 5.6. Initialization<br />

♦ 5.7. Initial Steps<br />

♦ 5.8. <strong>The</strong> First Power-On<br />

♦ 5.9. U-<strong>Boot</strong> Comm<strong>and</strong> Line Interface<br />

◊ 5.9.1. In<strong>for</strong>mation Comm<strong>and</strong>s<br />

⋅ 5.9.1.1. bdinfo - print Board Info structure<br />

⋅ 5.9.1.2. coninfo - print console devices <strong>and</strong> in<strong>for</strong>mations<br />

⋅ 5.9.1.3. flinfo - print FLASH memory in<strong>for</strong>mation<br />

⋅ 5.9.1.4. iminfo - print header in<strong>for</strong>mation <strong>for</strong> application image<br />

⋅ 5.9.1.5. help - print online help<br />

◊ 5.9.2. Memory Comm<strong>and</strong>s<br />

⋅ 5.9.2.1. base - print or set address offset<br />

⋅ 5.9.2.2. crc32 - checksum calculation<br />

⋅ 5.9.2.3. cmp - memory compare<br />

⋅ 5.9.2.4. cp - memory copy<br />

⋅ 5.9.2.5. md - memory display<br />

⋅ 5.9.2.6. mm - memory modify (auto-incrementing)<br />

⋅ 5.9.2.7. mtest - simple RAM test<br />

⋅ 5.9.2.8. mw - memory write (fill)<br />

⋅ 5.9.2.9. nm - memory modify (constant address)<br />

⋅ 5.9.2.10. loop - infinite loop on address range<br />

◊ 5.9.3. Flash Memory Comm<strong>and</strong>s<br />

⋅ 5.9.3.1. cp - memory copy<br />

⋅ 5.9.3.2. flinfo - print FLASH memory in<strong>for</strong>mation<br />

⋅ 5.9.3.3. erase - erase FLASH memory<br />

⋅ 5.9.3.4. protect - enable or disable FLASH write protection<br />

⋅ 5.9.3.5. mtdparts - define a <strong>Linux</strong> compatible MTD partition scheme<br />

◊ 5.9.4. Execution Control Comm<strong>and</strong>s<br />

⋅ 5.9.4.1. autoscr - run script from memory<br />

⋅ 5.9.4.2. bootm - boot application image from memory<br />

⋅ 5.9.4.3. go - start application at address 'addr'<br />

◊ 5.9.5. Download Comm<strong>and</strong>s<br />

⋅ 5.9.5.1. bootp - boot image via network using BOOTP/TFTP protocol<br />

⋅ 5.9.5.2. dhcp - invoke DHCP client to obtain IP/boot params<br />

⋅ 5.9.5.3. loadb - load binary file over serial line (kermit mode)<br />

⋅ 5.9.5.4. loads - load S-Record file over serial line<br />

⋅ 5.9.5.5. rarpboot- boot image via network using RARP/TFTP protocol<br />

⋅ 5.9.5.6. tftpboot- boot image via network using TFTP protocol<br />

◊ 5.9.6. Environment Variables Comm<strong>and</strong>s<br />

⋅ 5.9.6.1. printenv- print environment variables<br />

⋅ 5.9.6.2. saveenv - save environment variables to persistent storage<br />

⋅ 5.9.6.3. setenv - set environment variables<br />

⋅ 5.9.6.4. run - run comm<strong>and</strong>s in an environment variable<br />

⋅ 5.9.6.5. bootd - boot default, i.e., run 'bootcmd'<br />

◊ 5.9.7. Flattened Device Tree support<br />

⋅ 5.9.7.1. fdt addr - select FDT to work on<br />

<strong>The</strong> <strong>DENX</strong> U-<strong>Boot</strong> <strong>and</strong> <strong>Linux</strong> <strong>Guide</strong> (<strong>DULG</strong>) <strong>for</strong> canyonl<strong>and</strong>s 2


⋅ 5.9.7.2. fdt list - print one level<br />

⋅ 5.9.7.3. fdt print - recursive print<br />

⋅ 5.9.7.4. fdt mknode - create new nodes<br />

⋅ 5.9.7.5. fdt set - set node properties<br />

⋅ 5.9.7.6. fdt rm - remove nodes or properties<br />

⋅ 5.9.7.7. fdt move - move FDT blob to new address<br />

⋅ 5.9.7.8. fdt chosen - fixup dynamic info<br />

◊ 5.9.8. Special Comm<strong>and</strong>s<br />

⋅ 5.9.8.1. i2c - I2C sub-system<br />

◊ 5.9.9. Storage devices<br />

◊ 5.9.10. Miscellaneous Comm<strong>and</strong>s<br />

⋅ 5.9.10.1. echo - echo args to console<br />

⋅ 5.9.10.2. reset - Per<strong>for</strong>m RESET of the CPU<br />

⋅ 5.9.10.3. sleep - delay execution <strong>for</strong> some time<br />

⋅ 5.9.10.4. version - print monitor version<br />

⋅ 5.9.10.5. - alias <strong>for</strong> 'help'<br />

♦ 5.10. U-<strong>Boot</strong> Environment Variables<br />

♦ 5.11. U-<strong>Boot</strong> Scripting Capabilities<br />

♦ 5.12. U-<strong>Boot</strong> St<strong>and</strong>alone Applications<br />

◊ 5.12.1. "Hello World" Demo<br />

◊ 5.12.2. Timer Demo<br />

♦ 5.13. U-<strong>Boot</strong> Image Formats<br />

♦ 5.14. U-<strong>Boot</strong> Advanced Features<br />

◊ 5.14.1. <strong>Boot</strong> Count Limit<br />

◊ 5.14.2. Bitmap Support<br />

◊ 5.14.3. Splash Screen Support<br />

• 6. Embedded <strong>Linux</strong> Configuration<br />

♦ 6.1. Download <strong>and</strong> Unpack the <strong>Linux</strong> Kernel Sources<br />

♦ 6.2. Kernel Configuration <strong>and</strong> Compilation<br />

♦ 6.3. Installation<br />

• 7. <strong>Boot</strong>ing Embedded <strong>Linux</strong><br />

♦ 7.1. Introduction<br />

♦ 7.2. Flattened Device Tree Blob<br />

♦ 7.3. Passing Kernel Arguments<br />

♦ 7.4. <strong>Boot</strong> Arguments Unleashed<br />

♦ 7.5. Networked Operation with Root Filesystem over NFS<br />

◊ 7.5.1. <strong>Boot</strong>log of <strong>Linux</strong> kernel with Root Filesystem over NFS<br />

♦ 7.6. <strong>Boot</strong> from Flash Memory<br />

♦ 7.7. St<strong>and</strong>alone Operation with Ramdisk Image<br />

• 8. Building <strong>and</strong> Using Modules<br />

• 9. Advanced Topics<br />

♦ 9.1. Flash Filesystems<br />

◊ 9.1.1. Memory Technology Devices<br />

◊ 9.1.2. Journalling Flash File System<br />

◊ 9.1.3. Second Version of JFFS<br />

◊ 9.1.4. Compressed ROM Filesystem<br />

♦ 9.2. <strong>The</strong> TMPFS Virtual Memory Filesystem<br />

◊ 9.2.1. Mount Parameters<br />

◊ 9.2.2. Kernel Support <strong>for</strong> tmpfs<br />

◊ 9.2.3. Usage of tmpfs in Embedded Systems<br />

♦ 9.3. Adding Swap Space<br />

♦ 9.4. Splash Screen Support in <strong>Linux</strong><br />

♦ 9.5. Root File System: Design <strong>and</strong> Building<br />

◊ 9.5.1. Root File System on a Ramdisk<br />

<strong>The</strong> <strong>DENX</strong> U-<strong>Boot</strong> <strong>and</strong> <strong>Linux</strong> <strong>Guide</strong> (<strong>DULG</strong>) <strong>for</strong> canyonl<strong>and</strong>s 3


◊ 9.5.2. Root File System on a JFFS2 File System<br />

◊ 9.5.3. Root File System on a cramfs File System<br />

◊ 9.5.4. Root File System on a Read-Only ext2 File System<br />

◊ 9.5.5. Root File System on a Flash Card<br />

◊ 9.5.6. Root File System in a Read-Only File in a FAT File System<br />

♦ 9.6. Root File System Selection<br />

♦ 9.7. Overlay File Systems<br />

♦ 9.8. <strong>The</strong> Persistent RAM File system (PRAMFS)<br />

◊ 9.8.1. Mount Parameters<br />

◊ 9.8.2. Example<br />

• 10. Debugging<br />

♦<br />

♦<br />

10.1. Debugging of U-<strong>Boot</strong><br />

◊ 10.1.1. Debugging of U-<strong>Boot</strong> Be<strong>for</strong>e Relocation<br />

◊ 10.1.2. Debugging of U-<strong>Boot</strong> After Relocation<br />

10.2. <strong>Linux</strong> Kernel Debugging<br />

◊ 10.2.1. <strong>Linux</strong> Kernel <strong>and</strong> Statically Linked Device Drivers<br />

◊ 10.2.2. Dynamically Loaded Device Drivers (Modules)<br />

◊ 10.2.3. GDB Macros to Simplify Module Loading<br />

♦ 10.3. GDB Startup File <strong>and</strong> Utility Scripts<br />

♦ 10.4. Tips <strong>and</strong> Tricks<br />

♦ 10.5. Application Debugging<br />

◊ 10.5.1. Local Debugging<br />

◊ 10.5.2. Remote Debugging<br />

♦ 10.6. Debugging with Graphical User Interfaces<br />

• 11. Simple Embedded <strong>Linux</strong> Framework<br />

• 12. Books, Mailing Lists, Links, etc.<br />

♦ 12.1. Application Notes<br />

♦ 12.2. Further Reading<br />

◊ 12.2.1. <strong>Linux</strong> kernel<br />

◊ 12.2.2. General <strong>Linux</strong> / Unix programming<br />

◊ 12.2.3. Network Programming<br />

◊ 12.2.4. C++ programming<br />

◊ 12.2.5. Java programming<br />

◊ 12.2.6. PowerPC Programming<br />

◊ 12.2.7. Embedded Topics<br />

•<br />

♦ 12.3. Mailing Lists<br />

♦ 12.4. Links<br />

♦ 12.5. Tools<br />

13. Appendix<br />

♦ 13.1. Flat Device Tree<br />

♦ 13.2. BDI2000 Configuration file<br />

• 14. FAQ - Frequently Asked Questions<br />

♦<br />

♦<br />

14.1. ELDK<br />

◊ 14.1.1. ELDK Installation under FreeBSD<br />

◊ 14.1.2. ELDK Installation Hangs<br />

◊ 14.1.3. .gvfs: Permission Denied<br />

◊ 14.1.4. Installation on Local Harddisk<br />

◊ 14.1.5. ELDK Include Files Missing<br />

◊ 14.1.6. Using the ELDK on a 64 bit plat<strong>for</strong>m<br />

◊ 14.1.7. GDB Problems with BDI2000/BDI3000 on e500 Cores<br />

◊ 14.1.8. [[ELDK Installation Aborts][ELDK 2.x Installation Aborts]]<br />

14.2. U-<strong>Boot</strong><br />

◊ 14.2.1. Can U-<strong>Boot</strong> be configured such that it can be started in RAM<br />

◊ 14.2.2. Relocation cannot be done when using -mrelocatable<br />

<strong>The</strong> <strong>DENX</strong> U-<strong>Boot</strong> <strong>and</strong> <strong>Linux</strong> <strong>Guide</strong> (<strong>DULG</strong>) <strong>for</strong> canyonl<strong>and</strong>s 4


◊ 14.2.3. U-<strong>Boot</strong> crashes after relocation to RAM<br />

◊ 14.2.4. Warning - bad CRC, using default environment<br />

◊ 14.2.5. Wrong debug symbols after relocation<br />

◊ 14.2.6. Decoding U-<strong>Boot</strong> Crash Dumps<br />

◊ 14.2.7. Porting Problem: cannot move location counter backwards<br />

◊ 14.2.8. U-<strong>Boot</strong> Doesn't Run after Upgrading my Compiler<br />

◊ 14.2.9. How Can I Reduce <strong>The</strong> Image Size<br />

◊ 14.2.10. Erasing Flash Fails<br />

◊ 14.2.11. Ethernet Does Not Work<br />

◊ 14.2.12. Where Can I Get a Valid MAC Address from<br />

◊ 14.2.13. Why do I get TFTP timeouts<br />

◊ 14.2.14. Why is my Ethernet operation not reliable<br />

◊ 14.2.15. How the Comm<strong>and</strong> Line Parsing Works<br />

⋅ 14.2.15.1. Old, simple comm<strong>and</strong> line parser<br />

⋅ 14.2.15.2. Hush shell<br />

⋅ 14.2.15.3. Hush shell scripts<br />

⋅ 14.2.15.4. General rules<br />

◊ 14.2.16. How can I load <strong>and</strong> uncompress a compressed image<br />

◊ 14.2.17. My st<strong>and</strong>alone program does not work<br />

◊ 14.2.18. <strong>Linux</strong> hangs after uncompressing the kernel<br />

♦ 14.3. <strong>Linux</strong><br />

◊ 14.3.1. <strong>Linux</strong> crashes r<strong>and</strong>omly<br />

◊ 14.3.2. <strong>Linux</strong> crashes when uncompressing the kernel<br />

◊ 14.3.3. <strong>Linux</strong> Post Mortem Analysis<br />

◊ 14.3.4. <strong>Linux</strong> kernel register usage<br />

◊ 14.3.5. <strong>Linux</strong> Kernel Ignores my bootargs<br />

◊ 14.3.6. Cannot configure Root Filesystem over NFS<br />

◊ 14.3.7. <strong>Linux</strong> Kernel Panics because "init" process dies<br />

◊ 14.3.8. Unable to open an initial console<br />

◊ 14.3.9. Mounting a Filesystem over NFS hangs <strong>for</strong>ever<br />

◊ 14.3.10. Ethernet does not work in <strong>Linux</strong><br />

◊ 14.3.11. Loopback interface does not work<br />

◊ 14.3.12. <strong>Linux</strong> kernel messages are not printed on the console<br />

◊ 14.3.13. <strong>Linux</strong> ignores input when using the framebuffer driver<br />

◊ 14.3.14. How to switch off the screen saver <strong>and</strong> the blinking cursor<br />

◊ 14.3.15. BogoMIPS Value too low<br />

◊ 14.3.16. <strong>Linux</strong> Kernel crashes when using a ramdisk image<br />

◊ 14.3.17. Ramdisk Greater than 4 MB Causes Problems<br />

◊ 14.3.18. Combining a Kernel <strong>and</strong> a Ramdisk into a Multi-File Image<br />

◊ 14.3.19. Adding Files to Ramdisk is Non Persistent<br />

◊ 14.3.20. Kernel Configuration <strong>for</strong> PCMCIA<br />

◊ 14.3.21. Configure <strong>Linux</strong> <strong>for</strong> PCMCIA Cards using the Card Services package<br />

◊ 14.3.22. Configure <strong>Linux</strong> <strong>for</strong> PCMCIA Cards without the Card Services package<br />

⋅ 14.3.22.1. Using a MacOS Partition Table<br />

⋅ 14.3.22.2. Using a MS-DOS Partition Table<br />

◊ 14.3.23. <strong>Boot</strong>-Time Configuration of MTD Partitions<br />

◊ 14.3.24. Use NTP to synchronize system time against RTC<br />

◊ 14.3.25. Configure <strong>Linux</strong> <strong>for</strong> XIP (Execution In Place)<br />

⋅ 14.3.25.1. XIP Kernel<br />

⋅ 14.3.25.2. Cramfs Filesystem<br />

⋅ 14.3.25.3. Hints <strong>and</strong> Notes<br />

⋅ 14.3.25.4. Space requirements <strong>and</strong> RAM saving, an example<br />

◊ 14.3.26. Use SCC UART with Hardware H<strong>and</strong>shake<br />

◊ 14.3.27. How can I access U-<strong>Boot</strong> environment variables in <strong>Linux</strong><br />

<strong>The</strong> <strong>DENX</strong> U-<strong>Boot</strong> <strong>and</strong> <strong>Linux</strong> <strong>Guide</strong> (<strong>DULG</strong>) <strong>for</strong> canyonl<strong>and</strong>s 5


◊ 14.3.28. <strong>The</strong> =appWeb= server hangs *OR* /dev/r<strong>and</strong>om hangs<br />

◊ 14.3.29. Swapping over NFS<br />

♦ 14.4. Self<br />

◊ 14.4.1. How to Add Files to a SELF Ramdisk<br />

◊ 14.4.2. How to Increase the Size of the Ramdisk<br />

♦ 14.5. RTAI<br />

◊ 14.5.1. Conflicts with asm clobber list<br />

♦ 14.6. BDI2000<br />

◊ 14.6.1. Where can I find BDI2000 Configuration Files<br />

◊ 14.6.2. How to Debug <strong>Linux</strong> Exceptions<br />

◊ 14.6.3. How to single step through "RFI" instruction<br />

◊ 14.6.4. Setting a breakpoint doesn't work<br />

♦ 14.7. Motorola LITE5200 Board<br />

◊ 14.7.1. LITE5200 Installation Howto<br />

◊ 14.7.2. USB does not work on Lite5200 board<br />

• 15. Glossary<br />

1. Abstract<br />

This is the <strong>DENX</strong> U-<strong>Boot</strong> <strong>and</strong> <strong>Linux</strong> <strong>Guide</strong> to Embedded PowerPC, ARM <strong>and</strong> MIPS Systems.<br />

<strong>The</strong> document describes how to configure, build <strong>and</strong> use the firmware Das U-<strong>Boot</strong> (typically abbreviated as<br />

just "U-<strong>Boot</strong>") <strong>and</strong> the operating system <strong>Linux</strong> <strong>for</strong> Embedded PowerPC, ARM <strong>and</strong> MIPS Systems.<br />

<strong>The</strong> focus of this version of the document is on canyonl<strong>and</strong>s boards.<br />

This document was generated at 22 May 2009 - 10:15.<br />

• 2. Introduction<br />

♦ 2.1. Copyright<br />

♦ 2.2. Disclaimer<br />

♦ 2.3. Availability<br />

♦ 2.4. Credits<br />

♦ 2.5. Translations<br />

♦ 2.6. Feedback<br />

♦ 2.7. Conventions<br />

2. Introduction<br />

This document describes how to use the firmware U-<strong>Boot</strong> <strong>and</strong> the operating system <strong>Linux</strong> in Embedded<br />

PowerPC, ARM <strong>and</strong> MIPS Systems.<br />

<strong>The</strong>re are many steps along the way, <strong>and</strong> it is nearly impossible to cover them all in depth, but we will try to<br />

provide all necessary in<strong>for</strong>mation to get an embedded system running from scratch. This includes all the tools<br />

you will probably need to configure, build <strong>and</strong> run U-<strong>Boot</strong> <strong>and</strong> <strong>Linux</strong>.<br />

First, we describe how to install the Cross Development Tools Embedded <strong>Linux</strong> Development Kit which you<br />

probably need - at least when you use a st<strong>and</strong>ard x86 PC running <strong>Linux</strong> or a Sun Solaris 2.6 system as build<br />

environment.<br />

<strong>The</strong>n we describe what needs to be done to connect to the serial console port of your target: you will have to<br />

configure a terminal emulation program like cu or kermit.<br />

2. Introduction 6


In most cases you will want to load images into your target using ethernet; <strong>for</strong> this purpose you need TFTP<br />

<strong>and</strong> DHCP / BOOTP servers. A short description of their configuration is given.<br />

A description follows of what needs to be done to configure <strong>and</strong> build the U-<strong>Boot</strong> <strong>for</strong> a specific board, <strong>and</strong><br />

how to install it <strong>and</strong> get it working on that board.<br />

<strong>The</strong> configuration, building <strong>and</strong> installing of <strong>Linux</strong> in an embedded configuration is the next step. We use<br />

SELF, our Simple Embedded <strong>Linux</strong> Framework, to demonstrate how to set up both a development system<br />

(with the root filesystem mounted over NFS) <strong>and</strong> an embedded target configuration (running from a ramdisk<br />

image based on busybox).<br />

This document does not describe what needs to be done to port U-<strong>Boot</strong> or <strong>Linux</strong> to a new hardware plat<strong>for</strong>m.<br />

Instead, it is silently assumed that your board is already supported by U-<strong>Boot</strong> <strong>and</strong> <strong>Linux</strong>.<br />

<strong>The</strong> focus of this document is on canyonl<strong>and</strong>s boards.<br />

2.1. Copyright<br />

Copyright (C) 2001 - 2009 by Wolfgang Denk, <strong>DENX</strong> Software Engineering.<br />

Copyright (C) 2003 - 2009 by Detlev Zundel, <strong>DENX</strong> Software Engineering.<br />

Copyright (C) 2003 - 2009 by contributing authors<br />

You have the freedom to distribute copies of this document in any <strong>for</strong>mat or to create a derivative work of it<br />

<strong>and</strong> distribute it provided that you:<br />

• Distribute this document or the derivative work at no charge at all. It is not permitted to sell this<br />

document or the derivative work or to include it into any package or distribution that is not freely<br />

available to everybody.<br />

• Send your derivative work (in the most suitable <strong>for</strong>mat such as sgml) to the author.<br />

• License the derivative work with this same license or use GPL. Include a copyright notice <strong>and</strong> at least<br />

a pointer to the license used.<br />

• Give due credit to previous authors <strong>and</strong> major contributors.<br />

It is requested that corrections <strong>and</strong>/or comments be <strong>for</strong>warded to the author.<br />

If you are considering to create a derived work other than a translation, it is requested that you discuss your<br />

plans with the author.<br />

2.2. Disclaimer<br />

Use the in<strong>for</strong>mation in this document at your own risk. <strong>DENX</strong> disavows any potential liability <strong>for</strong> the contents<br />

of this document. Use of the concepts, examples, <strong>and</strong>/or other content of this document is entirely at your own<br />

risk. All copyrights are owned by their owners, unless specifically noted otherwise. Use of a term in this<br />

document should not be regarded as affecting the validity of any trademark or service mark. Naming of<br />

particular products or br<strong>and</strong>s should not be seen as endorsements.<br />

2.3. Availability<br />

<strong>The</strong> latest version of this document is available in a number of <strong>for</strong>mats:<br />

2.1. Copyright 7


• HTML http://www.denx.de/wiki/publish/<strong>DULG</strong>/<strong>DULG</strong>-canyonl<strong>and</strong>s.html<br />

• plain ASCII text http://www.denx.de/wiki/publish/<strong>DULG</strong>/<strong>DULG</strong>-canyonl<strong>and</strong>s.txt<br />

• PostScript European A4 <strong>for</strong>mat http://www.denx.de/wiki/publish/<strong>DULG</strong>/<strong>DULG</strong>-canyonl<strong>and</strong>s.ps<br />

• PDF European A4 <strong>for</strong>mat http://www.denx.de/wiki/publish/<strong>DULG</strong>/<strong>DULG</strong>-canyonl<strong>and</strong>s.pdf<br />

2.4. Credits<br />

A lot of the in<strong>for</strong>mation contained in this document was collected from several mailing lists. Thanks to<br />

anybody who contributed in one <strong>for</strong>m or another.<br />

2.5. Translations<br />

None yet.<br />

2.6. Feedback<br />

Any comments or suggestions can be mailed to the author: Wolfgang Denk at wd@denx.de.<br />

2.7. Conventions<br />

Descriptions<br />

Appearance<br />

Warnings<br />

Hint<br />

Notes<br />

Note.<br />

In<strong>for</strong>mation requiring special attention<br />

Warning<br />

File Names<br />

file.extension<br />

Directory Names<br />

directory<br />

Comm<strong>and</strong>s to be typed<br />

a comm<strong>and</strong><br />

Applications Names<br />

another<br />

application<br />

Prompt of users comm<strong>and</strong> under bash shell<br />

bash$<br />

Prompt of root users comm<strong>and</strong> under bash shell bash#<br />

Prompt of users comm<strong>and</strong> under tcsh shell<br />

tcsh$<br />

Environment Variables<br />

VARIABLE<br />

Emphasized word<br />

word<br />

Code Example ls -l<br />

• 3. Embedded <strong>Linux</strong> Development Kit<br />

♦ 3.1. ELDK Availability<br />

♦ 3.2. ELDK Getting Help<br />

♦ 3.3. Supported Host Systems<br />

♦ 3.4. Supported Target Architectures<br />

♦ 3.5. Installation<br />

◊ 3.5.1. Product Packaging<br />

◊ 3.5.2. Downloading the ELDK<br />

◊ 3.5.3. Initial Installation<br />

◊ 3.5.4. Installation <strong>and</strong> Removal of Individual Packages<br />

◊ 3.5.5. Removal of the Entire Installation<br />

♦ 3.6. Working with ELDK<br />

◊ 3.6.1. Switching Between Multiple Installations<br />

2.3. Availability 8


♦ 3.7. Mounting Target Components via NFS<br />

♦ 3.8. Rebuilding ELDK Components<br />

◊ 3.8.1. ELDK Source Distribution<br />

◊ 3.8.2. Rebuilding Target Packages<br />

◊ 3.8.3. Rebuilding ELDT Packages<br />

♦ 3.9. ELDK Packages<br />

◊ 3.9.1. List of ELDT Packages<br />

◊ 3.9.2. List of Target Packages<br />

♦ 3.10. Rebuilding the ELDK from Scratch<br />

◊ 3.10.1. ELDK Build Process Overview<br />

◊ 3.10.2. Setting Up ELDK Build Environment<br />

◊ 3.10.3. build.sh Usage<br />

◊ 3.10.4. Format of the cpkgs.lst <strong>and</strong> tpkgs.lst Files<br />

♦ 3.11. Notes <strong>for</strong> Solaris 2.x Host Environment<br />

3. Embedded <strong>Linux</strong> Development Kit<br />

<strong>The</strong> Embedded <strong>Linux</strong> Development Kit (ELDK) includes the GNU cross development tools, such as the<br />

compilers, binutils, gdb, etc., <strong>and</strong> a number of pre-built target tools <strong>and</strong> libraries necessary to provide some<br />

functionality on the target system.<br />

It is provided <strong>for</strong> free with full source code, including all patches, extensions, programs <strong>and</strong> scripts used to<br />

build the tools.<br />

Some versions of ELDK (4.1) are available in two versions, which use Glibc resp. uClibc as the main C<br />

library <strong>for</strong> the target packages.<br />

Packaging <strong>and</strong> installation is based on the RPM package manager.<br />

3.1. ELDK Availability<br />

<strong>The</strong> ELDK is available<br />

• on DVD-ROM from <strong>DENX</strong> Computer Systems<br />

• <strong>for</strong> download on the following server:<br />

FTP<br />

HTTP<br />

ftp://ftp.denx.de/pub/eldk/ http://www.denx.de/ftp/pub/eldk/<br />

• <strong>for</strong> download on the following mirrors:<br />

FTP<br />

ftp://ftp-stud.hs-esslingen.de/pub/Mirrors/eldk/<br />

ftp://mirror.switch.ch/mirror/eldk/<br />

ftp://sunsite.utk.edu/pub/linux/eldk/<br />

ftp://ftp.sunet.se/pub/<strong>Linux</strong>/distributions/eldk/<br />

HTTP<br />

http://ftp-stud.hs-esslingen.de/pub/Mirrors/eldk/<br />

http://mirror.switch.ch/ftp/mirror/eldk/<br />

http://sunsite.utk.edu/ftp/pub/linux/eldk/<br />

http://ftp.sunet.se/pub/<strong>Linux</strong>/distributions/eldk/<br />

3.1. ELDK Availability 9


3.2. ELDK Getting Help<br />

Community support <strong>for</strong> the ELDK is available through the ELDK Mailing List.<br />

Previous postings to this mailing list are available from the ELDK archives.<br />

Commercial support is also available; please feel free to contact <strong>DENX</strong> Software Engineering GmbH.<br />

3.3. Supported Host Systems<br />

<strong>The</strong> ELDK can be installed onto <strong>and</strong> operate with the following operating systems:<br />

• Fedora Core 4, 5, 6 Fedora 7, 8, 9<br />

• Red Hat <strong>Linux</strong> 7.3, 8.0, 9<br />

• SuSE <strong>Linux</strong> 8.x, 9.0, 9.1, 9.2, 9.3<br />

• OpenSUSE 10.2, 10.3 (32 Bit); OpenSUSE 11.0 (32 <strong>and</strong> 64 Bit)<br />

• Debian 3.0 (Woody), 3.1 (Sarge) <strong>and</strong> 4.0 (Etch)<br />

• Ubuntu 4.10, 5.04, 6.10, 8.04<br />

• FreeBSD 5.0<br />

Users also reported successful installation <strong>and</strong> use of the ELDK on the following host systems:<br />

• Suse <strong>Linux</strong> 7.2, 7.3<br />

• M<strong>and</strong>rake 8.2<br />

• Slackware 8.1beta2<br />

• Gentoo <strong>Linux</strong> 2006.1<br />

Note: It may be necessary, <strong>and</strong> is usually recommended, to install the latest available software updates on<br />

your host system. For example, on Fedora Core systems, you can use one of yum, apt-get or up2date to<br />

keep your systems current.<br />

3.4. Supported Target Architectures<br />

<strong>The</strong> ELDK includes target components <strong>and</strong> supports code generation <strong>for</strong> the following PowerPC types of<br />

processors:<br />

• ppc_4xx = AMCC 4xx processors without FPU<br />

• ppc_4xxFP = AMCC 4xx processors with FPU (440EP, 440EPx)<br />

• ppc_6xx = PowerPC processors based on 60x cores<br />

(This includes support <strong>for</strong> MPC5xxx, 7xx, 82xx <strong>and</strong> 83xx processors).<br />

• ppc_74xx = 74xx processors<br />

(This includes support <strong>for</strong> MPC86xx processors).<br />

• ppc_8xx = MPC8xx processors<br />

• ppc_85xx = MPC85xx processors<br />

<strong>The</strong>re is also an ELDK <strong>for</strong> ARM <strong>and</strong> MIPS systems.<br />

3.5. Installation<br />

3.5. Installation 10


3.5.1. Product Packaging<br />

Stable versions of the ELDK are distributed in the <strong>for</strong>m of an ISO image, which can be either burned onto a<br />

DVD or mounted directly, using the loopback <strong>Linux</strong> device driver (<strong>Linux</strong> host only).<br />

For the PowerPC target, the ELDK distribution was split into three independent ISO images: one targeting the<br />

4xx family of processors (AMCC), one targeting the ppc64 family of processors <strong>and</strong> another one <strong>for</strong> the 8xx,<br />

6xx, 74xx <strong>and</strong> 85xx families (Freescale). This makes the ISO images fit on st<strong>and</strong>ard DVDROM media.<br />

If you are not bound by the DVDROM size limitiation there is still a single image containing all 32-bit targets<br />

(AMCC <strong>and</strong> Freescale).<br />

Development versions of the ELDK are available as directory trees so it is easy to update individual packages;<br />

instructions <strong>for</strong> download of these trees <strong>and</strong> creation of ISO images from it is described in section 3.5.2.<br />

Downloading the ELDK.<br />

<strong>The</strong> ELDK contains an installation utility <strong>and</strong> a number of RPM packages, which are installed onto the hard<br />

disk of the cross development host by the installation procedure. <strong>The</strong> RPM packages can be logically divided<br />

into two parts:<br />

• Embedded <strong>Linux</strong> Development Tools (ELDT)<br />

• Target components<br />

<strong>The</strong> first part contains the cross development tools that are executed on the host system. Most notably, these<br />

are the GNU cross compiler, binutils, <strong>and</strong> gdb. For a full list of the provided ELDT packages, refer to section<br />

3.9.1. List of ELDT Packages below.<br />

<strong>The</strong> target components are pre-built tools <strong>and</strong> libraries which are executed on the target system. <strong>The</strong> ELDK<br />

includes necessary target components to provide a minimal working NFS-based environment <strong>for</strong> the target<br />

system. For a list of the target packages included in the ELDK, refer to section 3.9.2. List of Target Packages<br />

below.<br />

<strong>The</strong> ELDK contains several independent sets of the target packages, one <strong>for</strong> each supported target architecture<br />

CPU family. Each set has been built using compiler code generation <strong>and</strong> optimization options specific to the<br />

respective target CPU family.<br />

3.5.2. Downloading the ELDK<br />

You can either download the ready-to-burn ISO-images from one of the mirror sites (see 3.1. ELDK<br />

Availability), or you can download the individual files of the ELDK from the development directory tree <strong>and</strong><br />

either use these directly <strong>for</strong> installation or create an ISO image that can be burned on DVD-ROM.<br />

Change to a directory with sufficient free disk space; <strong>for</strong> the PowerPC version of the ELDK you need about<br />

1.6 GiB, or twice as much (3.2 GiB) if you also want to create an ISO image in this directory.<br />

To download the ISO image from the ppc-linux-x86/iso directory of one of the mirror sites you can use<br />

st<strong>and</strong>ard tools like wget or ncftpget, <strong>for</strong> example:<br />

bash$ wget ftp://ftp.sunet.se/pub/<strong>Linux</strong>/distributions/eldk/4.2/ppc-linux-x86/iso/ppc-2007-01-19.i<br />

If you want to download the whole ELDK directory tree instead you can - <strong>for</strong> example - use the ncftp FTP<br />

client:<br />

3.5.2. Downloading the ELDK 11


ash$ ncftp ftp.sunet.se<br />

...<br />

ncftp / > cd /pub/<strong>Linux</strong>/distributions/eldk/4.2<br />

ncftp /pub/<strong>Linux</strong>/distributions/eldk/4.2 > bin<br />

ncftp /pub/<strong>Linux</strong>/distributions/eldk/4.2 > get -R ppc-linux-x86/distribution<br />

...<br />

ncftp /pub/<strong>Linux</strong>/distributions/eldk/4.2 > bye<br />

If you don't find the ncftp tool on your system you can download the NcFTP client from<br />

http://www.ncftp.com/download/<br />

<strong>The</strong>re are a few executable files (binaries <strong>and</strong> scripts) in the ELDK tree. Make sure they have the execute<br />

permissions set in your local copy:<br />

bash$ <strong>for</strong> file in \<br />

> tools/bin/rpm \<br />

> tools/usr/lib/rpm/rpmd \<br />

> install \<br />

> ELDK_MAKEDEV \<br />

> ELDK_FIXOWNER<br />

> do<br />

> chmod +x ppc-linux-x86/distribution/$file<br />

> done<br />

Now create an ISO image from the directory tree:<br />

bash$ mkisofs \<br />

> -A "ELDK-4.2 -- Target: PowerPC -- Host: x86 <strong>Linux</strong>" \<br />

> -publisher "(C) `date "+%Y"` <strong>DENX</strong> Software Engineering, www.denx.de" \<br />

> -p "`id -nu`@`hostname` -- `date`" \<br />

> -V ppc-linux-x86 \<br />

> -l -J -R -o eldk-ppc-linux-x86.iso ppc-linux-x86/distribution<br />

This will create an ISO image eldk-ppc-linux-x86.iso in your local directory that can be burned on DVD or<br />

mounted using the loopback device <strong>and</strong> used <strong>for</strong> installation as described above. Of course you can use the<br />

local copy of the directory tree directly <strong>for</strong> the installation, too.<br />

Please refer to section 3.10.2. Setting Up ELDK Build Environment <strong>for</strong> instructions on obtaining the build<br />

environment needed to re-build the ELDK from scratch.<br />

3.5.3. Initial Installation<br />

<strong>The</strong> initial installation is per<strong>for</strong>med using the install utility located in the root of the ELDK ISO image<br />

directory tree. <strong>The</strong> install utility has the following syntax:<br />

$ ./install [-d ] [] [] ...<br />

-d Specifies the root directory of the ELDK being installed. If omitted, the ELDK goes into<br />

the current directory.<br />

Specifies the target CPU family the user desires to install. If one or more<br />

parameters are specified, only the target components specific to the<br />

respective CPU families are installed onto the host. If omitted, the target components <strong>for</strong><br />

all supported target architecture CPU families are installed.<br />

Note: Make sure that the "exec" option to the mount comm<strong>and</strong> is in effect when mounting the ELDK ISO<br />

image. Otherwise the install program cannot be executed. On some distributions, it may be necessary to<br />

modify the /etc/fstab file, adding the "exec" mount option to the cdrom entry - it may also be the case that<br />

other existing mount options, such as "user" prevent a particular configuration from mounting the ELDK<br />

DVD with appropriate "exec" permission. In such cases, consult your distribution documentation or mount the<br />

3.5.3. Initial Installation 12


DVD explicitly using a comm<strong>and</strong> such as "sudo mount -o exec /dev/cdrom /mnt/cdrom" (sudo allows regular<br />

users to run certain privileged comm<strong>and</strong>s but may not be configured - run the previous comm<strong>and</strong> as root<br />

without "sudo" in the case that "sudo" has not been setup <strong>for</strong> use on your particular GNU/<strong>Linux</strong> system).<br />

You can install the ELDK to any empty directory you wish, the only requirement being that you have to have<br />

write <strong>and</strong> execute permissions on the directory. <strong>The</strong> installation process does not require superuser privileges.<br />

Depending on the parameters the install utility is invoked with, it installs one or more sets of target<br />

components. <strong>The</strong> ELDT packages are installed in any case.<br />

Refer to section 3.6. Working with ELDK <strong>for</strong> a sample usage of the ELDK.<br />

Note: If you intend to use the installation as a root filesystem exported over NFS, then you now have to<br />

finish the configuration of the ELDK following the instructions in 3.7. Mounting Target Components via<br />

NFS.<br />

Note: Installation of the Glibc- <strong>and</strong> uClibc-based ELDK versions into one directory is not yet supported.<br />

Note: Installation of the 32-bit <strong>and</strong> 64-bit ELDK versions into one directory is not yet supported.<br />

3.5.4. Installation <strong>and</strong> Removal of Individual<br />

Packages<br />

<strong>The</strong> ELDK has an RPM-based structure. This means that on the ISO image, individual components of the<br />

ELDK are in the <strong>for</strong>m of RPM packages, <strong>and</strong> after installation, the ELDK maintains its own database which<br />

contains in<strong>for</strong>mation about installed packages. <strong>The</strong> RPM database is kept local to the specific ELDK<br />

installation, which allows you to have multiple independent ELDK installations on your host system. (That is,<br />

you can install several instances of ELDK under different directories <strong>and</strong> work with them independently).<br />

Also, this provides <strong>for</strong> easy installation <strong>and</strong> management of individual ELDK packages.<br />

To list the installed ELDK RPM packages, use the following comm<strong>and</strong>:<br />

bash$ ${CROSS_COMPILE}rpm -qa<br />

To remove an ELDK package, use the following comm<strong>and</strong>:<br />

bash$ ${CROSS_COMPILE}rpm -e <br />

To install a package, use the following comm<strong>and</strong>:<br />

bash$ ${CROSS_COMPILE}rpm -i <br />

To update a package, use the following comm<strong>and</strong>:<br />

bash$ ${CROSS_COMPILE}rpm -U <br />

For the above comm<strong>and</strong>s to work correctly, it is crucial that the correct rpm binary gets invoked. In case of<br />

multiple ELDK installations <strong>and</strong> RedHat-based host system, there may well be several rpm tools installed on<br />

the host system.<br />

You must make sure, either by using an explicit path or by having set an appropriate PATH environment<br />

variable, that when you invoke rpm to install/remove components of a ELDK installation, it is the ELDK's<br />

rpm utility that gets actually invoked. <strong>The</strong> rpm utility is located in the bin subdirectory relative to the ELDK<br />

root installation directory.<br />

3.5.4. Installation <strong>and</strong> Removal of Individual Packages 13


To avoid confusion with the host OS (RedHat) rpm utility, the ELDK creates symlinks to its rpm binary with<br />

the names such that it could be invoked using the ${CROSS_COMPILE}rpm notation, <strong>for</strong> all supported<br />

$CROSS_COMPILE values.<br />

<strong>The</strong> st<strong>and</strong>ard (host OS) rpm utility allows various macros <strong>and</strong> configuration parameters to specified in<br />

user-specific ~/.rpmrc <strong>and</strong> ~/.rpmmacros files. <strong>The</strong> ELDK rpm tool also has this capability, but the names of<br />

the user-specific configuration files are ~/.eldk_rpmrc <strong>and</strong> ~/.eldk_rpmmacros, respectively.<br />

3.5.5. Removal of the Entire Installation<br />

To remove the entire ELDK installation, use the following comm<strong>and</strong> while in the ELDK root directory:<br />

bash$ rm -rf <br />

where specifies the root directory of the ELDK to be removed.<br />

3.6. Working with ELDK<br />

After the initial installation is complete, all you have to do to start working with the ELDK is to set <strong>and</strong> export<br />

the CROSS_COMPILE environment variable. Optionally, you may wish to add the bin <strong>and</strong> usr/bin<br />

directories of your ELDK installation to the value of your PATH environment variable. For instance, a sample<br />

ELDK installation <strong>and</strong> usage scenario looks as follows:<br />

• Create a new directory where the ELDK is to be installed, say:<br />

bash$ mkdir /opt/eldk<br />

• Mount a CD or an ISO image with the distribution:<br />

bash$ mount /dev/cdrom /mnt/cdrom<br />

• Run the installation utility included on the distribution to install into that specified directory:<br />

bash$ /mnt/cdrom/install -d /opt/eldk<br />

• After the installation utility completes, export the CROSS_COMPILE variable:<br />

bash$ export CROSS_COMPILE=ppc_4xx-<br />

• <strong>The</strong> trailing '-' character in the CROSS_COMPILE variable value is optional <strong>and</strong> has no effect on<br />

the cross tools behavior. However, it is required when building <strong>Linux</strong> kernel <strong>and</strong> U-<strong>Boot</strong> images.<br />

• Add the directories /opt/eldk/usr/bin <strong>and</strong> /opt/eldk/bin to PATH:<br />

bash$ PATH=$PATH:/opt/eldk/usr/bin:/opt/eldk/bin<br />

• Compile a file:<br />

bash$ ${CROSS_COMPILE}gcc -o hello_world hello_world.c<br />

You can also call the cross tools using the generic prefix ppc-linux- <strong>for</strong> example:<br />

bash$ ppc-linux-gcc -o hello_world hello_world.c<br />

• or, equivalently:<br />

bash$ /opt/eldk/usr/ppc-linux/bin/gcc -o hello_world hello_world.c<br />

3.6. Working with ELDK 14


<strong>The</strong> value of the CROSS_COMPILE variable must correspond to the target CPU family you want the cross<br />

tools to work <strong>for</strong>. Refer to the table below <strong>for</strong> the supported CROSS_COMPILE variable values:<br />

3.6.A Table of possible values <strong>for</strong> $CROSS_COMPILE<br />

CROSS_COMPILE Value Predefined Compiler Flag<br />

FPU present<br />

or not<br />

ppc_4xx- -mcpu=403 No<br />

ppc_4xxFP- -mcpu=405fp Yes<br />

ppc_6xx- -mcpu=603 Yes<br />

ppc_74xx- -mcpu=7400 Yes<br />

ppc_8xx- -mcpu=860 No<br />

ppc_85xx- -mcpu=8540 Yes<br />

ppc64-linux- -mcpu=powerpc64 Yes<br />

For compatibility with older versions of the ELDK <strong>and</strong> with other toolkits the following values <strong>for</strong><br />

$CROSS_COMPILE can be used, too: ppc_7xx- <strong>and</strong> ppc_82xx-. <strong>The</strong>se are synonyms <strong>for</strong> ppc_6xx.<br />

3.6.1. Switching Between Multiple Installations<br />

No special actions are required from the user to switch between multiple ELDK installations on the same host<br />

system. Which ELDK installation is used is determined entirely by the filesystem location of the binary that is<br />

being invoked. This approach can be illustrated using the following example.<br />

Assume the directory /work/denx_tools/usr/bin, where the ppc-linux-gcc compiler binary has been<br />

installed, is a part of the PATH environment variable. <strong>The</strong> user types the comm<strong>and</strong> as follows:<br />

$ ppc_8xx-gcc -c myfile.c<br />

To load the correct include files, find the correct libraries, spec files, etc., the compiler needs to know the<br />

ELDK root directory. <strong>The</strong> compiler determines this in<strong>for</strong>mation by analyzing the shell comm<strong>and</strong> it was<br />

invoked with ( ppc_8xx-gcc - without specifying the explicit path in this example) <strong>and</strong>, if needed, the<br />

value of the PATH environment variable. Thus, the compiler knows that it has been executed from the<br />

/work/denx_tools/usr/bin directory.<br />

<strong>The</strong>n, it knows that the compiler is installed in the usr/bin subdirectory of the root installation directory, so the<br />

ELDK, the compiler is a part of, has been installed in the subdirectories of the /work/denx_tools directory.<br />

This means that the target include files are in /work/denx_tools//usr/include, <strong>and</strong> so on.<br />

3.7. Mounting Target Components via NFS<br />

<strong>The</strong> target components of the ELDK can be mounted via NFS as the root file system <strong>for</strong> your target machine.<br />

For instance, <strong>for</strong> an 8xx-based target, <strong>and</strong> assuming the ELDK has been installed into the /opt/eldk directory,<br />

you can use the following directory as the NFS-based root file system:<br />

/opt/eldk/ppc_8xx<br />

Be<strong>for</strong>e the NFS-mounted root file system can work, you must create necessary device nodes in the<br />

//dev directory. This process requires superuser privileges <strong>and</strong> thus<br />

cannot be done by the installation procedure (which typically runs as non-root). To facilitate creation of the<br />

device nodes, the ELDK provides a script named ELDK_MAKEDEV, which is located in the root of the ELDK<br />

distribution ISO image. <strong>The</strong> script acccepts the following optional arguments:<br />

3.7. Mounting Target Components via NFS 15


-d Specifies the root directory of the ELDK being installed. If omitted, then the current<br />

directory is assumed.<br />

-a Specifies the target CPU family directory. If omitted, all installed target architecture<br />

directories will be populated with the device nodes.<br />

-h Prints usage.<br />

# /mnt/cdrom/ELDK_MAKEDEV -d /opt/eldk<br />

NOTE: Compared to older versions of the ELDK, options <strong>and</strong> behaviour of this comm<strong>and</strong> have been changed<br />

significantly. Please read the documentation.<br />

Some of the target utilities included in the ELDK, such as mount <strong>and</strong> su, have the SUID bit set. This<br />

means that when run, they will have privileges of the file owner of these utilities. That is, normally, they will<br />

have the privileges of the user who installed the ELDK on the host system. However, <strong>for</strong> these utilities to<br />

work properly, they must have superuser privileges. This means that if the ELDK was not installed by the<br />

superuser, the file owner of the target ELDK utilities that have the SUID bit set must be changed to root<br />

be<strong>for</strong>e a target component may be mounted as the root file system. <strong>The</strong> ELDK distribution image contains an<br />

ELDK_FIXOWNER script, which you can use to change file owners of all the appropriate files of the ELDK<br />

installation to root. <strong>The</strong> script accepts the same arguments as the ELDK_MAKEDEV script above. Please note<br />

that you must have superuser privileges to run this script. For instance, if you have installed the ELDK in the<br />

/opt/eldk directory, you can use the following comm<strong>and</strong>s:<br />

# cd /opt/eldk<br />

# /mnt/cdrom/ELDK_FIXOWNER<br />

Please note, that in the case that the installation directory, where the new ELDK distribution is being installed,<br />

is already populated with other ELDK distributions, the execution of the ELDK_FIXOWNER script without<br />

arguments will make the script work with all installed ELDK target architecture directories. This could take<br />

some time. To save the time, please use the -a argument to specify the appropriate target architecture. For<br />

instance:<br />

# cd /opt/eldk<br />

# /mnt/cdrom/ELDK_FIXOWNER -a ppc_8xx<br />

3.8. Rebuilding ELDK Components<br />

3.8.1. ELDK Source Distribution<br />

<strong>The</strong> ELDK is distributed with the full sources of all the components, so you may rebuild any ELDK package.<br />

<strong>The</strong> sources are provided in the <strong>for</strong>m of SRPM packages, distributed as a separate ISO image.<br />

To rebuild a target or ELDT package, you must first install the appropriate source RPM package from the ISO<br />

image into the ELDK environment. This can be done using the following comm<strong>and</strong>:<br />

$ ${CROSS_COMPILE}rpm -i /mnt/cdrom/SRPMS/.src.rpm<br />

After an ELDK source RPM is installed using the above comm<strong>and</strong>, its spec file <strong>and</strong> sources can be found in<br />

the subdirectories of the /usr/src/denx subdirectory.<br />

<strong>The</strong> sections that follow provide detailed instructions on rebuilding ELDT <strong>and</strong> target components of the<br />

ELDK.<br />

3.8. Rebuilding ELDK Components 16


3.8.2. Rebuilding Target Packages<br />

All the target packages can be rebuilt from the provided source RPM packages. At first you have to install the<br />

Source RPM itself:<br />

bash$ ${CROSS_COMPILE}rpm -iv .src.rpm<br />

<strong>The</strong>n you can rebuild the binary target RPM using the following comm<strong>and</strong> from the ELDK environment:<br />

bash$ ${CROSS_COMPILE}rpmbuild -ba .spec<br />

In order <strong>for</strong> the rebuilding process to work correctly, the following conditions must be true:<br />

• <strong>The</strong> $CROSS_COMPILE environment variable must be set as appropriate <strong>for</strong> the target CPU family.<br />

• <strong>The</strong> /usr/ppc-linux/bin directory must be in PATH be<strong>for</strong>e the /usr/bin directory. This is<br />

to make sure that the comm<strong>and</strong> gcc results in the fact that the ELDK cross compiler is invoked,<br />

rather than the host gcc.<br />

3.8.3. Rebuilding ELDT Packages<br />

All the ELDT packages allow <strong>for</strong> rebuilding from the provided source RPM packages using the following<br />

comm<strong>and</strong> from the ELDK environment:<br />

$ unset CROSS_COMPILE<br />

$ /usr/bin/rpmbuild -ba <br />

In order <strong>for</strong> the rebuilding process to work correctly, make sure all of the following is true:<br />

• <strong>The</strong> $CROSS_COMPILE environment variable must NOT be set.<br />

• Do NOT use the $CROSS_COMPILE comm<strong>and</strong> prefix.<br />

• <strong>The</strong> /usr/ppc-linux/bin directory must NOT be in PATH. This is to make sure that the<br />

comm<strong>and</strong> gcc causes invokation of the host gcc, rather than the ELDK cross compiler.<br />

3.9. ELDK Packages<br />

3.9.1. List of ELDT Packages<br />

Package Name<br />

Package<br />

Version<br />

autoconf 2.61-8<br />

automake 1.10-5<br />

bison 2.3-3<br />

crosstool-devel 0.43-3<br />

dtc 20070802-1<br />

elocaledef 1-1<br />

3.9. ELDK Packages 17


ftdump 20070802-1<br />

gdb 6.7-2<br />

genext2fs 1.4.1-1<br />

info 4.8-15<br />

ldd 0.1-1<br />

libtool 1.5.22-11<br />

make 3.81-6<br />

mkcramfs 1.1-1<br />

mkimage 1.3.1-1<br />

mtd-utils 1.0.1-2<br />

rpm<br />

rpm-build<br />

4.4.2-46_2<br />

4.4.2-46_2<br />

sed 4.1.4-1<br />

texinfo 4.8-15<br />

Note: <strong>The</strong> crosstool 0.43 ELDT package provides the following packages: gcc 4.2.2, gcc-c++<br />

4.2.2, gcc-java 4.2.2, cpp 4.2.2 <strong>and</strong> binutils 2.17.90. For more in<strong>for</strong>mation about the<br />

crosstool package please refer to http://kegel.com/crosstool.<br />

3.9.2. List of Target Packages<br />

Package Name<br />

Package Version<br />

acl 2.2.39-3.1<br />

appweb 2.2.2-5<br />

attr 2.4.32-2<br />

autoconf 2.61-8<br />

bash 3.2-9<br />

bc 1.06-26<br />

bind<br />

9.4.1-8.P1<br />

binutils 2.17.90-1<br />

binutils-devel 2.17.90-1<br />

boa<br />

0.94.14-0.5.rc21<br />

busybox 1.7.1-2<br />

byacc 1.9.20050813-1<br />

bzip2 1.0.4-10<br />

bzip2-devel 1.0.4-10<br />

bzip2-libs 1.0.4-10<br />

3.9.1. List of ELDT Packages 18


ccid 1.2.1-10<br />

chkconfig 1.3.34-1<br />

coreutils 6.9-3<br />

cpio 2.6-27<br />

cpp 4.2.2-2<br />

cracklib 2.8.9-11<br />

cracklib-dicts 2.8.9-11<br />

crosstool-targetcomponents 0.43-3<br />

curl 7.16.2-1<br />

cyrus-sasl 2.1.22-6<br />

cyrus-sasl-devel 2.1.22-6<br />

cyrus-sasl-lib 2.1.22-6<br />

db4<br />

db4-devel<br />

db4-utils<br />

4.5.20-5_2<br />

4.5.20-5_2<br />

4.5.20-5_2<br />

device-mapper 1.02.17-7<br />

device-mapper-devel 1.02.17-7<br />

device-mapper-libs 1.02.17-7<br />

dhclient 3.0.5-38<br />

dhcp 3.0.5-38<br />

diffutils 2.8.1-16<br />

directfb 1.0.0-1<br />

dosfstools 2.11-8<br />

dropbear 0.50-1<br />

dtc 20070802-1<br />

duma 2.5.8-2<br />

e2fsprogs 1.39-11<br />

e2fsprogs-devel 1.39-11<br />

e2fsprogs-libs 1.39-11<br />

ethtool 5-1<br />

expat 1.95.8-9<br />

expat-devel 1.95.8-9<br />

file 4.21-1<br />

file-libs 4.21-1<br />

3.9.2. List of Target Packages 19


findutils 4.2.29-2<br />

flex 2.5.33-9<br />

freetype 2.3.4-3<br />

freetype-devel 2.3.4-3<br />

ftdump 20070802-1<br />

ftp 0.17-40<br />

gawk 3.1.5-15<br />

gcc 4.2.2-2<br />

gcc-c++ 4.2.2-2<br />

gcc-java 4.2.2-2<br />

gdb 6.7-1<br />

glib 1.2.10-26<br />

glib2 2.12.13-1<br />

glib2-devel 2.12.13-1<br />

glib-devel 1.2.10-26<br />

gmp 4.1.4-12.3<br />

grep 2.5.1-57<br />

groff 1.18.1.4-2<br />

gzip 1.3.11-2<br />

hdparm 6.9-3<br />

httpd 2.2.4-4.1<br />

httpd-devel 2.2.4-4.1<br />

httpd-manual 2.2.4-4.1<br />

initscripts 8.54.1-1<br />

iproute 2.6.20-2<br />

iptables 1.3.8-2<br />

iputils 20070202-3<br />

iscsitarget 0.4.15-1<br />

kbd 1.12-22<br />

kernel-headers 2.6.24-1<br />

kernel-source 2.6.24-1<br />

krb5-devel 1.6.1-2.1<br />

krb5-libs 1.6.1-2.1<br />

less 394-9<br />

3.9.2. List of Target Packages 20


libattr 2.4.32-2<br />

libattr-devel 2.4.32-2<br />

libcap 1.10-29<br />

libcap-devel 1.10-29<br />

libpng 1.2.16-1<br />

libpng-devel 1.2.16-1<br />

libsysfs 2.1.0-1<br />

libsysfs-devel 2.1.0-1<br />

libtermcap 2.0.8-46.1<br />

libtermcap-devel 2.0.8-46.1<br />

libtirpc<br />

libtirpc-devel<br />

0.1.7-7_2<br />

0.1.7-7_2<br />

libtool 1.5.22-11<br />

libtool-ltdl 1.5.22-11<br />

libtool-ltdl-devel 1.5.22-11<br />

libusb 0.1.12-7<br />

libusb-devel 0.1.12-7<br />

libuser 0.56.2-1<br />

libuser-devel 0.56.2-1<br />

libxml2 2.6.29-1<br />

logrotate 3.7.5-3.1<br />

lrzsz 0.12.20-22.1<br />

lsof 4.78-5<br />

ltp<br />

20080131-eldk2<br />

lvm2 2.02.24-1<br />

m4 1.4.8-2<br />

mailcap 2.1.23-1<br />

make 3.81-6<br />

MAKEDEV 3.23-1.2<br />

man<br />

1.6e-3<br />

mdadm 2.6.2-4<br />

microwindows 0.91-2<br />

microwindows-fonts 0.91-1<br />

mingetty 1.07-5.2.2<br />

3.9.2. List of Target Packages 21


mktemp 1.5-25<br />

module-init-tools<br />

3.3-0.pre11.1.0<br />

mtd-utils 1.0.1-2<br />

ncompress 4.2.4-49<br />

ncurses 5.6-17<br />

ncurses-devel 5.6-17<br />

net-snmp 5.4-14<br />

net-snmp-devel 5.4-14<br />

net-snmp-libs 5.4-14<br />

net-snmp-utils 5.4-14<br />

net-tools 1.60-82<br />

newt 0.52.6-30<br />

newt-devel 0.52.6-30<br />

nfs-utils 1.1.0-1<br />

ntp<br />

4.2.4p2-1<br />

open-iscsi 2.0-865.15<br />

openldap 2.3.34-3<br />

openldap-devel 2.3.34-3<br />

openssl<br />

openssl-devel<br />

oprofile<br />

0.9.8b-12_2<br />

0.9.8b-12_2<br />

0.9.2-8_2<br />

pam 0.99.7.1-5.1<br />

pam-devel 0.99.7.1-5.1<br />

passwd 0.74-3<br />

patch 2.5.4-29.2.2<br />

pciutils<br />

pciutils-devel<br />

pcmciautils<br />

2.2.4-3_2<br />

2.2.4-3_2<br />

014-9_2<br />

pcre 7.0-2<br />

pcsc-lite 1.3.3-1.0<br />

pcsc-lite-devel 1.3.3-1.0<br />

pcsc-lite-libs 1.3.3-1.0<br />

perl<br />

perl-libs<br />

5.8.8-18_2<br />

5.8.8-18_2<br />

3.9.2. List of Target Packages 22


popt 1.12-1<br />

portmap<br />

postgresql<br />

postgresql-devel<br />

postgresql-libs<br />

4.0-65_2<br />

8.2.4-1_2<br />

8.2.4-1_2<br />

8.2.4-1_2<br />

ppp 2.4.4-7<br />

procps 3.2.7-14<br />

psmisc 22.3-2<br />

python 2.5.1-1<br />

rdate 1.4-6<br />

readline 5.2-4<br />

readline-devel 5.2-4<br />

routed<br />

0.17-12_1<br />

rpcbind 0.1.4-6<br />

rpm<br />

rpm-build<br />

rpm-devel<br />

rpm-libs<br />

4.4.2-46_2<br />

4.4.2-46_2<br />

4.4.2-46_2<br />

4.4.2-46_2<br />

rsh 0.17-40<br />

rsh-server 0.17-40<br />

screen 4.0.3-50<br />

sed 4.1.5-7<br />

SELF 1.0-13<br />

setup<br />

2.6.4-1_2<br />

shadow-utils 4.0.18.1-15<br />

slang 2.0.7-17<br />

slang-devel 2.0.7-17<br />

smartmontools 5.38-2<br />

strace 4.5.15-1<br />

sysfsutils 2.1.0-1<br />

sysklogd 1.4.2-9<br />

sysvinit 2.86-17<br />

tar 1.15.1-26<br />

tcp_wrappers 7.6-48<br />

3.9.2. List of Target Packages 23


tcp_wrappers-devel 7.6-48<br />

tcp_wrappers-libs 7.6-48<br />

telnet 0.17-38<br />

telnet-server 0.17-38<br />

termcap 5.5-1.20060701.1<br />

tftp 0.42-4<br />

tftp-server 0.42-4<br />

thttpd<br />

2.25b-13<br />

time 1.7-29<br />

u-boot 1.3.1-1<br />

udev 106-4.1<br />

unixODBC 2.2.12-2<br />

unzip 5.52-4<br />

util-linux<br />

2.13-0.52_2<br />

vim-common 7.1.12-1<br />

vim-minimal 7.1.12-1<br />

vixie-cron 4.1-82<br />

vsftpd<br />

2.0.5-16_2<br />

which 2.16-8<br />

wireless-tools 28-4<br />

wpa_supplicant 0.5.7-3<br />

wu-ftpd 2.6.2-1<br />

xdd 65.013007-1<br />

xenomai 2.4.2-1<br />

xinetd 2.3.14-12<br />

zip 2.31-3<br />

zlib 1.2.3-10<br />

zlib-devel 1.2.3-10<br />

Note 1: Not all packages will be installed automatically; <strong>for</strong> example the boa <strong>and</strong> thttpd web servers<br />

are mutually exclusive - you will have to remove one package be<strong>for</strong>e you can (manually) install the other one.<br />

Note 2: <strong>The</strong> crosstool 0.43 target package provides the following packages: glibc 2.6,<br />

glibc-common 2.6, glibc-devel 2.6, libstdc++ 4.2.2, libgcj 4.2.2, libgcj-devel<br />

4.2.2 <strong>and</strong> libstdc++-devel 4.2.2. For more in<strong>for</strong>mation about the crosstool package please<br />

refer to http://kegel.com/crosstool<br />

Note 3: <strong>The</strong> Xenomai <strong>and</strong> gcc-java packages are unavailable in ARM ELDK version.<br />

3.9.2. List of Target Packages 24


3.10. Rebuilding the ELDK from Scratch<br />

In this section, you will find instructions on how to build the ELDK from scratch, using the pristine package<br />

sources available on the Internet, <strong>and</strong> patches, spec files, <strong>and</strong> build scripts provided on the ELDK source<br />

CD-ROM.<br />

3.10.1. ELDK Build Process Overview<br />

<strong>The</strong> ELDK uses the Fedora 7 <strong>Linux</strong> distribution as source code reference. Any modifications to Fedora's<br />

sources the ELDK has introduced are in the <strong>for</strong>m of patches applied by the RPM tool while building the<br />

packages. Also, the ELDK uses modified spec files <strong>for</strong> its RPM packages. So, the sources of almost every<br />

ELDK package consist of the following parts:<br />

• Fedora pristine sources or<br />

• ELDK source tarball,<br />

• ELDK patches,<br />

• ELDK spec file.<br />

<strong>The</strong> Fedora pristine sources may be obtained from the Internet, see<br />

http://download.fedora.redhat.com/pub/fedora/linux/core.<br />

<strong>The</strong> ELDK patches <strong>and</strong> spec files are available on the ELDK source CD-ROM <strong>and</strong> from the <strong>DENX</strong> GIT<br />

repositories. Also, <strong>for</strong> convenience, the pristine Fedora sources are available here, too.<br />

Please use the following comm<strong>and</strong>s to check out a copy of one of the modules:<br />

git-clone git://www.denx.de/git/eldk/module<br />

<strong>The</strong> following ELDK modules are available:<br />

Module Name<br />

tarballs<br />

build<br />

Contents<br />

Source tarballs<br />

Build tools, patches, <strong>and</strong> spec files<br />

SRPMS<br />

Fedora 7 sources<br />

<strong>The</strong>n you may switch to a specific release of the ELDK using the "git-checkout" comm<strong>and</strong>; <strong>for</strong> example, to<br />

get the files <strong>for</strong> ELDK release 4.1, please do the following from the module directory:<br />

git-checkout ELDK_4_2<br />

It must be noted that some of the packages which are included in the ELDK are not included in Fedora.<br />

Examples of such packages are appWeb, microwindows, <strong>and</strong> wu-ftpd. For these packages tarballs are<br />

provided in the <strong>DENX</strong> GIT repository.<br />

To facilitate building of the ELDK, a build infrastructure has been developed. <strong>The</strong> infrastructure is composed<br />

of the following components:<br />

• ELDK_BUILD script<br />

• build.sh script<br />

• cpkgs.lst file<br />

• tpkgs.lst file<br />

• SRPMS.lst file<br />

3.10. Rebuilding the ELDK from Scratch 25


• tarballs.lst file<br />

<strong>The</strong> ELDK_BUILD script is the main script of the ELDK build procedure. It is the tool that you would<br />

normally use to build the ELDK from scratch. In the simplest case, the script may be invoked without<br />

arguments, <strong>and</strong> it will per<strong>for</strong>m all necessary steps to build the ELDK in a fully automated way. You may pass<br />

the following optional arguments to the ELDK_BUILD script:<br />

-a target architecture: "arm", "ppc" or "ppc64", defaults to "ppc".<br />

-n <br />

-v ELDK version string<br />

-u<br />

-p <br />

an identification string <strong>for</strong> the build. Defaults to the value based on the build<br />

architecture <strong>and</strong> current date, <strong>and</strong> has the following <strong>for</strong>mat: -YYYY-MM-DD<br />

build the uClibc-based ELDK version (on the plat<strong>for</strong>ms <strong>and</strong> versions where this is<br />

available).<br />

Optional build directory. By default, build will place the work files <strong>and</strong> results in the<br />

current directory.<br />

Warning: <strong>The</strong> ELDK build scripts rely on st<strong>and</strong>ard behaviour of the RPM tool. Make sure you don't use<br />

non-st<strong>and</strong>ard settings in your personal ~/.rpmmacros file that might cause conflicts.<br />

build.sh is a supplementary script that is called by ELDK_BUILD to accomplish certain steps of the build.<br />

Refer to section 3.10.3. build.sh Usage below <strong>for</strong> more details.<br />

<strong>The</strong> cpkgs.lst <strong>and</strong> tpkgs.lst files are read by build.sh <strong>and</strong> must contain lines describing sub-steps of the eldt<br />

<strong>and</strong> trg build procedure steps. Essentially, the files contain the list of the ELDT <strong>and</strong> target packages to be<br />

included in the ELDK. <strong>The</strong> SRPMS.lst file contains the list of the Fedora source RPM packages used during<br />

the ELDK build. <strong>The</strong> tarballs.lst file contains the list of source tarballs of the packages that are included in the<br />

ELDK but are not present in Fedora 7.<br />

For the ELDK_BUILD script to work correctly, it must be invoked from a certain build environment created<br />

on the host system. <strong>The</strong> build environment can be either checked out from the <strong>DENX</strong> GIT repository (see<br />

section 3.10.2. Setting Up ELDK Build Environment below <strong>for</strong> details) or copied from the ELDK build<br />

environment CD-ROM.<br />

To be more specific, the following diagram outlines the build environment needed <strong>for</strong> correct operation of the<br />

ELDK_BUILD script:<br />

/<br />

build/cross_rpms//SPECS/...<br />

SOURCES/...<br />

target_rpms//SPECS/...<br />

SOURCES/...<br />

install/install.c<br />

Makefile<br />

misc/ELDK_MAKEDEV<br />

ELDK_FIXOWNER<br />

README.html<br />

cpkgs.lst<br />

tpkgs.lst<br />

build.sh<br />

ELDK_BUILD<br />

SRPMS.lst<br />

tarballs.lst<br />

tarballs/....<br />

3.10.1. ELDK Build Process Overview 26


SRPMS/....<br />

SRPMS-updates/....<br />

In subdirectories of the cross_rpms <strong>and</strong> target_rpms directories, the sources <strong>and</strong> RPM spec files of,<br />

respectively, the ELDT <strong>and</strong> target packages are stored. <strong>The</strong> install subdirectory contains the sources of the<br />

installation utility which will be built <strong>and</strong> placed in the root of the ISO image. tarballs directory contains the<br />

source tarballs of the packages that are included in the ELDK but are not present in Fedora 7.<br />

<strong>The</strong> SRPMS <strong>and</strong> SRPMS-updates directories may contain the source RPM packages of Fedora 7. <strong>The</strong><br />

ELDK_BUILD script looks <strong>for</strong> a package in the SRPMS directory <strong>and</strong> then, if the package is not found, in the<br />

SRPMS-updates directory. If some (or all) of the Fedora SRPMs needed <strong>for</strong> the build are missing in the<br />

directories, the ELDK_BUILD script will download the source RPMs automatically from the Internet.<br />

<strong>The</strong> ELDK build environment CD-ROM provides a ready-to-use ELDK build environment. Please refer to<br />

section 3.10.2. Setting Up ELDK Build Environment below <strong>for</strong> detailed instructions on setting up the build<br />

environment.<br />

<strong>The</strong> ELDK_BUILD script examines the contents of the ELDK_PREFIX environment variable to determine<br />

the root directory of the ELDK build environment. If the variable is not set when the script is invoked, it is<br />

assumed that the root directory of the ELDK build environment is /opt/eldk. To build the ELDK in the<br />

example directory layout given above, you must set <strong>and</strong> export the ELDK_PREFIX variable<br />

prior to invoking ELDK_BUILD.<br />

After all the build steps are complete, the following subdirectories are created in the ELDK build<br />

environment:<br />

build//work/<br />

- full ELDK environment<br />

build//logs/<br />

- build procedure log files<br />

build//results/b_cdrom/ - binary cdrom tree, ready <strong>for</strong> mkisofs<br />

results/s_cdrom/ - source cdrom tree, ready <strong>for</strong> mkisofs<br />

results/d_cdrom/ - debuginfo cdrom tree, ready <strong>for</strong> mkisofs<br />

On <strong>Linux</strong> hosts, the binary <strong>and</strong> source ISO images are created automatically by the ELDK_BUILD script <strong>and</strong><br />

placed in the results directory. On Solaris hosts, creating the ISO images is a manual step. Use the contents of<br />

the b_cdrom <strong>and</strong> s_cdrom directories <strong>for</strong> the contents of the ISO images.<br />

3.10.2. Setting Up ELDK Build Environment<br />

For your convenience, the ELDK build environment CD-ROM provides full ELDK build environment. All<br />

you need to do is copy the contents of the CD-ROM to an empty directory on your host system. Assuming the<br />

ELDK build environment CD-ROM is mounted at /mnt/cdrom, <strong>and</strong> the empty directory where you want to<br />

create the build environment is named /opt/eldk, use the following comm<strong>and</strong>s to create the build environment:<br />

bash$ cd /opt/eldk<br />

bash$ cp -r /mnt/cdrom/* .<br />

<strong>The</strong>se comm<strong>and</strong>s will create the directory structure as described in section 3.10.1. ELDK Build Process<br />

Overview above. All necessary scripts <strong>and</strong> ELDK specific source files will be placed in the build<br />

subdirectory, <strong>and</strong> the required tarballs can be found in the tarballs subdirectory. In the SRPMS subdirectory,<br />

you will find all the Fedora 7 SRPMS needed to build the ELDK.<br />

Alternatively, you can obtain the ELDK build environment from the <strong>DENX</strong> GIT repository. Two modules are<br />

provided <strong>for</strong> check out: build <strong>and</strong> tarballs. <strong>The</strong> first one contains the files <strong>for</strong> the build subdirectory in the<br />

build environment, <strong>and</strong> the second one contains source tarballs of the packages that are included in the ELDK<br />

but are not present in Fedora 7. To create the ELDK build environment from the <strong>DENX</strong> GIT repository, use<br />

3.10.2. Setting Up ELDK Build Environment 27


the following comm<strong>and</strong>s (the example below assumes that the root directory of the build environment is<br />

/opt/eldk):<br />

bash$ cd /opt/eldk<br />

bash$ git-clone git://www.denx.de/git/eldk/build<br />

bash$ git-clone git://www.denx.de/git/eldk/tarballs<br />

bash$ git-clone git://www.denx.de/git/eldk/SRPMS<br />

Note: To allow to install the ELDK on as many as possible <strong>Linux</strong> distributions (including old systems), we<br />

use a Red Hat 7.3 host system <strong>for</strong> building. Also, Fedora Core 5 is known to work as a build environment.<br />

Other, especially more recent <strong>Linux</strong> distributions, will most likely have problems. We there<strong>for</strong> provide a Red<br />

Hat 7.3 based root file system image than can run in some virtualization environment (like qemu etc.). Here is<br />

an application note with detailed instructions:<br />

http://www.denx.de/wiki/<strong>DULG</strong>/AN2009_02_EldkReleaseBuildEnvironment<br />

3.10.3. build.sh Usage<br />

If you wish to per<strong>for</strong>m only a part of the ELDK build procedure, <strong>for</strong> instance to re-build or update a certain<br />

package, it may sometimes be convenient to invoke the build.sh script manually, without the aid of the<br />

ELDK_BUILD script. Please note, however, that this approach is in general discouraged.<br />

<strong>The</strong> whole build procedure is logically divided into six steps, <strong>and</strong> the build.sh must be told which of the<br />

build steps to per<strong>for</strong>m. <strong>The</strong> build steps are defined as follows:<br />

• rpm - build RPM<br />

• eldt - build ELDT packages<br />

• seldt - save ELDT SRPM packages to create a source ISO image later on<br />

• trg - build target packages<br />

• biso - prepare the file tree to create the binary ISO image<br />

• siso - prepare the file tree to create the source ISO image<br />

• diso - prepare the file tree to create the debuginfo ISO image<br />

Further, the eldt <strong>and</strong> trg build steps are devided into sub-steps, as defined in the cpkgs.lst <strong>and</strong> tpkgs.lst<br />

files (see below <strong>for</strong> details). You may specify which sub-steps of the build step are to be per<strong>for</strong>med.<br />

<strong>The</strong> <strong>for</strong>mal syntax <strong>for</strong> the usage of build.sh is as follows:<br />

bash$ ./build.sh [-a ] [-n ] [-p ] [-r ] \<br />

[-w ] []<br />

-a target architecture: "ppc", "ppc64", "arm" or "mips", defaults to "ppc".<br />

-n an identification string <strong>for</strong> the build. It is used as a name <strong>for</strong> some directories<br />

created during the build. You may use <strong>for</strong> example the current date as the build<br />

name.<br />

-p is the name of the directory that contains the build environment. Refer to build<br />

overview above <strong>for</strong> description of the build environment.<br />

-r is the name of the directory where the resulting RPMs <strong>and</strong> SRPMs created on this<br />

step will be placed.<br />

-w is the name of the directory where the build is per<strong>for</strong>med.<br />

<br />

is the name of the build step that is to be per<strong>for</strong>med. Refer to the list of the build<br />

procedure steps above.<br />

3.10.3. build.sh Usage 28


is an optional parameter which identifies sub-steps of the step which are to be<br />

per<strong>for</strong>med. This is useful when you want to re-build only some specific packages.<br />

<strong>The</strong> numbers are defined in the cpkgs.lst <strong>and</strong> tpkgs.lst files discussed below. You<br />

can specify a range of numbers here. For instance, "2 5" means do steps from 2 to<br />

5, while simply "2" means do all steps starting at 2.<br />

Please note that you must never use build.sh to build the ELDK from scratch. For build.sh to work<br />

correctly, the script must be invoked from the build environment after a successful build using the<br />

ELDK_BUILD script. A possible scenario of build.sh usage is such that you have a build environment<br />

with results of a build per<strong>for</strong>med using the ELDK_BUILD script <strong>and</strong> want to re-build certain ELDT <strong>and</strong> target<br />

packages, <strong>for</strong> instance, because you have updated sources of a package or added a new package to the build.<br />

When building the target packages (during the trg buildstep), build.sh examines the contents of the<br />

TARGET_CPU_FAMILY_LIST environment variable, which may contain a list indicating which target CPU<br />

variants the packages must be built <strong>for</strong>. Possible CPU variants are 4xx, 4xxFP, 6xx, 74xx, 8xx, 85xx <strong>and</strong><br />

ppc64. For example, the comm<strong>and</strong> below rebuilds the target RPM listed in the tpckgs.lst file under the number<br />

of 47 (see section 3.10.4. Format of the cpkgs.lst <strong>and</strong> tpkgs.lst Files <strong>for</strong> description of the tpckgs.lst <strong>and</strong><br />

cpkgs.lst files), <strong>for</strong> the 8xx <strong>and</strong> 85xx CPUs:<br />

bash$ TARGET_CPU_FAMILY_LIST="8xx 85xx" \<br />

> /opt/eldk/build.sh -a ppc \<br />

> -n 2007-01-19 \<br />

> -p /opt/eldk/build/ppc-2007-01-19 \<br />

> -r /opt/eldk/build/ppc-2007-01-19/results \<br />

> -w /opt/eldk/build/ppc-2007-01-19/work \<br />

> trg 47 47<br />

Note: If you are going to invoke build.sh to re-build a package that has already been built in the build<br />

environment by the ELDK_BUILD script, then you must first manually uninstall the package from ELDK<br />

installation created by the build procedure under the work directory of the build environment.<br />

Note: It is recommended that you use the build.sh script only at the final stage of adding/updating a<br />

package to the ELDK. For debugging purposes, it is much more convenient <strong>and</strong> efficient to build both ELDT<br />

<strong>and</strong> target packages using a working ELDK installation, as described in the sections 3.8.2. Rebuilding Target<br />

Packages <strong>and</strong> 3.8.3. Rebuilding ELDT Packages above.<br />

3.10.4. Format of the cpkgs.lst <strong>and</strong> tpkgs.lst Files<br />

Each line of these files has the following <strong>for</strong>mat:<br />

\<br />

<br />

<strong>The</strong> ELDK source CD-ROM contains the cpkgs.lst <strong>and</strong> tpkgs.lst files used to build this version of the ELDK<br />

distribution. Use them as reference if you want to include any additional packages into the ELDK, or remove<br />

unneeded packages.<br />

To add a package to the ELDK you must add a line to either the cpkgs.lst file, if you are adding a ELDT<br />

package, or to the tpkgs.lst file, if it is a target package. Keep in mind that the relative positions of packages in<br />

the cpkgs.lst <strong>and</strong> tpkgs.lst files (the sub-step numbers) are very important. <strong>The</strong> build procedure builds the<br />

packages sequentially as defined in the *.lst files <strong>and</strong> installs the packages in the "work" environment as they<br />

are built. This implies that if a package depends on other packages, those packages must be specified earlier<br />

(with smaller sub-step numbers) in the *.lst files.<br />

Note: For cpkgs.lst, the package_version may be replaced by the special keyword "RHAUX". Such packages<br />

are used as auxiliary when building ELDK 4.2 on non-Fedora hosts. <strong>The</strong>se packages will be built <strong>and</strong> used<br />

3.10.4. Format of the cpkgs.lst <strong>and</strong> tpkgs.lst Files 29


during the build process, but will not be put into the ELDK 4.2 distribution ISO images.<br />

3.11. Notes <strong>for</strong> Solaris 2.x Host Environment<br />

If you use a Solaris 2.x host environment, you need additional freeware packages (mostly GNU tools) to<br />

install <strong>and</strong> especially to build the ELDK packages. <strong>The</strong> following table lists all required packages that must be<br />

installed on the Solaris host system be<strong>for</strong>e attempting to build <strong>and</strong>/or install the ELDK. All these files except<br />

those marked with (**) (<strong>and</strong> the RPM <strong>and</strong> zlib-1.1.2 packages, which are available at<br />

ftp://rpmfind.net/linux/solaris are available <strong>for</strong> free download at<br />

ftp://ftp.sunfreeware.com/pub/freeware/sparc/2.6/<br />

Necessary Freeware Packages:<br />

Package Version Instance File Name<br />

autoconf(**) 2.13 SMCautoc autoconf-2.13-sol26-sparc-local.gz<br />

automake(**) 1.4 SMCautom automake-1.4-sol26-sparc-local.gz<br />

bash 2.05 SMCbash bash-2.05-sol26-sparc-local.gz<br />

binutils 2.11.2 SMCbinut binutils-2.11.2-sol26-sparc-local.gz<br />

bison 1.28 SMCbison bison-1.28-sol26-sparc-local.gz<br />

bzip2 1.0.1 SMCbzip2 bzip2-1.0.1-sol26-sparc-local.gz<br />

ddd(*) 3.0 TUBddd ddd-3.0-sol26-sparc-local.gz<br />

diffutils 2.7 GNUdiffut diffutils-2.7-sol26-sparc-local.gz<br />

expect(*) 5.25 NTexpect expect-5.25-sol26-sparc-local.gz<br />

fileutils 4.0 SMCfileu fileutils-4.0-sol26-sparc-local.gz<br />

flex 2.5.4a FSFflex flex-2.5.4a-sol26-sparc-local.gz<br />

gawk 3.1.0 SMCgawk gawk-3.1.0-sol26-sparc-local.gz<br />

gcc 2.95.3 SMCgcc gcc-2.95.3-sol26-sparc-local.gz<br />

gettext 0.10.37 SMCgtext gettext-0.10.37-sol26-sparc-local.gz<br />

gzip 1.3 SMCgzip gzip-1.3-sol26-sparc-local<br />

libiconv 1.6.1 SMClibi libiconv-1.6.1-sol26-sparc-local.gz<br />

libtool 1.4 SMClibt libtool-1.4-sol26-sparc-local.gz<br />

m4 1.4 SMCm4 m4-1.4-sol26-sparc-local.gz<br />

make(**) 3.79.1 SMCmake make-3.79.1-sol26-sparc-local.gz<br />

ncurses 5.2 SMCncurs ncurses-5.2-sol26-sparc-local.gz<br />

patch 2.5 FSFpatch patch-2.5-sol26-sparc-local.gz<br />

perl(**) 5.005_03 SMCperl perl-5.005_03-sol26-sparc-local.gz<br />

python 1.5.2 SMCpython python-1.5.2-sol26-sparc-local.gz<br />

rpm 2.5.2 RPM rpm-2.5.2.pkg<br />

sed 3.02 SMCsed sed-3.02-sol26-sparc-local.gz<br />

tar 1.13.19 SMCtar tar-1.13.19-sol26-sparc-local.gz<br />

tcl(*) 8.3.3 SMCtcl tcl-8.3.3-sol26-sparc-local.gz<br />

texinfo 4.0 SMCtexi texinfo-4.0-sol26-sparc-local.gz<br />

textutils 2.0 SMCtextu textutils-2.0-sol26-sparc-local.gz<br />

unzip 5.32 IZunzip unzip-5.32-sol26-sparc-local.gz<br />

wget 1.7 SMCwget wget-1.7-sol26-sparc-local.gz<br />

zlib(**) 1.0.4 SMCzlib zlib-1.0.4-sol26-sparc-local.gz<br />

zlib 1.1.2 - zlib-1.1.2.tar.gz<br />

3.11. Notes <strong>for</strong> Solaris 2.x Host Environment 30


<strong>The</strong> packages marked "(*)" are not absolutely required, but sooner or later you will need them anyway so we<br />

recommend to install them.<br />

<strong>The</strong> packages marked "(**)" are older versions of the ones currently available at<br />

ftp://ftp.sunfreeware.com/pub/freeware/sparc/2.6/. You can obtain them from the <strong>DENX</strong> public FTP server.<br />

<strong>The</strong> following symbolic links must be created in order to be able to build the ELDK on a Solaris machine:<br />

/usr/local/bin/cc --> /usr/local/bin/gcc<br />

/usr/lib/libiconv.so.2 --> /usr/local/lib/libiconv.so.2<br />

/usr/lib/libncurses.so.5 --> /usr/local/lib/libncurses.so.5<br />

Additionally, to be able to build the ELDK on Solaris, you must place newer GNU gettext macros to the<br />

/usr/local/share/aclocal directory. This can be accomplished as follows:<br />

• Download the<br />

http://www.ibiblio.org/pub/packages/solaris/sparc/GNUgettext.0.10.40.SPARC.32bit.Solaris.8.pkg.tgz<br />

package.<br />

• Untar the package to a temporary directory <strong>and</strong> copy the macros to the /usr/local/share/aclocal<br />

directory:<br />

$ cp GNUgettext/root/usr/local/share/aclocal/*.m4 /usr/local/share/aclocal<br />

• 4. System Setup<br />

♦ 4.1. Serial Console Access<br />

♦ 4.2. Configuring the "cu" comm<strong>and</strong><br />

♦ 4.3. Configuring the "kermit" comm<strong>and</strong><br />

♦ 4.4. Using the "minicom" program<br />

♦ 4.5. Permission Denied Problems<br />

♦ 4.6. Configuration of a TFTP Server<br />

♦ 4.7. Configuration of a BOOTP / DHCP Server<br />

♦ 4.8. Configuring a NFS Server<br />

4. System Setup<br />

Some tools are needed to install <strong>and</strong> configure U-<strong>Boot</strong> <strong>and</strong> <strong>Linux</strong> on the target system. Also, especially during<br />

development, you will want to be able to interact with the target system. This section describes how to<br />

configure your host system <strong>for</strong> this purpose.<br />

4.1. Serial Console Access<br />

To use U-<strong>Boot</strong> <strong>and</strong> <strong>Linux</strong> as a development system <strong>and</strong> to make full use of all their capabilities you will need<br />

access to a serial console port on your target system. Later, U-<strong>Boot</strong> <strong>and</strong> <strong>Linux</strong> can be configured to allow <strong>for</strong><br />

automatic execution without any user interaction.<br />

<strong>The</strong>re are several ways to access the serial console port on your target system, such as using a terminal server,<br />

but the most common way is to attach it to a serial port on your host. Additionally, you will need a terminal<br />

emulation program on your host system, such as cu or kermit.<br />

4. System Setup 31


4.2. Configuring the "cu" comm<strong>and</strong><br />

<strong>The</strong> cu comm<strong>and</strong> is part of the UUCP package <strong>and</strong> can be used to act as a dial-in terminal. It can also do<br />

simple file transfers, which can be used in U-<strong>Boot</strong> <strong>for</strong> image download.<br />

On RedHat systems you can check if the UUCP package is installed as follows:<br />

$ rpm -q uucp<br />

If necessary, install the UUCP package from your distribution media.<br />

To configure cu <strong>for</strong> use with U-<strong>Boot</strong> <strong>and</strong> <strong>Linux</strong> please make sure that the following entries are present in the<br />

UUCP configuration files; depending on your target configuration the serial port <strong>and</strong>/or the console baudrate<br />

may be different from the values used in this example: (/dev/ttyS0, 115200 bps, 8N1):<br />

• /etc/uucp/sys:<br />

#<br />

# /dev/ttyS0 at 115200 bps:<br />

#<br />

system<br />

S0@115200<br />

port<br />

serial0_115200<br />

time<br />

any<br />

• /etc/uucp/port:<br />

#<br />

# /dev/ttyS0 at 115200 bps:<br />

#<br />

port<br />

serial0_115200<br />

type<br />

direct<br />

device<br />

/dev/ttyS0<br />

speed 115200<br />

hardflow false<br />

You can then connect to the serial line using the comm<strong>and</strong><br />

$ cu S0@115200<br />

Connected.<br />

To disconnect, type the escape character '~' followed by '.' at the beginning of a line.<br />

See also: cu(1), info uucp.<br />

4.3. Configuring the "kermit" comm<strong>and</strong><br />

<strong>The</strong> name kermit st<strong>and</strong>s <strong>for</strong> a whole family of communications software <strong>for</strong> serial <strong>and</strong> network connections.<br />

<strong>The</strong> fact that it is available <strong>for</strong> most computers <strong>and</strong> operating systems makes it especially well suited <strong>for</strong> our<br />

purposes.<br />

kermit executes the comm<strong>and</strong>s in its initialization file, .kermrc, in your home directory be<strong>for</strong>e it executes<br />

any other comm<strong>and</strong>s, so this can be easily used to customize its behaviour using appropriate initialization<br />

comm<strong>and</strong>s. <strong>The</strong> following settings are recommended <strong>for</strong> use with U-<strong>Boot</strong> <strong>and</strong> <strong>Linux</strong>:<br />

4.2. Configuring the "cu" comm<strong>and</strong> 32


• ~/.kermrc:<br />

set line /dev/ttyS0<br />

set speed 115200<br />

set carrier-watch off<br />

set h<strong>and</strong>shake none<br />

set flow-control none<br />

robust<br />

set file type bin<br />

set file name lit<br />

set rec pack 1000<br />

set send pack 1000<br />

set window 5<br />

This example assumes that you use the first serial port of your host system (/dev/ttyS0) at a baudrate of<br />

115200 to connect to the target's serial console port.<br />

You can then connect to the serial line:<br />

$ kermit -c<br />

Connecting to /dev/ttyS0, speed 115200.<br />

<strong>The</strong> escape character is Ctrl-\ (ASCII 28, FS)<br />

Type the escape character followed by C to get back,<br />

or followed by to see other options.<br />

----------------------------------------------------<br />

Due to licensing conditions you will often find two kermit packages in your GNU/<strong>Linux</strong> distribution. In<br />

this case you will want to install the ckermit package. <strong>The</strong> gkermit package is only a comm<strong>and</strong> line tool<br />

implementing the kermit transfer protocol.<br />

If you cannot find kermit on the distribution media <strong>for</strong> your <strong>Linux</strong> host system, you can download it<br />

from the kermit project home page: http://www.columbia.edu/kermit/<br />

4.4. Using the "minicom" program<br />

minicom is another popular serial communication program. Un<strong>for</strong>tunately, many users have reported<br />

problems using it with U-<strong>Boot</strong> <strong>and</strong> <strong>Linux</strong>, especially when trying to use it <strong>for</strong> serial image download. It's use<br />

is there<strong>for</strong>e discouraged.<br />

4.5. Permission Denied Problems<br />

<strong>The</strong> terminal emulation program must have write access to the serial port <strong>and</strong> to any locking files that are used<br />

to prevent concurrent access from other applications. Depending on the used <strong>Linux</strong> distribution you may have<br />

to make sure that:<br />

• the serial device belongs to the same group as the cu comm<strong>and</strong>, <strong>and</strong> that the permissions of cu have<br />

the setgid bit set<br />

• the kermit belongs to the same group as cu <strong>and</strong> has the setgid bit set<br />

• the /var/lock directory belongs to the same group as the cu comm<strong>and</strong>, <strong>and</strong> that the write permissions<br />

<strong>for</strong> the group are set<br />

4.3. Configuring the "kermit" comm<strong>and</strong> 33


4.6. Configuration of a TFTP Server<br />

<strong>The</strong> fastest way to use U-<strong>Boot</strong> to load a <strong>Linux</strong> kernel or an application image is file transfer over Ethernet. For<br />

this purpose, U-<strong>Boot</strong> implements the TFTP protocol (see the tftpboot comm<strong>and</strong> in U-<strong>Boot</strong>).<br />

To enable TFTP support on your host system you must make sure that the TFTP daemon program<br />

/usr/sbin/in.tftpd is installed. On RedHat systems you can verify this by running:<br />

$ rpm -q tftp-server<br />

If necessary, install the TFTP daemon program from your distribution media.<br />

Most <strong>Linux</strong> distributions disable the TFTP service by default. To enable it <strong>for</strong> example on RedHat systems,<br />

edit the file /etc/xinetd.d/tftp <strong>and</strong> remove the line<br />

disable = yes<br />

or change it into a comment line by putting a hash character in front of it:<br />

# default: off<br />

# description: <strong>The</strong> tftp server serves files using the trivial file transfer<br />

# protocol. <strong>The</strong> tftp protocol is often used to boot diskless<br />

# workstations, download configuration files to network-aware printers,<br />

# <strong>and</strong> to start the installation process <strong>for</strong> some operating systems.<br />

service tftp<br />

{<br />

socket_type<br />

= dgram<br />

protocol<br />

= udp<br />

wait<br />

= yes<br />

user<br />

= root<br />

server<br />

= /usr/sbin/in.tftpd<br />

server_args<br />

= -s /tftpboot<br />

# disable = yes<br />

per_source = 11<br />

cps = 100 2<br />

}<br />

Also, make sure that the /tftpboot directory exists <strong>and</strong> is world-readable (permissions at least "dr-xr-xr-x").<br />

4.7. Configuration of a BOOTP / DHCP Server<br />

BOOTP resp. DHCP can be used to automatically pass configuration in<strong>for</strong>mation to the target. <strong>The</strong> only<br />

thing the target must "know" about itself is its own Ethernet hardware (MAC) address. <strong>The</strong> following<br />

comm<strong>and</strong> can be used to check if DHCP support is available on your host system:<br />

$ rpm -q dhcp<br />

If necessary, install the DHCP package from your distribution media.<br />

<strong>The</strong>n you have to create the DHCP configuration file /etc/dhcpd.conf that matches your network setup. <strong>The</strong><br />

following example gives you an idea what to do:<br />

subnet 192.168.0.0 netmask 255.255.0.0 {<br />

option routers 192.168.1.1;<br />

option subnet-mask 255.255.0.0;<br />

option domain-name<br />

"local.net";<br />

4.6. Configuration of a TFTP Server 34


option domain-name-servers ns.local.net;<br />

}<br />

host trgt { hardware ethernet 00:30:BF:01:02:D0;<br />

fixed-address 192.168.100.6;<br />

option root-path "/opt/eldk-4.2/ppc_4xx";<br />

option host-name "canyonl<strong>and</strong>s";<br />

next-server 192.168.1.1;<br />

filename<br />

"/tftpboot/canyonl<strong>and</strong>s/uImage";<br />

}<br />

With this configuration, the DHCP server will reply to a request from the target with the ethernet address<br />

00:30:BF:01:02:D0 with the following in<strong>for</strong>mation:<br />

• <strong>The</strong> target is located in the subnet 192.168.0.0 which uses the netmask 255.255.0.0.<br />

• <strong>The</strong> target has the hostname canyonl<strong>and</strong>s <strong>and</strong> the IP address 192.168.100.6.<br />

• <strong>The</strong> host with the IP address 192.168.1.1 will provide the boot image <strong>for</strong> the target <strong>and</strong> provide<br />

NFS server function in cases when the target mounts it's root filesystem over NFS.<br />

<strong>The</strong> host listed with the next-server option can be different from the host that is running the<br />

DHCP server.<br />

• <strong>The</strong> host provides the file /tftpboot/canyonl<strong>and</strong>s/uImage as boot image <strong>for</strong> the target.<br />

• <strong>The</strong> target can mount the directory /opt/eldk-4.2/ppc_4xx on the NFS server as root filesystem.<br />

4.8. Configuring a NFS Server<br />

For a development environment it is very convenient when the host <strong>and</strong> the target can share the same files<br />

over the network. <strong>The</strong> easiest way <strong>for</strong> such a setup is when the host provides NFS server functionality <strong>and</strong><br />

exports a directory that can be mounted from the target as the root filesystem.<br />

Assuming NFS server functionality is already provided by your host, the only configuration that needs to be<br />

added is an entry <strong>for</strong> your target root directory to your /etc/exports file, <strong>for</strong> instance like this:<br />

/opt/eldk-4.2/ppc_4xx<br />

192.168.0.0/255.255.0.0(rw,no_root_squash,sync)<br />

This line exports the /opt/eldk-4.2/ppc_4xx directory with read <strong>and</strong> write permissions to all hosts on the<br />

192.168.0.0 subnet.<br />

After modifying the /etc/exports file you must make sure the NFS system is notified about the change, <strong>for</strong><br />

instance by issuing the comm<strong>and</strong>:<br />

# /sbin/service nfs restart<br />

• 5. Das U-<strong>Boot</strong><br />

♦ 5.1. Current Versions<br />

♦ 5.2. Unpacking the Source Code<br />

♦ 5.3. Configuration<br />

♦ 5.4. Installation<br />

◊<br />

5.4.1. Be<strong>for</strong>e You Begin<br />

⋅ 5.4.1.1. Installation Requirements<br />

⋅ 5.4.1.2. Board Identification Data<br />

4.7. Configuration of a BOOTP / DHCP Server 35


◊ 5.4.2. Installation Using a BDM/JTAG Debugger<br />

◊ 5.4.3. Installation using U-<strong>Boot</strong><br />

♦ 5.5. Tool Installation<br />

♦ 5.6. Initialization<br />

♦ 5.7. Initial Steps<br />

♦ 5.8. <strong>The</strong> First Power-On<br />

♦ 5.9. U-<strong>Boot</strong> Comm<strong>and</strong> Line Interface<br />

◊<br />

◊<br />

◊<br />

◊<br />

◊<br />

◊<br />

◊<br />

5.9.1. In<strong>for</strong>mation Comm<strong>and</strong>s<br />

⋅ 5.9.1.1. bdinfo - print Board Info structure<br />

⋅ 5.9.1.2. coninfo - print console devices <strong>and</strong> in<strong>for</strong>mations<br />

⋅ 5.9.1.3. flinfo - print FLASH memory in<strong>for</strong>mation<br />

⋅ 5.9.1.4. iminfo - print header in<strong>for</strong>mation <strong>for</strong> application image<br />

⋅ 5.9.1.5. help - print online help<br />

5.9.2. Memory Comm<strong>and</strong>s<br />

⋅ 5.9.2.1. base - print or set address offset<br />

⋅ 5.9.2.2. crc32 - checksum calculation<br />

⋅ 5.9.2.3. cmp - memory compare<br />

⋅ 5.9.2.4. cp - memory copy<br />

⋅ 5.9.2.5. md - memory display<br />

⋅ 5.9.2.6. mm - memory modify (auto-incrementing)<br />

⋅ 5.9.2.7. mtest - simple RAM test<br />

⋅ 5.9.2.8. mw - memory write (fill)<br />

⋅ 5.9.2.9. nm - memory modify (constant address)<br />

⋅ 5.9.2.10. loop - infinite loop on address range<br />

5.9.3. Flash Memory Comm<strong>and</strong>s<br />

⋅ 5.9.3.1. cp - memory copy<br />

⋅ 5.9.3.2. flinfo - print FLASH memory in<strong>for</strong>mation<br />

⋅ 5.9.3.3. erase - erase FLASH memory<br />

⋅ 5.9.3.4. protect - enable or disable FLASH write protection<br />

⋅ 5.9.3.5. mtdparts - define a <strong>Linux</strong> compatible MTD partition scheme<br />

5.9.4. Execution Control Comm<strong>and</strong>s<br />

⋅ 5.9.4.1. autoscr - run script from memory<br />

⋅ 5.9.4.2. bootm - boot application image from memory<br />

⋅ 5.9.4.3. go - start application at address 'addr'<br />

5.9.5. Download Comm<strong>and</strong>s<br />

⋅ 5.9.5.1. bootp - boot image via network using BOOTP/TFTP protocol<br />

⋅ 5.9.5.2. dhcp - invoke DHCP client to obtain IP/boot params<br />

⋅ 5.9.5.3. loadb - load binary file over serial line (kermit mode)<br />

⋅ 5.9.5.4. loads - load S-Record file over serial line<br />

⋅ 5.9.5.5. rarpboot- boot image via network using RARP/TFTP protocol<br />

⋅ 5.9.5.6. tftpboot- boot image via network using TFTP protocol<br />

5.9.6. Environment Variables Comm<strong>and</strong>s<br />

⋅ 5.9.6.1. printenv- print environment variables<br />

⋅ 5.9.6.2. saveenv - save environment variables to persistent storage<br />

⋅ 5.9.6.3. setenv - set environment variables<br />

⋅ 5.9.6.4. run - run comm<strong>and</strong>s in an environment variable<br />

⋅ 5.9.6.5. bootd - boot default, i.e., run 'bootcmd'<br />

5.9.7. Flattened Device Tree support<br />

⋅ 5.9.7.1. fdt addr - select FDT to work on<br />

⋅ 5.9.7.2. fdt list - print one level<br />

⋅ 5.9.7.3. fdt print - recursive print<br />

⋅ 5.9.7.4. fdt mknode - create new nodes<br />

⋅ 5.9.7.5. fdt set - set node properties<br />

⋅ 5.9.7.6. fdt rm - remove nodes or properties<br />

4.8. Configuring a NFS Server 36


⋅ 5.9.7.7. fdt move - move FDT blob to new address<br />

⋅ 5.9.7.8. fdt chosen - fixup dynamic info<br />

◊ 5.9.8. Special Comm<strong>and</strong>s<br />

⋅ 5.9.8.1. i2c - I2C sub-system<br />

◊ 5.9.9. Storage devices<br />

◊ 5.9.10. Miscellaneous Comm<strong>and</strong>s<br />

⋅ 5.9.10.1. echo - echo args to console<br />

⋅ 5.9.10.2. reset - Per<strong>for</strong>m RESET of the CPU<br />

⋅ 5.9.10.3. sleep - delay execution <strong>for</strong> some time<br />

⋅ 5.9.10.4. version - print monitor version<br />

⋅ 5.9.10.5. - alias <strong>for</strong> 'help'<br />

♦ 5.10. U-<strong>Boot</strong> Environment Variables<br />

♦ 5.11. U-<strong>Boot</strong> Scripting Capabilities<br />

♦ 5.12. U-<strong>Boot</strong> St<strong>and</strong>alone Applications<br />

◊ 5.12.1. "Hello World" Demo<br />

◊ 5.12.2. Timer Demo<br />

♦ 5.13. U-<strong>Boot</strong> Image Formats<br />

♦ 5.14. U-<strong>Boot</strong> Advanced Features<br />

◊ 5.14.1. <strong>Boot</strong> Count Limit<br />

◊ 5.14.2. Bitmap Support<br />

◊ 5.14.3. Splash Screen Support<br />

5. Das U-<strong>Boot</strong><br />

5.1. Current Versions<br />

Das U-<strong>Boot</strong> (or just "U-<strong>Boot</strong>" <strong>for</strong> short) is Open Source Firmware <strong>for</strong> Embedded PowerPC, ARM, MIPS, x86<br />

<strong>and</strong> other processors. <strong>The</strong> U-<strong>Boot</strong> project is hosted by <strong>DENX</strong>, where you can also find the project home page:<br />

http://www.denx.de/wiki/U-<strong>Boot</strong>/<br />

<strong>The</strong> current version of the U-<strong>Boot</strong> source code can be retrieved from the <strong>DENX</strong> "git" repository.<br />

You can browse the "git" repositories at http://git.denx.de/<br />

<strong>The</strong> trees can be accessed through the git, HTTP, <strong>and</strong> rsync protocols. For example you can use one of the<br />

following comm<strong>and</strong>s to create a local clone of one of the source trees:<br />

git clone git://git.denx.de/u-boot.git u-boot/<br />

git clone http://git.denx.de/u-boot.git u-boot/<br />

git clone rsync://git.denx.de/u-boot.git u-boot/<br />

For details please see here.<br />

Official releases of U-<strong>Boot</strong> are also available through FTP. Compressed tar archives can downloaded from<br />

the directory ftp://ftp.denx.de/pub/u-boot/.<br />

5.2. Unpacking the Source Code<br />

If you used GIT to get a copy of the U-<strong>Boot</strong> sources, then you can skip this next step since you already have<br />

an unpacked directory tree. If you downloaded a compressed tarball from the <strong>DENX</strong> FTP server, you can<br />

unpack it as follows:<br />

5.2. Unpacking the Source Code 37


$ cd /opt/eldk/usr/src<br />

$ wget ftp://ftp.denx.de/pub/u-boot/u-boot-1.3.2.tar.bz2<br />

$ rm -f u-boot<br />

$ bunzip2 < u-boot-1.3.2.tar.bz2 | tar xf -<br />

$ ln -s u-boot-1.3.2 u-boot<br />

$ cd u-boot<br />

5.3. Configuration<br />

After changing to the directory with the U-<strong>Boot</strong> source code you should make sure that there are no build<br />

results from any previous configurations left:<br />

$ make distclean<br />

<strong>The</strong> following (model) comm<strong>and</strong> configures U-<strong>Boot</strong> <strong>for</strong> the canyonl<strong>and</strong>s board:<br />

$ make canyonl<strong>and</strong>s_config<br />

And finally we can compile the tools <strong>and</strong> U-<strong>Boot</strong> itself:<br />

$ make all<br />

By default the build is per<strong>for</strong>med locally <strong>and</strong> the objects are saved in the source directory. One of the two<br />

methods can be used to change this behaviour <strong>and</strong> build U-<strong>Boot</strong> to some external directory:<br />

1. Add O= to the make comm<strong>and</strong> line invocations:<br />

make O=/tmp/build distclean<br />

make O=/tmp/build canyonl<strong>and</strong>s_config<br />

make O=/tmp/build all<br />

Note that if the 'O=output/dir' option is used then it must be used <strong>for</strong> all invocations of make.<br />

2. Set environment variable BUILD_DIR to point to the desired location:<br />

export BUILD_DIR=/tmp/build<br />

make distclean<br />

make canyonl<strong>and</strong>s_config<br />

make all<br />

Note that the comm<strong>and</strong> line "O=" setting overrides the BUILD_DIR environment variable.<br />

5.4. Installation<br />

5.4.1. Be<strong>for</strong>e You Begin<br />

5.4.1.1. Installation Requirements<br />

<strong>The</strong> following section assumes that flash memory is used as the storage device <strong>for</strong> the firmware on your<br />

board. If this is not the case, the following instructions will not work - you will probably have to replace the<br />

storage device (probably ROM or EPROM) on such systems to install or update U-<strong>Boot</strong>.<br />

5.4.1. Be<strong>for</strong>e You Begin 38


5.4.1.2. Board Identification Data<br />

All %BOARDNAME% boards use a serial number <strong>for</strong> identification<br />

purposes. Also, all boards have at least one ethernet (MAC) address<br />

assigned. You may lose your warranty on the board if this data gets<br />

lost. Be<strong>for</strong>e installing U-<strong>Boot</strong> or otherwise changing the software<br />

configuration of a board (like erasing some flash memory) you should<br />

make sure that you have all necessary in<strong>for</strong>mation about such data.<br />

5.4.2. Installation Using a BDM/JTAG Debugger<br />

A fast <strong>and</strong> simple way to write new data to flash memory is via the use of a debugger or flash programmer<br />

with a BDM or JTAG interface. In cases where there is no running firmware at all (<strong>for</strong> instance on new<br />

hardware), this is usually the only way to install any software at all.<br />

We use (<strong>and</strong> highly recommend) the BDI2000 by Abatron .<br />

Other BDM / JTAG debuggers may work too, but how to use them is beyond the scope of this document.<br />

Please see the documentation <strong>for</strong> the tool you want to use.<br />

Be<strong>for</strong>e you can use the BDI2000 you have to configure it. A configuration file that can be used with<br />

canyonl<strong>and</strong>s boards is included in section 13.2. BDI2000 Configuration file<br />

To install a new U-<strong>Boot</strong> image on your canyonl<strong>and</strong>s board using a BDI2000, proceed as follows:<br />

Note: Included topic <strong>DULG</strong>Data_canyonl<strong>and</strong>s.InstallU<strong>Boot</strong>UsingBDI2000 does not exist yet<br />

5.4.3. Installation using U-<strong>Boot</strong><br />

If U-<strong>Boot</strong> is already installed <strong>and</strong> running on your board, you can use these instructions to download another<br />

U-<strong>Boot</strong> image to replace the current one.<br />

Warning: Be<strong>for</strong>e you can install the new image, you have to erase the current one. If anything goes wrong<br />

your board will be dead. It is strongly recommended that:<br />

• you have a backup of the old, working U-<strong>Boot</strong> image<br />

• you know how to install an image on a virgin system<br />

Proceed as follows:<br />

Note: Included topic <strong>DULG</strong>Data_canyonl<strong>and</strong>s.InstallU<strong>Boot</strong>UsingU<strong>Boot</strong> does not exist yet<br />

5.5. Tool Installation<br />

U-<strong>Boot</strong> uses a special image <strong>for</strong>mat when loading the <strong>Linux</strong> kernel or ramdisk or other images. This image<br />

contains (among other things) in<strong>for</strong>mation about the time of creation, operating system, compression type,<br />

image type, image name <strong>and</strong> CRC32 checksums.<br />

<strong>The</strong> tool mkimage is used to create such images or to display the in<strong>for</strong>mation they contain. When using the<br />

ELDK, the mkimage comm<strong>and</strong> is already included with the other ELDK tools.<br />

5.5. Tool Installation 39


If you don't use the ELDK then you should install mkimage in some directory that is in your comm<strong>and</strong><br />

search PATH, <strong>for</strong> instance:<br />

$ cp tools/mkimage /usr/local/bin/<br />

5.6. Initialization<br />

To initialize the U-<strong>Boot</strong> firmware running on your canyonl<strong>and</strong>s board, you have to connect a terminal to the<br />

board's serial console port.<br />

<strong>The</strong> default configuration of the console port on the canyonl<strong>and</strong>s board uses a baudrate of 115200/8N1<br />

(115200 bps, 8 Bit per character, no parity, 1 stop bit, no h<strong>and</strong>shake).<br />

If you are running <strong>Linux</strong> on your host system we recommend either kermit or cu as terminal emulation<br />

programs. Do not use minicom, since this has caused problems <strong>for</strong> many users, especially <strong>for</strong> software<br />

download over the serial port.<br />

For the configuration of your terminal program see section 4.1. Serial Console Access<br />

Make sure that both hardware <strong>and</strong> software flow control are disabled.<br />

5.7. Initial Steps<br />

In the default configuration, U-<strong>Boot</strong> operates in an interactive mode which provides a simple comm<strong>and</strong><br />

line-oriented user interface using a serial console on port UART1.<br />

In the simplest case, this means that U-<strong>Boot</strong> shows a prompt (default: =>) when it is ready to receive user<br />

input. You then type a comm<strong>and</strong>, <strong>and</strong> press enter. U-<strong>Boot</strong> will try to run the required action(s), <strong>and</strong> then<br />

prompt <strong>for</strong> another comm<strong>and</strong>.<br />

To see a list of the available U-<strong>Boot</strong> comm<strong>and</strong>s, you can type help (or simply ). This will print a list of all<br />

comm<strong>and</strong>s that are available in your current configuration. [Please note that U-<strong>Boot</strong> provides a lot of<br />

configuration options; not all options are available <strong>for</strong> all processors <strong>and</strong> boards, <strong>and</strong> some options might be<br />

simply not selected <strong>for</strong> your configuration.]<br />

=> help<br />

- alias <strong>for</strong> 'help'<br />

askenv - get environment variables from stdin<br />

autoscr - run script from memory<br />

base - print or set address offset<br />

bdinfo - print Board Info structure<br />

boot - boot default, i.e., run 'bootcmd'<br />

bootd - boot default, i.e., run 'bootcmd'<br />

bootelf - <strong>Boot</strong> from an ELF image in memory<br />

bootm - boot application image from memory<br />

bootp - boot image via network using <strong>Boot</strong>P/TFTP protocol<br />

bootstrap - program the I2C bootstrap EEPROM<br />

bootvx - <strong>Boot</strong> vxWorks from an ELF image<br />

cmp - memory compare<br />

coninfo - print console devices <strong>and</strong> in<strong>for</strong>mation<br />

cp - memory copy<br />

crc32 - checksum calculation<br />

date - get/set/reset date & time<br />

dhcp - invoke DHCP client to obtain IP/boot params<br />

dtt - Digital <strong>The</strong>rmometer <strong>and</strong> <strong>The</strong>rmostat<br />

5.7. Initial Steps 40


echo - echo args to console<br />

eeprom - EEPROM sub-system<br />

erase - erase FLASH memory<br />

exit - exit script<br />

ext2load- load binary file from a Ext2 filesystem<br />

ext2ls - list files in a directory (default /)<br />

fatinfo - print in<strong>for</strong>mation about filesystem<br />

fatload - load binary file from a dos filesystem<br />

fatls - list files in a directory (default /)<br />

fdt - flattened device tree utility comm<strong>and</strong>s<br />

flinfo - print FLASH memory in<strong>for</strong>mation<br />

getdcr - Get an AMCC PPC 4xx DCR's value<br />

getidcr - Get a register value via indirect DCR addressing<br />

go - start application at address 'addr'<br />

help - print online help<br />

icrc32 - checksum calculation<br />

iloop - infinite loop on address range<br />

imd - i2c memory display<br />

iminfo - print header in<strong>for</strong>mation <strong>for</strong> application image<br />

imls - list all images found in flash<br />

imm - i2c memory modify (auto-incrementing)<br />

imw - memory write (fill)<br />

imxtract- extract a part of a multi-image<br />

inm - memory modify (constant address)<br />

iprobe - probe to discover valid I2C chip addresses<br />

irqinfo - print in<strong>for</strong>mation about IRQs<br />

isdram - print SDRAM configuration in<strong>for</strong>mation<br />

itest - return true/false on integer compare<br />

loadb - load binary file over serial line (kermit mode)<br />

loads - load S-Record file over serial line<br />

loady - load binary file over serial line (ymodem mode)<br />

loop - infinite loop on address range<br />

loopw - infinite write loop on address range<br />

md - memory display<br />

mdc - memory display cyclic<br />

mii - MII utility comm<strong>and</strong>s<br />

mm - memory modify (auto-incrementing)<br />

mtest - simple RAM test<br />

mw - memory write (fill)<br />

mwc - memory write cyclic<br />

n<strong>and</strong> - NAND sub-system<br />

nboot - boot from NAND device<br />

nfs - boot image via network using NFS protocol<br />

nm - memory modify (constant address)<br />

pci - list <strong>and</strong> access PCI Configuration Space<br />

ping - send ICMP ECHO_REQUEST to network host<br />

printenv- print environment variables<br />

protect - enable or disable FLASH write protection<br />

rarpboot- boot image via network using RARP/TFTP protocol<br />

reginfo - print register in<strong>for</strong>mation<br />

reset - Per<strong>for</strong>m RESET of the CPU<br />

run - run comm<strong>and</strong>s in an environment variable<br />

saveenv - save environment variables to persistent storage<br />

setdcr - Set an AMCC PPC 4xx DCR's value<br />

setenv - set environment variables<br />

setidcr - Set a register value via indirect DCR addressing<br />

sleep - delay execution <strong>for</strong> some time<br />

test - minimal test like /bin/sh<br />

tftpboot- boot image via network using TFTP protocol<br />

usb - USB sub-system<br />

usbboot - boot from USB device<br />

version - print monitor version<br />

=><br />

With the comm<strong>and</strong> help you can get additional in<strong>for</strong>mation about most comm<strong>and</strong>s:<br />

5.7. Initial Steps 41


=> help tftpboot<br />

tftpboot [loadAddress] [[hostIPaddr:]bootfilename]<br />

=><br />

=> help setenv printenv<br />

setenv name value ...<br />

- set environment variable 'name' to 'value ...'<br />

setenv name<br />

- delete environment variable 'name'<br />

printenv<br />

- print values of all environment variables<br />

printenv name ...<br />

- print value of environment variable 'name'<br />

=><br />

Most comm<strong>and</strong>s can be abbreviated as long as the string remains unambiguous:<br />

=> help fli tftp<br />

flinfo<br />

- print in<strong>for</strong>mation <strong>for</strong> all FLASH memory banks<br />

flinfo N<br />

- print in<strong>for</strong>mation <strong>for</strong> FLASH memory bank # N<br />

tftpboot [loadAddress] [[hostIPaddr:]bootfilename]<br />

=><br />

5.8. <strong>The</strong> First Power-On<br />

Note: If you bought your canyonl<strong>and</strong>s board with U-<strong>Boot</strong> already installed, you can skip this section since<br />

the manufacturer probably has already per<strong>for</strong>med these steps.<br />

Connect the port labeled UART1 on your canyonl<strong>and</strong>s board to the designated serial port of your host, start<br />

the terminal program, <strong>and</strong> connect the power supply of your canyonl<strong>and</strong>s board. You should see messages like<br />

this:<br />

=> reset<br />

U-<strong>Boot</strong> 1.3.3-rc2-01466-g4f27098 (May 1 2008 - 13:57:57)<br />

CPU: AMCC PowerPC 460EX Rev. A at 600 MHz (PLB=200, OPB=100, EBC=100 MHz)<br />

Security/Kasumi support<br />

<strong>Boot</strong>strap Option H - <strong>Boot</strong> ROM Location I2C (Addr 0x52)<br />

Internal PCI arbiter disabled<br />

32 kB I-Cache 32 kB D-Cache<br />

Board: Canyonl<strong>and</strong>s - AMCC PPC460EX Evaluation Board, 2*PCIe, Rev. 13<br />

I2C: ready<br />

DTT: 1 is 48 C<br />

DRAM: 256 MB (ECC not enabled, 400 MHz, CL3)<br />

FLASH: 64 MB<br />

NAND: 32 MiB<br />

PCI: Bus Dev VenId DevId Class Int<br />

PCIE0: link is not up.<br />

PCIE0: initialization as root-complex failed<br />

PCIE1: link is not up.<br />

PCIE1: initialization as root-complex failed<br />

5.8. <strong>The</strong> First Power-On 42


Net:<br />

ppc_4xx_eth0, ppc_4xx_eth1<br />

Type run flash_nfs to mount root filesystem over NFS<br />

Hit any key to stop autoboot: 0<br />

=><br />

=><br />

You can interrupt the "Count-Down" by pressing any key. If you don't you will probably see some (harmless)<br />

error messages because the system has not been initialized yet.<br />

In some cases you may see a message<br />

*** Warning - bad CRC, using default environment<br />

This is harmless <strong>and</strong> will go away as soon as you have initialized <strong>and</strong> saved the environment variables.<br />

At first you have to enter the serial number <strong>and</strong> the ethernet address of your board. Pay special attention here<br />

since these parameters are write protected <strong>and</strong> cannot be changed once saved (usually this is done by the<br />

manufacturer of the board). To enter the data you have to use the U-<strong>Boot</strong> comm<strong>and</strong> setenv, followed by the<br />

variable name <strong>and</strong> the data, all separated by white space (blank <strong>and</strong>/or TAB characters). Use the variable<br />

name serial# <strong>for</strong> the board ID <strong>and</strong>/or serial number, <strong>and</strong> ethaddr <strong>for</strong> the ethernet address, <strong>for</strong> instance:<br />

=> setenv ethaddr !!!!!!FILL_THIS!!!!!!<br />

=> setenv serial# CF56-216F-400A<br />

Use the printenv comm<strong>and</strong> to verify that you have entered the correct values:<br />

=> printenv serial# ethaddr<br />

## Error: "serial#" not defined<br />

ethaddr=5e:ed:18:38:81:85<br />

=><br />

Please double check that the printed values are correct! You will not be able to correct any errors later! If<br />

there is something wrong, reset the board <strong>and</strong> restart from the beginning; otherwise you can store the<br />

parameters permanently using the saveenv comm<strong>and</strong>:<br />

=> saveenv<br />

Saving Environment to Flash...<br />

Un-Protected 1 sectors<br />

Un-Protected 1 sectors<br />

Erasing Flash...<br />

. done<br />

Erased 1 sectors<br />

Writing to Flash... done<br />

Protected 1 sectors<br />

Protected 1 sectors<br />

=><br />

5.9. U-<strong>Boot</strong> Comm<strong>and</strong> Line Interface<br />

<strong>The</strong> following section describes the most important comm<strong>and</strong>s available in U-<strong>Boot</strong>. Please note that U-<strong>Boot</strong> is<br />

highly configurable, so not all of these comm<strong>and</strong>s may be available in the configuration of U-<strong>Boot</strong> installed<br />

on your hardware, or additional comm<strong>and</strong>s may exist. You can use the help comm<strong>and</strong> to print a list of all<br />

available comm<strong>and</strong>s <strong>for</strong> your configuration.<br />

5.9. U-<strong>Boot</strong> Comm<strong>and</strong> Line Interface 43


For most comm<strong>and</strong>s, you do not need to type in the full comm<strong>and</strong> name; instead it is sufficient to type a few<br />

characters. For instance, help can be abbreviated as h.<br />

<strong>The</strong> behaviour of some comm<strong>and</strong>s depends of the configuration of U-<strong>Boot</strong> <strong>and</strong> on the definition of some<br />

variables in your U-<strong>Boot</strong> environment.<br />

All U-<strong>Boot</strong> comm<strong>and</strong>s expect numbers to be entered in hexadecimal input <strong>for</strong>mat.<br />

Be careful not to use edit keys besides 'Backspace', as hidden characters in things like environment<br />

variables can be very difficult to find.<br />

5.9.1. In<strong>for</strong>mation Comm<strong>and</strong>s<br />

5.9.1.1. bdinfo - print Board Info structure<br />

=> help bdinfo<br />

bdinfo - No help available.<br />

=><br />

<strong>The</strong> bdinfo comm<strong>and</strong> (short: bdi) prints the in<strong>for</strong>mation that U-<strong>Boot</strong> passes about the board such as<br />

memory addresses <strong>and</strong> sizes, clock frequencies, MAC address, etc. This in<strong>for</strong>mation is mainly needed to be<br />

passed to the <strong>Linux</strong> kernel.<br />

=> bdi<br />

memstart = 0x00000000<br />

memsize = 0x10000000<br />

flashstart = 0xFC000000<br />

flashsize = 0x04000000<br />

flashoffset = 0x00000000<br />

sramstart = 0x00000000<br />

sramsize = 0x00000000<br />

bootflags = 0xFFFDFC84<br />

intfreq = 600 MHz<br />

busfreq = 200 MHz<br />

ethaddr = 5E:ED:18:38:81:85<br />

eth1addr = 5E:ED:18:38:81:86<br />

IP addr = 192.168.100.6<br />

baudrate = 115200 bps<br />

=><br />

5.9.1.2. coninfo - print console devices <strong>and</strong> in<strong>for</strong>mations<br />

=> help conin<br />

coninfo<br />

=><br />

<strong>The</strong> coninfo comm<strong>and</strong> (short: conin) displays in<strong>for</strong>mation about the available console I/O devices.<br />

=> conin<br />

List of available devices:<br />

serial 80000003 SIO stdin stdout stderr<br />

serial1 00000003 .IO<br />

serial0 00000003 .IO<br />

=><br />

5.9.1. In<strong>for</strong>mation Comm<strong>and</strong>s 44


<strong>The</strong> output contains the device name, flags, <strong>and</strong> the current usage. For example, the output<br />

serial<br />

80000003 SIO stdin stdout stderr<br />

means that the serial device is a system device (flag 'S') which provides input (flag 'I') <strong>and</strong> output<br />

(flag 'O') functionality <strong>and</strong> is currently assigned to the 3 st<strong>and</strong>ard I/O streams stdin, stdout <strong>and</strong><br />

stderr.<br />

5.9.1.3. flinfo - print FLASH memory in<strong>for</strong>mation<br />

=> help flinfo<br />

flinfo<br />

- print in<strong>for</strong>mation <strong>for</strong> all FLASH memory banks<br />

flinfo N<br />

- print in<strong>for</strong>mation <strong>for</strong> FLASH memory bank # N<br />

=><br />

<strong>The</strong> comm<strong>and</strong> flinfo (short: fli) can be used to get in<strong>for</strong>mation about the available flash memory (see<br />

Flash Memory Comm<strong>and</strong>s below).<br />

=> fli<br />

Bank # 1: CFI con<strong>for</strong>mant FLASH (16 x 16) Size: 64 MB in 512 Sectors<br />

AMD St<strong>and</strong>ard comm<strong>and</strong> set, Manufacturer ID: 0x01, Device ID: 0x227E<br />

Erase timeout: 16384 ms, write timeout: 2 ms<br />

Buffer write timeout: 5 ms, buffer size: 32 bytes<br />

Sector Start Addresses:<br />

FC000000 E FC020000 E FC040000 E FC060000 E FC080000 E<br />

FC0A0000 E FC0C0000 E FC0E0000 E FC100000 E FC120000 E<br />

FC140000 E FC160000 E FC180000 E FC1A0000 E FC1C0000 E<br />

FC1E0000 E FC200000 E FC220000 E FC240000 E FC260000 E<br />

FC280000 E FC2A0000 E FC2C0000 E FC2E0000 E FC300000 E<br />

FC320000 E FC340000 E FC360000 E FC380000 E FC3A0000 E<br />

FC3C0000 E FC3E0000 E FC400000 E FC420000 E FC440000 E<br />

FC460000 E FC480000 E FC4A0000 E FC4C0000 E FC4E0000 E<br />

FC500000 E FC520000 E FC540000 E FC560000 E FC580000 E<br />

FC5A0000 E FC5C0000 E FC5E0000 E FC600000 E FC620000 E<br />

FC640000 E FC660000 E FC680000 E FC6A0000 E FC6C0000 E<br />

FC6E0000 E FC700000 E FC720000 E FC740000 E FC760000 E<br />

FC780000 E FC7A0000 E FC7C0000 E FC7E0000 E FC800000 E<br />

FC820000 E FC840000 E FC860000 E FC880000 E FC8A0000 E<br />

FC8C0000 E FC8E0000 E FC900000 E FC920000 E FC940000 E<br />

FC960000 E FC980000 E FC9A0000 E FC9C0000 E FC9E0000 E<br />

FCA00000 E FCA20000 E FCA40000 E FCA60000 E FCA80000 E<br />

FCAA0000 E FCAC0000 E FCAE0000 E FCB00000 E FCB20000 E<br />

FCB40000 E FCB60000 E FCB80000 E FCBA0000 E FCBC0000 E<br />

FCBE0000 E FCC00000 E FCC20000 E FCC40000 E FCC60000 E<br />

FCC80000 E FCCA0000 E FCCC0000 E FCCE0000 E FCD00000 E<br />

FCD20000 E FCD40000 E FCD60000 E FCD80000 E FCDA0000 E<br />

FCDC0000 E FCDE0000 E FCE00000 E FCE20000 E FCE40000 E<br />

FCE60000 E FCE80000 E FCEA0000 E FCEC0000 E FCEE0000 E<br />

FCF00000 E FCF20000 E FCF40000 E FCF60000 E FCF80000 E<br />

FCFA0000 E FCFC0000 E FCFE0000 E FD000000 E FD020000 E<br />

FD040000 E FD060000 E FD080000 E FD0A0000 E FD0C0000 E<br />

FD0E0000 E FD100000 E FD120000 E FD140000 E FD160000 E<br />

FD180000 E FD1A0000 E FD1C0000 E FD1E0000 E FD200000 E<br />

FD220000 E FD240000 E FD260000 E FD280000 E FD2A0000 E<br />

FD2C0000 E FD2E0000 E FD300000 E FD320000 E FD340000 E<br />

FD360000 E FD380000 E FD3A0000 E FD3C0000 E FD3E0000 E<br />

5.9.1.2. coninfo - print console devices <strong>and</strong> in<strong>for</strong>mations 45


FD400000 E FD420000 E FD440000 E FD460000 E FD480000 E<br />

FD4A0000 E FD4C0000 E FD4E0000 E FD500000 E FD520000 E<br />

FD540000 E FD560000 E FD580000 E FD5A0000 E FD5C0000 E<br />

FD5E0000 E FD600000 E FD620000 E FD640000 E FD660000 E<br />

FD680000 E FD6A0000 E FD6C0000 E FD6E0000 E FD700000 E<br />

FD720000 E FD740000 E FD760000 E FD780000 E FD7A0000 E<br />

FD7C0000 E FD7E0000 E FD800000 E FD820000 E FD840000 E<br />

FD860000 E FD880000 E FD8A0000 E FD8C0000 E FD8E0000 E<br />

FD900000 E FD920000 E FD940000 E FD960000 E FD980000 E<br />

FD9A0000 E FD9C0000 E FD9E0000 E FDA00000 E FDA20000 E<br />

FDA40000 E FDA60000 E FDA80000 E FDAA0000 E FDAC0000 E<br />

FDAE0000 E FDB00000 E FDB20000 E FDB40000 E FDB60000 E<br />

FDB80000 E FDBA0000 E FDBC0000 E FDBE0000 E FDC00000 E<br />

FDC20000 E FDC40000 E FDC60000 E FDC80000 E FDCA0000 E<br />

FDCC0000 E FDCE0000 E FDD00000 E FDD20000 E FDD40000 E<br />

FDD60000 E FDD80000 E FDDA0000 E FDDC0000 E FDDE0000 E<br />

FDE00000 E FDE20000 E FDE40000 E FDE60000 E FDE80000 E<br />

FDEA0000 E FDEC0000 E FDEE0000 E FDF00000 E FDF20000 E<br />

FDF40000 E FDF60000 E FDF80000 E FDFA0000 E FDFC0000 E<br />

FDFE0000 E FE000000 E FE020000 E FE040000 E FE060000 E<br />

FE080000 E FE0A0000 E FE0C0000 E FE0E0000 E FE100000 E<br />

FE120000 E FE140000 E FE160000 E FE180000 E FE1A0000 E<br />

FE1C0000 E FE1E0000 E FE200000 E FE220000 E FE240000 E<br />

FE260000 E FE280000 E FE2A0000 E FE2C0000 E FE2E0000 E<br />

FE300000 E FE320000 E FE340000 E FE360000 E FE380000 E<br />

FE3A0000 E FE3C0000 E FE3E0000 E FE400000 E FE420000 E<br />

FE440000 E FE460000 E FE480000 E FE4A0000 E FE4C0000 E<br />

FE4E0000 E FE500000 E FE520000 E FE540000 E FE560000 E<br />

FE580000 E FE5A0000 E FE5C0000 E FE5E0000 E FE600000 E<br />

FE620000 E FE640000 E FE660000 E FE680000 E FE6A0000 E<br />

FE6C0000 E FE6E0000 E FE700000 E FE720000 E FE740000 E<br />

FE760000 E FE780000 E FE7A0000 E FE7C0000 E FE7E0000 E<br />

FE800000 E FE820000 E FE840000 E FE860000 E FE880000 E<br />

FE8A0000 E FE8C0000 E FE8E0000 E FE900000 E FE920000 E<br />

FE940000 E FE960000 E FE980000 E FE9A0000 E FE9C0000 E<br />

FE9E0000 E FEA00000 E FEA20000 E FEA40000 E FEA60000 E<br />

FEA80000 E FEAA0000 E FEAC0000 E FEAE0000 E FEB00000 E<br />

FEB20000 E FEB40000 E FEB60000 E FEB80000 E FEBA0000 E<br />

FEBC0000 E FEBE0000 E FEC00000 E FEC20000 E FEC40000 E<br />

FEC60000 E FEC80000 E FECA0000 E FECC0000 E FECE0000 E<br />

FED00000 E FED20000 E FED40000 E FED60000 E FED80000 E<br />

FEDA0000 E FEDC0000 E FEDE0000 E FEE00000 E FEE20000 E<br />

FEE40000 E FEE60000 E FEE80000 E FEEA0000 E FEEC0000 E<br />

FEEE0000 E FEF00000 E FEF20000 E FEF40000 E FEF60000 E<br />

FEF80000 E FEFA0000 E FEFC0000 E FEFE0000 E FF000000 E<br />

FF020000 E FF040000 E FF060000 E FF080000 E FF0A0000 E<br />

FF0C0000 E FF0E0000 E FF100000 E FF120000 E FF140000 E<br />

FF160000 E FF180000 E FF1A0000 E FF1C0000 E FF1E0000 E<br />

FF200000 E FF220000 E FF240000 E FF260000 E FF280000 E<br />

FF2A0000 E FF2C0000 E FF2E0000 E FF300000 E FF320000 E<br />

FF340000 E FF360000 E FF380000 E FF3A0000 E FF3C0000 E<br />

FF3E0000 E FF400000 E FF420000 E FF440000 E FF460000 E<br />

FF480000 E FF4A0000 E FF4C0000 E FF4E0000 E FF500000 E<br />

FF520000 E FF540000 E FF560000 E FF580000 E FF5A0000 E<br />

FF5C0000 E FF5E0000 E FF600000 E FF620000 E FF640000 E<br />

FF660000 E FF680000 E FF6A0000 E FF6C0000 E FF6E0000 E<br />

FF700000 E FF720000 E FF740000 E FF760000 E FF780000 E<br />

FF7A0000 E FF7C0000 E FF7E0000 E FF800000 E FF820000 E<br />

FF840000 E FF860000 E FF880000 E FF8A0000 E FF8C0000 E<br />

FF8E0000 E FF900000 E FF920000 E FF940000 E FF960000 E<br />

FF980000 E FF9A0000 E FF9C0000 E FF9E0000 E FFA00000 E<br />

FFA20000 E FFA40000 E FFA60000 E FFA80000 E FFAA0000 E<br />

FFAC0000 E FFAE0000 E FFB00000 E FFB20000 E FFB40000 E<br />

FFB60000 E FFB80000 E FFBA0000 E FFBC0000 E FFBE0000 E<br />

FFC00000 E FFC20000 E FFC40000 E FFC60000 E FFC80000 E<br />

FFCA0000 E FFCC0000 E FFCE0000 E FFD00000 E FFD20000 E<br />

FFD40000 E FFD60000 E FFD80000 E FFDA0000 E FFDC0000 E<br />

5.9.1.3. flinfo - print FLASH memory in<strong>for</strong>mation 46


FFDE0000 E FFE00000 E FFE20000 E FFE40000 E FFE60000 E<br />

FFE80000 E FFEA0000 E FFEC0000 E FFEE0000 E FFF00000 E<br />

FFF20000 E FFF40000 E FFF60000 RO FFF80000 RO FFFA0000 RO<br />

FFFC0000 RO FFFE0000 RO<br />

=><br />

5.9.1.4. iminfo - print header in<strong>for</strong>mation <strong>for</strong> application<br />

image<br />

=> help iminfo<br />

iminfo addr [addr ...]<br />

- print header in<strong>for</strong>mation <strong>for</strong> application image starting at<br />

address 'addr' in memory; this includes verification of the<br />

image contents (magic number, header <strong>and</strong> payload checksums)<br />

=><br />

iminfo (short: imi) is used to print the header in<strong>for</strong>mation <strong>for</strong> images like <strong>Linux</strong> kernels or ramdisks. It<br />

prints (among other in<strong>for</strong>mation) the image name, type <strong>and</strong> size <strong>and</strong> verifies that the CRC32 checksums stored<br />

within the image are OK.<br />

/tftpboot/canyonl<strong>and</strong>s/uImage-duts: u-boot/PPC<strong>Boot</strong> image<br />

=> setenv bootfile /tftpboot/canyonl<strong>and</strong>s/uImage-duts<br />

=><br />

=> setenv ram_ws 100000<br />

=> tftp ${ram_ws} ${bootfile}<br />

Waiting <strong>for</strong> PHY auto negotiation to complete... done<br />

ENET Speed is 1000 Mbps - FULL duplex connection (EMAC0)<br />

Using ppc_4xx_eth0 device<br />

TFTP from server 192.168.1.1; our IP address is 192.168.100.6<br />

Filename '/tftpboot/canyonl<strong>and</strong>s/uImage-duts'.<br />

Load address: 0x100000<br />

Loading: *T #################################################################<br />

######################################################<br />

done<br />

Bytes transferred = 1744326 (1a9dc6 hex)<br />

=><br />

=> imi 100000<br />

## Checking Image at 00100000 ...<br />

Legacy image found<br />

Image Name: <strong>Linux</strong>-2.6.25-rc8-01016-g94bf13b-<br />

Created: 2008-04-10 9:50:08 UTC<br />

Image Type: PowerPC <strong>Linux</strong> Kernel Image (gzip compressed)<br />

Data Size: 1744262 Bytes = 1.7 MB<br />

Load Address: 00000000<br />

Entry Point: 00000000<br />

Verifying Checksum ... OK<br />

=><br />

Like with many other comm<strong>and</strong>s, the exact operation of this comm<strong>and</strong> can be controlled by the settings of<br />

some U-<strong>Boot</strong> environment variables (here: the verify variable). See below <strong>for</strong> details.<br />

5.9.1.5. help - print online help<br />

=> help help<br />

help [comm<strong>and</strong> ...]<br />

- show help in<strong>for</strong>mation (<strong>for</strong> 'comm<strong>and</strong>')<br />

'help' prints online help <strong>for</strong> the monitor comm<strong>and</strong>s.<br />

5.9.1.4. iminfo - print header in<strong>for</strong>mation <strong>for</strong> application image 47


Without arguments, it prints a short usage message <strong>for</strong> all comm<strong>and</strong>s.<br />

To get detailed help in<strong>for</strong>mation <strong>for</strong> specific comm<strong>and</strong>s you can type<br />

'help' with one or more comm<strong>and</strong> names as arguments.<br />

=><br />

<strong>The</strong> help comm<strong>and</strong> (short: h or ) prints online help. Without any arguments, it prints a list of all U-<strong>Boot</strong><br />

comm<strong>and</strong>s that are available in your configuration of U-<strong>Boot</strong>. You can get detailed in<strong>for</strong>mation <strong>for</strong> a specific<br />

comm<strong>and</strong> by typing its name as argument to the help comm<strong>and</strong>:<br />

=> help protect<br />

protect on start end<br />

- protect FLASH from addr 'start' to addr 'end'<br />

protect on start +len<br />

- protect FLASH from addr 'start' to end of sect w/addr 'start'+'len'-1<br />

protect on N:SF[-SL]<br />

- protect sectors SF-SL in FLASH bank # N<br />

protect on bank N<br />

- protect FLASH bank # N<br />

protect on all<br />

- protect all FLASH banks<br />

protect off start end<br />

- make FLASH from addr 'start' to addr 'end' writable<br />

protect off start +len<br />

- make FLASH from addr 'start' to end of sect w/addr 'start'+'len'-1 wrtable<br />

protect off N:SF[-SL]<br />

- make sectors SF-SL writable in FLASH bank # N<br />

protect off bank N<br />

- make FLASH bank # N writable<br />

protect off all<br />

- make all FLASH banks writable<br />

=><br />

5.9.2. Memory Comm<strong>and</strong>s<br />

5.9.2.1. base - print or set address offset<br />

=> help base<br />

base<br />

- print address offset <strong>for</strong> memory comm<strong>and</strong>s<br />

base off<br />

- set address offset <strong>for</strong> memory comm<strong>and</strong>s to 'off'<br />

=><br />

You can use the base comm<strong>and</strong> (short: ba) to print or set a "base address" that is used as address offset <strong>for</strong><br />

all memory comm<strong>and</strong>s; the default value of the base address is 0, so all addresses you enter are used<br />

unmodified. However, when you repeatedly have to access a certain memory region (like the internal memory<br />

of some embedded PowerPC processors) it can be very convenient to set the base address to the start of this<br />

area <strong>and</strong> then use only the offsets:<br />

=> base<br />

Base Address: 0x00000000<br />

=><br />

5.9.2. Memory Comm<strong>and</strong>s 48


=> md 0 c<br />

00000000: ffff0000 00000000 ffffffff ffffffff ................<br />

00000010: ffff0000 00000000 ffffffff ffffffff ................<br />

00000020: 7c8000a6 70840020 41820008 64630001 |...p.. A...dc..<br />

=><br />

=> base 100000<br />

Base Address: 0x00100000<br />

=><br />

=> md 0 c<br />

00100000: 27051956 6aa09851 47f3731e 0000009e '..Vj..QG.s.....<br />

00100010: 00000000 00000000 f54c21db 05070600 .........L!.....<br />

00100020: 6175746f 73637220 6578616d 706c6520 autoscr example<br />

=><br />

5.9.2.2. crc32 - checksum calculation<br />

<strong>The</strong> crc32 comm<strong>and</strong> (short: crc) can be used to caculate a CRC32 checksum over a range of memory:<br />

=> crc 100004 3FC<br />

CRC32 <strong>for</strong> 00100004 ... 001003ff ==> 3c82ba9d<br />

=><br />

When used with 3 arguments, the comm<strong>and</strong> stores the calculated checksum at the given address:<br />

=> crc 100004 3FC 100000<br />

CRC32 <strong>for</strong> 00100004 ... 001003ff ==> 3c82ba9d<br />

=><br />

=> md 100000 4<br />

00100000: 3c82ba9d 6aa09851 47f3731e 0000009e <br />

As you can see, the CRC32 checksum was not only printed, but also stored at address 0x100000.<br />

5.9.2.3. cmp - memory compare<br />

=> help cmp<br />

cmp [.b, .w, .l] addr1 addr2 count<br />

- compare memory<br />

=><br />

With the cmp comm<strong>and</strong> you can test of the contents of two memory areas is identical or not. <strong>The</strong> comm<strong>and</strong><br />

will either test the whole area as specified by the 3rd (length) argument, or stop at the first difference.<br />

=> cmp 100000 200000 400<br />

word at 0x00100000 (0x3c82ba9d) != word at 0x00200000 (0xfda7aec5)<br />

Total of 0 words were the same<br />

=><br />

=> md 100000 C<br />

00100000: 3c82ba9d 6aa09851 47f3731e 0000009e <br />

=> md 200000 C<br />

00200000: fda7aec5 7c42d757 e4bd86f8 e0f1e5c8 ....|B.W........<br />

00200010: 4b74f157 a82c74b8 ea13e792 faec767f Kt.W.,t.......v.<br />

00200020: 74e3cb5d f4dc3a04 1e65bc42 4bf7bfc0 t..]..:..e.BK...<br />

=><br />

5.9.2.1. base - print or set address offset 49


Like most memory comm<strong>and</strong>s the cmp can access the memory in different sizes: as 32 bit (long word), 16 bit<br />

(word) or 8 bit (byte) data. If invoked just as cmp the default size (32 bit or long words) is used; the same can<br />

be selected explicitely by typing cmp.l instead. If you want to access memory as 16 bit or word data, you<br />

can use the variant cmp.w instead; <strong>and</strong> to access memory as 8 bit or byte data please use cmp.b.<br />

Please note that the count argument specifies the number of data items to process, i. e. the number of long<br />

words or words or bytes to compare.<br />

=> cmp.l 100000 200000 400<br />

word at 0x00100000 (0x3c82ba9d) != word at 0x00200000 (0xfda7aec5)<br />

Total of 0 words were the same<br />

=><br />

=> cmp.w 100000 200000 800<br />

halfword at 0x00100000 (0x3c82) != halfword at 0x00200000 (0xfda7)<br />

Total of 0 halfwords were the same<br />

=><br />

=> cmp.b 100000 200000 1000<br />

byte at 0x00100000 (0x3c) != byte at 0x00200000 (0xfd)<br />

Total of 0 bytes were the same<br />

=><br />

5.9.2.4. cp - memory copy<br />

=> help cp<br />

cp [.b, .w, .l] source target count<br />

- copy memory<br />

=><br />

<strong>The</strong> cp is used to copy memory areas.<br />

=> cp 200000 100000 10000<br />

=><br />

<strong>The</strong> cp underst<strong>and</strong>s the type extensions .l, .w <strong>and</strong> .b :<br />

=> cp.l 200000 100000 10000<br />

=><br />

=> cp.w 200000 100000 20000<br />

=><br />

=> cp.b 200000 100000 40000<br />

=><br />

5.9.2.5. md - memory display<br />

=> help md<br />

md [.b, .w, .l] address [# of objects]<br />

- memory display<br />

=><br />

<strong>The</strong> md can be used to display memory contents both as hexadecimal <strong>and</strong> ASCII data.<br />

=> md 100000<br />

5.9.2.3. cmp - memory compare 50


00100000: fda7aec5 7c42d757 e4bd86f8 e0f1e5c8 ....|B.W........<br />

00100010: 4b74f157 a82c74b8 ea13e792 faec767f Kt.W.,t.......v.<br />

00100020: 74e3cb5d f4dc3a04 1e65bc42 4bf7bfc0 t..]..:..e.BK...<br />

=><br />

=><br />

=><br />

=><br />

This comm<strong>and</strong>, too, can be used with the type extensions .l, .w <strong>and</strong> .b :<br />

=> md.w 100000<br />

00100000: fda7 aec5 7c42 d757 e4bd 86f8 e0f1 e5c8 ....|B.W........<br />

00100010: 4b74 f157 a82c 74b8 Kt.W.,t.<br />

=><br />

=> md.b 100000<br />

00100000: fd a7 ae c5 7c 42 d7 57 e4 bd 86 f8 ....|B.W....<br />

=><br />

<strong>The</strong> last displayed memory address <strong>and</strong> the value of the count argument are remembered, so when you enter<br />

md again without arguments it will automatically continue at the next address, <strong>and</strong> use the same count again.<br />

=> md.b 100000 20<br />

00100000: fd a7 ae c5 7c 42 d7 57 e4 bd 86 f8 e0 f1 e5 c8 ....|B.W........<br />

00100010: 4b 74 f1 57 a8 2c 74 b8 ea 13 e7 92 fa ec 76 7f Kt.W.,t.......v.<br />

=><br />

=> md.w 100000<br />

00100000: fda7 aec5 7c42 d757 e4bd 86f8 e0f1 e5c8 ....|B.W........<br />

00100010: 4b74 f157 a82c 74b8 ea13 e792 faec 767f Kt.W.,t.......v.<br />

00100020: 74e3 cb5d f4dc 3a04 1e65 bc42 4bf7 bfc0 t..]..:..e.BK...<br />

00100030: c744 e937 9da0 3af3 f9f9 7902 bc74 f4a4 .D.7..:...y..t..<br />

=><br />

=> md 100000<br />

00100000: fda7aec5 7c42d757 e4bd86f8 e0f1e5c8 ....|B.W........<br />

00100010: 4b74f157 a82c74b8 ea13e792 faec767f Kt.W.,t.......v.<br />

00100020: 74e3cb5d f4dc3a04 1e65bc42 4bf7bfc0 t..]..:..e.BK...<br />

00100030: c744e937 9da03af3 f9f97902 bc74f4a4 .D.7..:...y..t..<br />

00100040: 260fb31b 749b7b0c baadbd0d fa52fadf &...t.{......R..<br />

00100050: 2c6cbbf5 ae5613d7 9fdea1bc 45382c8d ,l...V......E8,.<br />

00100060: 95b49da0 3d5d437b f33686b8 2616d8f9 ....=]C{.6..&...<br />

00100070: c1f68fdb f849d974 0fe5eb2d 807dae8e .....I.t...-.}..<br />

=><br />

5.9.2.6. mm - memory modify (auto-incrementing)<br />

=> help mm<br />

mm [.b, .w, .l] address<br />

- memory modify, auto increment address<br />

=><br />

<strong>The</strong> mm is a method to interactively modify memory contents. It will display the address <strong>and</strong> current contents<br />

<strong>and</strong> then prompt <strong>for</strong> user input. If you enter a legal hexadecimal number, this new value will be written to the<br />

address. <strong>The</strong>n the next address will be prompted. If you don't enter any value <strong>and</strong> just press ENTER, then the<br />

contents of this address will remain unchanged. <strong>The</strong> comm<strong>and</strong> stops as soon as you enter any data that is not a<br />

hex number (like .):<br />

=> mm 100000<br />

00100000: fda7aec5 0<br />

5.9.2.5. md - memory display 51


00100004: 7c42d757 aabbccdd<br />

00100008: e4bd86f8 01234567<br />

0010000c: e0f1e5c8 .<br />

=><br />

=> md 100000 10<br />

00100000: 00000000 aabbccdd 01234567 e0f1e5c8 .........#Eg....<br />

00100010: 4b74f157 a82c74b8 ea13e792 faec767f Kt.W.,t.......v.<br />

00100020: 74e3cb5d f4dc3a04 1e65bc42 4bf7bfc0 t..]..:..e.BK...<br />

00100030: c744e937 9da03af3 f9f97902 bc74f4a4 .D.7..:...y..t..<br />

=><br />

Again this comm<strong>and</strong> can be used with the type extensions .l, .w <strong>and</strong> .b :<br />

=> mm.w 100000<br />

00100000: 0000 0101<br />

00100002: 0000 0202<br />

00100004: aabb 4321<br />

00100006: ccdd 8765<br />

00100008: 0123 .<br />

=><br />

=> md 100000 10<br />

00100000: 01010202 43218765 01234567 e0f1e5c8 ....C!.e.#Eg....<br />

00100010: 4b74f157 a82c74b8 ea13e792 faec767f Kt.W.,t.......v.<br />

00100020: 74e3cb5d f4dc3a04 1e65bc42 4bf7bfc0 t..]..:..e.BK...<br />

00100030: c744e937 9da03af3 f9f97902 bc74f4a4 .D.7..:...y..t..<br />

=><br />

=> mm.b 100000<br />

00100000: 01 48<br />

00100001: 01 65<br />

00100002: 02 6c<br />

00100003: 02 6c<br />

00100004: 43 6f<br />

00100005: 21 20<br />

00100006: 87 20<br />

00100007: 65 20<br />

00100008: 01 .<br />

=><br />

=> md 100000 10<br />

00100000: 48656c6c 6f202020 01234567 e0f1e5c8 Hello .#Eg....<br />

00100010: 4b74f157 a82c74b8 ea13e792 faec767f Kt.W.,t.......v.<br />

00100020: 74e3cb5d f4dc3a04 1e65bc42 4bf7bfc0 t..]..:..e.BK...<br />

00100030: c744e937 9da03af3 f9f97902 bc74f4a4 .D.7..:...y..t..<br />

=><br />

5.9.2.7. mtest - simple RAM test<br />

=> help mtest<br />

mtest [start [end [pattern]]]<br />

- simple RAM read/write test<br />

=><br />

<strong>The</strong> mtest provides a simple memory test.<br />

=> mtest 100000 200000<br />

Pattern 00000000 Writing...<br />

=><br />

Reading...Pattern FFFFFFFF Writing...<br />

5.9.2.6. mm - memory modify (auto-incrementing) 52


This tests writes to memory, thus modifying the memory contents. It will fail when applied to ROM or<br />

flash memory.<br />

This comm<strong>and</strong> may crash the system when the tested memory range includes areas that are needed <strong>for</strong> the<br />

operation of the U-<strong>Boot</strong> firnware (like exception vector code, or U-<strong>Boot</strong>'s internal program code, stack or<br />

heap memory areas).<br />

5.9.2.8. mw - memory write (fill)<br />

=> help mw<br />

mw [.b, .w, .l] address value [count]<br />

- write memory<br />

=><br />

<strong>The</strong> mw is a way to initialize (fill) memory with some value. When called without a count argument, the value<br />

will be written only to the specified address. When used with a count, then a whole memory areas will be<br />

initialized with this value:<br />

=> md 100000 10<br />

00100000: 0000000f 00000010 00000011 00000012 ................<br />

00100010: 00000013 00000014 00000015 00000016 ................<br />

00100020: 00000017 00000018 00000019 0000001a ................<br />

00100030: 0000001b 0000001c 0000001d 0000001e ................<br />

=><br />

=> mw 100000 aabbccdd<br />

=><br />

=> md 100000 10<br />

00100000: aabbccdd 00000010 00000011 00000012 ................<br />

00100010: 00000013 00000014 00000015 00000016 ................<br />

00100020: 00000017 00000018 00000019 0000001a ................<br />

00100030: 0000001b 0000001c 0000001d 0000001e ................<br />

=><br />

=> mw 100000 0 6<br />

=><br />

=> md 100000 10<br />

00100000: 00000000 00000000 00000000 00000000 ................<br />

00100010: 00000000 00000000 00000015 00000016 ................<br />

00100020: 00000017 00000018 00000019 0000001a ................<br />

00100030: 0000001b 0000001c 0000001d 0000001e ................<br />

=><br />

This is another comm<strong>and</strong> that accepts the type extensions .l, .w <strong>and</strong> .b :<br />

=> mw.w 100004 1155 6<br />

=><br />

=> md 100000 10<br />

00100000: 00000000 11551155 11551155 11551155 .....U.U.U.U.U.U<br />

00100010: 00000000 00000000 00000015 00000016 ................<br />

00100020: 00000017 00000018 00000019 0000001a ................<br />

00100030: 0000001b 0000001c 0000001d 0000001e ................<br />

=><br />

=> mw.b 100007 ff 7<br />

=><br />

=> md 100000 10<br />

00100000: 00000000 115511ff ffffffff ffff1155 .....U.........U<br />

00100010: 00000000 00000000 00000015 00000016 ................<br />

00100020: 00000017 00000018 00000019 0000001a ................<br />

00100030: 0000001b 0000001c 0000001d 0000001e ................<br />

5.9.2.7. mtest - simple RAM test 53


=><br />

5.9.2.9. nm - memory modify (constant address)<br />

=> help nm<br />

nm [.b, .w, .l] address<br />

- memory modify, read <strong>and</strong> keep address<br />

=><br />

<strong>The</strong> nm comm<strong>and</strong> (non-incrementing memory modify) can be used to interactively write different data several<br />

times to the same address. This can be useful <strong>for</strong> instance to access <strong>and</strong> modify device registers:<br />

=> nm.b 100000<br />

00100000: 00 48<br />

00100000: 48 65<br />

00100000: 65 6c<br />

00100000: 6c 6c<br />

00100000: 6c 6f<br />

00100000: 6f .<br />

=><br />

=> md 100000 8<br />

00100000: 6f000000 115511ff ffffffff ffff1155 o....U.........U<br />

00100010: 00000000 00000000 00000015 00000016 ................<br />

=><br />

<strong>The</strong> nm comm<strong>and</strong> too accepts the type extensions .l, .w <strong>and</strong> .b.<br />

5.9.2.10. loop - infinite loop on address range<br />

=> help loop<br />

loop [.b, .w, .l] address number_of_objects<br />

- loop on a set of addresses<br />

=><br />

<strong>The</strong> loop comm<strong>and</strong> reads in a tight loop from a range of memory. This is intended as a special <strong>for</strong>m of a<br />

memory test, since this comm<strong>and</strong> tries to read the memory as fast as possible.<br />

This comm<strong>and</strong> will never terminate. <strong>The</strong>re is no way to stop it but to reset the board!<br />

=> loop 100000 8<br />

5.9.3. Flash Memory Comm<strong>and</strong>s<br />

5.9.3.1. cp - memory copy<br />

=> help cp<br />

cp [.b, .w, .l] source target count<br />

- copy memory<br />

=><br />

5.9.3. Flash Memory Comm<strong>and</strong>s 54


<strong>The</strong> cp comm<strong>and</strong> "knows" about flash memory areas <strong>and</strong> will automatically invoke the necessary flash<br />

programming algorithm when the target area is in flash memory.<br />

=> cp.b 100000 FF900000 40000<br />

Copy to Flash... done<br />

=><br />

Writing to flash memory may fail when the target area has not been erased (see erase below), or if it is<br />

write-protected (see protect below).<br />

=> cp.b 100000 FF900000 40000<br />

Copy to Flash... Can't write to protected Flash sectors<br />

=><br />

Remember that the count argument specifies the number of items to copy. If you have a "length" instead (=<br />

byte count) you should use cp.b or you will have to calculate the correct number of items.<br />

5.9.3.2. flinfo - print FLASH memory in<strong>for</strong>mation<br />

<strong>The</strong> comm<strong>and</strong> flinfo (short: fli) can be used to get in<strong>for</strong>mation about the available flash memory. <strong>The</strong><br />

number of flash banks is printed with in<strong>for</strong>mation about the size <strong>and</strong> organization into flash "sectors" or erase<br />

units. For all sectors the start addresses are printed; write-protected sectors are marked as read-only (RO).<br />

Some configurations of U-<strong>Boot</strong> also mark empty sectors with an (E).<br />

=> fli<br />

Bank # 1: CFI con<strong>for</strong>mant FLASH (16 x 16) Size: 64 MB in 512 Sectors<br />

AMD St<strong>and</strong>ard comm<strong>and</strong> set, Manufacturer ID: 0x01, Device ID: 0x227E<br />

Erase timeout: 16384 ms, write timeout: 2 ms<br />

Buffer write timeout: 5 ms, buffer size: 32 bytes<br />

Sector Start Addresses:<br />

FC000000 E FC020000 E FC040000 E FC060000 E FC080000 E<br />

FC0A0000 E FC0C0000 E FC0E0000 E FC100000 E FC120000 E<br />

FC140000 E FC160000 E FC180000 E FC1A0000 E FC1C0000 E<br />

FC1E0000 E FC200000 E FC220000 E FC240000 E FC260000 E<br />

FC280000 E FC2A0000 E FC2C0000 E FC2E0000 E FC300000 E<br />

FC320000 E FC340000 E FC360000 E FC380000 E FC3A0000 E<br />

FC3C0000 E FC3E0000 E FC400000 E FC420000 E FC440000 E<br />

FC460000 E FC480000 E FC4A0000 E FC4C0000 E FC4E0000 E<br />

FC500000 E FC520000 E FC540000 E FC560000 E FC580000 E<br />

FC5A0000 E FC5C0000 E FC5E0000 E FC600000 E FC620000 E<br />

FC640000 E FC660000 E FC680000 E FC6A0000 E FC6C0000 E<br />

FC6E0000 E FC700000 E FC720000 E FC740000 E FC760000 E<br />

FC780000 E FC7A0000 E FC7C0000 E FC7E0000 E FC800000 E<br />

FC820000 E FC840000 E FC860000 E FC880000 E FC8A0000 E<br />

FC8C0000 E FC8E0000 E FC900000 E FC920000 E FC940000 E<br />

FC960000 E FC980000 E FC9A0000 E FC9C0000 E FC9E0000 E<br />

FCA00000 E FCA20000 E FCA40000 E FCA60000 E FCA80000 E<br />

FCAA0000 E FCAC0000 E FCAE0000 E FCB00000 E FCB20000 E<br />

FCB40000 E FCB60000 E FCB80000 E FCBA0000 E FCBC0000 E<br />

FCBE0000 E FCC00000 E FCC20000 E FCC40000 E FCC60000 E<br />

FCC80000 E FCCA0000 E FCCC0000 E FCCE0000 E FCD00000 E<br />

FCD20000 E FCD40000 E FCD60000 E FCD80000 E FCDA0000 E<br />

FCDC0000 E FCDE0000 E FCE00000 E FCE20000 E FCE40000 E<br />

FCE60000 E FCE80000 E FCEA0000 E FCEC0000 E FCEE0000 E<br />

FCF00000 E FCF20000 E FCF40000 E FCF60000 E FCF80000 E<br />

FCFA0000 E FCFC0000 E FCFE0000 E FD000000 E FD020000 E<br />

FD040000 E FD060000 E FD080000 E FD0A0000 E FD0C0000 E<br />

5.9.3.1. cp - memory copy 55


FD0E0000 E FD100000 E FD120000 E FD140000 E FD160000 E<br />

FD180000 E FD1A0000 E FD1C0000 E FD1E0000 E FD200000 E<br />

FD220000 E FD240000 E FD260000 E FD280000 E FD2A0000 E<br />

FD2C0000 E FD2E0000 E FD300000 E FD320000 E FD340000 E<br />

FD360000 E FD380000 E FD3A0000 E FD3C0000 E FD3E0000 E<br />

FD400000 E FD420000 E FD440000 E FD460000 E FD480000 E<br />

FD4A0000 E FD4C0000 E FD4E0000 E FD500000 E FD520000 E<br />

FD540000 E FD560000 E FD580000 E FD5A0000 E FD5C0000 E<br />

FD5E0000 E FD600000 E FD620000 E FD640000 E FD660000 E<br />

FD680000 E FD6A0000 E FD6C0000 E FD6E0000 E FD700000 E<br />

FD720000 E FD740000 E FD760000 E FD780000 E FD7A0000 E<br />

FD7C0000 E FD7E0000 E FD800000 E FD820000 E FD840000 E<br />

FD860000 E FD880000 E FD8A0000 E FD8C0000 E FD8E0000 E<br />

FD900000 E FD920000 E FD940000 E FD960000 E FD980000 E<br />

FD9A0000 E FD9C0000 E FD9E0000 E FDA00000 E FDA20000 E<br />

FDA40000 E FDA60000 E FDA80000 E FDAA0000 E FDAC0000 E<br />

FDAE0000 E FDB00000 E FDB20000 E FDB40000 E FDB60000 E<br />

FDB80000 E FDBA0000 E FDBC0000 E FDBE0000 E FDC00000 E<br />

FDC20000 E FDC40000 E FDC60000 E FDC80000 E FDCA0000 E<br />

FDCC0000 E FDCE0000 E FDD00000 E FDD20000 E FDD40000 E<br />

FDD60000 E FDD80000 E FDDA0000 E FDDC0000 E FDDE0000 E<br />

FDE00000 E FDE20000 E FDE40000 E FDE60000 E FDE80000 E<br />

FDEA0000 E FDEC0000 E FDEE0000 E FDF00000 E FDF20000 E<br />

FDF40000 E FDF60000 E FDF80000 E FDFA0000 E FDFC0000 E<br />

FDFE0000 E FE000000 E FE020000 E FE040000 E FE060000 E<br />

FE080000 E FE0A0000 E FE0C0000 E FE0E0000 E FE100000 E<br />

FE120000 E FE140000 E FE160000 E FE180000 E FE1A0000 E<br />

FE1C0000 E FE1E0000 E FE200000 E FE220000 E FE240000 E<br />

FE260000 E FE280000 E FE2A0000 E FE2C0000 E FE2E0000 E<br />

FE300000 E FE320000 E FE340000 E FE360000 E FE380000 E<br />

FE3A0000 E FE3C0000 E FE3E0000 E FE400000 E FE420000 E<br />

FE440000 E FE460000 E FE480000 E FE4A0000 E FE4C0000 E<br />

FE4E0000 E FE500000 E FE520000 E FE540000 E FE560000 E<br />

FE580000 E FE5A0000 E FE5C0000 E FE5E0000 E FE600000 E<br />

FE620000 E FE640000 E FE660000 E FE680000 E FE6A0000 E<br />

FE6C0000 E FE6E0000 E FE700000 E FE720000 E FE740000 E<br />

FE760000 E FE780000 E FE7A0000 E FE7C0000 E FE7E0000 E<br />

FE800000 E FE820000 E FE840000 E FE860000 E FE880000 E<br />

FE8A0000 E FE8C0000 E FE8E0000 E FE900000 E FE920000 E<br />

FE940000 E FE960000 E FE980000 E FE9A0000 E FE9C0000 E<br />

FE9E0000 E FEA00000 E FEA20000 E FEA40000 E FEA60000 E<br />

FEA80000 E FEAA0000 E FEAC0000 E FEAE0000 E FEB00000 E<br />

FEB20000 E FEB40000 E FEB60000 E FEB80000 E FEBA0000 E<br />

FEBC0000 E FEBE0000 E FEC00000 E FEC20000 E FEC40000 E<br />

FEC60000 E FEC80000 E FECA0000 E FECC0000 E FECE0000 E<br />

FED00000 E FED20000 E FED40000 E FED60000 E FED80000 E<br />

FEDA0000 E FEDC0000 E FEDE0000 E FEE00000 E FEE20000 E<br />

FEE40000 E FEE60000 E FEE80000 E FEEA0000 E FEEC0000 E<br />

FEEE0000 E FEF00000 E FEF20000 E FEF40000 E FEF60000 E<br />

FEF80000 E FEFA0000 E FEFC0000 E FEFE0000 E FF000000 E<br />

FF020000 E FF040000 E FF060000 E FF080000 E FF0A0000 E<br />

FF0C0000 E FF0E0000 E FF100000 E FF120000 E FF140000 E<br />

FF160000 E FF180000 E FF1A0000 E FF1C0000 E FF1E0000 E<br />

FF200000 E FF220000 E FF240000 E FF260000 E FF280000 E<br />

FF2A0000 E FF2C0000 E FF2E0000 E FF300000 E FF320000 E<br />

FF340000 E FF360000 E FF380000 E FF3A0000 E FF3C0000 E<br />

FF3E0000 E FF400000 E FF420000 E FF440000 E FF460000 E<br />

FF480000 E FF4A0000 E FF4C0000 E FF4E0000 E FF500000 E<br />

FF520000 E FF540000 E FF560000 E FF580000 E FF5A0000 E<br />

FF5C0000 E FF5E0000 E FF600000 E FF620000 E FF640000 E<br />

FF660000 E FF680000 E FF6A0000 E FF6C0000 E FF6E0000 E<br />

FF700000 E FF720000 E FF740000 E FF760000 E FF780000 E<br />

FF7A0000 E FF7C0000 E FF7E0000 E FF800000 E FF820000 E<br />

FF840000 E FF860000 E FF880000 E FF8A0000 E FF8C0000 E<br />

FF8E0000 E FF900000 E FF920000 E FF940000 E FF960000 E<br />

FF980000 E FF9A0000 E FF9C0000 E FF9E0000 E FFA00000 E<br />

FFA20000 E FFA40000 E FFA60000 E FFA80000 E FFAA0000 E<br />

5.9.3.2. flinfo - print FLASH memory in<strong>for</strong>mation 56


FFAC0000 E FFAE0000 E FFB00000 E FFB20000 E FFB40000 E<br />

FFB60000 E FFB80000 E FFBA0000 E FFBC0000 E FFBE0000 E<br />

FFC00000 E FFC20000 E FFC40000 E FFC60000 E FFC80000 E<br />

FFCA0000 E FFCC0000 E FFCE0000 E FFD00000 E FFD20000 E<br />

FFD40000 E FFD60000 E FFD80000 E FFDA0000 E FFDC0000 E<br />

FFDE0000 E FFE00000 E FFE20000 E FFE40000 E FFE60000 E<br />

FFE80000 E FFEA0000 E FFEC0000 E FFEE0000 E FFF00000 E<br />

FFF20000 E FFF40000 E FFF60000 RO FFF80000 RO FFFA0000 RO<br />

FFFC0000 RO FFFE0000 RO<br />

=><br />

5.9.3.3. erase - erase FLASH memory<br />

=> help era<br />

erase start end<br />

- erase FLASH from addr 'start' to addr 'end'<br />

erase start +len<br />

- erase FLASH from addr 'start' to the end of sect w/addr 'start'+'len'-1<br />

erase N:SF[-SL]<br />

- erase sectors SF-SL in FLASH bank # N<br />

erase bank N<br />

- erase FLASH bank # N<br />

erase all<br />

- erase all FLASH banks<br />

=><br />

<strong>The</strong> erase comm<strong>and</strong> (short: era) is used to erase the contents of one or more sectors of the flash memory. It<br />

is one of the more complex comm<strong>and</strong>s; the help output shows this.<br />

Probably the most frequent usage of this comm<strong>and</strong> is to pass the start <strong>and</strong> end addresses of the area to be<br />

erased:<br />

=> era FF900000 FF95FFFF<br />

... done<br />

Erased 3 sectors<br />

=><br />

Note that both the start <strong>and</strong> end addresses <strong>for</strong> this comm<strong>and</strong> must point exactly at the start resp. end<br />

addresses of flash sectors. Otherwise the comm<strong>and</strong> will not be executed.<br />

Another way to select certain areas of the flash memory <strong>for</strong> the erase comm<strong>and</strong> uses the notation of flash<br />

banks <strong>and</strong> sectors:<br />

Technically speaking, a bank is an area of memory implemented by one or more memory chips that are<br />

connected to the same chip select signal of the CPU, <strong>and</strong> a flash sector or erase unit is the smallest area that<br />

can be erased in one operation.<br />

For practical purposes it is sufficient to remember that with flash memory a bank is something that eventually<br />

may be erased as a whole in a single operation. This may be more efficient (faster) than erasing the same area<br />

sector by sector.<br />

[It depends on the actual type of flash chips used on the board if such a fast bank erase algorithm exists, <strong>and</strong><br />

on the implementation of the flash device driver if is actually used.]<br />

In U-<strong>Boot</strong>, flash banks are numbered starting with 1, while flash sectors start with 0.<br />

5.9.3.3. erase - erase FLASH memory 57


To erase the same flash area as specified using start <strong>and</strong> end addresses in the example above you could also<br />

type:<br />

=> era 1:455-456<br />

Erase Flash Sectors 455-456 in Bank # 1<br />

.. done<br />

=><br />

To erase a whole bank of flash memory you can use a comm<strong>and</strong> like this one:<br />

=> era bank 1<br />

Erase Flash Bank # 1 - Warning: 5 protected sectors will not be erased!<br />

.................................................................................................<br />

=><br />

Note that a warning message is printed because some write protected sectors exist in this flash bank which<br />

were not erased.<br />

With the comm<strong>and</strong>:<br />

=> era all<br />

Erase Flash Bank # 1 - Warning: 5 protected sectors will not be erased!<br />

.................................................................................................<br />

=><br />

the whole flash memory (except <strong>for</strong> the write-protected sectors) can be erased.<br />

5.9.3.4. protect - enable or disable FLASH write protection<br />

=> help protect<br />

protect on start end<br />

- protect FLASH from addr 'start' to addr 'end'<br />

protect on start +len<br />

- protect FLASH from addr 'start' to end of sect w/addr 'start'+'len'-1<br />

protect on N:SF[-SL]<br />

- protect sectors SF-SL in FLASH bank # N<br />

protect on bank N<br />

- protect FLASH bank # N<br />

protect on all<br />

- protect all FLASH banks<br />

protect off start end<br />

- make FLASH from addr 'start' to addr 'end' writable<br />

protect off start +len<br />

- make FLASH from addr 'start' to end of sect w/addr 'start'+'len'-1 wrtable<br />

protect off N:SF[-SL]<br />

- make sectors SF-SL writable in FLASH bank # N<br />

protect off bank N<br />

- make FLASH bank # N writable<br />

protect off all<br />

- make all FLASH banks writable<br />

=><br />

<strong>The</strong> protect comm<strong>and</strong> is another complex one. It is used to set certain parts of the flash memory to<br />

read-only mode or to make them writable again. Flash memory that is "protected" (= read-only) cannot be<br />

written (with the cp comm<strong>and</strong>) or erased (with the erase comm<strong>and</strong>). Protected areas are marked as (RO)<br />

(<strong>for</strong> "read-only") in the output of the flinfo comm<strong>and</strong>:<br />

5.9.3.4. protect - enable or disable FLASH write protection 58


=> fli<br />

Bank # 1: CFI con<strong>for</strong>mant FLASH (16 x 16) Size: 64 MB in 512 Sectors<br />

AMD St<strong>and</strong>ard comm<strong>and</strong> set, Manufacturer ID: 0x01, Device ID: 0x227E<br />

Erase timeout: 16384 ms, write timeout: 2 ms<br />

Buffer write timeout: 5 ms, buffer size: 32 bytes<br />

Sector Start Addresses:<br />

FC000000 E FC020000 E FC040000 E FC060000 E FC080000 E<br />

FC0A0000 E FC0C0000 E FC0E0000 E FC100000 E FC120000 E<br />

FC140000 E FC160000 E FC180000 E FC1A0000 E FC1C0000 E<br />

FC1E0000 E FC200000 E FC220000 E FC240000 E FC260000 E<br />

FC280000 E FC2A0000 E FC2C0000 E FC2E0000 E FC300000 E<br />

FC320000 E FC340000 E FC360000 E FC380000 E FC3A0000 E<br />

FC3C0000 E FC3E0000 E FC400000 E FC420000 E FC440000 E<br />

FC460000 E FC480000 E FC4A0000 E FC4C0000 E FC4E0000 E<br />

FC500000 E FC520000 E FC540000 E FC560000 E FC580000 E<br />

FC5A0000 E FC5C0000 E FC5E0000 E FC600000 E FC620000 E<br />

FC640000 E FC660000 E FC680000 E FC6A0000 E FC6C0000 E<br />

FC6E0000 E FC700000 E FC720000 E FC740000 E FC760000 E<br />

FC780000 E FC7A0000 E FC7C0000 E FC7E0000 E FC800000 E<br />

FC820000 E FC840000 E FC860000 E FC880000 E FC8A0000 E<br />

FC8C0000 E FC8E0000 E FC900000 E FC920000 E FC940000 E<br />

FC960000 E FC980000 E FC9A0000 E FC9C0000 E FC9E0000 E<br />

FCA00000 E FCA20000 E FCA40000 E FCA60000 E FCA80000 E<br />

FCAA0000 E FCAC0000 E FCAE0000 E FCB00000 E FCB20000 E<br />

FCB40000 E FCB60000 E FCB80000 E FCBA0000 E FCBC0000 E<br />

FCBE0000 E FCC00000 E FCC20000 E FCC40000 E FCC60000 E<br />

FCC80000 E FCCA0000 E FCCC0000 E FCCE0000 E FCD00000 E<br />

FCD20000 E FCD40000 E FCD60000 E FCD80000 E FCDA0000 E<br />

FCDC0000 E FCDE0000 E FCE00000 E FCE20000 E FCE40000 E<br />

FCE60000 E FCE80000 E FCEA0000 E FCEC0000 E FCEE0000 E<br />

FCF00000 E FCF20000 E FCF40000 E FCF60000 E FCF80000 E<br />

FCFA0000 E FCFC0000 E FCFE0000 E FD000000 E FD020000 E<br />

FD040000 E FD060000 E FD080000 E FD0A0000 E FD0C0000 E<br />

FD0E0000 E FD100000 E FD120000 E FD140000 E FD160000 E<br />

FD180000 E FD1A0000 E FD1C0000 E FD1E0000 E FD200000 E<br />

FD220000 E FD240000 E FD260000 E FD280000 E FD2A0000 E<br />

FD2C0000 E FD2E0000 E FD300000 E FD320000 E FD340000 E<br />

FD360000 E FD380000 E FD3A0000 E FD3C0000 E FD3E0000 E<br />

FD400000 E FD420000 E FD440000 E FD460000 E FD480000 E<br />

FD4A0000 E FD4C0000 E FD4E0000 E FD500000 E FD520000 E<br />

FD540000 E FD560000 E FD580000 E FD5A0000 E FD5C0000 E<br />

FD5E0000 E FD600000 E FD620000 E FD640000 E FD660000 E<br />

FD680000 E FD6A0000 E FD6C0000 E FD6E0000 E FD700000 E<br />

FD720000 E FD740000 E FD760000 E FD780000 E FD7A0000 E<br />

FD7C0000 E FD7E0000 E FD800000 E FD820000 E FD840000 E<br />

FD860000 E FD880000 E FD8A0000 E FD8C0000 E FD8E0000 E<br />

FD900000 E FD920000 E FD940000 E FD960000 E FD980000 E<br />

FD9A0000 E FD9C0000 E FD9E0000 E FDA00000 E FDA20000 E<br />

FDA40000 E FDA60000 E FDA80000 E FDAA0000 E FDAC0000 E<br />

FDAE0000 E FDB00000 E FDB20000 E FDB40000 E FDB60000 E<br />

FDB80000 E FDBA0000 E FDBC0000 E FDBE0000 E FDC00000 E<br />

FDC20000 E FDC40000 E FDC60000 E FDC80000 E FDCA0000 E<br />

FDCC0000 E FDCE0000 E FDD00000 E FDD20000 E FDD40000 E<br />

FDD60000 E FDD80000 E FDDA0000 E FDDC0000 E FDDE0000 E<br />

FDE00000 E FDE20000 E FDE40000 E FDE60000 E FDE80000 E<br />

FDEA0000 E FDEC0000 E FDEE0000 E FDF00000 E FDF20000 E<br />

FDF40000 E FDF60000 E FDF80000 E FDFA0000 E FDFC0000 E<br />

FDFE0000 E FE000000 E FE020000 E FE040000 E FE060000 E<br />

FE080000 E FE0A0000 E FE0C0000 E FE0E0000 E FE100000 E<br />

FE120000 E FE140000 E FE160000 E FE180000 E FE1A0000 E<br />

FE1C0000 E FE1E0000 E FE200000 E FE220000 E FE240000 E<br />

FE260000 E FE280000 E FE2A0000 E FE2C0000 E FE2E0000 E<br />

FE300000 E FE320000 E FE340000 E FE360000 E FE380000 E<br />

FE3A0000 E FE3C0000 E FE3E0000 E FE400000 E FE420000 E<br />

5.9.3.4. protect - enable or disable FLASH write protection 59


FE440000 E FE460000 E FE480000 E FE4A0000 E FE4C0000 E<br />

FE4E0000 E FE500000 E FE520000 E FE540000 E FE560000 E<br />

FE580000 E FE5A0000 E FE5C0000 E FE5E0000 E FE600000 E<br />

FE620000 E FE640000 E FE660000 E FE680000 E FE6A0000 E<br />

FE6C0000 E FE6E0000 E FE700000 E FE720000 E FE740000 E<br />

FE760000 E FE780000 E FE7A0000 E FE7C0000 E FE7E0000 E<br />

FE800000 E FE820000 E FE840000 E FE860000 E FE880000 E<br />

FE8A0000 E FE8C0000 E FE8E0000 E FE900000 E FE920000 E<br />

FE940000 E FE960000 E FE980000 E FE9A0000 E FE9C0000 E<br />

FE9E0000 E FEA00000 E FEA20000 E FEA40000 E FEA60000 E<br />

FEA80000 E FEAA0000 E FEAC0000 E FEAE0000 E FEB00000 E<br />

FEB20000 E FEB40000 E FEB60000 E FEB80000 E FEBA0000 E<br />

FEBC0000 E FEBE0000 E FEC00000 E FEC20000 E FEC40000 E<br />

FEC60000 E FEC80000 E FECA0000 E FECC0000 E FECE0000 E<br />

FED00000 E FED20000 E FED40000 E FED60000 E FED80000 E<br />

FEDA0000 E FEDC0000 E FEDE0000 E FEE00000 E FEE20000 E<br />

FEE40000 E FEE60000 E FEE80000 E FEEA0000 E FEEC0000 E<br />

FEEE0000 E FEF00000 E FEF20000 E FEF40000 E FEF60000 E<br />

FEF80000 E FEFA0000 E FEFC0000 E FEFE0000 E FF000000 E<br />

FF020000 E FF040000 E FF060000 E FF080000 E FF0A0000 E<br />

FF0C0000 E FF0E0000 E FF100000 E FF120000 E FF140000 E<br />

FF160000 E FF180000 E FF1A0000 E FF1C0000 E FF1E0000 E<br />

FF200000 E FF220000 E FF240000 E FF260000 E FF280000 E<br />

FF2A0000 E FF2C0000 E FF2E0000 E FF300000 E FF320000 E<br />

FF340000 E FF360000 E FF380000 E FF3A0000 E FF3C0000 E<br />

FF3E0000 E FF400000 E FF420000 E FF440000 E FF460000 E<br />

FF480000 E FF4A0000 E FF4C0000 E FF4E0000 E FF500000 E<br />

FF520000 E FF540000 E FF560000 E FF580000 E FF5A0000 E<br />

FF5C0000 E FF5E0000 E FF600000 E FF620000 E FF640000 E<br />

FF660000 E FF680000 E FF6A0000 E FF6C0000 E FF6E0000 E<br />

FF700000 E FF720000 E FF740000 E FF760000 E FF780000 E<br />

FF7A0000 E FF7C0000 E FF7E0000 E FF800000 E FF820000 E<br />

FF840000 E FF860000 E FF880000 E FF8A0000 E FF8C0000 E<br />

FF8E0000 E FF900000 E FF920000 E FF940000 E FF960000 E<br />

FF980000 E FF9A0000 E FF9C0000 E FF9E0000 E FFA00000 E<br />

FFA20000 E FFA40000 E FFA60000 E FFA80000 E FFAA0000 E<br />

FFAC0000 E FFAE0000 E FFB00000 E FFB20000 E FFB40000 E<br />

FFB60000 E FFB80000 E FFBA0000 E FFBC0000 E FFBE0000 E<br />

FFC00000 E FFC20000 E FFC40000 E FFC60000 E FFC80000 E<br />

FFCA0000 E FFCC0000 E FFCE0000 E FFD00000 E FFD20000 E<br />

FFD40000 E FFD60000 E FFD80000 E FFDA0000 E FFDC0000 E<br />

FFDE0000 E FFE00000 E FFE20000 E FFE40000 E FFE60000 E<br />

FFE80000 E FFEA0000 E FFEC0000 E FFEE0000 E FFF00000 E<br />

FFF20000 E FFF40000 E FFF60000 RO FFF80000 RO FFFA0000 RO<br />

FFFC0000 RO FFFE0000 RO<br />

=><br />

=> prot on FF900000 FF97FFFF<br />

Protected 4 sectors<br />

=><br />

=> fli<br />

Bank # 1: CFI con<strong>for</strong>mant FLASH (16 x 16) Size: 64 MB in 512 Sectors<br />

AMD St<strong>and</strong>ard comm<strong>and</strong> set, Manufacturer ID: 0x01, Device ID: 0x227E<br />

Erase timeout: 16384 ms, write timeout: 2 ms<br />

Buffer write timeout: 5 ms, buffer size: 32 bytes<br />

Sector Start Addresses:<br />

FC000000 E FC020000 E FC040000 E FC060000 E FC080000 E<br />

FC0A0000 E FC0C0000 E FC0E0000 E FC100000 E FC120000 E<br />

FC140000 E FC160000 E FC180000 E FC1A0000 E FC1C0000 E<br />

FC1E0000 E FC200000 E FC220000 E FC240000 E FC260000 E<br />

FC280000 E FC2A0000 E FC2C0000 E FC2E0000 E FC300000 E<br />

FC320000 E FC340000 E FC360000 E FC380000 E FC3A0000 E<br />

FC3C0000 E FC3E0000 E FC400000 E FC420000 E FC440000 E<br />

FC460000 E FC480000 E FC4A0000 E FC4C0000 E FC4E0000 E<br />

FC500000 E FC520000 E FC540000 E FC560000 E FC580000 E<br />

FC5A0000 E FC5C0000 E FC5E0000 E FC600000 E FC620000 E<br />

5.9.3.4. protect - enable or disable FLASH write protection 60


FC640000 E FC660000 E FC680000 E FC6A0000 E FC6C0000 E<br />

FC6E0000 E FC700000 E FC720000 E FC740000 E FC760000 E<br />

FC780000 E FC7A0000 E FC7C0000 E FC7E0000 E FC800000 E<br />

FC820000 E FC840000 E FC860000 E FC880000 E FC8A0000 E<br />

FC8C0000 E FC8E0000 E FC900000 E FC920000 E FC940000 E<br />

FC960000 E FC980000 E FC9A0000 E FC9C0000 E FC9E0000 E<br />

FCA00000 E FCA20000 E FCA40000 E FCA60000 E FCA80000 E<br />

FCAA0000 E FCAC0000 E FCAE0000 E FCB00000 E FCB20000 E<br />

FCB40000 E FCB60000 E FCB80000 E FCBA0000 E FCBC0000 E<br />

FCBE0000 E FCC00000 E FCC20000 E FCC40000 E FCC60000 E<br />

FCC80000 E FCCA0000 E FCCC0000 E FCCE0000 E FCD00000 E<br />

FCD20000 E FCD40000 E FCD60000 E FCD80000 E FCDA0000 E<br />

FCDC0000 E FCDE0000 E FCE00000 E FCE20000 E FCE40000 E<br />

FCE60000 E FCE80000 E FCEA0000 E FCEC0000 E FCEE0000 E<br />

FCF00000 E FCF20000 E FCF40000 E FCF60000 E FCF80000 E<br />

FCFA0000 E FCFC0000 E FCFE0000 E FD000000 E FD020000 E<br />

FD040000 E FD060000 E FD080000 E FD0A0000 E FD0C0000 E<br />

FD0E0000 E FD100000 E FD120000 E FD140000 E FD160000 E<br />

FD180000 E FD1A0000 E FD1C0000 E FD1E0000 E FD200000 E<br />

FD220000 E FD240000 E FD260000 E FD280000 E FD2A0000 E<br />

FD2C0000 E FD2E0000 E FD300000 E FD320000 E FD340000 E<br />

FD360000 E FD380000 E FD3A0000 E FD3C0000 E FD3E0000 E<br />

FD400000 E FD420000 E FD440000 E FD460000 E FD480000 E<br />

FD4A0000 E FD4C0000 E FD4E0000 E FD500000 E FD520000 E<br />

FD540000 E FD560000 E FD580000 E FD5A0000 E FD5C0000 E<br />

FD5E0000 E FD600000 E FD620000 E FD640000 E FD660000 E<br />

FD680000 E FD6A0000 E FD6C0000 E FD6E0000 E FD700000 E<br />

FD720000 E FD740000 E FD760000 E FD780000 E FD7A0000 E<br />

FD7C0000 E FD7E0000 E FD800000 E FD820000 E FD840000 E<br />

FD860000 E FD880000 E FD8A0000 E FD8C0000 E FD8E0000 E<br />

FD900000 E FD920000 E FD940000 E FD960000 E FD980000 E<br />

FD9A0000 E FD9C0000 E FD9E0000 E FDA00000 E FDA20000 E<br />

FDA40000 E FDA60000 E FDA80000 E FDAA0000 E FDAC0000 E<br />

FDAE0000 E FDB00000 E FDB20000 E FDB40000 E FDB60000 E<br />

FDB80000 E FDBA0000 E FDBC0000 E FDBE0000 E FDC00000 E<br />

FDC20000 E FDC40000 E FDC60000 E FDC80000 E FDCA0000 E<br />

FDCC0000 E FDCE0000 E FDD00000 E FDD20000 E FDD40000 E<br />

FDD60000 E FDD80000 E FDDA0000 E FDDC0000 E FDDE0000 E<br />

FDE00000 E FDE20000 E FDE40000 E FDE60000 E FDE80000 E<br />

FDEA0000 E FDEC0000 E FDEE0000 E FDF00000 E FDF20000 E<br />

FDF40000 E FDF60000 E FDF80000 E FDFA0000 E FDFC0000 E<br />

FDFE0000 E FE000000 E FE020000 E FE040000 E FE060000 E<br />

FE080000 E FE0A0000 E FE0C0000 E FE0E0000 E FE100000 E<br />

FE120000 E FE140000 E FE160000 E FE180000 E FE1A0000 E<br />

FE1C0000 E FE1E0000 E FE200000 E FE220000 E FE240000 E<br />

FE260000 E FE280000 E FE2A0000 E FE2C0000 E FE2E0000 E<br />

FE300000 E FE320000 E FE340000 E FE360000 E FE380000 E<br />

FE3A0000 E FE3C0000 E FE3E0000 E FE400000 E FE420000 E<br />

FE440000 E FE460000 E FE480000 E FE4A0000 E FE4C0000 E<br />

FE4E0000 E FE500000 E FE520000 E FE540000 E FE560000 E<br />

FE580000 E FE5A0000 E FE5C0000 E FE5E0000 E FE600000 E<br />

FE620000 E FE640000 E FE660000 E FE680000 E FE6A0000 E<br />

FE6C0000 E FE6E0000 E FE700000 E FE720000 E FE740000 E<br />

FE760000 E FE780000 E FE7A0000 E FE7C0000 E FE7E0000 E<br />

FE800000 E FE820000 E FE840000 E FE860000 E FE880000 E<br />

FE8A0000 E FE8C0000 E FE8E0000 E FE900000 E FE920000 E<br />

FE940000 E FE960000 E FE980000 E FE9A0000 E FE9C0000 E<br />

FE9E0000 E FEA00000 E FEA20000 E FEA40000 E FEA60000 E<br />

FEA80000 E FEAA0000 E FEAC0000 E FEAE0000 E FEB00000 E<br />

FEB20000 E FEB40000 E FEB60000 E FEB80000 E FEBA0000 E<br />

FEBC0000 E FEBE0000 E FEC00000 E FEC20000 E FEC40000 E<br />

FEC60000 E FEC80000 E FECA0000 E FECC0000 E FECE0000 E<br />

FED00000 E FED20000 E FED40000 E FED60000 E FED80000 E<br />

FEDA0000 E FEDC0000 E FEDE0000 E FEE00000 E FEE20000 E<br />

FEE40000 E FEE60000 E FEE80000 E FEEA0000 E FEEC0000 E<br />

FEEE0000 E FEF00000 E FEF20000 E FEF40000 E FEF60000 E<br />

FEF80000 E FEFA0000 E FEFC0000 E FEFE0000 E FF000000 E<br />

5.9.3.4. protect - enable or disable FLASH write protection 61


FF020000 E FF040000 E FF060000 E FF080000 E FF0A0000 E<br />

FF0C0000 E FF0E0000 E FF100000 E FF120000 E FF140000 E<br />

FF160000 E FF180000 E FF1A0000 E FF1C0000 E FF1E0000 E<br />

FF200000 E FF220000 E FF240000 E FF260000 E FF280000 E<br />

FF2A0000 E FF2C0000 E FF2E0000 E FF300000 E FF320000 E<br />

FF340000 E FF360000 E FF380000 E FF3A0000 E FF3C0000 E<br />

FF3E0000 E FF400000 E FF420000 E FF440000 E FF460000 E<br />

FF480000 E FF4A0000 E FF4C0000 E FF4E0000 E FF500000 E<br />

FF520000 E FF540000 E FF560000 E FF580000 E FF5A0000 E<br />

FF5C0000 E FF5E0000 E FF600000 E FF620000 E FF640000 E<br />

FF660000 E FF680000 E FF6A0000 E FF6C0000 E FF6E0000 E<br />

FF700000 E FF720000 E FF740000 E FF760000 E FF780000 E<br />

FF7A0000 E FF7C0000 E FF7E0000 E FF800000 E FF820000 E<br />

FF840000 E FF860000 E FF880000 E FF8A0000 E FF8C0000 E<br />

FF8E0000 E FF900000 E RO FF920000 E RO FF940000 E RO FF960000 E RO<br />

FF980000 E FF9A0000 E FF9C0000 E FF9E0000 E FFA00000 E<br />

FFA20000 E FFA40000 E FFA60000 E FFA80000 E FFAA0000 E<br />

FFAC0000 E FFAE0000 E FFB00000 E FFB20000 E FFB40000 E<br />

FFB60000 E FFB80000 E FFBA0000 E FFBC0000 E FFBE0000 E<br />

FFC00000 E FFC20000 E FFC40000 E FFC60000 E FFC80000 E<br />

FFCA0000 E FFCC0000 E FFCE0000 E FFD00000 E FFD20000 E<br />

FFD40000 E FFD60000 E FFD80000 E FFDA0000 E FFDC0000 E<br />

FFDE0000 E FFE00000 E FFE20000 E FFE40000 E FFE60000 E<br />

FFE80000 E FFEA0000 E FFEC0000 E FFEE0000 E FFF00000 E<br />

FFF20000 E FFF40000 E FFF60000 RO FFF80000 RO FFFA0000 RO<br />

FFFC0000 RO FFFE0000 RO<br />

=><br />

=> era FF900000 FF97FFFF<br />

- Warning: 4 protected sectors will not be erased!<br />

done<br />

Erased 4 sectors<br />

=><br />

=> prot off 1:455<br />

Un-Protect Flash Sectors 455-455 in Bank # 1<br />

=><br />

=> fli<br />

Bank # 1: CFI con<strong>for</strong>mant FLASH (16 x 16) Size: 64 MB in 512 Sectors<br />

AMD St<strong>and</strong>ard comm<strong>and</strong> set, Manufacturer ID: 0x01, Device ID: 0x227E<br />

Erase timeout: 16384 ms, write timeout: 2 ms<br />

Buffer write timeout: 5 ms, buffer size: 32 bytes<br />

Sector Start Addresses:<br />

FC000000 E FC020000 E FC040000 E FC060000 E FC080000 E<br />

FC0A0000 E FC0C0000 E FC0E0000 E FC100000 E FC120000 E<br />

FC140000 E FC160000 E FC180000 E FC1A0000 E FC1C0000 E<br />

FC1E0000 E FC200000 E FC220000 E FC240000 E FC260000 E<br />

FC280000 E FC2A0000 E FC2C0000 E FC2E0000 E FC300000 E<br />

FC320000 E FC340000 E FC360000 E FC380000 E FC3A0000 E<br />

FC3C0000 E FC3E0000 E FC400000 E FC420000 E FC440000 E<br />

FC460000 E FC480000 E FC4A0000 E FC4C0000 E FC4E0000 E<br />

FC500000 E FC520000 E FC540000 E FC560000 E FC580000 E<br />

FC5A0000 E FC5C0000 E FC5E0000 E FC600000 E FC620000 E<br />

FC640000 E FC660000 E FC680000 E FC6A0000 E FC6C0000 E<br />

FC6E0000 E FC700000 E FC720000 E FC740000 E FC760000 E<br />

FC780000 E FC7A0000 E FC7C0000 E FC7E0000 E FC800000 E<br />

FC820000 E FC840000 E FC860000 E FC880000 E FC8A0000 E<br />

FC8C0000 E FC8E0000 E FC900000 E FC920000 E FC940000 E<br />

FC960000 E FC980000 E FC9A0000 E FC9C0000 E FC9E0000 E<br />

FCA00000 E FCA20000 E FCA40000 E FCA60000 E FCA80000 E<br />

FCAA0000 E FCAC0000 E FCAE0000 E FCB00000 E FCB20000 E<br />

FCB40000 E FCB60000 E FCB80000 E FCBA0000 E FCBC0000 E<br />

FCBE0000 E FCC00000 E FCC20000 E FCC40000 E FCC60000 E<br />

FCC80000 E FCCA0000 E FCCC0000 E FCCE0000 E FCD00000 E<br />

FCD20000 E FCD40000 E FCD60000 E FCD80000 E FCDA0000 E<br />

FCDC0000 E FCDE0000 E FCE00000 E FCE20000 E FCE40000 E<br />

FCE60000 E FCE80000 E FCEA0000 E FCEC0000 E FCEE0000 E<br />

5.9.3.4. protect - enable or disable FLASH write protection 62


FCF00000 E FCF20000 E FCF40000 E FCF60000 E FCF80000 E<br />

FCFA0000 E FCFC0000 E FCFE0000 E FD000000 E FD020000 E<br />

FD040000 E FD060000 E FD080000 E FD0A0000 E FD0C0000 E<br />

FD0E0000 E FD100000 E FD120000 E FD140000 E FD160000 E<br />

FD180000 E FD1A0000 E FD1C0000 E FD1E0000 E FD200000 E<br />

FD220000 E FD240000 E FD260000 E FD280000 E FD2A0000 E<br />

FD2C0000 E FD2E0000 E FD300000 E FD320000 E FD340000 E<br />

FD360000 E FD380000 E FD3A0000 E FD3C0000 E FD3E0000 E<br />

FD400000 E FD420000 E FD440000 E FD460000 E FD480000 E<br />

FD4A0000 E FD4C0000 E FD4E0000 E FD500000 E FD520000 E<br />

FD540000 E FD560000 E FD580000 E FD5A0000 E FD5C0000 E<br />

FD5E0000 E FD600000 E FD620000 E FD640000 E FD660000 E<br />

FD680000 E FD6A0000 E FD6C0000 E FD6E0000 E FD700000 E<br />

FD720000 E FD740000 E FD760000 E FD780000 E FD7A0000 E<br />

FD7C0000 E FD7E0000 E FD800000 E FD820000 E FD840000 E<br />

FD860000 E FD880000 E FD8A0000 E FD8C0000 E FD8E0000 E<br />

FD900000 E FD920000 E FD940000 E FD960000 E FD980000 E<br />

FD9A0000 E FD9C0000 E FD9E0000 E FDA00000 E FDA20000 E<br />

FDA40000 E FDA60000 E FDA80000 E FDAA0000 E FDAC0000 E<br />

FDAE0000 E FDB00000 E FDB20000 E FDB40000 E FDB60000 E<br />

FDB80000 E FDBA0000 E FDBC0000 E FDBE0000 E FDC00000 E<br />

FDC20000 E FDC40000 E FDC60000 E FDC80000 E FDCA0000 E<br />

FDCC0000 E FDCE0000 E FDD00000 E FDD20000 E FDD40000 E<br />

FDD60000 E FDD80000 E FDDA0000 E FDDC0000 E FDDE0000 E<br />

FDE00000 E FDE20000 E FDE40000 E FDE60000 E FDE80000 E<br />

FDEA0000 E FDEC0000 E FDEE0000 E FDF00000 E FDF20000 E<br />

FDF40000 E FDF60000 E FDF80000 E FDFA0000 E FDFC0000 E<br />

FDFE0000 E FE000000 E FE020000 E FE040000 E FE060000 E<br />

FE080000 E FE0A0000 E FE0C0000 E FE0E0000 E FE100000 E<br />

FE120000 E FE140000 E FE160000 E FE180000 E FE1A0000 E<br />

FE1C0000 E FE1E0000 E FE200000 E FE220000 E FE240000 E<br />

FE260000 E FE280000 E FE2A0000 E FE2C0000 E FE2E0000 E<br />

FE300000 E FE320000 E FE340000 E FE360000 E FE380000 E<br />

FE3A0000 E FE3C0000 E FE3E0000 E FE400000 E FE420000 E<br />

FE440000 E FE460000 E FE480000 E FE4A0000 E FE4C0000 E<br />

FE4E0000 E FE500000 E FE520000 E FE540000 E FE560000 E<br />

FE580000 E FE5A0000 E FE5C0000 E FE5E0000 E FE600000 E<br />

FE620000 E FE640000 E FE660000 E FE680000 E FE6A0000 E<br />

FE6C0000 E FE6E0000 E FE700000 E FE720000 E FE740000 E<br />

FE760000 E FE780000 E FE7A0000 E FE7C0000 E FE7E0000 E<br />

FE800000 E FE820000 E FE840000 E FE860000 E FE880000 E<br />

FE8A0000 E FE8C0000 E FE8E0000 E FE900000 E FE920000 E<br />

FE940000 E FE960000 E FE980000 E FE9A0000 E FE9C0000 E<br />

FE9E0000 E FEA00000 E FEA20000 E FEA40000 E FEA60000 E<br />

FEA80000 E FEAA0000 E FEAC0000 E FEAE0000 E FEB00000 E<br />

FEB20000 E FEB40000 E FEB60000 E FEB80000 E FEBA0000 E<br />

FEBC0000 E FEBE0000 E FEC00000 E FEC20000 E FEC40000 E<br />

FEC60000 E FEC80000 E FECA0000 E FECC0000 E FECE0000 E<br />

FED00000 E FED20000 E FED40000 E FED60000 E FED80000 E<br />

FEDA0000 E FEDC0000 E FEDE0000 E FEE00000 E FEE20000 E<br />

FEE40000 E FEE60000 E FEE80000 E FEEA0000 E FEEC0000 E<br />

FEEE0000 E FEF00000 E FEF20000 E FEF40000 E FEF60000 E<br />

FEF80000 E FEFA0000 E FEFC0000 E FEFE0000 E FF000000 E<br />

FF020000 E FF040000 E FF060000 E FF080000 E FF0A0000 E<br />

FF0C0000 E FF0E0000 E FF100000 E FF120000 E FF140000 E<br />

FF160000 E FF180000 E FF1A0000 E FF1C0000 E FF1E0000 E<br />

FF200000 E FF220000 E FF240000 E FF260000 E FF280000 E<br />

FF2A0000 E FF2C0000 E FF2E0000 E FF300000 E FF320000 E<br />

FF340000 E FF360000 E FF380000 E FF3A0000 E FF3C0000 E<br />

FF3E0000 E FF400000 E FF420000 E FF440000 E FF460000 E<br />

FF480000 E FF4A0000 E FF4C0000 E FF4E0000 E FF500000 E<br />

FF520000 E FF540000 E FF560000 E FF580000 E FF5A0000 E<br />

FF5C0000 E FF5E0000 E FF600000 E FF620000 E FF640000 E<br />

FF660000 E FF680000 E FF6A0000 E FF6C0000 E FF6E0000 E<br />

FF700000 E FF720000 E FF740000 E FF760000 E FF780000 E<br />

FF7A0000 E FF7C0000 E FF7E0000 E FF800000 E FF820000 E<br />

FF840000 E FF860000 E FF880000 E FF8A0000 E FF8C0000 E<br />

5.9.3.4. protect - enable or disable FLASH write protection 63


FF8E0000 E FF900000 E RO FF920000 E RO FF940000 E RO FF960000 E RO<br />

FF980000 E FF9A0000 E FF9C0000 E FF9E0000 E FFA00000 E<br />

FFA20000 E FFA40000 E FFA60000 E FFA80000 E FFAA0000 E<br />

FFAC0000 E FFAE0000 E FFB00000 E FFB20000 E FFB40000 E<br />

FFB60000 E FFB80000 E FFBA0000 E FFBC0000 E FFBE0000 E<br />

FFC00000 E FFC20000 E FFC40000 E FFC60000 E FFC80000 E<br />

FFCA0000 E FFCC0000 E FFCE0000 E FFD00000 E FFD20000 E<br />

FFD40000 E FFD60000 E FFD80000 E FFDA0000 E FFDC0000 E<br />

FFDE0000 E FFE00000 E FFE20000 E FFE40000 E FFE60000 E<br />

FFE80000 E FFEA0000 E FFEC0000 E FFEE0000 E FFF00000 E<br />

FFF20000 E FFF40000 E FFF60000 RO FFF80000 RO FFFA0000 RO<br />

FFFC0000 RO FFFE0000 RO<br />

=><br />

=> era 1:455<br />

Erase Flash Sectors 455-455 in Bank # 1<br />

. done<br />

=><br />

<strong>The</strong> actual level of protection depends on the flash chips used on your hardware, <strong>and</strong> on the<br />

implementation of the flash device driver <strong>for</strong> this board. In most cases U-<strong>Boot</strong> provides just a simple<br />

software-protection, i. e. it prevents you from erasing or overwriting important stuff by accident (like the<br />

U-<strong>Boot</strong> code itself or U-<strong>Boot</strong>'s environment variables), but it cannot prevent you from circumventing these<br />

restrictions - a nasty user who is loading <strong>and</strong> running his own flash driver code cannot <strong>and</strong> will not be stopped<br />

by this mechanism. Also, in most cases this protection is only effective while running U-<strong>Boot</strong>, i. e. any<br />

operating system will not know about "protected" flash areas <strong>and</strong> will happily erase these if requested to do<br />

so.<br />

5.9.3.5. mtdparts - define a <strong>Linux</strong> compatible MTD partition<br />

scheme<br />

U-<strong>Boot</strong> implements two different approaches to define a MTD partition scheme that can be shared easily with<br />

the linux kernel.<br />

<strong>The</strong> first one is to define a single, static partition in your board config file, <strong>for</strong> example:<br />

#undef CONFIG_JFFS2_CMDLINE<br />

#define CONFIG_JFFS2_DEV<br />

"nor0"<br />

#define CONFIG_JFFS2_PART_SIZE 0xFFFFFFFF /* use whole device */<br />

#define CONFIG_JFFS2_PART_SIZE 0x00100000 /* use 1MB */<br />

#define CONFIG_JFFS2_PART_OFFSET 0x00000000<br />

<strong>The</strong> second method uses the <strong>Linux</strong> kernel's mtdparts comm<strong>and</strong> line option <strong>and</strong> dynamic partitioning:<br />

#define CONFIG_JFFS2_CMDLINE<br />

#define MTDIDS_DEFAULT "nor1=zuma-1,nor2=zuma-2"<br />

#define MTDPARTS_DEFAULT "mtdparts=zuma-1:-(jffs2),zuma-2:-(user)"<br />

Comm<strong>and</strong> line of course produces bigger images, <strong>and</strong> may be inappropriate <strong>for</strong> some targets, so by default it's<br />

off.<br />

<strong>The</strong> mtdparts comm<strong>and</strong> offers an easy to use <strong>and</strong> powerful interface to define the contents of the<br />

environment variable of the same name that can be passed as boot argument to the <strong>Linux</strong> kernel:<br />

=> help mtdparts<br />

mtdparts<br />

- list partition table<br />

mtdparts delall<br />

- delete all partitions<br />

mtdparts del part-id<br />

5.9.3.5. mtdparts - define a <strong>Linux</strong> compatible MTD partition scheme 64


- delete partition (e.g. part-id = n<strong>and</strong>0,1)<br />

mtdparts add [@] [] [ro]<br />

- add partition<br />

mtdparts default<br />

- reset partition table to defaults<br />

-----<br />

this comm<strong>and</strong> uses three environment variables:<br />

'partition' - keeps current partition identifier<br />

partition := <br />

:= ,part_num<br />

'mtdids' - linux kernel mtd device id u-boot device id mapping<br />

mtdids=[,,...]<br />

:= =<br />

:= 'n<strong>and</strong>'|'nor'<br />

:= mtd device number, 0...<br />

:= unique device tag used by linux kernel to find mtd device (mtd->name)<br />

'mtdparts' - partition list<br />

mtdparts=mtdparts=[;...]<br />

:= :[,...]<br />

:= unique device tag used by linux kernel to find mtd device (mtd->name)<br />

:= [@][][]<br />

:= st<strong>and</strong>ard linux memsize OR '-' to denote all remaining space<br />

:= partition start offset within the device<br />

:= '(' NAME ')'<br />

:= when set to 'ro' makes partition read-only (not used, passed to kernel)<br />

For example, on some target system the mtdparts comm<strong>and</strong> might display this in<strong>for</strong>mation:<br />

=> mtdparts<br />

device nor0 , # parts = 4<br />

#: name size offset mask_flags<br />

0: firmware 0x00100000 0x00000000 1<br />

1: kernel 0x00180000 0x00100000 0<br />

2: small-fs 0x00d80000 0x00280000 0<br />

3: big-fs 0x01000000 0x01000000 0<br />

active partition: nor0,0 - (firmware) 0x00100000 @ 0x00000000<br />

defaults:<br />

mtdids : nor0=TQM5200-0<br />

mtdparts: mtdparts=TQM5200-0:1m(firmware),1536k(kernel),3584k(small-fs),2m(initrd),8m(misc),16m(b<br />

<strong>The</strong> partition table printed here obviously differs from the default value <strong>for</strong> the mtdparts variable printed in<br />

the last line. To verify this, we can check the current content of this variable:<br />

=> print mtdparts<br />

mtdparts=mtdparts=TQM5200-0:1024k(firmware)ro,1536k(kernel),13824k(small-fs),16m(big-fs)<br />

<strong>and</strong> we can see that it exactly matches the partition table printed above.<br />

Now let's switch back to the default settings:<br />

5.9.3.5. mtdparts - define a <strong>Linux</strong> compatible MTD partition scheme 65


=> mtdparts default<br />

=> mtdparts<br />

device nor0 , # parts = 6<br />

#: name size offset mask_flags<br />

0: firmware 0x00100000 0x00000000 0<br />

1: kernel 0x00180000 0x00100000 0<br />

2: small-fs 0x00380000 0x00280000 0<br />

3: initrd 0x00200000 0x00600000 0<br />

4: misc 0x00800000 0x00800000 0<br />

5: big-fs 0x01000000 0x01000000 0<br />

active partition: nor0,0 - (firmware) 0x00100000 @ 0x00000000<br />

defaults:<br />

mtdids : nor0=TQM5200-0<br />

mtdparts: mtdparts=TQM5200-0:1m(firmware),1536k(kernel),3584k(small-fs),2m(initrd),8m(misc),16m(b<br />

=> print mtdparts<br />

mtdparts=mtdparts=TQM5200-0:1m(firmware),1536k(kernel),3584k(small-fs),2m(initrd),8m(misc),16m(bi<br />

<strong>The</strong>n we delete the last 4 partitions ("small-fs", "initrd", "misc" <strong>and</strong> "big-fs") ...<br />

=> mtdparts del small-fs<br />

=> mtdparts del initrd<br />

=> mtdparts del misc<br />

=> mtdparts del big-fs<br />

=> mtdparts<br />

device nor0 , # parts = 2<br />

#: name size offset mask_flags<br />

0: firmware 0x00100000 0x00000000 0<br />

1: kernel 0x00180000 0x00100000 0<br />

active partition: nor0,0 - (firmware) 0x00100000 @ 0x00000000<br />

defaults:<br />

mtdids : nor0=TQM5200-0<br />

mtdparts: mtdparts=TQM5200-0:1m(firmware),1536k(kernel),3584k(small-fs),2m(initrd),8m(misc),16m(b<br />

... <strong>and</strong> combine the free space into a singe big partition:<br />

=> mtdparts add nor0 - new-part<br />

=> mtdparts<br />

device nor0 , # parts = 3<br />

#: name size offset mask_flags<br />

0: firmware 0x00100000 0x00000000 0<br />

1: kernel 0x00180000 0x00100000 0<br />

2: new-part 0x01d80000 0x00280000 0<br />

active partition: nor0,0 - (firmware) 0x00100000 @ 0x00000000<br />

defaults:<br />

mtdids : nor0=TQM5200-0<br />

mtdparts: mtdparts=TQM5200-0:1m(firmware),1536k(kernel),3584k(small-fs),2m(initrd),8m(misc),16m(b<br />

=> print mtdparts<br />

mtdparts=mtdparts=TQM5200-0:1m(firmware),1536k(kernel),30208k(new-part)<br />

5.9.4. Execution Control Comm<strong>and</strong>s<br />

5.9.4. Execution Control Comm<strong>and</strong>s 66


5.9.4.1. autoscr - run script from memory<br />

=> help autoscr<br />

autoscr [addr] - run script starting at addr - A valid autoscr header must be present<br />

=><br />

With the autoscr comm<strong>and</strong> you can run "shell" scripts under U-<strong>Boot</strong>: You create a U-<strong>Boot</strong> script image by<br />

simply writing the comm<strong>and</strong>s you want to run into a text file; then you will have to use the mkimage tool to<br />

convert this text file into a U-<strong>Boot</strong> image (using the image type script).<br />

This image can be loaded like any other image file, <strong>and</strong> with autoscr you can run the comm<strong>and</strong>s in such an<br />

image. For instance, the following text file:<br />

echo<br />

echo Network Configuration:<br />

echo ----------------------<br />

echo Target:<br />

printenv ipaddr hostname<br />

echo<br />

echo Server:<br />

printenv serverip rootpath<br />

echo<br />

can be converted into a U-<strong>Boot</strong> script image using the mkimage comm<strong>and</strong> like this:<br />

Now you can load <strong>and</strong> execute this script image in U-<strong>Boot</strong>:<br />

=> tftp 100000 /tftpboot/canyonl<strong>and</strong>s/example.img<br />

ENET Speed is 1000 Mbps - FULL duplex connection (EMAC0)<br />

Using ppc_4xx_eth0 device<br />

TFTP from server 192.168.1.1; our IP address is 192.168.100.6<br />

Filename '/tftpboot/canyonl<strong>and</strong>s/example.img'.<br />

Load address: 0x100000<br />

Loading: *#<br />

done<br />

Bytes transferred = 222 (de hex)<br />

=><br />

=> imi<br />

## Checking Image at 00100000 ...<br />

Legacy image found<br />

Image Name: autoscr example script<br />

Created: 2008-04-02 11:50:54 UTC<br />

Image Type: PowerPC <strong>Linux</strong> Script (uncompressed)<br />

Data Size: 158 Bytes = 0.2 kB<br />

Load Address: 00000000<br />

Entry Point: 00000000<br />

Contents:<br />

Image 0: 150 Bytes = 0.1 kB<br />

Verifying Checksum ... OK<br />

=><br />

=> autoscr 100000<br />

## Executing script at 00100000<br />

Network Configuration:<br />

----------------------<br />

5.9.4.1. autoscr - run script from memory 67


Target:<br />

ipaddr=192.168.100.6<br />

hostname=canyonl<strong>and</strong>s<br />

Server:<br />

serverip=192.168.1.1<br />

rootpath=/opt/eldk/ppc_4xxFP<br />

=><br />

5.9.4.2. bootm - boot application image from memory<br />

=> help bootm<br />

bootm [addr [arg ...]]<br />

- boot application image stored in memory<br />

passing arguments 'arg ...'; when booting a <strong>Linux</strong> kernel,<br />

'arg' can be the address of an initrd image<br />

When booting a <strong>Linux</strong> kernel which requires a flat device-tree<br />

a third argument is required which is the address of the<br />

device-tree blob. To boot that kernel without an initrd image,<br />

use a '-' <strong>for</strong> the second argument. If you do not pass a third<br />

a bd_info struct will be passed instead<br />

=><br />

<strong>The</strong> bootm comm<strong>and</strong> is used to start operating system images. From the image header it gets in<strong>for</strong>mation<br />

about the type of the operating system, the file compression method used (if any), the load <strong>and</strong> entry point<br />

addresses, etc. <strong>The</strong> comm<strong>and</strong> will then load the image to the required memory address, uncompressing it on<br />

the fly if necessary. Depending on the OS it will pass the required boot arguments <strong>and</strong> start the OS at it's entry<br />

point.<br />

<strong>The</strong> first argument to bootm is the memory address (in RAM, ROM or flash memory) where the image is<br />

stored, followed by optional arguments that depend on the OS.<br />

<strong>Linux</strong> requires the flattened device tree blob to be passed at boot time, <strong>and</strong> bootm expects its third<br />

argument to be the address of the blob in memory. Second argument to bootm depens on whether an<br />

initrd initial ramdisk image is to be used. If the kernel should be booted without the initial ramdisk, the<br />

second argument should be given as "-", otherwise it is interpreted as the start address of initrd (in RAM,<br />

ROM or flash memory).<br />

To boot a <strong>Linux</strong> kernel image without a initrd ramdisk image, the following comm<strong>and</strong> can be used:<br />

=> bootm ${kernel_addr} - ${fdt_addr}<br />

If a ramdisk image shall be used, you can type:<br />

=> bootm ${kernel_addr} ${ramdisk_addr} ${fdt_addr}<br />

Both examples of course imply that the variables used are set to correct addresses <strong>for</strong> a kernel, fdt blob <strong>and</strong> a<br />

initrd ramdisk image.<br />

When booting images that have been loaded to RAM (<strong>for</strong> instance using TFTP download) you have to be<br />

careful that the locations where the (compressed) images were stored do not overlap with the memory needed<br />

to load the uncompressed kernel. For instance, if you load a ramdisk image at a location in low memory, it<br />

may be overwritten when the <strong>Linux</strong> kernel gets loaded. This will cause undefined system crashes.<br />

5.9.4.2. bootm - boot application image from memory 68


5.9.4.3. go - start application at address 'addr'<br />

=> help go<br />

go addr [arg ...]<br />

- start application at address 'addr'<br />

passing 'arg' as arguments<br />

=><br />

U-<strong>Boot</strong> has support <strong>for</strong> so-called st<strong>and</strong>alone applications. <strong>The</strong>se are programs that do not require the complex<br />

environment of an operating system to run. Instead they can be loaded <strong>and</strong> executed by U-<strong>Boot</strong> directly,<br />

utilizing U-<strong>Boot</strong>'s service functions like console I/O or malloc() <strong>and</strong> free().<br />

This can be used to dynamically load <strong>and</strong> run special extensions to U-<strong>Boot</strong> like special hardware test routines<br />

or bootstrap code to load an OS image from some filesystem.<br />

<strong>The</strong> go comm<strong>and</strong> is used to start such st<strong>and</strong>alone applications. <strong>The</strong> optional arguments are passed to the<br />

application without modification. For more in<strong>for</strong>matoin see 5.12. U-<strong>Boot</strong> St<strong>and</strong>alone Applications.<br />

5.9.5. Download Comm<strong>and</strong>s<br />

5.9.5.1. bootp - boot image via network using BOOTP/TFTP<br />

protocol<br />

=> help bootp<br />

bootp [loadAddress] [bootfilename]<br />

=><br />

5.9.5.2. dhcp - invoke DHCP client to obtain IP/boot params<br />

=> help dhcp<br />

dhcp<br />

=><br />

5.9.5.3. loadb - load binary file over serial line (kermit mode)<br />

=> help loadb<br />

loadb [ off ] [ baud ]<br />

- load binary file over serial line with offset 'off' <strong>and</strong> baudrate 'baud'<br />

=><br />

With kermit you can download binary data via the serial line. Here we show how to download uImage, the<br />

<strong>Linux</strong> kernel image. Please make sure, that you have set up kermit as described in section 4.3. Configuring<br />

the "kermit" comm<strong>and</strong> <strong>and</strong> then type:<br />

=> loadb 100000<br />

## Ready <strong>for</strong> binary (kermit) download ...<br />

Ctrl-\c<br />

(Back at denx.denx.de)<br />

5.9.5. Download Comm<strong>and</strong>s 69


----------------------------------------------------<br />

C-Kermit 7.0.197, 8 Feb 2000, <strong>for</strong> <strong>Linux</strong><br />

Copyright (C) 1985, 2000,<br />

Trustees of Columbia University in the City of New York.<br />

Type or HELP <strong>for</strong> help.<br />

Kermit> send /bin /tftpboot/pImage<br />

...<br />

Kermit> connect<br />

Connecting to /dev/ttyS0, speed 115200.<br />

<strong>The</strong> escape character is Ctrl-\ (ASCII 28, FS)<br />

Type the escape character followed by C to get back,<br />

or followed by to see other options.<br />

----------------------------------------------------<br />

= 550260 Bytes<br />

## Start Addr = 0x00100000<br />

=> iminfo 100000<br />

## Checking Image at 00100000 ...<br />

Image Name: <strong>Linux</strong>-2.4.4<br />

Created: 2002-07-02 22:10:11 UTC<br />

Image Type: PowerPC <strong>Linux</strong> Kernel Image (gzip compressed)<br />

Data Size: 550196 Bytes = 537 kB = 0 MB<br />

Load Address: 00000000<br />

Entry Point: 00000000<br />

Verifying Checksum ... OK<br />

5.9.5.4. loads - load S-Record file over serial line<br />

=> help loads<br />

loads [ off ] [ baud ]<br />

- load S-Record file over serial line with offset 'off' <strong>and</strong> baudrate 'baud'<br />

=><br />

5.9.5.5. rarpboot- boot image via network using RARP/TFTP<br />

protocol<br />

=> help rarp<br />

rarpboot [loadAddress] [bootfilename]<br />

=><br />

5.9.5.6. tftpboot- boot image via network using TFTP<br />

protocol<br />

=> help tftp<br />

tftpboot [loadAddress] [[hostIPaddr:]bootfilename]<br />

=><br />

5.9.6. Environment Variables Comm<strong>and</strong>s<br />

5.9.6. Environment Variables Comm<strong>and</strong>s 70


5.9.6.1. printenv- print environment variables<br />

=> help printenv<br />

printenv<br />

- print values of all environment variables<br />

printenv name ...<br />

- print value of environment variable 'name'<br />

=><br />

<strong>The</strong> printenv comm<strong>and</strong> prints one, several or all variables of the U-<strong>Boot</strong> environment. When arguments<br />

are given, these are interpreted as the names of environment variables which will be printed with their values:<br />

=> printenv ipaddr hostname netmask<br />

ipaddr=192.168.100.6<br />

hostname=canyonl<strong>and</strong>s<br />

netmask=255.255.0.0<br />

=><br />

Without arguments, printenv prints all a list with all variables in the environment <strong>and</strong> their values, plus<br />

some statistics about the current usage <strong>and</strong> the total size of the memory available <strong>for</strong> the environment.<br />

=> printenv<br />

bootcmd=run flash_self<br />

bootdelay=5<br />

baudrate=115200<br />

loads_echo=1<br />

preboot=echo;echo Type "run flash_nfs" to mount root filesystem over NFS;echo<br />

hostname=canyonl<strong>and</strong>s<br />

rootpath=/opt/eldk/ppc_4xxFP<br />

netdev=eth0<br />

nfsargs=setenv bootargs root=/dev/nfs rw nfsroot=${serverip}:${rootpath}<br />

ramargs=setenv bootargs root=/dev/ram rw<br />

addip=setenv bootargs ${bootargs} ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}:${hostname}:${<br />

addtty=setenv bootargs ${bootargs} console=ttyS0,${baudrate}<br />

flash_self=run ramargs addip addtty;bootm ${kernel_addr} ${ramdisk_addr} ${fdt_addr}<br />

flash_nfs=run nfsargs addip addtty;bootm ${kernel_addr} - ${fdt_addr}<br />

net_nfs=tftp ${kernel_addr_r} ${bootfile}; tftp ${fdt_addr_r} ${fdt_file}; run nfsargs addip addt<br />

kernel_addr_r=400000<br />

initrd_high=30000000<br />

load=tftp 200000 ${hostname}/u-boot.bin<br />

update=protect off fffa0000 ffffffff;era fffa0000 ffffffff;cp.b ${fileaddr} fffa0000 ${filesize};<br />

upd=run load update<br />

nload=tftp 200000 ${hostname}/u-boot-n<strong>and</strong>.bin<br />

nupdate=n<strong>and</strong> erase 0 100000;n<strong>and</strong> write 200000 0 100000;setenv filesize;saveenv<br />

nupd=run nload nupdate<br />

pciconfighost=1<br />

pcie_mode=RP:RP<br />

ethaddr=5e:ed:18:38:81:85<br />

eth1addr=5e:ed:18:38:81:86<br />

ethact=ppc_4xx_eth0<br />

fdt_addr=FC1E0000<br />

fdt_addr_r=00b00000<br />

fdt_file=/tftpboot/canyonl<strong>and</strong>s/canyonl<strong>and</strong>s.dtb<br />

kernel_addr=FC000000<br />

ramdisk_addr=FC200000<br />

stdin=serial<br />

stdout=serial<br />

stderr=serial<br />

ver=U-<strong>Boot</strong> 1.3.3-rc2-01466-g4f27098 (May 1 2008 - 13:57:57)<br />

bootfile=/tftpboot/canyonl<strong>and</strong>s/uImage-duts<br />

5.9.6.1. printenv- print environment variables 71


am_ws=100000<br />

filesize=1A9DC6<br />

fileaddr=100000<br />

netmask=255.255.0.0<br />

ipaddr=192.168.100.6<br />

serverip=192.168.1.1<br />

Environment size: 1647/16379 bytes<br />

=><br />

5.9.6.2. saveenv - save environment variables to persistent<br />

storage<br />

=> help saveenv<br />

saveenv - No help available.<br />

=><br />

All changes you make to the U-<strong>Boot</strong> environment are made in RAM only. <strong>The</strong>y are lost as soon as you reboot<br />

the system. If you want to make your changes permanent you have to use the saveenv comm<strong>and</strong> to write a<br />

copy of the environment settings to persistent storage, from where they are automatically loaded during<br />

startup:<br />

=> saveenv<br />

Saving Environment to Flash...<br />

Un-Protected 1 sectors<br />

Un-Protected 1 sectors<br />

Erasing Flash...<br />

. done<br />

Erased 1 sectors<br />

Writing to Flash... done<br />

Protected 1 sectors<br />

Protected 1 sectors<br />

=><br />

5.9.6.3. setenv - set environment variables<br />

=> help setenv<br />

setenv name value ...<br />

- set environment variable 'name' to 'value ...'<br />

setenv name<br />

- delete environment variable 'name'<br />

=><br />

To modify the U-<strong>Boot</strong> environment you have to use the setenv comm<strong>and</strong>. When called with exactly one<br />

argument, it will delete any variable of that name from U-<strong>Boot</strong>'s environment, if such a variable exists. Any<br />

storage occupied <strong>for</strong> such a variable will be automatically reclaimed:<br />

=> setenv foo This is an example value.<br />

=><br />

=> printenv foo<br />

foo=This is an example value.<br />

=><br />

=> setenv foo<br />

=><br />

=> printenv foo<br />

5.9.6.2. saveenv - save environment variables to persistent storage 72


## Error: "foo" not defined<br />

=><br />

When called with more arguments, the first one will again be the name of the variable, <strong>and</strong> all following<br />

arguments will (concatenated by single space characters) <strong>for</strong>m the value that gets stored <strong>for</strong> this variable. New<br />

variables will be automatically created, existing ones overwritten.<br />

=> printenv bar<br />

## Error: "bar" not defined<br />

=><br />

=> setenv bar This is a new example.<br />

=><br />

=> printenv bar<br />

bar=This is a new example.<br />

=><br />

Remember st<strong>and</strong>ard shell quoting rules when the value of a variable shall contain characters that have a<br />

special meaning to the comm<strong>and</strong> line parser (like the $ character that is used <strong>for</strong> variable substitution or the<br />

semicolon which separates comm<strong>and</strong>s). Use the backslash (\) character to escape such special characters, or<br />

enclose the whole phrase in apstrophes ('). Use "${name}" <strong>for</strong> variable expansion (see 14.2.15. How the<br />

Comm<strong>and</strong> Line Parsing Works <strong>for</strong> details).<br />

=> setenv cons_opts 'console=tty0 console=ttyS0,${baudrate}'<br />

=><br />

=> printenv cons_opts<br />

cons_opts=console=tty0 console=ttyS0,${baudrate}<br />

=><br />

<strong>The</strong>re is no restriction on the characters that can be used in a variable name except the restrictions imposed<br />

by the comm<strong>and</strong> line parser (like using backslash <strong>for</strong> quoting, space <strong>and</strong> tab characters to separate arguments,<br />

or semicolon <strong>and</strong> newline to separate comm<strong>and</strong>s). Even strange input like "=-/|()+=" is a perfectly legal<br />

variable name in U-<strong>Boot</strong>.<br />

A common mistake is to write<br />

setenv name=value<br />

instead of<br />

setenv name value<br />

<strong>The</strong>re will be no error message, which lets you believe everything went OK, but it didn't: instead of setting the<br />

variable name to the value value you tried to delete a variable with the name name=value - this is probably<br />

not what you intended! Always remember that name <strong>and</strong> value have to be separated by space <strong>and</strong>/or tab<br />

characters!<br />

5.9.6.4. run - run comm<strong>and</strong>s in an environment variable<br />

=> help run<br />

run var [...]<br />

- run the comm<strong>and</strong>s in the environment variable(s) 'var'<br />

=><br />

You can use U-<strong>Boot</strong> environment variables to store comm<strong>and</strong>s <strong>and</strong> even sequences of comm<strong>and</strong>s. To execute<br />

5.9.6.3. setenv - set environment variables 73


such a comm<strong>and</strong>, you use the run comm<strong>and</strong>:<br />

=> setenv test echo This is a test;printenv ipaddr;echo Done.<br />

ipaddr=192.168.100.6<br />

Done.<br />

=><br />

=> printenv test<br />

test=echo This is a test<br />

=><br />

=> run test<br />

This is a test<br />

=><br />

You can call run with several variables as arguments, in which case these comm<strong>and</strong>s will be executed in<br />

sequence:<br />

=> setenv test2 echo This is another Test;printenv hostname;echo Done.<br />

hostname=canyonl<strong>and</strong>s<br />

Done.<br />

=><br />

=> printenv test test2<br />

test=echo This is a test<br />

test2=echo This is another Test<br />

=><br />

=> run test test2<br />

This is a test<br />

This is another Test<br />

=><br />

If a U-<strong>Boot</strong> variable contains several comm<strong>and</strong>s (separated by semicolon), <strong>and</strong> one of these comm<strong>and</strong>s<br />

fails when you "run" this variable, the remaining comm<strong>and</strong>s will be executed anyway.<br />

If you execute several variables with one call to run, any failing comm<strong>and</strong> will cause "run" to terminate, i.<br />

e. the remaining variables are not executed.<br />

5.9.6.5. bootd - boot default, i.e., run 'bootcmd'<br />

=> help boot<br />

boot - No help available.<br />

=><br />

<strong>The</strong> bootd (short: boot) executes the default boot comm<strong>and</strong>, i. e. what happens when you don't interrupt<br />

the initial countdown. This is a synonym <strong>for</strong> the run bootcmd comm<strong>and</strong>.<br />

5.9.7. Flattened Device Tree support<br />

U-<strong>Boot</strong> is capable of quite comprehensive h<strong>and</strong>ling of the flattened device tree blob, implemented by the fdt<br />

family of comm<strong>and</strong>s:<br />

=> help fdt<br />

fdt addr [] - Set the fdt location to <br />

fdt boardsetup<br />

- Do board-specific set up<br />

fdt move - Copy the fdt to <strong>and</strong> make it active<br />

fdt print []<br />

- Recursive print starting at <br />

fdt list [] - Print one level starting at <br />

5.9.7. Flattened Device Tree support 74


fdt set [] - Set [to ]<br />

fdt mknode <br />

- Create a new node after <br />

fdt rm [] - Delete the node or <br />

fdt header<br />

- Display header info<br />

fdt bootcpu <br />

- Set boot cpuid<br />

fdt memory <br />

- Add/Update memory node<br />

fdt rsvmem print<br />

- Show current mem reserves<br />

fdt rsvmem add - Add a mem reserve<br />

fdt rsvmem delete <br />

- Delete a mem reserves<br />

fdt chosen - Add/update the /chosen branch in the tree<br />

NOTE: If the path or property you are setting/printing has a '#' character<br />

or spaces, you MUST escape it with a \ character or quote it with ".<br />

=><br />

5.9.7.1. fdt addr - select FDT to work on<br />

First, the blob that is to be operated on should be stored in memory, <strong>and</strong> U-<strong>Boot</strong> has to be in<strong>for</strong>med about its<br />

location by the fdt addr comm<strong>and</strong>. Once this comm<strong>and</strong> has been issued, all subsequent fdt h<strong>and</strong>ling<br />

comm<strong>and</strong>s will use the blob stored at the given address. This address can be changed later on by issuing fdt<br />

addr or fdt move comm<strong>and</strong>. Here's how to load the blob into memory <strong>and</strong> tell U-<strong>Boot</strong> its location:<br />

=> print fdt_addr_r<br />

fdt_addr_r=00b00000<br />

=><br />

=> print fdt_file<br />

fdt_file=/tftpboot/canyonl<strong>and</strong>s/canyonl<strong>and</strong>s.dtb<br />

=><br />

=> tftp ${fdt_addr_r} ${fdt_file}<br />

ENET Speed is 1000 Mbps - FULL duplex connection (EMAC0)<br />

Using ppc_4xx_eth0 device<br />

TFTP from server 192.168.1.1; our IP address is 192.168.100.6<br />

Filename '/tftpboot/canyonl<strong>and</strong>s/canyonl<strong>and</strong>s.dtb'.<br />

Load address: 0xb00000<br />

Loading: *#<br />

done<br />

Bytes transferred = 10000 (2710 hex)<br />

=><br />

=> fdt addr ${fdt_addr_r}<br />

=><br />

5.9.7.2. fdt list - print one level<br />

Having selected the device tree stored in the blob just loaded, we can inspect its contents. As an FDT usually<br />

is quite extensive, it is easier to get in<strong>for</strong>mation about the structure by looking at selected levels rather than<br />

full hierarchies. fdt list allows us to do exactly this. Let's have a look at the hierarchy one level below the<br />

cpus node:<br />

Note: Included topic <strong>DULG</strong>Data_canyonl<strong>and</strong>s.U<strong>Boot</strong>FDTCmdList does not exist yet<br />

5.9.7.3. fdt print - recursive print<br />

To print a complete subtree we use fdt print. In comparison to the previous example it is obvious that the<br />

whole subtree is printed:<br />

=> fdt print /<br />

/ {<br />

#address-cells = ;<br />

5.9.7.1. fdt addr - select FDT to work on 75


#size-cells = ;<br />

model = "amcc,canyonl<strong>and</strong>s";<br />

compatible = "amcc,canyonl<strong>and</strong>s";<br />

dcr-parent = ;<br />

aliases {<br />

ethernet0 = "/plb/opb/ethernet@ef600e00";<br />

ethernet1 = "/plb/opb/ethernet@ef600f00";<br />

serial0 = "/plb/opb/serial@ef600300";<br />

serial1 = "/plb/opb/serial@ef600400";<br />

};<br />

cpus {<br />

#address-cells = ;<br />

#size-cells = ;<br />

cpu@0 {<br />

device_type = "cpu";<br />

model = "PowerPC,460EX";<br />

reg = ;<br />

clock-frequency = ;<br />

timebase-frequency = ;<br />

i-cache-line-size = ;<br />

d-cache-line-size = ;<br />

i-cache-size = ;<br />

d-cache-size = ;<br />

dcr-controller;<br />

dcr-access-method = "native";<br />

linux,ph<strong>and</strong>le = ;<br />

};<br />

};<br />

memory {<br />

device_type = "memory";<br />

reg = ;<br />

};<br />

interrupt-controller0 {<br />

compatible = "ibm,uic-460ex", "ibm,uic";<br />

interrupt-controller;<br />

cell-index = ;<br />

dcr-reg = ;<br />

#address-cells = ;<br />

#size-cells = ;<br />

#interrupt-cells = ;<br />

linux,ph<strong>and</strong>le = ;<br />

};<br />

interrupt-controller1 {<br />

compatible = "ibm,uic-460ex", "ibm,uic";<br />

interrupt-controller;<br />

cell-index = ;<br />

dcr-reg = ;<br />

#address-cells = ;<br />

#size-cells = ;<br />

#interrupt-cells = ;<br />

interrupts = ;<br />

interrupt-parent = ;<br />

linux,ph<strong>and</strong>le = ;<br />

};<br />

interrupt-controller2 {<br />

compatible = "ibm,uic-460ex", "ibm,uic";<br />

interrupt-controller;<br />

cell-index = ;<br />

dcr-reg = ;<br />

#address-cells = ;<br />

#size-cells = ;<br />

#interrupt-cells = ;<br />

interrupts = ;<br />

interrupt-parent = ;<br />

linux,ph<strong>and</strong>le = ;<br />

};<br />

interrupt-controller3 {<br />

5.9.7.3. fdt print - recursive print 76


compatible = "ibm,uic-460ex", "ibm,uic";<br />

interrupt-controller;<br />

cell-index = ;<br />

dcr-reg = ;<br />

#address-cells = ;<br />

#size-cells = ;<br />

#interrupt-cells = ;<br />

interrupts = ;<br />

interrupt-parent = ;<br />

linux,ph<strong>and</strong>le = ;<br />

};<br />

sdr {<br />

compatible = "ibm,sdr-460ex";<br />

dcr-reg = ;<br />

};<br />

cpr {<br />

compatible = "ibm,cpr-460ex";<br />

dcr-reg = ;<br />

};<br />

plb {<br />

compatible = "ibm,plb-460ex", "ibm,plb4";<br />

#address-cells = ;<br />

#size-cells = ;<br />

ranges;<br />

clock-frequency = ;<br />

sdram {<br />

compatible = "ibm,sdram-460ex", "ibm,sdram-405gp";<br />

dcr-reg = ;<br />

};<br />

mcmal {<br />

compatible = "ibm,mcmal-460ex", "ibm,mcmal2";<br />

dcr-reg = ;<br />

num-tx-chans = ;<br />

num-rx-chans = ;<br />

#address-cells = ;<br />

#size-cells = ;<br />

interrupt-parent = ;<br />

interrupts = ;<br />

linux,ph<strong>and</strong>le = ;<br />

};<br />

ehci@bffd0400 {<br />

compatible = "ibm,usb-ehci-460ex", "usb-ehci";<br />

interrupt-parent = ;<br />

interrupts = ;<br />

reg = ;<br />

};<br />

usb@bffd0000 {<br />

compatible = "ohci-le";<br />

reg = ;<br />

interrupt-parent = ;<br />

interrupts = ;<br />

};<br />

usbotg@bff80000 {<br />

compatible = "amcc,usb-otg-460ex";<br />

reg = ;<br />

interrupt-parent = ;<br />

interrupts = ;<br />

#interrupt-cells = ;<br />

#address-cells = ;<br />

#size-cells = ;<br />

interrupt-map = ;<br />

interrupt-map-mask = ;<br />

linux,ph<strong>and</strong>le = ;<br />

};<br />

sata@bffd1000 {<br />

compatible = "amcc,sata-460ex";<br />

reg = ;<br />

5.9.7.3. fdt print - recursive print 77


interrupt-parent = ;<br />

interrupts = ;<br />

};<br />

opb {<br />

compatible = "ibm,opb-460ex", "ibm,opb";<br />

#address-cells = ;<br />

#size-cells = ;<br />

ranges = ;<br />

clock-frequency = ;<br />

ebc {<br />

compatible = "ibm,ebc-460ex", "ibm,ebc";<br />

dcr-reg = ;<br />

#address-cells = ;<br />

#size-cells = ;<br />

clock-frequency = ;<br />

interrupts = ;<br />

interrupt-parent = ;<br />

nor_flash@0,0 {<br />

compatible = "amd,s29gl512n", "cfi-flash";<br />

bank-width = ;<br />

reg = ;<br />

#address-cells = ;<br />

#size-cells = ;<br />

partition@0 {<br />

label = "kernel";<br />

reg = ;<br />

};<br />

partition@1e0000 {<br />

label = "dtb";<br />

reg = ;<br />

};<br />

partition@200000 {<br />

label = "root";<br />

reg = ;<br />

};<br />

partition@400000 {<br />

label = "user";<br />

reg = ;<br />

};<br />

partition@3f60000 {<br />

label = "env";<br />

reg = ;<br />

};<br />

partition@3fa0000 {<br />

label = "u-boot";<br />

reg = ;<br />

};<br />

};<br />

};<br />

serial@ef600300 {<br />

device_type = "serial";<br />

compatible = "ns16550";<br />

reg = ;<br />

virtual-reg = ;<br />

clock-frequency = ;<br />

current-speed = ;<br />

interrupt-parent = ;<br />

interrupts = ;<br />

};<br />

serial@ef600400 {<br />

device_type = "serial";<br />

compatible = "ns16550";<br />

reg = ;<br />

virtual-reg = ;<br />

clock-frequency = ;<br />

current-speed = ;<br />

interrupt-parent = ;<br />

5.9.7.3. fdt print - recursive print 78


interrupts = ;<br />

};<br />

serial@ef600500 {<br />

device_type = "serial";<br />

compatible = "ns16550";<br />

reg = ;<br />

virtual-reg = ;<br />

clock-frequency = ;<br />

current-speed = ;<br />

interrupt-parent = ;<br />

interrupts = ;<br />

};<br />

serial@ef600600 {<br />

device_type = "serial";<br />

compatible = "ns16550";<br />

reg = ;<br />

virtual-reg = ;<br />

clock-frequency = ;<br />

current-speed = ;<br />

interrupt-parent = ;<br />

interrupts = ;<br />

};<br />

i2c@ef600700 {<br />

compatible = "ibm,iic-460ex", "ibm,iic";<br />

reg = ;<br />

interrupt-parent = ;<br />

interrupts = ;<br />

};<br />

i2c@ef600800 {<br />

compatible = "ibm,iic-460ex", "ibm,iic";<br />

reg = ;<br />

interrupt-parent = ;<br />

interrupts = ;<br />

};<br />

emac-zmii@ef600d00 {<br />

compatible = "ibm,zmii-460ex", "ibm,zmii";<br />

reg = ;<br />

};<br />

emac-rgmii@ef601500 {<br />

compatible = "ibm,rgmii-460ex", "ibm,rgmii";<br />

reg = ;<br />

has-mdio;<br />

linux,ph<strong>and</strong>le = ;<br />

};<br />

emac-tah@ef601350 {<br />

compatible = "ibm,tah-460ex", "ibm,tah";<br />

reg = ;<br />

linux,ph<strong>and</strong>le = ;<br />

};<br />

emac-tah@ef601450 {<br />

compatible = "ibm,tah-460ex", "ibm,tah";<br />

reg = ;<br />

linux,ph<strong>and</strong>le = ;<br />

};<br />

ethernet@ef600e00 {<br />

device_type = "network";<br />

compatible = "ibm,emac-460ex", "ibm,emac4";<br />

interrupt-parent = ;<br />

interrupts = ;<br />

#interrupt-cells = ;<br />

#address-cells = ;<br />

#size-cells = ;<br />

interrupt-map = ;<br />

reg = ;<br />

local-mac-address = [00 00 00 00 00 00];<br />

mal-device = ;<br />

mal-tx-channel = ;<br />

5.9.7.3. fdt print - recursive print 79


mal-rx-channel = ;<br />

cell-index = ;<br />

max-frame-size = ;<br />

rx-fifo-size = ;<br />

tx-fifo-size = ;<br />

phy-mode = "rgmii";<br />

phy-map = ;<br />

rgmii-device = ;<br />

rgmii-channel = ;<br />

tah-device = ;<br />

tah-channel = ;<br />

has-inverted-stacr-oc;<br />

has-new-stacr-staopc;<br />

linux,ph<strong>and</strong>le = ;<br />

};<br />

ethernet@ef600f00 {<br />

device_type = "network";<br />

compatible = "ibm,emac-460ex", "ibm,emac4";<br />

interrupt-parent = ;<br />

interrupts = ;<br />

#interrupt-cells = ;<br />

#address-cells = ;<br />

#size-cells = ;<br />

interrupt-map = ;<br />

reg = ;<br />

local-mac-address = [00 00 00 00 00 00];<br />

mal-device = ;<br />

mal-tx-channel = ;<br />

mal-rx-channel = ;<br />

cell-index = ;<br />

max-frame-size = ;<br />

rx-fifo-size = ;<br />

tx-fifo-size = ;<br />

phy-mode = "rgmii";<br />

phy-map = ;<br />

rgmii-device = ;<br />

rgmii-channel = ;<br />

tah-device = ;<br />

tah-channel = ;<br />

has-inverted-stacr-oc;<br />

has-new-stacr-staopc;<br />

mdio-device = ;<br />

linux,ph<strong>and</strong>le = ;<br />

};<br />

};<br />

pci@c0ec00000 {<br />

device_type = "pci";<br />

#interrupt-cells = ;<br />

#size-cells = ;<br />

#address-cells = ;<br />

compatible = "ibm,plb-pcix-460ex", "ibm,plb-pcix";<br />

primary;<br />

large-inbound-windows;<br />

enable-msi-hole;<br />

reg =


};<br />

=><br />

};<br />

};<br />

primary;<br />

port = ;<br />

reg = ;<br />

dcr-reg = ;<br />

sdr-base = ;<br />

ranges = <br />

=> fdt mknode / testnode<br />

=><br />

=> fdt list /<br />

/ {<br />

#address-cells = ;<br />

#size-cells = ;<br />

model = "amcc,canyonl<strong>and</strong>s";<br />

compatible = "amcc,canyonl<strong>and</strong>s";<br />

dcr-parent = ;<br />

testnode {<br />

};<br />

aliases {<br />

};<br />

cpus {<br />

};<br />

5.9.7.4. fdt mknode - create new nodes 81


memory {<br />

};<br />

interrupt-controller0 {<br />

};<br />

interrupt-controller1 {<br />

};<br />

interrupt-controller2 {<br />

};<br />

interrupt-controller3 {<br />

};<br />

sdr {<br />

};<br />

cpr {<br />

};<br />

plb {<br />

};<br />

};<br />

=><br />

=> fdt list /testnode<br />

testnode {<br />

};<br />

=><br />

5.9.7.5. fdt set - set node properties<br />

Now, let's create a property at the newly created node; again we'll use fdt list <strong>for</strong> verification:<br />

=> fdt set /testnode testprop testvalue<br />

=><br />

=> fdt list /testnode<br />

testnode {<br />

testprop = "testvalue";<br />

};<br />

=><br />

5.9.7.6. fdt rm - remove nodes or properties<br />

<strong>The</strong> fdt rm comm<strong>and</strong> is used to remove nodes <strong>and</strong> properties. Let's delete the test property created in the<br />

previous paragraph <strong>and</strong> verify the results:<br />

=> fdt rm /testnode testprop<br />

=><br />

=> fdt list /testnode<br />

testnode {<br />

};<br />

=><br />

=> fdt rm /testnode<br />

=><br />

=> fdt list /<br />

/ {<br />

#address-cells = ;<br />

#size-cells = ;<br />

model = "amcc,canyonl<strong>and</strong>s";<br />

compatible = "amcc,canyonl<strong>and</strong>s";<br />

dcr-parent = ;<br />

aliases {<br />

};<br />

cpus {<br />

};<br />

memory {<br />

};<br />

5.9.7.5. fdt set - set node properties 82


};<br />

=><br />

interrupt-controller0 {<br />

};<br />

interrupt-controller1 {<br />

};<br />

interrupt-controller2 {<br />

};<br />

interrupt-controller3 {<br />

};<br />

sdr {<br />

};<br />

cpr {<br />

};<br />

plb {<br />

};<br />

5.9.7.7. fdt move - move FDT blob to new address<br />

To move the blob from one memory location to another we will use the fdt move comm<strong>and</strong>. Besides<br />

moving the blob, it makes the new address the "active" one - similar to fdt addr:<br />

=> fdt move ${fdt_addr_r} 200000<br />

=><br />

=> fdt list /<br />

/ {<br />

#address-cells = ;<br />

#size-cells = ;<br />

model = "amcc,canyonl<strong>and</strong>s";<br />

compatible = "amcc,canyonl<strong>and</strong>s";<br />

dcr-parent = ;<br />

aliases {<br />

};<br />

cpus {<br />

};<br />

memory {<br />

};<br />

interrupt-controller0 {<br />

};<br />

interrupt-controller1 {<br />

};<br />

interrupt-controller2 {<br />

};<br />

interrupt-controller3 {<br />

};<br />

sdr {<br />

};<br />

cpr {<br />

};<br />

plb {<br />

};<br />

};<br />

=><br />

=> fdt mknod / foobar<br />

=><br />

=> fdt list /<br />

/ {<br />

#address-cells = ;<br />

#size-cells = ;<br />

model = "amcc,canyonl<strong>and</strong>s";<br />

compatible = "amcc,canyonl<strong>and</strong>s";<br />

dcr-parent = ;<br />

foobar {<br />

};<br />

5.9.7.6. fdt rm - remove nodes or properties 83


aliases {<br />

};<br />

cpus {<br />

};<br />

memory {<br />

};<br />

interrupt-controller0 {<br />

};<br />

interrupt-controller1 {<br />

};<br />

interrupt-controller2 {<br />

};<br />

interrupt-controller3 {<br />

};<br />

sdr {<br />

};<br />

cpr {<br />

};<br />

plb {<br />

};<br />

};<br />

=><br />

=> fdt addr ${fdt_addr_r}<br />

=><br />

=> fdt list /<br />

/ {<br />

#address-cells = ;<br />

#size-cells = ;<br />

model = "amcc,canyonl<strong>and</strong>s";<br />

compatible = "amcc,canyonl<strong>and</strong>s";<br />

dcr-parent = ;<br />

aliases {<br />

};<br />

cpus {<br />

};<br />

memory {<br />

};<br />

interrupt-controller0 {<br />

};<br />

interrupt-controller1 {<br />

};<br />

interrupt-controller2 {<br />

};<br />

interrupt-controller3 {<br />

};<br />

sdr {<br />

};<br />

cpr {<br />

};<br />

plb {<br />

};<br />

};<br />

=><br />

5.9.7.8. fdt chosen - fixup dynamic info<br />

One of the modifications made by U-<strong>Boot</strong> to the blob be<strong>for</strong>e passing it to the kernel is the addition of the<br />

/chosen node. <strong>Linux</strong> 2.6 Documentation/powerpc/booting-without-of.txt says that this node is used to store<br />

"some variable environment in<strong>for</strong>mation, like the arguments, or the default input/output devices." To <strong>for</strong>ce<br />

U-<strong>Boot</strong> to add the /chosen node to the current blob, fdt chosen comm<strong>and</strong> can be used. Let's now verify<br />

its operation:<br />

=> fdt list /<br />

5.9.7.7. fdt move - move FDT blob to new address 84


{<br />

#address-cells = ;<br />

#size-cells = ;<br />

model = "amcc,canyonl<strong>and</strong>s";<br />

compatible = "amcc,canyonl<strong>and</strong>s";<br />

dcr-parent = ;<br />

aliases {<br />

};<br />

cpus {<br />

};<br />

memory {<br />

};<br />

interrupt-controller0 {<br />

};<br />

interrupt-controller1 {<br />

};<br />

interrupt-controller2 {<br />

};<br />

interrupt-controller3 {<br />

};<br />

sdr {<br />

};<br />

cpr {<br />

};<br />

plb {<br />

};<br />

};<br />

=><br />

=> fdt chosen<br />

=><br />

=> fdt list /<br />

/ {<br />

#address-cells = ;<br />

#size-cells = ;<br />

model = "amcc,canyonl<strong>and</strong>s";<br />

compatible = "amcc,canyonl<strong>and</strong>s";<br />

dcr-parent = ;<br />

chosen {<br />

};<br />

aliases {<br />

};<br />

cpus {<br />

};<br />

memory {<br />

};<br />

interrupt-controller0 {<br />

};<br />

interrupt-controller1 {<br />

};<br />

interrupt-controller2 {<br />

};<br />

interrupt-controller3 {<br />

};<br />

sdr {<br />

};<br />

cpr {<br />

};<br />

plb {<br />

};<br />

};<br />

=><br />

=> fdt list /chosen<br />

chosen {<br />

};<br />

=><br />

5.9.7.8. fdt chosen - fixup dynamic info 85


Note: fdt boardsetup per<strong>for</strong>ms board-specific blob updates, most commonly setting clock frequencies,<br />

etc. Discovering its operation is left as an excercise <strong>for</strong> the reader.<br />

5.9.8. Special Comm<strong>and</strong>s<br />

5.9.8.1. i2c - I2C sub-system<br />

=> help iprobe<br />

iprobe<br />

-discover valid I2C chip addresses<br />

=><br />

=> help icrc32<br />

icrc32 chip address[.0, .1, .2] count<br />

- compute CRC32 checksum<br />

=><br />

=> help imw<br />

imw chip address[.0, .1, .2] value [count]<br />

- memory write (fill)<br />

=><br />

=> help inm<br />

inm chip address[.0, .1, .2]<br />

- memory modify, read <strong>and</strong> keep address<br />

=><br />

=> help imm<br />

imm chip address[.0, .1, .2]<br />

- memory modify, auto increment address<br />

=><br />

=> help imd<br />

imd chip address[.0, .1, .2] [# of objects]<br />

- i2c memory display<br />

=><br />

=> help iloop<br />

iloop chip address[.0, .1, .2] [# of objects]<br />

- loop, reading a set of addresses<br />

=><br />

5.9.9. Storage devices<br />

This chapter introduces comm<strong>and</strong>s to work with storage devices, i.e. ATA, CF, SATA, SCSI, USB, NAND,<br />

etc. connected to the board.<br />

5.9.10. Miscellaneous Comm<strong>and</strong>s<br />

5.9.10.1. echo - echo args to console<br />

=> help echo<br />

echo [args..]<br />

- echo args to console; \c suppresses newline<br />

5.9.10. Miscellaneous Comm<strong>and</strong>s 86


=><br />

<strong>The</strong> echo comm<strong>and</strong> echoes the arguments to the console:<br />

=> echo <strong>The</strong> quick brown fox jumped over the lazy dog.<br />

<strong>The</strong> quick brown fox jumped over the lazy dog.<br />

=><br />

5.9.10.2. reset - Per<strong>for</strong>m RESET of the CPU<br />

=> help reset<br />

reset - No help available.<br />

=><br />

<strong>The</strong> reset comm<strong>and</strong> reboots the system.<br />

5.9.10.3. sleep - delay execution <strong>for</strong> some time<br />

=> help sleep<br />

sleep N<br />

- delay execution <strong>for</strong> N seconds (N is _decimal_ !!!)<br />

=><br />

<strong>The</strong> sleep comm<strong>and</strong> pauses execution <strong>for</strong> the number of seconds given as the argument:<br />

=> date ; sleep 5 ; date<br />

Date: 2061-22-03 (Wednesday) Time: 11:25:33<br />

Date: 2061-22-03 (Wednesday) Time: 11:25:38<br />

=><br />

5.9.10.4. version - print monitor version<br />

=> help version<br />

version - No help available.<br />

=><br />

You can print the version <strong>and</strong> build date of the U-<strong>Boot</strong> image running on your system using the version<br />

comm<strong>and</strong> (short: vers):<br />

=> version<br />

U-<strong>Boot</strong> 1.3.3-rc2-01466-g4f27098 (May 1 2008 - 13:57:57)<br />

=><br />

5.9.10.5. - alias <strong>for</strong> 'help'<br />

You can use as a short <strong>for</strong>m <strong>for</strong> the help comm<strong>and</strong> (see description above).<br />

5.9.10.1. echo - echo args to console 87


5.10. U-<strong>Boot</strong> Environment Variables<br />

<strong>The</strong> U-<strong>Boot</strong> environment is a block of memory that is kept on persistent storage <strong>and</strong> copied to RAM when<br />

U-<strong>Boot</strong> starts. It is used to store environment variables which can be used to configure the system. <strong>The</strong><br />

environment is protected by a CRC32 checksum.<br />

This section lists the most important environment variables, some of which have a special meaning to U-<strong>Boot</strong>.<br />

You can use these variables to configure the behaviour of U-<strong>Boot</strong> to your liking.<br />

• autoload: if set to "no" (or any string beginning with 'n'), the rarpb, bootp or dhcp comm<strong>and</strong>s<br />

will per<strong>for</strong>m only a configuration lookup from the BOOTP / DHCP server, but not try to load any<br />

image using TFTP.<br />

• autostart: if set to "yes", an image loaded using the rarpb, bootp, dhcp, tftp, disk, or<br />

docb comm<strong>and</strong>s will be automatically started (by internally calling the bootm comm<strong>and</strong>).<br />

• baudrate: a decimal number that selects the console baudrate (in bps). Only a predefined list of<br />

baudrate settings is available.<br />

When you change the baudrate (using the "setenv baudrate ..." comm<strong>and</strong>), U-<strong>Boot</strong> will switch the<br />

baudrate of the console terminal <strong>and</strong> wait <strong>for</strong> a newline which must be entered with the new speed<br />

setting. This is to make sure you can actually type at the new speed. If this fails, you have to reset the<br />

board (which will operate at the old speed since you were not able to saveenv the new settings.)<br />

If no "baudrate" variable is defined, the default baudrate of 115200 is used.<br />

• bootargs: <strong>The</strong> contents of this variable are passed to the <strong>Linux</strong> kernel as boot arguments (aka<br />

"comm<strong>and</strong> line").<br />

• bootcmd: This variable defines a comm<strong>and</strong> string that is automatically executed when the initial<br />

countdown is not interrupted.<br />

This comm<strong>and</strong> is only executed when the variable bootdelay is also defined!<br />

• bootdelay: After reset, U-<strong>Boot</strong> will wait this number of seconds be<strong>for</strong>e it executes the contents of<br />

the bootcmd variable. During this time a countdown is printed, which can be interrupted by pressing<br />

any key.<br />

Set this variable to 0 boot without delay. Be careful: depending on the contents of your bootcmd<br />

variable, this can prevent you from entering interactive comm<strong>and</strong>s again <strong>for</strong>ever!<br />

Set this variable to -1 to disable autoboot.<br />

• bootfile: name of the default image to load with TFTP<br />

• cpuclk: (Only with MPC859 / MPC866 / MPC885 processors) On some processors, the CPU clock<br />

frequency can be adjusted by the user (<strong>for</strong> example to optimize per<strong>for</strong>mance versus power<br />

dissipation). On such systems the cpuclk variable can be set to the desired CPU clock value, in<br />

MHz. If the cpuclk variable exists <strong>and</strong> its value is within the compile-time defined limits<br />

(CFG_866_CPUCLK_MIN <strong>and</strong> CFG_866_CPUCLK_MAX = minimum resp. maximum allowed CPU<br />

clock), then the specified value is used. Otherwise, the default CPU clock value is set.<br />

• ethaddr: Ethernet MAC address <strong>for</strong> first/only ethernet interface (= eth0 in <strong>Linux</strong>).<br />

This variable can be set only once (usually during manufacturing of the board). U-<strong>Boot</strong> refuses to<br />

delete or overwrite this variable once it has been set.<br />

• eth1addr: Ethernet MAC address <strong>for</strong> second ethernet interface (= eth1 in <strong>Linux</strong>).<br />

5.10. U-<strong>Boot</strong> Environment Variables 88


• eth2addr: Ethernet MAC address <strong>for</strong> third ethernet interface (= eth2 in <strong>Linux</strong>).<br />

...<br />

• initrd_high: used to restrict positioning of initrd ramdisk images:<br />

If this variable is not set, initrd images will be copied to the highest possible address in RAM; this is<br />

usually what you want since it allows <strong>for</strong> maximum initrd size. If <strong>for</strong> some reason you want to make<br />

sure that the initrd image is loaded below the CFG_BOOTMAPSZ limit, you can set this environment<br />

variable to a value of "no" or "off" or "0". Alternatively, you can set it to a maximum upper address to<br />

use (U-<strong>Boot</strong> will still check that it does not overwrite the U-<strong>Boot</strong> stack <strong>and</strong> data).<br />

For instance, when you have a system with 16 MB RAM, <strong>and</strong> want to reserve 4 MB from use by<br />

<strong>Linux</strong>, you can do this by adding "mem=12M" to the value of the "bootargs" variable. However, now<br />

you must make sure that the initrd image is placed in the first 12 MB as well - this can be done with<br />

=> setenv initrd_high 00c00000<br />

Setting initrd_high to the highest possible address in your system (0xFFFFFFFF) prevents U-<strong>Boot</strong> from<br />

copying the image to RAM at all. This allows <strong>for</strong> faster boot times, but requires a <strong>Linux</strong> kernel with zero-copy<br />

ramdisk support.<br />

• ipaddr: IP address; needed <strong>for</strong> tftp comm<strong>and</strong><br />

• loadaddr: Default load address <strong>for</strong> comm<strong>and</strong>s like tftp or loads.<br />

• loads_echo: If set to 1, all characters received during a serial download (using the loads<br />

comm<strong>and</strong>) are echoed back. This might be needed by some terminal emulations (like cu), but may as<br />

well just take time on others.<br />

• mtdparts: This variable (usually defined using the mtdparts comm<strong>and</strong>) allows to share a common<br />

MTD partition scheme between U-<strong>Boot</strong> <strong>and</strong> the <strong>Linux</strong> kernel.<br />

• pram: If the "Protected RAM" feature is enabled in your board's configuration, this variable can be<br />

defined to enable the reservation of such "protected RAM", i. e. RAM which is not overwritten by<br />

U-<strong>Boot</strong>. Define this variable to hold the number of kB you want to reserve <strong>for</strong> pRAM. Note that the<br />

board info structure will still show the full amount of RAM. If pRAM is reserved, a new environment<br />

variable "mem" will automatically be defined to hold the amount of remaining RAM in a <strong>for</strong>m that<br />

can be passed as boot argument to <strong>Linux</strong>, <strong>for</strong> instance like that:<br />

=> setenv bootargs ${bootargs} mem=\${mem}<br />

=> saveenv<br />

This way you can tell <strong>Linux</strong> not to use this memory, either, which results in a memory region that will not be<br />

affected by reboots.<br />

• serverip: TFTP server IP address; needed <strong>for</strong> tftp comm<strong>and</strong>.<br />

• serial#: contains hardware identification in<strong>for</strong>mation such as type string <strong>and</strong>/or serial number.<br />

This variable can be set only once (usually during manufacturing of the board). U-<strong>Boot</strong> refuses to<br />

delete or overwrite this variable once it hass been set.<br />

• silent: If the configuration option CONFIG_SILENT_CONSOLE has been enabled <strong>for</strong> your board,<br />

setting this variable to any value will suppress all console messages. Please see<br />

doc/README.silent <strong>for</strong> details.<br />

5.10. U-<strong>Boot</strong> Environment Variables 89


• verify: If set to n or no disables the checksum calculation over the complete image in the bootm<br />

comm<strong>and</strong> to trade speed <strong>for</strong> safety in the boot process. Note that the header checksum is still verified.<br />

<strong>The</strong> following environment variables may be used <strong>and</strong> automatically updated by the network boot comm<strong>and</strong>s<br />

(bootp, dhcp, or tftp), depending the in<strong>for</strong>mation provided by your boot server:<br />

• bootfile: see above<br />

• dnsip: IP address of your Domain Name Server<br />

• gatewayip: IP address of the Gateway (Router) to use<br />

• hostname: Target hostname<br />

• ipaddr: see above<br />

• netmask: Subnet Mask<br />

• rootpath: Pathname of the root filesystem on the NFS server<br />

• serverip: see above<br />

• filesize: Size (as hex number in bytes) of the file downloaded using the last bootp, dhcp, or<br />

tftp comm<strong>and</strong>.<br />

5.11. U-<strong>Boot</strong> Scripting Capabilities<br />

U-<strong>Boot</strong> allows to store comm<strong>and</strong>s or comm<strong>and</strong> sequences in a plain text file. Using the mkimage tool you<br />

can then convert this file into a script image which can be executed using U-<strong>Boot</strong>'s autoscr comm<strong>and</strong>.<br />

For example, assume that you will have to run the following sequence of comm<strong>and</strong>s on many boards, so you<br />

store them in a text file, say "setenv-comm<strong>and</strong>s":<br />

bash$ cat setenv-comm<strong>and</strong>s<br />

setenv loadaddr 00200000<br />

echo ===== U-<strong>Boot</strong> settings =====<br />

setenv u-boot /tftpboot/TQM860L/u-boot.bin<br />

setenv u-boot_addr 40000000<br />

setenv load_u-boot 'tftp ${loadaddr} ${u-boot}'<br />

setenv install_u-boot 'protect off ${u-boot_addr} +${filesize};era ${u-boot_addr} +${filesize};cp<br />

setenv update_u-boot run load_u-boot install_u-boot<br />

echo ===== <strong>Linux</strong> Kernel settings =====<br />

setenv bootfile /tftpboot/TQM860L/uImage<br />

setenv kernel_addr 40040000<br />

setenv load_kernel 'tftp ${loadaddr} ${bootfile};'<br />

setenv install_kernel 'era ${kernel_addr} +${filesize};cp.b ${loadaddr} ${kernel_addr} ${filesize<br />

setenv update_kernel run load_kernel install_kernel<br />

echo ===== Ramdisk settings =====<br />

setenv ramdisk /tftpboot/TQM860L/uRamdisk<br />

setenv ramdisk_addr 40100000<br />

setenv load_ramdisk 'tftp ${loadaddr} ${ramdisk};'<br />

setenv install_ramdisk 'era ${ramdisk_addr} +${filesize};cp.b ${loadaddr} ${ramdisk_addr} ${files<br />

setenv update_ramdisk run load_ramdisk install_ramdisk<br />

echo ===== Save new definitions =====<br />

saveenv<br />

bash$<br />

To convert the text file into a script image <strong>for</strong> U-<strong>Boot</strong>, you have to use the mkimage tool as follows:<br />

bash$ mkimage -T script -C none -n 'Demo Script File' -d setenv-comm<strong>and</strong>s setenv.img<br />

Image Name: Demo Script File<br />

Created: Mon Jun 6 13:33:14 2005<br />

Image Type: PowerPC <strong>Linux</strong> Script (uncompressed)<br />

Data Size: 1147 Bytes = 1.12 kB = 0.00 MB<br />

Load Address: 0x00000000<br />

Entry Point: 0x00000000<br />

5.11. U-<strong>Boot</strong> Scripting Capabilities 90


Contents:<br />

Image 0: 1139 Bytes = 1 kB = 0 MB<br />

bash$<br />

On the target, you can download this image as usual (<strong>for</strong> example, using the "tftp" comm<strong>and</strong>). Use the<br />

"autoscr" comm<strong>and</strong> to execute it:<br />

=> tftp 100000 /tftpboot/TQM860L/setenv.img<br />

Using FEC ETHERNET device<br />

TFTP from server 192.168.3.1; our IP address is 192.168.3.80<br />

Filename '/tftpboot/TQM860L/setenv.img'.<br />

Load address: 0x100000<br />

Loading: #<br />

done<br />

Bytes transferred = 1211 (4bb hex)<br />

=> imi 100000<br />

## Checking Image at 00100000 ...<br />

Image Name: Demo Script File<br />

Created: 2005-06-06 11:33:14 UTC<br />

Image Type: PowerPC <strong>Linux</strong> Script (uncompressed)<br />

Data Size: 1147 Bytes = 1.1 kB<br />

Load Address: 00000000<br />

Entry Point: 00000000<br />

Verifying Checksum ... OK<br />

=> autoscr 100000<br />

## Executing script at 00100000<br />

===== U-<strong>Boot</strong> settings =====<br />

===== <strong>Linux</strong> Kernel settings =====<br />

===== Ramdisk settings =====<br />

===== Save new definitions =====<br />

Saving Environment to Flash...<br />

Un-Protected 1 sectors<br />

Un-Protected 1 sectors<br />

Erasing Flash...<br />

. done<br />

Erased 1 sectors<br />

Writing to Flash... done<br />

Protected 1 sectors<br />

Protected 1 sectors<br />

=><br />

Hint: maximum flexibility can be achieved if you are using the Hush shell as comm<strong>and</strong> interpreter in<br />

U-<strong>Boot</strong>; see section 14.2.15. How the Comm<strong>and</strong> Line Parsing Works<br />

5.12. U-<strong>Boot</strong> St<strong>and</strong>alone Applications<br />

U-<strong>Boot</strong> supports "st<strong>and</strong>alone" applications, which are loaded dynamically; these applications can have access<br />

to the U-<strong>Boot</strong> console I/O functions, memory allocation <strong>and</strong> interrupt services.<br />

A couple of simple examples are included with the U-<strong>Boot</strong> source code:<br />

5.12.1. "Hello World" Demo<br />

examples/hello_world.c contains a small "Hello World" Demo application; it is automatically compiled when<br />

you build U-<strong>Boot</strong>. It's configured to run at address 0x00040004, so you can play with it like that:<br />

=> loads<br />

## Ready <strong>for</strong> S-Record download ...<br />

~>examples/hello_world.srec<br />

1 2 3 4 5 6 7 8 9 10 11 ...<br />

5.12. U-<strong>Boot</strong> St<strong>and</strong>alone Applications 91


[file transfer complete]<br />

[connected]<br />

## Start Addr = 0x00040004<br />

=> go 40004 Hello World! This is a test.<br />

## Starting application at 0x00040004 ...<br />

Hello World<br />

argc = 7<br />

argv[0] = "40004"<br />

argv[1] = "Hello"<br />

argv[2] = "World!"<br />

argv[3] = "This"<br />

argv[4] = "is"<br />

argv[5] = "a"<br />

argv[6] = "test."<br />

argv[7] = ""<br />

Hit any key to exit ...<br />

## Application terminated, rc = 0x0<br />

Alternatively, you can of course use TFTP to download the image over the network. In this case the binary<br />

image (hello_world.bin) is used.<br />

Note that the entry point of the program is at offset 0x0004 from the start of file, i. e. the download address<br />

<strong>and</strong> the entry point address differ by four bytes.<br />

=> tftp 40000 /tftpboot/hello_world.bin<br />

...<br />

=> go 40004 This is another test.<br />

## Starting application at 0x00040004 ...<br />

Hello World<br />

argc = 5<br />

argv[0] = "40004"<br />

argv[1] = "This"<br />

argv[2] = "is"<br />

argv[3] = "another"<br />

argv[4] = "test."<br />

argv[5] = ""<br />

Hit any key to exit ...<br />

## Application terminated, rc = 0x0<br />

5.12.2. Timer Demo<br />

This example is only available on MPC8xx CPUs.<br />

This example, which demonstrates how to register a CPM interrupt h<strong>and</strong>ler with the U-<strong>Boot</strong> code, can be<br />

found in examples/timer.c. Here, a CPM timer is set up to generate an interrupt every second. <strong>The</strong> interrupt<br />

service routine is trivial, just printing a '.' character, but this is just a demo program. <strong>The</strong> application can be<br />

controlled by the following keys:<br />

- print current values og the CPM Timer registers<br />

b - enable interrupts <strong>and</strong> start timer<br />

e - stop timer <strong>and</strong> disable interrupts<br />

q - quit application<br />

=> loads<br />

## Ready <strong>for</strong> S-Record download ...<br />

~>examples/timer.srec<br />

1 2 3 4 5 6 7 8 9 10 11 ...<br />

[file transfer complete]<br />

5.12.1. "Hello World" Demo 92


[connected]<br />

## Start Addr = 0x00040004<br />

=> go 40004<br />

## Starting application at 0x00040004 ...<br />

TIMERS=0xfff00980<br />

Using timer 1<br />

tgcr @ 0xfff00980, tmr @ 0xfff00990, trr @ 0xfff00994, tcr @ 0xfff00998, tcn @ 0xfff0099c, t<br />

Hit 'b':<br />

[q, b, e, ] Set interval 1000000 us<br />

Enabling timer<br />

Hit '':<br />

[q, b, e, ] ........<br />

tgcr=0x1, tmr=0xff1c, trr=0x3d09, tcr=0x0, tcn=0xef6, ter=0x0<br />

Hit '':<br />

[q, b, e, ] .<br />

tgcr=0x1, tmr=0xff1c, trr=0x3d09, tcr=0x0, tcn=0x2ad4, ter=0x0<br />

Hit '':<br />

[q, b, e, ] .<br />

tgcr=0x1, tmr=0xff1c, trr=0x3d09, tcr=0x0, tcn=0x1efc, ter=0x0<br />

Hit '':<br />

[q, b, e, ] .<br />

tgcr=0x1, tmr=0xff1c, trr=0x3d09, tcr=0x0, tcn=0x169d, ter=0x0<br />

Hit 'e':<br />

[q, b, e, ] ...Stopping timer<br />

Hit 'q':<br />

[q, b, e, ] ## Application terminated, rc = 0x0<br />

5.13. U-<strong>Boot</strong> Image Formats<br />

U-<strong>Boot</strong> operates on "image" files which can be basically anything, preceeded by a special header; see the<br />

definitions in include/image.h <strong>for</strong> details; basically, the header defines the following image properties:<br />

• Target Operating System (Provisions <strong>for</strong> OpenBSD, NetBSD, FreeBSD, 4.4BSD, <strong>Linux</strong>, SVR4, Esix,<br />

Solaris, Irix, SCO, Dell, NCR, LynxOS, pSOS, QNX, RTEMS, ARTOS, Unity OS; Currently<br />

supported: <strong>Linux</strong>, NetBSD, VxWorks, QNX, RTEMS, ARTOS, Unity OS).<br />

• Target CPU Architecture (Provisions <strong>for</strong> Alpha, ARM, Intel x86, IA64, MIPS, MIPS, PowerPC, IBM<br />

S390, SuperH, Sparc, Sparc 64 Bit, M68K, NIOS; Currently supported: ARM, PowerPC, MIPS,<br />

MIPS64, M68K, NIOS).<br />

• Compression Type (Provisions <strong>for</strong> uncompressed, gzip, bzip2; Currently supported: uncompressed,<br />

gzip, bzip2).<br />

• Load Address<br />

• Entry Point<br />

• Image Name<br />

• Image Timestamp<br />

<strong>The</strong> header is marked by a special Magic Number, <strong>and</strong> both the header <strong>and</strong> the data portions of the image are<br />

secured against corruption by CRC32 checksums.<br />

5.13. U-<strong>Boot</strong> Image Formats 93


5.14. U-<strong>Boot</strong> Advanced Features<br />

5.14.1. <strong>Boot</strong> Count Limit<br />

<strong>The</strong> Open Source Development Labs Carrier Grade <strong>Linux</strong> Requirements Definition version 2.0<br />

(http://www.osdl.org/docs/carrier_grade_linux_requirements_definition___version_20_final_public_draft.pdf)<br />

contains the following requirement definition (ID PLT.4.0, p. 44):<br />

CGL shall provide support <strong>for</strong> detecting a repeating reboot cycle due to recurring failures <strong>and</strong> will go to an<br />

offline state if this occurs.<br />

This feature is available in U-<strong>Boot</strong> if you enable the CONFIG_BOOTCOUNT_LIMIT configuration option.<br />

<strong>The</strong> implementation uses the following environment variables:<br />

bootcount:<br />

This variable will be automatically created if it does not exist, <strong>and</strong> it will be updated at each reset of<br />

the processor. After a power-on reset, it will be initialized with 1, <strong>and</strong> each reboot will increment the<br />

value by 1.<br />

bootlimit:<br />

If this variable exists, its contents are taken as the maximum number of reboot cycles allowed.<br />

altbootcmd:<br />

If, after a reboot, the new value of bootcount exceeds the value of bootlimit, then instead of<br />

the st<strong>and</strong>ard boot action (executing the contents of bootcmd) an alternate boot action will be<br />

per<strong>for</strong>med, <strong>and</strong> the contents of altbootcmd will be executed.<br />

If the variable bootlimit is not defined in the environment, the <strong>Boot</strong> Count Limit feature is disabled. If it is<br />

enabled, but altbootcmd is not defined, then U-<strong>Boot</strong> will drop into interactive mode <strong>and</strong> remain there.<br />

It is the responsibility of some application code (typically a <strong>Linux</strong> application) to reset the variable<br />

bootcount, thus allowing <strong>for</strong> more boot cycles.<br />

At the moment, the <strong>Boot</strong> Count Limit feature is available only <strong>for</strong> MPC8xx <strong>and</strong> MPC82xx PowerPC<br />

processors.<br />

• uboot<strong>Boot</strong>countAccess.c: C-source: bootcount access through /proc file system<br />

5.14.2. Bitmap Support<br />

By adding the CFG_CMD_BMP option to your CONFIG_COMMANDS comm<strong>and</strong> selections you can enable<br />

support <strong>for</strong> bitmap images in U-<strong>Boot</strong>. This will add bmp to the list of comm<strong>and</strong>s in your configuration of<br />

U-<strong>Boot</strong>:<br />

=> help bmp<br />

bmp info - display image info<br />

bmp display - display image<br />

This comm<strong>and</strong> can be used to show in<strong>for</strong>mation about bitmap images or to display the images on your screen.<br />

Example:<br />

5.14.2. Bitmap Support 94


=> tftp 100000 /tftpboot/LWMON/denk_startup.bmp<br />

TFTP from server 192.168.3.1; our IP address is 192.168.3.74<br />

Filename '/tftpboot/LWMON/denk_startup.bmp'.<br />

Load address: 0x100000<br />

Loading: #############################################################<br />

done<br />

Bytes transferred = 308278 (4b436 hex)<br />

=> bmp info 100000<br />

Image size : 640 x 480<br />

Bits per pixel: 8<br />

Compression : 0<br />

=> bmp display 100000<br />

To keep the code in U-<strong>Boot</strong> simple <strong>and</strong> as fast as possible, the bitmap images must match the color depth of<br />

your framebuffer device. For example, if your display is configured <strong>for</strong> a color depth of 8 bpp (bit per pixel)<br />

then the bmp comm<strong>and</strong> will complain if you try to load images with a different color depth:<br />

=> tftp 100000 /tftpboot/LWMON/Bergkirchen.bmp<br />

TFTP from server 192.168.3.1; our IP address is 192.168.3.74<br />

Filename '/tftpboot/LWMON/Bergkirchen.bmp'.<br />

Load address: 0x100000<br />

Loading: #################################################################<br />

#################################################################<br />

###################################################<br />

done<br />

Bytes transferred = 921654 (e1036 hex)<br />

=> bmp i 100000<br />

Image size : 640 x 480<br />

Bits per pixel: 24<br />

Compression : 0<br />

=> bmp d 100000<br />

Error: 8 bit/pixel mode, but BMP has 24 bit/pixel<br />

(As you can see above, the sub-comm<strong>and</strong>s "info" <strong>and</strong> "display" can be abbreviated as "i" resp. "d" .)<br />

Images that are bigger than your framebuffer device will be clipped on the top <strong>and</strong> right h<strong>and</strong> side.<br />

Images that are smaller than the display will be loaded into the top left corner.<br />

Since loading an image will define a new color map, the remainder of the display will appear with<br />

incorrect colors. It is there<strong>for</strong>e recommended that all images match exactly the size of the current display<br />

device. We accepted these restrictions since speed was top priority, <strong>and</strong> all attempts to implement scaling or<br />

optimizing the color maps would slow down the display too much. It is much easier to per<strong>for</strong>m the necessary<br />

trans<strong>for</strong>mations on the development host, where a plethora of tools is available.<br />

For example, to convert existing images to bitmap files with the required color depth (here: 8 bpp), the<br />

"PBM" -Tools can be used (PBM = portable pix map - see "man 5 ppm" ):<br />

bash$ jpegtopnm Bergkirchen.jpg | \<br />

> ppmquant 256 | \<br />

> ppmtobmp -bpp 8 >Bergkirchen-8bit.bmp<br />

jpegtopnm: WRITING PPM FILE<br />

ppmquant: making histogram...<br />

ppmquant: too many colors!<br />

ppmquant: scaling colors from maxval=255 to maxval=127 to improve clustering...<br />

ppmquant: making histogram...<br />

ppmquant: too many colors!<br />

ppmquant: scaling colors from maxval=127 to maxval=63 to improve clustering...<br />

ppmquant: making histogram...<br />

ppmquant: 9760 colors found<br />

ppmquant: choosing 256 colors...<br />

ppmquant: mapping image to new colors...<br />

5.14.2. Bitmap Support 95


ppmtobmp: analyzing colors...<br />

ppmtobmp: 231 colors found<br />

ppmtobmp: Writing 8 bits per pixel with a color pallette<br />

This gives the following results on the target:<br />

=> tftp 100000 /tftpboot/LWMON/Bergkirchen-8bit.bmp<br />

TFTP from server 192.168.3.1; our IP address is 192.168.3.74<br />

Filename '/tftpboot/LWMON/Bergkirchen-8bit.bmp'.<br />

Load address: 0x100000<br />

Loading: #############################################################<br />

done<br />

Bytes transferred = 308278 (4b436 hex)<br />

=> bmp i 100000<br />

Image size : 640 x 480<br />

Bits per pixel: 8<br />

Compression : 0<br />

=> bmp d 100000<br />

5.14.3. Splash Screen Support<br />

Even if you manage to boot U-<strong>Boot</strong> <strong>and</strong> <strong>Linux</strong> into a graphical user application within 5 or 6 seconds of<br />

power-on (which is not difficult), many customers expect to see "something" immediately. U-<strong>Boot</strong> supports<br />

the concept of a splash screen <strong>for</strong> such purposes.<br />

To enable splash screen support, you have to add a "#define CONFIG_SPLASH_SCREEN" to your board<br />

configuration file. This will also implicitly enable U-<strong>Boot</strong> Bitmap Support.<br />

After power-on, U-<strong>Boot</strong> will test if the environment variable "splashimage" is defined, <strong>and</strong> if it contains<br />

the address of a valid bitmap image. If this is the case, the normal startup messages will be suppressed <strong>and</strong> the<br />

defined splash screen will be displayed instead. Also, all output (devices stdout <strong>and</strong> stderr ) will be<br />

suppressed (redirected to the "nulldev" device).<br />

For example, to install this feature on a system, proceed as follows:<br />

=> tftp 100000 /tftpboot/denx_startup.bmp<br />

TFTP from server 192.168.3.1; our IP address is 192.168.3.74<br />

Filename '/tftpboot/denx_startup.bmp'.<br />

Load address: 0x100000<br />

Loading: #############################################################<br />

done<br />

Bytes transferred = 308278 (4b436 hex)<br />

=> cp.b 100000 41F80000 $filesize<br />

Copy to Flash... done<br />

=> setenv splashimage 41F80000<br />

=> saveenv<br />

Saving Environment to Flash...<br />

Un-Protected 1 sectors<br />

Erasing Flash...<br />

. done<br />

Erased 1 sectors<br />

Writing to Flash... done<br />

Protected 1 sectors<br />

=> bmp info $splashimage<br />

Image size : 640 x 480<br />

Bits per pixel: 8<br />

Compression : 0<br />

Note that, <strong>for</strong> perfect operation, this option has to be complemented by matching Splash Screen Support in<br />

5.14.3. Splash Screen Support 96


<strong>Linux</strong>.<br />

• 6. Embedded <strong>Linux</strong> Configuration<br />

♦ 6.1. Download <strong>and</strong> Unpack the <strong>Linux</strong> Kernel Sources<br />

♦ 6.2. Kernel Configuration <strong>and</strong> Compilation<br />

♦ 6.3. Installation<br />

6. Embedded <strong>Linux</strong> Configuration<br />

6.1. Download <strong>and</strong> Unpack the <strong>Linux</strong> Kernel Sources<br />

You can download the <strong>Linux</strong> Kernel Sources from our anonymous git server at http://git.denx.de/. To<br />

checkout the module <strong>for</strong> the first time, proceed as follows:<br />

bash$ cd /opt/eldk/usr/src<br />

bash$ git clone git://git.denx.de/linux-2.6-denx.git linux-2.6-denx<br />

bash$ cd linux-2.6-denx<br />

6.2. Kernel Configuration <strong>and</strong> Compilation<br />

<strong>The</strong> canyonl<strong>and</strong>s board is fully supported by <strong>DENX</strong> Software Engineering. This means that you will always<br />

be able to build a working default configuration with just minimal interaction.<br />

Please be aware that you will need the "powerpc" cross development tools <strong>for</strong> the following steps. Make sure<br />

that the directory which contains the binaries of your ELDK are in your PATH.<br />

To be sure that no intermediate results of previous builds are left in your <strong>Linux</strong> kernel source tree you can<br />

clean it up as follows:<br />

bash$ make mrproper<br />

<strong>The</strong> following comm<strong>and</strong> selects a st<strong>and</strong>ard configuration <strong>for</strong> the canyonl<strong>and</strong>s board that has been extensively<br />

tested. It is recommended to use this as a starting point <strong>for</strong> other, customized configurations:<br />

bash$ make ARCH=powerpc CROSS_COMPILE=ppc_4xx- canyonl<strong>and</strong>s_defconfig<br />

Note: <strong>The</strong> name of this default configuration file is arch/powerpc/configs/XXX_defconfig . By<br />

listing the contents of the arch/powerpc/configs/ directory you can easily find out which other default<br />

configurations are available.<br />

If you don't want to change the default configuration you can now continue to use it to build a kernel image:<br />

bash$ make ARCH=powerpc CROSS_COMPILE=ppc_4xx- uImage<br />

Otherwise you can modify the kernel configuration as follows:<br />

bash$ make ARCH=powerpc CROSS_COMPILE=ppc_4xx- config<br />

or<br />

bash$ make ARCH=powerpc CROSS_COMPILE=ppc_4xx- menuconfig<br />

6. Embedded <strong>Linux</strong> Configuration 97


Note: Because of problems (especially with some older <strong>Linux</strong> kernel versions) the use of "make xconfig"<br />

is not recommended.<br />

bash$ make ARCH=powerpc CROSS_COMPILE=ppc_4xx- uImage<br />

<strong>The</strong> make target uImage uses the tool mkimage (from the U-<strong>Boot</strong> package) to create a <strong>Linux</strong> kernel image in<br />

arch/powerpc/boot/uImage<br />

which is immediately usable <strong>for</strong> download <strong>and</strong> booting with U-<strong>Boot</strong>.<br />

In case you configured modules you will also need to compile the modules:<br />

make ARCH=powerpc CROSS_COMPILE=ppc_4xx- modules<br />

add install the modules (make sure to pass the correct root path <strong>for</strong> module installation):<br />

bash$ make ARCH=powerpc CROSS_COMPILE=ppc_4xx- INSTALL_MOD_PATH=/opt/eldk-4.2/ppc_4xx modules_ins<br />

6.3. Installation<br />

For now it is sufficient to copy the <strong>Linux</strong> kernel image into the directory used by your TFTP server:<br />

bash$ cp arch/powerpc/boot/uImage /tftpboot/uImage<br />

• 7. <strong>Boot</strong>ing Embedded <strong>Linux</strong><br />

♦ 7.1. Introduction<br />

♦ 7.2. Flattened Device Tree Blob<br />

♦ 7.3. Passing Kernel Arguments<br />

♦ 7.4. <strong>Boot</strong> Arguments Unleashed<br />

♦ 7.5. Networked Operation with Root Filesystem over NFS<br />

◊ 7.5.1. <strong>Boot</strong>log of <strong>Linux</strong> kernel with Root Filesystem over NFS<br />

♦ 7.6. <strong>Boot</strong> from Flash Memory<br />

♦ 7.7. St<strong>and</strong>alone Operation with Ramdisk Image<br />

7. <strong>Boot</strong>ing Embedded <strong>Linux</strong><br />

7.1. Introduction<br />

In principle, if you have a <strong>Linux</strong> kernel image <strong>and</strong> the flattened device tree blob somewhere in system<br />

memory (RAM, ROM, flash...), then all you need to boot the system is the bootm comm<strong>and</strong>. Assume a<br />

<strong>Linux</strong> kernel image has been stored at address 0xFC000000 <strong>and</strong> the flattened device tree blob has been stored<br />

at address 0xFC1E0000 - then you can boot this image with the following comm<strong>and</strong>:<br />

=> bootm FC000000 - FC1E0000<br />

7.2. Flattened Device Tree Blob<br />

<strong>Linux</strong> kernel expects certain in<strong>for</strong>mation on the hardware that it runs on. For kernels compiled with<br />

ARCH=powerpc, this in<strong>for</strong>mation has the <strong>for</strong>m of a device tree, which is based on the Open Firmware<br />

7.2. Flattened Device Tree Blob 98


specification. <strong>Boot</strong>loaders like U-<strong>Boot</strong> that do not implement the Open Firmware API, are expected to pass to<br />

the kernel a binary <strong>for</strong>m of the flattened device tree, commonly referred to as FDT blob or simply the blob.<br />

Device trees are defined in human-readable text files, which are part of the <strong>Linux</strong> 2.6 source tree. Device tree<br />

source <strong>for</strong> the canyonl<strong>and</strong>s board is found in arch/powerpc/boot/dts/canyonl<strong>and</strong>s.dts file.<br />

Be<strong>for</strong>e the device tree can be passed to the kernel, it has to be compiled to the binary <strong>for</strong>m by the dtc<br />

compiler. Current version of the dtc compiler is maintained at, <strong>and</strong> can be downloaded from,<br />

http://www.jdl.com/. It is also included with ELDK 4.2. Here's how to compile the blob <strong>for</strong> canyonl<strong>and</strong>s:<br />

dtc -b 0 -V 17 -p 0x1000 -I dts -O dtb -f arch/powerpc/boot/dts/canyonl<strong>and</strong>s.dts > /tftpboot/canyo<br />

After the blob has been compiled, it has to be transferred to target's memory, <strong>for</strong> example over the TFTP<br />

protocol using U-<strong>Boot</strong>'s tftp comm<strong>and</strong>. <strong>The</strong>n, the blob is passed to the kernel by the bootm comm<strong>and</strong>, <strong>and</strong><br />

its address in memory is one of the arguments to bootm - refer to the description of this comm<strong>and</strong> in<br />

U<strong>Boot</strong>CmdGroupExec <strong>for</strong> more details. Note that U-<strong>Boot</strong> makes some automatic modifications to the blob<br />

be<strong>for</strong>e passing it to the kernel - mainly adding <strong>and</strong> modifying in<strong>for</strong>mation that is learnt at run-time.<br />

U-<strong>Boot</strong> also has provisions to alter a flattened device tree in arbitrary ways from the comm<strong>and</strong> line, refer to<br />

the description of the fdt comm<strong>and</strong>s found in U<strong>Boot</strong>CmdGroupMisc.<br />

Notes:<br />

• Flattened Device Tree custodian's page at http://www.denx.de/wiki/U-<strong>Boot</strong>/U<strong>Boot</strong>FdtInfo contains<br />

useful in<strong>for</strong>mation, <strong>and</strong> a number of references.<br />

• At the time of this writing (September 2007) blob h<strong>and</strong>ling is still a very fresh feature <strong>and</strong> undergonig<br />

frequent changes. Reader is encouraged to watch the u-boot-users <strong>and</strong> linuxppc-dev mailing<br />

lists <strong>for</strong> important news (required version of the dtc compiler, blob compilation options, flattened<br />

device tree source file structure, etc.).<br />

7.3. Passing Kernel Arguments<br />

In nearly all cases, you will want to pass additional in<strong>for</strong>mation to the <strong>Linux</strong> kernel; <strong>for</strong> instance, in<strong>for</strong>mation<br />

about the root device or network configuration.<br />

In U-<strong>Boot</strong>, this is supported using the bootargs environment variable. Its contents are automatically passed<br />

to the <strong>Linux</strong> kernel as boot arguments (or "comm<strong>and</strong> line" arguments). This allows the use of the same <strong>Linux</strong><br />

kernel image in a wide range of configurations. For instance, by just changing the contents of the bootargs<br />

variable you can use the very same <strong>Linux</strong> kernel image to boot with an initrd ramdisk image, with a root<br />

filesystem over NFS, with a CompactFlash disk or from a flash filesystem.<br />

As one example, to boot the <strong>Linux</strong> kernel image at address 0x200000 using the initrd ramdisk image at<br />

address 0x400000 as root filesystem, <strong>and</strong> with the flattened device tree blob at address 0x600000, you can use<br />

the following comm<strong>and</strong>s:<br />

=> setenv bootargs root=/dev/ram rw<br />

=> bootm 200000 400000 600000<br />

To boot the same kernel image with a root filesystem over NFS, the following comm<strong>and</strong> sequence can be<br />

used. This example assumes that your NFS server has the IP address "192.168.1.1" <strong>and</strong> exports the directory<br />

"/opt/eldk-4.2/ppc_4xx" as root filesystem <strong>for</strong> the target. <strong>The</strong> target has been assigned the IP address<br />

"192.168.100.6" <strong>and</strong> the hostname "canyonl<strong>and</strong>s". A netmask of "255.255.0.0" is used:<br />

=> setenv bootargs root=/dev/nfs rw nfsroot=192.168.1.1:/opt/eldk-4.2/ppc_4xx ip=192.168.100.6:19<br />

=> bootm 200000 - 600000<br />

7.3. Passing Kernel Arguments 99


Please see also the files Documentation/initrd.txt <strong>and</strong> Documentation/nfsroot.txt in your<br />

<strong>Linux</strong> kernel source directory <strong>for</strong> more in<strong>for</strong>mation about which options can be passed to the <strong>Linux</strong> kernel.<br />

Note: Once your system is up <strong>and</strong> running, if you have a simple shell login, you can normally examine the<br />

boot arguments that were used by the kernel <strong>for</strong> the most recent boot with the comm<strong>and</strong>:<br />

$ cat /proc/cmdline<br />

7.4. <strong>Boot</strong> Arguments Unleashed<br />

Passing comm<strong>and</strong> line arguments to the <strong>Linux</strong> kernel allows <strong>for</strong> very flexible <strong>and</strong> efficient configuration<br />

which is especially important in Embedded Systems. It is somewhat strange that these features are nearly<br />

undocumented everywhere else. One reason <strong>for</strong> that is certainly the very limited capabilities of other boot<br />

loaders.<br />

It is especially U-<strong>Boot</strong>'s capability to easily define, store, <strong>and</strong> use environment variables that makes it such a<br />

powerful tool in this area. In the examples above we have already seen how we can use <strong>for</strong> instance the root<br />

<strong>and</strong> ip boot arguments to pass in<strong>for</strong>mation about the root filesystem or network configuration. <strong>The</strong> ip<br />

argument is not only useful in configurations with root filesystem over NFS; if the <strong>Linux</strong> kernel has the<br />

CONFIG_IP_PNP configuration enabled (IP kernel level autoconfiguration), this can be used to enable<br />

automatic configuration of IP addresses of devices <strong>and</strong> of the routing table during kernel boot, based on either<br />

in<strong>for</strong>mation supplied on the kernel comm<strong>and</strong> line or by BOOTP or RARP protocols.<br />

<strong>The</strong> advantage of this mechanism is that you don't have to spend precious system memory (RAM <strong>and</strong> flash)<br />

<strong>for</strong> network configuration tools like ifconfig or route - especially in Embedded Systems where you<br />

seldom have to change the network configuration while the system is running.<br />

We can use U-<strong>Boot</strong> environment variables to store all necessary configuration parameters:<br />

=> setenv ipaddr 192.168.100.6<br />

=> setenv serverip 192.168.1.1<br />

=> setenv netmask 255.255.0.0<br />

=> setenv hostname canyonl<strong>and</strong>s<br />

=> setenv rootpath /opt/eldk-4.2/ppc_4xx<br />

=> saveenv<br />

<strong>The</strong>n you can use these variables to build the boot arguments to be passed to the <strong>Linux</strong> kernel:<br />

=> setenv nfsargs 'root=/dev/nfs rw nfsroot=${serverip}:${rootpath}'<br />

Note how apostrophes are used to delay the substitution of the referenced environment variables. This way,<br />

the current values of these variables get inserted when assigning values to the "bootargs" variable itself<br />

later, i. e. when it gets assembled from the given parts be<strong>for</strong>e passing it to the kernel. This allows us to simply<br />

redefine any of the variables (say, the value of "ipaddr" if it has to be changed), <strong>and</strong> the changes will<br />

automatically propagate to the <strong>Linux</strong> kernel.<br />

Note: You cannot use this method directly to define <strong>for</strong> example the "bootargs" environment variable,<br />

as the implicit usage of this variable by the "bootm" comm<strong>and</strong> will not trigger variable expansion - this<br />

happens only when using the "setenv" comm<strong>and</strong>.<br />

In the next step, this can be used <strong>for</strong> a flexible method to define the "bootargs" environment variable by<br />

using a function-like approach to build the boot arguments step by step:<br />

=> setenv ramargs setenv bootargs root=/dev/ram rw<br />

=> setenv nfsargs 'setenv bootargs root=/dev/nfs rw nfsroot=${serverip}:${rootpath}'<br />

7.4. <strong>Boot</strong> Arguments Unleashed 100


=> setenv addip 'setenv bootargs ${bootargs} ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}:${h<br />

=> setenv ram_root 'run ramargs addip;bootm ${kernel_addr} ${ramdisk_addr} ${fdt_addr} '<br />

=> setenv nfs_root 'run nfsargs addip;bootm ${kernel_addr} - ${fdt_addr} '<br />

In this setup we define two variables, ram_root <strong>and</strong> nfs_root, to boot with root filesystem from a<br />

ramdisk image or over NFS, respecively. <strong>The</strong> variables can be executed using U-<strong>Boot</strong>'s run comm<strong>and</strong>. <strong>The</strong>se<br />

variables make use of the run comm<strong>and</strong> itself:<br />

• First, either run ramargs or run nfsargs is used to initialize the bootargs environment<br />

variable as needed to boot with ramdisk image or with root over NFS.<br />

• <strong>The</strong>n, in both cases, run addip is used to append the ip parameter to use the <strong>Linux</strong> kernel IP<br />

autoconfiguration mechanism <strong>for</strong> configuration of the network settings.<br />

• Finally, the bootm comm<strong>and</strong> is used with three resp. two address arguments to boot the <strong>Linux</strong> kernel<br />

image with resp. without a ramdisk image. (We assume here that the variables kernel_addr ,<br />

ramdisk_addr <strong>and</strong> fdt_addr have already been set.)<br />

This method can be easily extended to add more customization options when needed.<br />

If you have used U-<strong>Boot</strong>'s network comm<strong>and</strong>s be<strong>for</strong>e (<strong>and</strong>/or read the documentation), you will probably have<br />

recognized that the names of the U-<strong>Boot</strong> environment variables we used in the examples above are exactly the<br />

same as those used with the U-<strong>Boot</strong> comm<strong>and</strong>s to boot over a network using DHCP or BOOTP. That means<br />

that, instead of manually setting network configuration parameters like IP address, etc., these variables will be<br />

set automatically to the values retrieved with the network boot protocols. This will be explained in detail in<br />

the examples below.<br />

7.5. Networked Operation with Root Filesystem<br />

over NFS<br />

You can use the printenv comm<strong>and</strong> on the Target to find out which comm<strong>and</strong>s get executed by U-<strong>Boot</strong> to<br />

load <strong>and</strong> boot the <strong>Linux</strong> kernel:<br />

=> printenv<br />

bootcmd=bootp %MIF_KIB_ADDR_R%; setenv bootargs root=/dev/nfs rw nfsroot=${serverip}:${rootpath}<br />

bootdelay=5<br />

baudrate=115200<br />

stdin=serial<br />

stdout=serial<br />

stderr=serial<br />

...<br />

After Power-On or reset the system will initialize <strong>and</strong> then wait <strong>for</strong> a key-press on the console port. <strong>The</strong><br />

duration of this countdown is determined by the contents of the bootdelay environment variable (default: 5<br />

seconds).<br />

If no key is pressed, the comm<strong>and</strong> (or the list of comm<strong>and</strong>s) stored in the environment variable bootcmd is<br />

executed. If you press a key, you get a prompt at the console port which allows <strong>for</strong> interactive comm<strong>and</strong> input.<br />

In the example above the following comm<strong>and</strong>s are executed sequentially:<br />

bootp %MIF_KIB_ADDR_R%<br />

setenv bootargs root=/dev/nfs nfsroot=${serverip}:${rootpath} ip=${ipaddr}:${serverip}:${gatewayi<br />

bootm %MIF_KIB_ADDR_R% -<br />

7.5. Networked Operation with Root Filesystem over NFS 101


<strong>The</strong>se comm<strong>and</strong>s take the following effect (pay attention <strong>for</strong> the modification of environment variables by<br />

these comm<strong>and</strong>s):<br />

• bootp: This comm<strong>and</strong> uses the BOOTP protocol to ask a boot server <strong>for</strong> in<strong>for</strong>mation about our<br />

system <strong>and</strong> to load a boot image (which will usually be a multi-image file containing a <strong>Linux</strong> kernel<br />

<strong>and</strong> a flattened device tree blob). <strong>The</strong> comm<strong>and</strong> will use passed address of %MIF_KIB_ADDR_R%<br />

to load the file.<br />

=> bootp %MIF_KIB_ADDR_R%<br />

BOOTP broadcast 1<br />

ARP broadcast 0<br />

TFTP from server 192.168.1.1; our IP address is 192.168.100.6<br />

Filename '%MIF_KIB%'<br />

Load address: 0x%MIF_KIB_ADDR_R%<br />

Loading: ########################################################################################<br />

done<br />

=> printenv<br />

bootcmd=bootp %MIF_KIB_ADDR_R%; setenv bootargs root=/dev/nfs rw nfsroot=${serverip}:${rootpath}<br />

bootdelay=5<br />

baudrate=115200<br />

stdin=serial<br />

stdout=serial<br />

stderr=serial<br />

bootfile=%MIF_KIB%<br />

gatewayip=192.168.1.1<br />

netmask=255.255.0.0<br />

hostname=canyonl<strong>and</strong>s<br />

rootpath=/opt/eldk-4.2/ppc_4xx<br />

ipaddr=192.168.100.6<br />

serverip=192.168.1.1<br />

dnsip=192.168.1.1<br />

...<br />

<strong>The</strong> Target sends a BOOTP request on the network, <strong>and</strong> (assuming there is a BOOTP server available)<br />

receives a reply that contains the IP address (ipaddr=192.168.100.6) <strong>and</strong> other network in<strong>for</strong>mation<br />

<strong>for</strong> the target (hostname=canyonl<strong>and</strong>s, serverip=192.168.1.1, gatewayip=192.168.1.1,<br />

netmask=255.255.0.0).<br />

Also, the name of the boot image (bootfile= %MIF_KIB% ) <strong>and</strong> the root directory on a NFS server<br />

(rootpath=/opt/eldk-4.2/ppc_4xx) was transmitted.<br />

U-<strong>Boot</strong> then automatically downloaded the bootimage from the server using TFTP.<br />

You can use the comm<strong>and</strong> iminfo (Image Info, or short imi) to verify the contents of the loaded image:<br />

/tftpboot/canyonl<strong>and</strong>s/uImage-duts: u-boot/PPC<strong>Boot</strong> image<br />

=> setenv bootfile /tftpboot/canyonl<strong>and</strong>s/uImage-duts<br />

=><br />

=> setenv ram_ws 100000<br />

=> tftp ${ram_ws} ${bootfile}<br />

Waiting <strong>for</strong> PHY auto negotiation to complete... done<br />

ENET Speed is 1000 Mbps - FULL duplex connection (EMAC0)<br />

Using ppc_4xx_eth0 device<br />

TFTP from server 192.168.1.1; our IP address is 192.168.100.6<br />

Filename '/tftpboot/canyonl<strong>and</strong>s/uImage-duts'.<br />

Load address: 0x100000<br />

Loading: *T #################################################################<br />

######################################################<br />

7.5. Networked Operation with Root Filesystem over NFS 102


done<br />

Bytes transferred = 1744326 (1a9dc6 hex)<br />

=><br />

=> imi 100000<br />

## Checking Image at 00100000 ...<br />

Legacy image found<br />

Image Name: <strong>Linux</strong>-2.6.25-rc8-01016-g94bf13b-<br />

Created: 2008-04-10 9:50:08 UTC<br />

Image Type: PowerPC <strong>Linux</strong> Kernel Image (gzip compressed)<br />

Data Size: 1744262 Bytes = 1.7 MB<br />

Load Address: 00000000<br />

Entry Point: 00000000<br />

Verifying Checksum ... OK<br />

=><br />

This tells you that we loaded a compressed <strong>Linux</strong> kernel image, <strong>and</strong> that the file was not corrupted, since the<br />

CRC32 checksum is OK.<br />

setenv bootargs root=/dev/nfs rw nfsroot=${serverip}:${rootpath} \<br />

ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}:${hostname}::off<br />

This comm<strong>and</strong> defines the environment variable bootargs. (If an old definition exists, it is deleted first).<br />

<strong>The</strong> contents of this variable is passed as comm<strong>and</strong> line to the LInux kernel when it is booted (hence the<br />

name). Note how U-<strong>Boot</strong> uses variable substitution to dynamically modify the boot arguments depending on<br />

the in<strong>for</strong>mation we got from the BOOTP server.<br />

To verify, you can run this comm<strong>and</strong> manually:<br />

=> setenv bootargs root=/dev/nfs rw nfsroot=${serverip}:${rootpath} ip=${ipaddr}:${serverip}:${ga<br />

=> printenv<br />

...<br />

bootargs=root=/dev/nfs rw nfsroot=192.168.1.1:/opt/eldk-4.2/ppc_4xx ip=192.168.100.6:192.168.1.1:<br />

...<br />

This comm<strong>and</strong> line passes the following in<strong>for</strong>mation to the <strong>Linux</strong> kernel:<br />

• root=/dev/nfs rw: the root filesystem will be mounted using NFS, <strong>and</strong> it will be writable.<br />

• nfsroot=192.168.1.1:/opt/eldk-4.2/ppc_4xx: the NFS server has the IP address<br />

192.168.1.1, <strong>and</strong> exports the directory /opt/eldk-4.2/ppc_4xx <strong>for</strong> our system to use as root filesystem.<br />

• ip=192.168.100.6:192.168.1.1:192.168.1.1:255.255.0.0:canyonl<strong>and</strong>s::off:<br />

the target has the IP address 192.168.100.6; the NFS server is 192.168.1.1; there is a<br />

gateway at IP address 192.168.1.1; the netmask is 255.255.0.0 <strong>and</strong> our hostname is<br />

canyonl<strong>and</strong>s. <strong>The</strong> first ethernet interface (eth0) willbe used, <strong>and</strong> the <strong>Linux</strong> kernel will<br />

immediately use this network configuration <strong>and</strong> not try to re-negotiate it (IP autoconfiguration is<br />

off).<br />

See Documentation/nfsroot.txt in you <strong>Linux</strong> kernel source directory <strong>for</strong> more in<strong>for</strong>mation about these<br />

parameters <strong>and</strong> other options.<br />

• bootm: This comm<strong>and</strong> boots an operating system image that resides somewhere in the system<br />

memory (RAM or flash - the m in the name is <strong>for</strong> memory). In this case we passed<br />

%MIF_KIB_ADDR_R% as the address of the multi-image file.<br />

7.5. Networked Operation with Root Filesystem over NFS 103


7.5.1. <strong>Boot</strong>log of <strong>Linux</strong> kernel with Root Filesystem over<br />

NFS<br />

=><br />

=> setenv rootpath /opt/eldk/ppc_4xx/<br />

=> run flash_nfs<br />

## <strong>Boot</strong>ing kernel from Legacy Image at fc000000 ...<br />

Image Name: <strong>Linux</strong>-2.6.25-rc8-01016-g94bf13b-<br />

Created: 2008-04-10 9:50:08 UTC<br />

Image Type: PowerPC <strong>Linux</strong> Kernel Image (gzip compressed)<br />

Data Size: 1744262 Bytes = 1.7 MB<br />

Load Address: 00000000<br />

Entry Point: 00000000<br />

Verifying Checksum ... OK<br />

Uncompressing Kernel Image ... OK<br />

## Flattened Device Tree blob at fc1e0000<br />

<strong>Boot</strong>ing using the fdt blob at 0xfc1e0000<br />

Loading Device Tree to 007fd000, end 007ff70f ... OK<br />

Using Canyonl<strong>and</strong>s machine description<br />

<strong>Linux</strong> version 2.6.25-rc8-01016-g94bf13b-dirty (stefan@ubuntu) (gcc version 4.2.2) #54 Thu Apr 10<br />

Zone PFN ranges:<br />

DMA 0 -> 65536<br />

Normal 65536 -> 65536<br />

Movable zone start PFN <strong>for</strong> each node<br />

early_node_map[1] active PFN ranges<br />

0: 0 -> 65536<br />

Built 1 zonelists in Zone order, mobility grouping on. Total pages: 65024<br />

Kernel comm<strong>and</strong> line: root=/dev/nfs rw nfsroot=192.168.1.1:/opt/eldk/ppc_4xx/ ip=192.168.100.6:192<br />

UIC0 (32 IRQ sources) at DCR 0xc0<br />

UIC1 (32 IRQ sources) at DCR 0xd0<br />

UIC2 (32 IRQ sources) at DCR 0xe0<br />

UIC3 (32 IRQ sources) at DCR 0xf0<br />

PID hash table entries: 1024 (order: 10, 4096 bytes)<br />

clocksource: timebase mult[6aaaab] shift[22] registered<br />

Dentry cache hash table entries: 32768 (order: 5, 131072 bytes)<br />

Inode-cache hash table entries: 16384 (order: 4, 65536 bytes)<br />

Memory: 255872k/262144k available (3464k kernel code, 6028k reserved, 124k data, 132k bss, 156k i<br />

SLUB: Genslabs=10, HWalign=32, Order=0-1, MinObjects=4, CPUs=1, Nodes=1<br />

Mount-cache hash table entries: 512<br />

net_namespace: 152 bytes<br />

NET: Registered protocol family 16<br />

PCIE1: Checking link...<br />

PCIE1: No device detected.<br />

PCI host bridge /plb/pciex@d20000000 (primary) ranges:<br />

MEM 0x0000000e80000000..0x0000000effffffff -> 0x0000000080000000<br />

IO 0x0000000f80010000..0x0000000f8001ffff -> 0x0000000000000000<br />

4xx PCI DMA offset set to 0x00000000<br />

PCIE1: successfully set as root-complex<br />

PCI host bridge /plb/pci@c0ec00000 (primary) ranges:<br />

MEM 0x0000000d80000000..0x0000000dffffffff -> 0x0000000080000000<br />

IO 0x0000000c08000000..0x0000000c0800ffff -> 0x0000000000000000<br />

4xx PCI DMA offset set to 0x00000000<br />

PCI: Probing PCI hardware<br />

PCI: Hiding 4xx host bridge resources 0000:80:00.0<br />

PCI: Bridge: 0000:80:00.0<br />

IO window: disabled.<br />

MEM window: disabled.<br />

PREFETCH window: disabled.<br />

SCSI subsystem initialized<br />

usbcore: registered new interface driver usbfs<br />

usbcore: registered new interface driver hub<br />

usbcore: registered new device driver usb<br />

NET: Registered protocol family 2<br />

IP route cache hash table entries: 2048 (order: 1, 8192 bytes)<br />

7.5.1. <strong>Boot</strong>log of <strong>Linux</strong> kernel with Root Filesystem over NFS 104


TCP established hash table entries: 8192 (order: 4, 65536 bytes)<br />

TCP bind hash table entries: 8192 (order: 3, 32768 bytes)<br />

TCP: Hash tables configured (established 8192 bind 8192)<br />

TCP reno registered<br />

io scheduler noop registered<br />

io scheduler anticipatory registered (default)<br />

io scheduler deadline registered<br />

io scheduler cfq registered<br />

Serial: 8250/16550 driver $Revision: 1.2 $ 4 ports, IRQ sharing enabled<br />

serial8250.0: ttyS0 at MMIO 0x4ef600300 (irq = 18) is a 16550A<br />

console [ttyS0] enabled<br />

serial8250.0: ttyS1 at MMIO 0x4ef600400 (irq = 19) is a 16550A<br />

serial8250.0: ttyS2 at MMIO 0x4ef600500 (irq = 29) is a 16550A<br />

serial8250.0: ttyS3 at MMIO 0x4ef600600 (irq = 20) is a 16550A<br />

4ef600300.serial: ttyS0 at MMIO 0x4ef600300 (irq = 18) is a 16550A<br />

4ef600400.serial: ttyS1 at MMIO 0x4ef600400 (irq = 19) is a 16550A<br />

4ef600500.serial: ttyS2 at MMIO 0x4ef600500 (irq = 29) is a 16550A<br />

4ef600600.serial: ttyS3 at MMIO 0x4ef600600 (irq = 20) is a 16550A<br />

brd: module loaded<br />

Intel(R) PRO/1000 Network Driver - version 7.3.20-k2-NAPI<br />

Copyright (c) 1999-2006 Intel Corporation.<br />

PPC 4xx OCP EMAC driver, version 3.54<br />

MAL v2 /plb/mcmal, 2 TX channels, 16 RX channels<br />

ZMII /plb/opb/emac-zmii@ef600d00 initialized<br />

RGMII /plb/opb/emac-rgmii@ef601500 initialized with MDIO support<br />

TAH /plb/opb/emac-tah@ef601350 initialized<br />

TAH /plb/opb/emac-tah@ef601450 initialized<br />

/plb/opb/emac-rgmii@ef601500: input 0 in RGMII mode<br />

eth0: EMAC-0 /plb/opb/ethernet@ef600e00, MAC 5e:ed:18:38:81:85<br />

eth0: found Generic MII PHY (0x00)<br />

/plb/opb/emac-rgmii@ef601500: input 1 in RGMII mode<br />

eth1: EMAC-1 /plb/opb/ethernet@ef600f00, MAC 5e:ed:18:38:81:86<br />

eth1: found Generic MII PHY (0x01)<br />

Driver 'sd' needs updating - please use bus_type methods<br />

sata_dwc: DW SATA host Id=0x00000000, Version=0x3138322a<br />

dw_ahb_dma_init: start=4bffd0800 size=400<br />

sata_dwc: SATA DMA initialized registers=0xd1054800<br />

scsi0 : sata-dwc<br />

ata1: SATA max UDMA/133 irq 22<br />

sata_dwc_error_h<strong>and</strong>ler<br />

ata_eh_recover: line 2646<br />

ata_eh_reset: line 2127<br />

ata_eh_reset: line 2163<br />

ata_eh_reset: line 2176<br />

ata_eh_reset: line 2196<br />

ata_eh_reset: line 2234<br />

ata_eh_reset: line 2272<br />

ata1: SATA link down (SStatus 0 SControl 300)<br />

ata_eh_reset: line 2304<br />

sata_dwc_error_h<strong>and</strong>ler<br />

ata_eh_recover: line 2646<br />

4cc000000.nor_flash: Found 1 x16 devices at 0x0 in 16-bit bank<br />

Amd/Fujitsu Extended Query Table at 0x0040<br />

4cc000000.nor_flash: CFI does not contain boot bank location. Assuming top.<br />

number of CFI chips: 1<br />

cfi_cmdset_0002: Disabling erase-suspend-program due to code brokenness.<br />

Red<strong>Boot</strong> partition parsing not available<br />

Creating 6 MTD partitions on "4cc000000.nor_flash":<br />

0x00000000-0x001e0000 : "kernel"<br />

0x001e0000-0x00200000 : "dtb"<br />

0x00200000-0x00400000 : "root"<br />

0x00400000-0x03f60000 : "user"<br />

0x03f60000-0x03fa0000 : "env"<br />

0x03fa0000-0x04000000 : "u-boot"<br />

NDFC NAND Driver initialized. Chip-Rev: 0x00000111<br />

NAND device: Manufacturer ID: 0x20, Chip ID: 0x75 (ST Micro NAND 32MiB 3,3V 8-bit)<br />

Scanning device <strong>for</strong> bad blocks<br />

7.5.1. <strong>Boot</strong>log of <strong>Linux</strong> kernel with Root Filesystem over NFS 105


Bad eraseblock 1011 at 0x00fcc000<br />

Number of partitions 3<br />

Creating 3 MTD partitions on "NAND 32MiB 3,3V 8-bit":<br />

0x00000000-0x00060000 : "u-boot"<br />

0x00060000-0x00068000 : "env"<br />

0x00068000-0x02000000 : "content"<br />

ppc-of-ohci 4bffd0000.usb: OF OHCI<br />

ppc-of-ohci 4bffd0000.usb: new USB bus registered, assigned bus number 1<br />

ppc-of-ohci 4bffd0000.usb: irq 37, io mem 0x4bffd0000<br />

usb usb1: configuration #1 chosen from 1 choice<br />

hub 1-0:1.0: USB hub found<br />

hub 1-0:1.0: 1 port detected<br />

usb usb1: New USB device found, idVendor=1d6b, idProduct=0001<br />

usb usb1: New USB device strings: Mfr=3, Product=2, SerialNumber=1<br />

usb usb1: Product: OF OHCI<br />

usb usb1: Manufacturer: <strong>Linux</strong> 2.6.25-rc8-01016-g94bf13b-dirty ohci_hcd<br />

usb usb1: SerialNumber: PPC-OF USB<br />

Initializing USB Mass Storage driver...<br />

usbcore: registered new interface driver usb-storage<br />

USB Mass Storage support registered.<br />

dwc_otg: version 2.60a 22-NOV-2006<br />

dwc_otg: Shared Tx FIFO mode<br />

dwc_otg: Using Slave mode<br />

dwc_otg dwc_otg.0: DWC OTG Controller<br />

dwc_otg dwc_otg.0: new USB bus registered, assigned bus number 2<br />

dwc_otg dwc_otg.0: irq 28, io mem 0x00000000<br />

dwc_otg: dwc_otg_core_host_init: Unable to clear halt on channel 1<br />

dwc_otg: Init: Port Power op_state=4<br />

usb usb2: configuration #1 chosen from 1 choice<br />

hub 2-0:1.0: USB hub found<br />

hub 2-0:1.0: 1 port detected<br />

usb usb2: New USB device found, idVendor=1d6b, idProduct=0002<br />

usb usb2: New USB device strings: Mfr=3, Product=2, SerialNumber=1<br />

usb usb2: Product: DWC OTG Controller<br />

usb usb2: Manufacturer: <strong>Linux</strong> 2.6.25-rc8-01016-g94bf13b-dirty dwc_otg_hcd<br />

usb usb2: SerialNumber: dwc_otg.0<br />

i2c /dev entries driver<br />

IBM IIC driver v2.1<br />

TCP cubic registered<br />

NET: Registered protocol family 1<br />

NET: Registered protocol family 17<br />

RPC: Registered udp transport module.<br />

RPC: Registered tcp transport module.<br />

/home/stefan/git/linux-2.6/denx-merge-sr/drivers/rtc/hctosys.c: unable to open rtc device (rtc0)<br />

eth0: link is down<br />

IP-Config: Complete:<br />

device=eth0, addr=192.168.100.6, mask=255.255.0.0, gw=255.255.255.255,<br />

host=canyonl<strong>and</strong>s, domain=, nis-domain=(none),<br />

bootserver=192.168.1.1, rootserver=192.168.1.1, rootpath=<br />

Looking up port of RPC 100003/2 on 192.168.1.1<br />

eth0: link is up, 1000 FDX, pause enabled<br />

Looking up port of RPC 100005/1 on 192.168.1.1<br />

VFS: Mounted root (nfs filesystem).<br />

Freeing unused kernel memory: 156k init<br />

modprobe: FATAL: Could not load /lib/modules/2.6.25-rc8-01016-g94bf13b-dirty/modules.dep: No such<br />

modprobe: FATAL: Could not load /lib/modules/2.6.25-rc8-01016-g94bf13b-dirty/modules.dep: No such<br />

INIT: version 2.86 booting<br />

Welcome to <strong>DENX</strong> Embedded <strong>Linux</strong> Environment<br />

Press 'I' to enter interactive startup.<br />

modprobe: FATAL: Could not load /lib/modules/2.6.25-rc8-01016-g94bf13b-dirty/modules.dep: No such<br />

modprobe: FATAL: Could not load /lib/modules/2.6.25-rc8-01016-g94bf13b-dirty/modules.dep: No such<br />

Cannot access the Hardware Clock via any known method.<br />

Use the --debug option to see the details of our search <strong>for</strong> an access method.<br />

7.5.1. <strong>Boot</strong>log of <strong>Linux</strong> kernel with Root Filesystem over NFS 106


Setting clock : Thu Jan 1 01:00:07 CET 1970 [ OK ]<br />

Building the cache [ OK ]<br />

Setting hostname canyonl<strong>and</strong>s: [ OK ]<br />

Mounting local filesystems: [ OK ]<br />

Enabling /etc/fstab swaps: [ OK ]<br />

INIT: Entering runlevel: 3<br />

Entering non-interactive startup<br />

FATAL: Could not load /lib/modules/2.6.25-rc8-01016-g94bf13b-dirty/modules.dep: No such file or d<br />

Bringing up loopback interface: [ OK ]<br />

FATAL: Could not load /lib/modules/2.6.25-rc8-01016-g94bf13b-dirty/modules.dep: No such file or d<br />

Starting system logger: [ OK ]<br />

Starting kernel logger: [ OK ]<br />

Starting rpcbind: [ OK ]<br />

Mounting NFS filesystems: [ OK ]<br />

Mounting other filesystems: [ OK ]<br />

Starting xinetd: [ OK ]<br />

<strong>DENX</strong> ELDK version 4.2 build 2008-03-27<br />

<strong>Linux</strong> 2.6.25-rc8-01016-g94bf13b-dirty on a ppc<br />

canyonl<strong>and</strong>s login: root<br />

Last login: Thu Jan 1 01:00:31 on console<br />

-bash-3.2#<br />

7.6. <strong>Boot</strong> from Flash Memory<br />

<strong>The</strong> previous section described how to load the <strong>Linux</strong> kernel image over ethernet using TFTP. This is<br />

especially well suited <strong>for</strong> your development <strong>and</strong> test environment, when the kernel image is still undergoing<br />

frequent changes, <strong>for</strong> instance because you are modifying kernel code or configuration.<br />

Later in your development cycle you will work on application code or device drivers, which can be loaded<br />

dynamically as modules. If the <strong>Linux</strong> kernel remains the same then you can save the time needed <strong>for</strong> the<br />

TFTP download <strong>and</strong> put the kernel image into the flash memory of your canyonl<strong>and</strong>s board.<br />

<strong>The</strong> U-<strong>Boot</strong> comm<strong>and</strong> flinfo can be used to display in<strong>for</strong>mation about the available on-board flash on your<br />

system:<br />

=> fli<br />

Bank # 1: CFI con<strong>for</strong>mant FLASH (16 x 16) Size: 64 MB in 512 Sectors<br />

AMD St<strong>and</strong>ard comm<strong>and</strong> set, Manufacturer ID: 0x01, Device ID: 0x227E<br />

Erase timeout: 16384 ms, write timeout: 2 ms<br />

Buffer write timeout: 5 ms, buffer size: 32 bytes<br />

Sector Start Addresses:<br />

FC000000 E FC020000 E FC040000 E FC060000 E FC080000 E<br />

FC0A0000 E FC0C0000 E FC0E0000 E FC100000 E FC120000 E<br />

FC140000 E FC160000 E FC180000 E FC1A0000 E FC1C0000 E<br />

FC1E0000 E FC200000 E FC220000 E FC240000 E FC260000 E<br />

FC280000 E FC2A0000 E FC2C0000 E FC2E0000 E FC300000 E<br />

FC320000 E FC340000 E FC360000 E FC380000 E FC3A0000 E<br />

FC3C0000 E FC3E0000 E FC400000 E FC420000 E FC440000 E<br />

FC460000 E FC480000 E FC4A0000 E FC4C0000 E FC4E0000 E<br />

FC500000 E FC520000 E FC540000 E FC560000 E FC580000 E<br />

FC5A0000 E FC5C0000 E FC5E0000 E FC600000 E FC620000 E<br />

FC640000 E FC660000 E FC680000 E FC6A0000 E FC6C0000 E<br />

FC6E0000 E FC700000 E FC720000 E FC740000 E FC760000 E<br />

FC780000 E FC7A0000 E FC7C0000 E FC7E0000 E FC800000 E<br />

FC820000 E FC840000 E FC860000 E FC880000 E FC8A0000 E<br />

FC8C0000 E FC8E0000 E FC900000 E FC920000 E FC940000 E<br />

FC960000 E FC980000 E FC9A0000 E FC9C0000 E FC9E0000 E<br />

7.6. <strong>Boot</strong> from Flash Memory 107


FCA00000 E FCA20000 E FCA40000 E FCA60000 E FCA80000 E<br />

FCAA0000 E FCAC0000 E FCAE0000 E FCB00000 E FCB20000 E<br />

FCB40000 E FCB60000 E FCB80000 E FCBA0000 E FCBC0000 E<br />

FCBE0000 E FCC00000 E FCC20000 E FCC40000 E FCC60000 E<br />

FCC80000 E FCCA0000 E FCCC0000 E FCCE0000 E FCD00000 E<br />

FCD20000 E FCD40000 E FCD60000 E FCD80000 E FCDA0000 E<br />

FCDC0000 E FCDE0000 E FCE00000 E FCE20000 E FCE40000 E<br />

FCE60000 E FCE80000 E FCEA0000 E FCEC0000 E FCEE0000 E<br />

FCF00000 E FCF20000 E FCF40000 E FCF60000 E FCF80000 E<br />

FCFA0000 E FCFC0000 E FCFE0000 E FD000000 E FD020000 E<br />

FD040000 E FD060000 E FD080000 E FD0A0000 E FD0C0000 E<br />

FD0E0000 E FD100000 E FD120000 E FD140000 E FD160000 E<br />

FD180000 E FD1A0000 E FD1C0000 E FD1E0000 E FD200000 E<br />

FD220000 E FD240000 E FD260000 E FD280000 E FD2A0000 E<br />

FD2C0000 E FD2E0000 E FD300000 E FD320000 E FD340000 E<br />

FD360000 E FD380000 E FD3A0000 E FD3C0000 E FD3E0000 E<br />

FD400000 E FD420000 E FD440000 E FD460000 E FD480000 E<br />

FD4A0000 E FD4C0000 E FD4E0000 E FD500000 E FD520000 E<br />

FD540000 E FD560000 E FD580000 E FD5A0000 E FD5C0000 E<br />

FD5E0000 E FD600000 E FD620000 E FD640000 E FD660000 E<br />

FD680000 E FD6A0000 E FD6C0000 E FD6E0000 E FD700000 E<br />

FD720000 E FD740000 E FD760000 E FD780000 E FD7A0000 E<br />

FD7C0000 E FD7E0000 E FD800000 E FD820000 E FD840000 E<br />

FD860000 E FD880000 E FD8A0000 E FD8C0000 E FD8E0000 E<br />

FD900000 E FD920000 E FD940000 E FD960000 E FD980000 E<br />

FD9A0000 E FD9C0000 E FD9E0000 E FDA00000 E FDA20000 E<br />

FDA40000 E FDA60000 E FDA80000 E FDAA0000 E FDAC0000 E<br />

FDAE0000 E FDB00000 E FDB20000 E FDB40000 E FDB60000 E<br />

FDB80000 E FDBA0000 E FDBC0000 E FDBE0000 E FDC00000 E<br />

FDC20000 E FDC40000 E FDC60000 E FDC80000 E FDCA0000 E<br />

FDCC0000 E FDCE0000 E FDD00000 E FDD20000 E FDD40000 E<br />

FDD60000 E FDD80000 E FDDA0000 E FDDC0000 E FDDE0000 E<br />

FDE00000 E FDE20000 E FDE40000 E FDE60000 E FDE80000 E<br />

FDEA0000 E FDEC0000 E FDEE0000 E FDF00000 E FDF20000 E<br />

FDF40000 E FDF60000 E FDF80000 E FDFA0000 E FDFC0000 E<br />

FDFE0000 E FE000000 E FE020000 E FE040000 E FE060000 E<br />

FE080000 E FE0A0000 E FE0C0000 E FE0E0000 E FE100000 E<br />

FE120000 E FE140000 E FE160000 E FE180000 E FE1A0000 E<br />

FE1C0000 E FE1E0000 E FE200000 E FE220000 E FE240000 E<br />

FE260000 E FE280000 E FE2A0000 E FE2C0000 E FE2E0000 E<br />

FE300000 E FE320000 E FE340000 E FE360000 E FE380000 E<br />

FE3A0000 E FE3C0000 E FE3E0000 E FE400000 E FE420000 E<br />

FE440000 E FE460000 E FE480000 E FE4A0000 E FE4C0000 E<br />

FE4E0000 E FE500000 E FE520000 E FE540000 E FE560000 E<br />

FE580000 E FE5A0000 E FE5C0000 E FE5E0000 E FE600000 E<br />

FE620000 E FE640000 E FE660000 E FE680000 E FE6A0000 E<br />

FE6C0000 E FE6E0000 E FE700000 E FE720000 E FE740000 E<br />

FE760000 E FE780000 E FE7A0000 E FE7C0000 E FE7E0000 E<br />

FE800000 E FE820000 E FE840000 E FE860000 E FE880000 E<br />

FE8A0000 E FE8C0000 E FE8E0000 E FE900000 E FE920000 E<br />

FE940000 E FE960000 E FE980000 E FE9A0000 E FE9C0000 E<br />

FE9E0000 E FEA00000 E FEA20000 E FEA40000 E FEA60000 E<br />

FEA80000 E FEAA0000 E FEAC0000 E FEAE0000 E FEB00000 E<br />

FEB20000 E FEB40000 E FEB60000 E FEB80000 E FEBA0000 E<br />

FEBC0000 E FEBE0000 E FEC00000 E FEC20000 E FEC40000 E<br />

FEC60000 E FEC80000 E FECA0000 E FECC0000 E FECE0000 E<br />

FED00000 E FED20000 E FED40000 E FED60000 E FED80000 E<br />

FEDA0000 E FEDC0000 E FEDE0000 E FEE00000 E FEE20000 E<br />

FEE40000 E FEE60000 E FEE80000 E FEEA0000 E FEEC0000 E<br />

FEEE0000 E FEF00000 E FEF20000 E FEF40000 E FEF60000 E<br />

FEF80000 E FEFA0000 E FEFC0000 E FEFE0000 E FF000000 E<br />

FF020000 E FF040000 E FF060000 E FF080000 E FF0A0000 E<br />

FF0C0000 E FF0E0000 E FF100000 E FF120000 E FF140000 E<br />

FF160000 E FF180000 E FF1A0000 E FF1C0000 E FF1E0000 E<br />

FF200000 E FF220000 E FF240000 E FF260000 E FF280000 E<br />

FF2A0000 E FF2C0000 E FF2E0000 E FF300000 E FF320000 E<br />

FF340000 E FF360000 E FF380000 E FF3A0000 E FF3C0000 E<br />

7.6. <strong>Boot</strong> from Flash Memory 108


FF3E0000 E FF400000 E FF420000 E FF440000 E FF460000 E<br />

FF480000 E FF4A0000 E FF4C0000 E FF4E0000 E FF500000 E<br />

FF520000 E FF540000 E FF560000 E FF580000 E FF5A0000 E<br />

FF5C0000 E FF5E0000 E FF600000 E FF620000 E FF640000 E<br />

FF660000 E FF680000 E FF6A0000 E FF6C0000 E FF6E0000 E<br />

FF700000 E FF720000 E FF740000 E FF760000 E FF780000 E<br />

FF7A0000 E FF7C0000 E FF7E0000 E FF800000 E FF820000 E<br />

FF840000 E FF860000 E FF880000 E FF8A0000 E FF8C0000 E<br />

FF8E0000 E FF900000 E FF920000 E FF940000 E FF960000 E<br />

FF980000 E FF9A0000 E FF9C0000 E FF9E0000 E FFA00000 E<br />

FFA20000 E FFA40000 E FFA60000 E FFA80000 E FFAA0000 E<br />

FFAC0000 E FFAE0000 E FFB00000 E FFB20000 E FFB40000 E<br />

FFB60000 E FFB80000 E FFBA0000 E FFBC0000 E FFBE0000 E<br />

FFC00000 E FFC20000 E FFC40000 E FFC60000 E FFC80000 E<br />

FFCA0000 E FFCC0000 E FFCE0000 E FFD00000 E FFD20000 E<br />

FFD40000 E FFD60000 E FFD80000 E FFDA0000 E FFDC0000 E<br />

FFDE0000 E FFE00000 E FFE20000 E FFE40000 E FFE60000 E<br />

FFE80000 E FFEA0000 E FFEC0000 E FFEE0000 E FFF00000 E<br />

FFF20000 E FFF40000 E FFF60000 RO FFF80000 RO FFFA0000 RO<br />

FFFC0000 RO FFFE0000 RO<br />

=><br />

From this output you can see the total amount of flash memory, <strong>and</strong> how it is divided in blocks (Erase Units<br />

or Sectors). <strong>The</strong> RO markers show blocks of flash memory that are write protected (by software) - this is the<br />

area where U-<strong>Boot</strong> is stored. <strong>The</strong> remaining flash memory is available <strong>for</strong> other use.<br />

For instance, we can store the <strong>Linux</strong> kernel image in flash starting at the start address of the next free flash<br />

sector. Be<strong>for</strong>e we can do this we must make sure that the flash memory in that region is empty - a <strong>Linux</strong><br />

kernel image is typically around 600...700 kB, so to be on the safe side we dedicate the whole area from<br />

0xFC000000 to 0xFC17FFFF <strong>for</strong> the kernel image. Keep in mind that with flash memory only whole erase<br />

units can be cleared.<br />

After having deleted the target flash area, you can download the <strong>Linux</strong> image <strong>and</strong> write it to flash. Below is a<br />

transcript of the complete operation with a final iminfo comm<strong>and</strong> to check the newly placed <strong>Linux</strong> kernel<br />

image in the flash memory.<br />

=><br />

=> setenv kernel_addr FC000000<br />

=><br />

=> prot off FC000000 FC17FFFF<br />

Un-Protected 12 sectors<br />

=><br />

=> era FC000000 FC17FFFF<br />

............ done<br />

Erased 12 sectors<br />

=><br />

=> tftp 100000 /tftpboot/canyonl<strong>and</strong>s/uImage-duts<br />

ENET Speed is 1000 Mbps - FULL duplex connection (EMAC0)<br />

Using ppc_4xx_eth0 device<br />

TFTP from server 192.168.1.1; our IP address is 192.168.100.6<br />

Filename '/tftpboot/canyonl<strong>and</strong>s/uImage-duts'.<br />

Load address: 0x100000<br />

Loading: *#################################################################<br />

######################################################<br />

done<br />

Bytes transferred = 1744326 (1a9dc6 hex)<br />

=><br />

=> imi 100000<br />

## Checking Image at 00100000 ...<br />

Legacy image found<br />

Image Name: <strong>Linux</strong>-2.6.25-rc8-01016-g94bf13b-<br />

7.6. <strong>Boot</strong> from Flash Memory 109


Created: 2008-04-10 9:50:08 UTC<br />

Image Type: PowerPC <strong>Linux</strong> Kernel Image (gzip compressed)<br />

Data Size: 1744262 Bytes = 1.7 MB<br />

Load Address: 00000000<br />

Entry Point: 00000000<br />

Verifying Checksum ... OK<br />

=><br />

=> setenv ram_ws 100000<br />

=><br />

=> cp.b ${ram_ws} ${kernel_addr} ${filesize}<br />

Copy to Flash... done<br />

=><br />

=> iminfo ${kernel_addr}<br />

## Checking Image at fc000000 ...<br />

Legacy image found<br />

Image Name: <strong>Linux</strong>-2.6.25-rc8-01016-g94bf13b-<br />

Created: 2008-04-10 9:50:08 UTC<br />

Image Type: PowerPC <strong>Linux</strong> Kernel Image (gzip compressed)<br />

Data Size: 1744262 Bytes = 1.7 MB<br />

Load Address: 00000000<br />

Entry Point: 00000000<br />

Verifying Checksum ... OK<br />

=><br />

=> saveenv<br />

Saving Environment to Flash...<br />

Un-Protected 1 sectors<br />

Un-Protected 1 sectors<br />

Erasing Flash...<br />

. done<br />

Erased 1 sectors<br />

Writing to Flash... done<br />

Protected 1 sectors<br />

Protected 1 sectors<br />

=><br />

Note how the filesize variable (which gets set by the TFTP transfer) is used to automatically adjust <strong>for</strong><br />

the actual image size.<br />

Since kernel requires the flattened device tree blob to be passed at boot time, you have to also write the blob<br />

to the flash memory. Below is a transcript of this operation.<br />

=><br />

=> setenv fdt_addr FC1E0000<br />

=><br />

=> prot off FC1E0000 FC1FFFFF<br />

Un-Protected 1 sectors<br />

=><br />

=> era FC1E0000 FC1FFFFF<br />

. done<br />

Erased 1 sectors<br />

=><br />

=> tftp 100000 /tftpboot/canyonl<strong>and</strong>s/canyonl<strong>and</strong>s.dtb<br />

Waiting <strong>for</strong> PHY auto negotiation to complete... done<br />

ENET Speed is 1000 Mbps - FULL duplex connection (EMAC0)<br />

Using ppc_4xx_eth0 device<br />

TFTP from server 192.168.1.1; our IP address is 192.168.100.6<br />

Filename '/tftpboot/canyonl<strong>and</strong>s/canyonl<strong>and</strong>s.dtb'.<br />

Load address: 0x100000<br />

Loading: *T #<br />

done<br />

Bytes transferred = 10000 (2710 hex)<br />

=><br />

7.6. <strong>Boot</strong> from Flash Memory 110


=> md 100000<br />

00100000: d00dfeed 00002710 000000b8 00001b08 ......'.........<br />

00100010: 00000028 00000011 00000010 00000000 ...(............<br />

00100020: 000002f5 00001a50 00000000 00000000 .......P........<br />

00100030: 00000000 00000000 00000000 00000000 ................<br />

00100040: 00000000 00000000 00000000 00000000 ................<br />

00100050: 00000000 00000000 00000000 00000000 ................<br />

00100060: 00000000 00000000 00000000 00000000 ................<br />

00100070: 00000000 00000000 00000000 00000000 ................<br />

00100080: 00000000 00000000 00000000 00000000 ................<br />

00100090: 00000000 00000000 00000000 00000000 ................<br />

001000a0: 00000000 00000000 00000000 00000000 ................<br />

001000b0: 00000000 00000000 00000001 00000000 ................<br />

001000c0: 00000003 00000004 00000000 00000002 ................<br />

001000d0: 00000003 00000004 0000000f 00000001 ................<br />

001000e0: 00000003 00000011 0000001b 616d6363 ............amcc<br />

001000f0: 2c63616e 796f6e6c 616e6473 00000000 ,canyonl<strong>and</strong>s....<br />

=><br />

=> setenv ram_ws 100000<br />

=><br />

=> cp.b ${ram_ws} ${fdt_addr} ${filesize}<br />

Copy to Flash... done<br />

=><br />

=> md ${fdt_addr}<br />

fc1e0000: d00dfeed 00002710 000000b8 00001b08 ......'.........<br />

fc1e0010: 00000028 00000011 00000010 00000000 ...(............<br />

fc1e0020: 000002f5 00001a50 00000000 00000000 .......P........<br />

fc1e0030: 00000000 00000000 00000000 00000000 ................<br />

fc1e0040: 00000000 00000000 00000000 00000000 ................<br />

fc1e0050: 00000000 00000000 00000000 00000000 ................<br />

fc1e0060: 00000000 00000000 00000000 00000000 ................<br />

fc1e0070: 00000000 00000000 00000000 00000000 ................<br />

fc1e0080: 00000000 00000000 00000000 00000000 ................<br />

fc1e0090: 00000000 00000000 00000000 00000000 ................<br />

fc1e00a0: 00000000 00000000 00000000 00000000 ................<br />

fc1e00b0: 00000000 00000000 00000001 00000000 ................<br />

fc1e00c0: 00000003 00000004 00000000 00000002 ................<br />

fc1e00d0: 00000003 00000004 0000000f 00000001 ................<br />

fc1e00e0: 00000003 00000011 0000001b 616d6363 ............amcc<br />

fc1e00f0: 2c63616e 796f6e6c 616e6473 00000000 ,canyonl<strong>and</strong>s....<br />

=><br />

=> setenv filesize<br />

=><br />

=> saveenv<br />

Saving Environment to Flash...<br />

Un-Protected 1 sectors<br />

Un-Protected 1 sectors<br />

Erasing Flash...<br />

. done<br />

Erased 1 sectors<br />

Writing to Flash... done<br />

Protected 1 sectors<br />

Protected 1 sectors<br />

=><br />

Now we can boot directly from flash. All we need to do is passing the in-flash address of the image<br />

(FC000000) <strong>and</strong> the in-flash address of the flattened device tree (FC1E0000) with the bootm comm<strong>and</strong>; we<br />

also make the definition of the bootargs variable permanent now:<br />

=> setenv bootcmd bootm FC000000 - FC1E0000<br />

=> setenv bootargs root=/dev/nfs rw nfsroot=${serverip}:${rootpath} ip=${ipaddr}:${serverip}:${ga<br />

Use printenv to verify that everything is OK be<strong>for</strong>e you save the environment settings:<br />

=> printenv<br />

7.6. <strong>Boot</strong> from Flash Memory 111


ootdelay=5<br />

baudrate=115200<br />

stdin=serial<br />

stdout=serial<br />

stderr=serial<br />

bootcmd=bootm FC000000 - FC1E0000<br />

bootargs=root=/dev/nfs rw nfsroot=192.168.1.1:/opt/eldk-4.2/ppc_4xx<br />

ip=192.168.100.6:192.168.1.1:192.168.1.1:255.255.0.0:canyonl<strong>and</strong>s::off<br />

....<br />

=> saveenv<br />

To test booting from flash you can now reset the board (either by power-cycling it, or using the U-<strong>Boot</strong><br />

comm<strong>and</strong> reset), or you can manually call the boot comm<strong>and</strong> which will run the comm<strong>and</strong>s in the<br />

bootcmd variable:<br />

<strong>Linux</strong> version 2.6.25-rc8-01016-g94bf13b-dirty (stefan@ubuntu) (gcc version 4.2.2) #54 Thu Apr 10<br />

=> run flash_self<br />

## <strong>Boot</strong>ing kernel from Legacy Image at fc000000 ...<br />

Image Name: <strong>Linux</strong>-2.6.25-rc8-01016-g94bf13b-<br />

Created: 2008-04-10 9:50:08 UTC<br />

Image Type: PowerPC <strong>Linux</strong> Kernel Image (gzip compressed)<br />

Data Size: 1744262 Bytes = 1.7 MB<br />

Load Address: 00000000<br />

Entry Point: 00000000<br />

Verifying Checksum ... OK<br />

Uncompressing Kernel Image ... OK<br />

## Flattened Device Tree blob at fc1e0000<br />

<strong>Boot</strong>ing using the fdt blob at 0xfc1e0000<br />

## Loading init Ramdisk from Legacy Image at fc200000 ...<br />

Image Name: Simple Embedded <strong>Linux</strong> Framework<br />

Created: 2008-03-27 17:13:20 UTC<br />

Image Type: PowerPC <strong>Linux</strong> RAMDisk Image (gzip compressed)<br />

Data Size: 1855932 Bytes = 1.8 MB<br />

Load Address: 00000000<br />

Entry Point: 00000000<br />

Verifying Checksum ... OK<br />

Loading Device Tree to 007fd000, end 007ff70f ... OK<br />

Loading Ramdisk to 0fd11000, end 0fed61bc ... OK<br />

Using Canyonl<strong>and</strong>s machine description<br />

Found initrd at 0xcfd11000:0xcfed61bc<br />

Zone PFN ranges:<br />

DMA 0 -> 65536<br />

Normal 65536 -> 65536<br />

Movable zone start PFN <strong>for</strong> each node<br />

early_node_map[1] active PFN ranges<br />

0: 0 -> 65536<br />

Built 1 zonelists in Zone order, mobility grouping on. Total pages: 65024<br />

7.7. St<strong>and</strong>alone Operation with Ramdisk Image<br />

When your application development is completed, you usually will want to run your Embedded System<br />

st<strong>and</strong>alone, i. e. independent from external resources like NFS filesystems. Instead of mounting the root<br />

filesystem from a remote server you can use a compressed ramdisk image, which is stored in flash memory<br />

<strong>and</strong> loaded into RAM when the system boots.<br />

Ramdisk images <strong>for</strong> tests can be found in the ftp://ftp.denx.de/pub/<strong>Linux</strong>PPC/usr/src/SELF/images/<br />

directories.<br />

Load the ramdisk image into RAM <strong>and</strong> write it to flash as follows:<br />

7.7. St<strong>and</strong>alone Operation with Ramdisk Image 112


=> setenv ramdisk_addr FC200000<br />

=><br />

=> setenv ram_ws 100000<br />

=><br />

=> prot off FC200000 FC3FFFFF<br />

Un-Protected 16 sectors<br />

=><br />

=> era FC200000 FC3FFFFF<br />

................ done<br />

Erased 16 sectors<br />

=><br />

=> tftp 100000 /tftpboot/canyonl<strong>and</strong>s/uRamdisk<br />

ENET Speed is 1000 Mbps - FULL duplex connection (EMAC0)<br />

Using ppc_4xx_eth0 device<br />

TFTP from server 192.168.1.1; our IP address is 192.168.100.6<br />

Filename '/tftpboot/canyonl<strong>and</strong>s/uRamdisk'.<br />

Load address: 0x100000<br />

Loading: *#################################################################<br />

##############################################################<br />

done<br />

Bytes transferred = 1855996 (1c51fc hex)<br />

=><br />

=> imi 100000<br />

## Checking Image at 00100000 ...<br />

Legacy image found<br />

Image Name: Simple Embedded <strong>Linux</strong> Framework<br />

Created: 2008-03-27 17:13:20 UTC<br />

Image Type: PowerPC <strong>Linux</strong> RAMDisk Image (gzip compressed)<br />

Data Size: 1855932 Bytes = 1.8 MB<br />

Load Address: 00000000<br />

Entry Point: 00000000<br />

Verifying Checksum ... OK<br />

=><br />

=> cp.b ${ram_ws} ${ramdisk_addr} ${filesize}<br />

Copy to Flash... done<br />

=><br />

=> imi ${ramdisk_addr}<br />

## Checking Image at fc200000 ...<br />

Legacy image found<br />

Image Name: Simple Embedded <strong>Linux</strong> Framework<br />

Created: 2008-03-27 17:13:20 UTC<br />

Image Type: PowerPC <strong>Linux</strong> RAMDisk Image (gzip compressed)<br />

Data Size: 1855932 Bytes = 1.8 MB<br />

Load Address: 00000000<br />

Entry Point: 00000000<br />

Verifying Checksum ... OK<br />

=><br />

=> saveenv<br />

Saving Environment to Flash...<br />

Un-Protected 1 sectors<br />

Un-Protected 1 sectors<br />

Erasing Flash...<br />

. done<br />

Erased 1 sectors<br />

Writing to Flash... done<br />

Protected 1 sectors<br />

Protected 1 sectors<br />

=><br />

To tell the <strong>Linux</strong> kernel to use the ramdisk image as root filesystem you have to modify the comm<strong>and</strong> line<br />

arguments passed to the kernel, <strong>and</strong> pass ramdisk image address as the second argument to the bootm<br />

comm<strong>and</strong> (first argument is the memory address of the <strong>Linux</strong> kernel image, the third one is the memory<br />

7.7. St<strong>and</strong>alone Operation with Ramdisk Image 113


address of the flattened device tree blob):<br />

=> run flash_self<br />

## <strong>Boot</strong>ing kernel from Legacy Image at fc000000 ...<br />

Image Name: <strong>Linux</strong>-2.6.25-rc8-01016-g94bf13b-<br />

Created: 2008-04-10 9:50:08 UTC<br />

Image Type: PowerPC <strong>Linux</strong> Kernel Image (gzip compressed)<br />

Data Size: 1744262 Bytes = 1.7 MB<br />

Load Address: 00000000<br />

Entry Point: 00000000<br />

Verifying Checksum ... OK<br />

Uncompressing Kernel Image ... OK<br />

## Flattened Device Tree blob at fc1e0000<br />

<strong>Boot</strong>ing using the fdt blob at 0xfc1e0000<br />

## Loading init Ramdisk from Legacy Image at fc200000 ...<br />

Image Name: Simple Embedded <strong>Linux</strong> Framework<br />

Created: 2008-03-27 17:13:20 UTC<br />

Image Type: PowerPC <strong>Linux</strong> RAMDisk Image (gzip compressed)<br />

Data Size: 1855932 Bytes = 1.8 MB<br />

Load Address: 00000000<br />

Entry Point: 00000000<br />

Verifying Checksum ... OK<br />

Loading Device Tree to 007fd000, end 007ff70f ... OK<br />

Loading Ramdisk to 0fd11000, end 0fed61bc ... OK<br />

Using Canyonl<strong>and</strong>s machine description<br />

<strong>Linux</strong> version 2.6.25-rc8-01016-g94bf13b-dirty (stefan@ubuntu) (gcc version 4.2.2) #54 Thu Apr 10<br />

Found initrd at 0xcfd11000:0xcfed61bc<br />

Zone PFN ranges:<br />

DMA 0 -> 65536<br />

Normal 65536 -> 65536<br />

Movable zone start PFN <strong>for</strong> each node<br />

early_node_map[1] active PFN ranges<br />

0: 0 -> 65536<br />

Built 1 zonelists in Zone order, mobility grouping on. Total pages: 65024<br />

Kernel comm<strong>and</strong> line: root=/dev/ram rw ip=192.168.100.6:192.168.1.1::255.255.0.0:canyonl<strong>and</strong>s:eth0:<br />

UIC0 (32 IRQ sources) at DCR 0xc0<br />

UIC1 (32 IRQ sources) at DCR 0xd0<br />

UIC2 (32 IRQ sources) at DCR 0xe0<br />

UIC3 (32 IRQ sources) at DCR 0xf0<br />

PID hash table entries: 1024 (order: 10, 4096 bytes)<br />

clocksource: timebase mult[6aaaab] shift[22] registered<br />

Dentry cache hash table entries: 32768 (order: 5, 131072 bytes)<br />

Inode-cache hash table entries: 16384 (order: 4, 65536 bytes)<br />

Memory: 253952k/262144k available (3464k kernel code, 7844k reserved, 124k data, 132k bss, 156k i<br />

SLUB: Genslabs=10, HWalign=32, Order=0-1, MinObjects=4, CPUs=1, Nodes=1<br />

Mount-cache hash table entries: 512<br />

net_namespace: 152 bytes<br />

NET: Registered protocol family 16<br />

PCIE1: Checking link...<br />

PCIE1: No device detected.<br />

PCI host bridge /plb/pciex@d20000000 (primary) ranges:<br />

MEM 0x0000000e80000000..0x0000000effffffff -> 0x0000000080000000<br />

IO 0x0000000f80010000..0x0000000f8001ffff -> 0x0000000000000000<br />

4xx PCI DMA offset set to 0x00000000<br />

PCIE1: successfully set as root-complex<br />

PCI host bridge /plb/pci@c0ec00000 (primary) ranges:<br />

MEM 0x0000000d80000000..0x0000000dffffffff -> 0x0000000080000000<br />

IO 0x0000000c08000000..0x0000000c0800ffff -> 0x0000000000000000<br />

4xx PCI DMA offset set to 0x00000000<br />

PCI: Probing PCI hardware<br />

PCI: Hiding 4xx host bridge resources 0000:80:00.0<br />

PCI: Bridge: 0000:80:00.0<br />

IO window: disabled.<br />

MEM window: disabled.<br />

PREFETCH window: disabled.<br />

7.7. St<strong>and</strong>alone Operation with Ramdisk Image 114


SCSI subsystem initialized<br />

usbcore: registered new interface driver usbfs<br />

usbcore: registered new interface driver hub<br />

usbcore: registered new device driver usb<br />

NET: Registered protocol family 2<br />

IP route cache hash table entries: 2048 (order: 1, 8192 bytes)<br />

TCP established hash table entries: 8192 (order: 4, 65536 bytes)<br />

TCP bind hash table entries: 8192 (order: 3, 32768 bytes)<br />

TCP: Hash tables configured (established 8192 bind 8192)<br />

TCP reno registered<br />

checking if image is initramfs...it isn't (no cpio magic); looks like an initrd<br />

Freeing initrd memory: 1812k freed<br />

io scheduler noop registered<br />

io scheduler anticipatory registered (default)<br />

io scheduler deadline registered<br />

io scheduler cfq registered<br />

Serial: 8250/16550 driver $Revision: 1.2 $ 4 ports, IRQ sharing enabled<br />

serial8250.0: ttyS0 at MMIO 0x4ef600300 (irq = 18) is a 16550A<br />

console [ttyS0] enabled<br />

serial8250.0: ttyS1 at MMIO 0x4ef600400 (irq = 19) is a 16550A<br />

serial8250.0: ttyS2 at MMIO 0x4ef600500 (irq = 29) is a 16550A<br />

serial8250.0: ttyS3 at MMIO 0x4ef600600 (irq = 20) is a 16550A<br />

4ef600300.serial: ttyS0 at MMIO 0x4ef600300 (irq = 18) is a 16550A<br />

4ef600400.serial: ttyS1 at MMIO 0x4ef600400 (irq = 19) is a 16550A<br />

4ef600500.serial: ttyS2 at MMIO 0x4ef600500 (irq = 29) is a 16550A<br />

4ef600600.serial: ttyS3 at MMIO 0x4ef600600 (irq = 20) is a 16550A<br />

brd: module loaded<br />

Intel(R) PRO/1000 Network Driver - version 7.3.20-k2-NAPI<br />

Copyright (c) 1999-2006 Intel Corporation.<br />

PPC 4xx OCP EMAC driver, version 3.54<br />

MAL v2 /plb/mcmal, 2 TX channels, 16 RX channels<br />

ZMII /plb/opb/emac-zmii@ef600d00 initialized<br />

RGMII /plb/opb/emac-rgmii@ef601500 initialized with MDIO support<br />

TAH /plb/opb/emac-tah@ef601350 initialized<br />

TAH /plb/opb/emac-tah@ef601450 initialized<br />

/plb/opb/emac-rgmii@ef601500: input 0 in RGMII mode<br />

eth0: EMAC-0 /plb/opb/ethernet@ef600e00, MAC 5e:ed:18:38:81:85<br />

eth0: found Generic MII PHY (0x00)<br />

/plb/opb/emac-rgmii@ef601500: input 1 in RGMII mode<br />

eth1: EMAC-1 /plb/opb/ethernet@ef600f00, MAC 5e:ed:18:38:81:86<br />

eth1: found Generic MII PHY (0x01)<br />

Driver 'sd' needs updating - please use bus_type methods<br />

sata_dwc: DW SATA host Id=0x00000000, Version=0x3138322a<br />

dw_ahb_dma_init: start=4bffd0800 size=400<br />

sata_dwc: SATA DMA initialized registers=0xd1054800<br />

scsi0 : sata-dwc<br />

ata1: SATA max UDMA/133 irq 22<br />

sata_dwc_error_h<strong>and</strong>ler<br />

ata_eh_recover: line 2646<br />

ata_eh_reset: line 2127<br />

ata_eh_reset: line 2163<br />

ata_eh_reset: line 2176<br />

ata_eh_reset: line 2196<br />

ata_eh_reset: line 2234<br />

ata_eh_reset: line 2272<br />

ata1: SATA link down (SStatus 0 SControl 300)<br />

ata_eh_reset: line 2304<br />

sata_dwc_error_h<strong>and</strong>ler<br />

ata_eh_recover: line 2646<br />

4cc000000.nor_flash: Found 1 x16 devices at 0x0 in 16-bit bank<br />

Amd/Fujitsu Extended Query Table at 0x0040<br />

4cc000000.nor_flash: CFI does not contain boot bank location. Assuming top.<br />

number of CFI chips: 1<br />

cfi_cmdset_0002: Disabling erase-suspend-program due to code brokenness.<br />

Red<strong>Boot</strong> partition parsing not available<br />

Creating 6 MTD partitions on "4cc000000.nor_flash":<br />

0x00000000-0x001e0000 : "kernel"<br />

7.7. St<strong>and</strong>alone Operation with Ramdisk Image 115


0x001e0000-0x00200000 : "dtb"<br />

0x00200000-0x00400000 : "root"<br />

0x00400000-0x03f60000 : "user"<br />

0x03f60000-0x03fa0000 : "env"<br />

0x03fa0000-0x04000000 : "u-boot"<br />

NDFC NAND Driver initialized. Chip-Rev: 0x00000111<br />

NAND device: Manufacturer ID: 0x20, Chip ID: 0x75 (ST Micro NAND 32MiB 3,3V 8-bit)<br />

Scanning device <strong>for</strong> bad blocks<br />

Bad eraseblock 1011 at 0x00fcc000<br />

Number of partitions 3<br />

Creating 3 MTD partitions on "NAND 32MiB 3,3V 8-bit":<br />

0x00000000-0x00060000 : "u-boot"<br />

0x00060000-0x00068000 : "env"<br />

0x00068000-0x02000000 : "content"<br />

ppc-of-ohci 4bffd0000.usb: OF OHCI<br />

ppc-of-ohci 4bffd0000.usb: new USB bus registered, assigned bus number 1<br />

ppc-of-ohci 4bffd0000.usb: irq 37, io mem 0x4bffd0000<br />

usb usb1: configuration #1 chosen from 1 choice<br />

hub 1-0:1.0: USB hub found<br />

hub 1-0:1.0: 1 port detected<br />

usb usb1: New USB device found, idVendor=1d6b, idProduct=0001<br />

usb usb1: New USB device strings: Mfr=3, Product=2, SerialNumber=1<br />

usb usb1: Product: OF OHCI<br />

usb usb1: Manufacturer: <strong>Linux</strong> 2.6.25-rc8-01016-g94bf13b-dirty ohci_hcd<br />

usb usb1: SerialNumber: PPC-OF USB<br />

Initializing USB Mass Storage driver...<br />

usbcore: registered new interface driver usb-storage<br />

USB Mass Storage support registered.<br />

dwc_otg: version 2.60a 22-NOV-2006<br />

dwc_otg: Shared Tx FIFO mode<br />

dwc_otg: Using Slave mode<br />

dwc_otg dwc_otg.0: DWC OTG Controller<br />

dwc_otg dwc_otg.0: new USB bus registered, assigned bus number 2<br />

dwc_otg dwc_otg.0: irq 28, io mem 0x00000000<br />

dwc_otg: dwc_otg_core_host_init: Unable to clear halt on channel 1<br />

dwc_otg: Init: Port Power op_state=4<br />

usb usb2: configuration #1 chosen from 1 choice<br />

hub 2-0:1.0: USB hub found<br />

hub 2-0:1.0: 1 port detected<br />

usb usb2: New USB device found, idVendor=1d6b, idProduct=0002<br />

usb usb2: New USB device strings: Mfr=3, Product=2, SerialNumber=1<br />

usb usb2: Product: DWC OTG Controller<br />

usb usb2: Manufacturer: <strong>Linux</strong> 2.6.25-rc8-01016-g94bf13b-dirty dwc_otg_hcd<br />

usb usb2: SerialNumber: dwc_otg.0<br />

i2c /dev entries driver<br />

IBM IIC driver v2.1<br />

TCP cubic registered<br />

NET: Registered protocol family 1<br />

NET: Registered protocol family 17<br />

RPC: Registered udp transport module.<br />

RPC: Registered tcp transport module.<br />

/home/stefan/git/linux-2.6/denx-merge-sr/drivers/rtc/hctosys.c: unable to open rtc device (rtc0)<br />

eth0: link is down<br />

IP-Config: Complete:<br />

device=eth0, addr=192.168.100.6, mask=255.255.0.0, gw=255.255.255.255,<br />

host=canyonl<strong>and</strong>s, domain=, nis-domain=(none),<br />

bootserver=192.168.1.1, rootserver=192.168.1.1, rootpath=<br />

RAMDISK: Compressed image found at block 0<br />

VFS: Mounted root (ext2 filesystem).<br />

Freeing unused kernel memory: 156k init<br />

eth0: link is up, 1000 FDX, pause enabled<br />

init started: BusyBox v1.7.1 (2008-03-27 18:07:38 MET)<br />

starting pid 810, tty '': '/etc/rc.sh'<br />

starting pid 815, tty '': '/bin/application'<br />

### Application running ...<br />

starting pid 821, tty '': '/bin/sh'<br />

~ #<br />

7.7. St<strong>and</strong>alone Operation with Ramdisk Image 116


~ #<br />

• 9. Advanced Topics<br />

♦ 9.1. Flash Filesystems<br />

◊ 9.1.1. Memory Technology Devices<br />

◊ 9.1.2. Journalling Flash File System<br />

◊ 9.1.3. Second Version of JFFS<br />

◊ 9.1.4. Compressed ROM Filesystem<br />

♦ 9.2. <strong>The</strong> TMPFS Virtual Memory Filesystem<br />

◊ 9.2.1. Mount Parameters<br />

◊ 9.2.2. Kernel Support <strong>for</strong> tmpfs<br />

◊ 9.2.3. Usage of tmpfs in Embedded Systems<br />

♦ 9.3. Adding Swap Space<br />

♦ 9.4. Splash Screen Support in <strong>Linux</strong><br />

♦ 9.5. Root File System: Design <strong>and</strong> Building<br />

◊ 9.5.1. Root File System on a Ramdisk<br />

◊ 9.5.2. Root File System on a JFFS2 File System<br />

◊ 9.5.3. Root File System on a cramfs File System<br />

◊ 9.5.4. Root File System on a Read-Only ext2 File System<br />

◊ 9.5.5. Root File System on a Flash Card<br />

◊ 9.5.6. Root File System in a Read-Only File in a FAT File System<br />

♦ 9.6. Root File System Selection<br />

♦ 9.7. Overlay File Systems<br />

♦ 9.8. <strong>The</strong> Persistent RAM File system (PRAMFS)<br />

◊ 9.8.1. Mount Parameters<br />

◊ 9.8.2. Example<br />

9. Advanced Topics<br />

This section lists some advanced topics of interest to users of U-<strong>Boot</strong> <strong>and</strong> <strong>Linux</strong>.<br />

9.1. Flash Filesystems<br />

9.1.1. Memory Technology Devices<br />

All currently available flash filesystems are based on the Memory Technology Devices MTD layer, so you<br />

must enable (at least) the following configuration options to get flash filesystem support in your system:<br />

CONFIG_MTD=y<br />

CONFIG_MTD_PARTITIONS=y<br />

CONFIG_MTD_CHAR=y<br />

CONFIG_MTD_BLOCK=y<br />

CONFIG_MTD_CFI=y<br />

CONFIG_MTD_GEN_PROBE=y<br />

CONFIG_MTD_CFI_AMDSTD=y<br />

CONFIG_MTD_ROM=y<br />

CONFIG_MTD_canyonl<strong>and</strong>s=y<br />

Note: this configuration uses CFI con<strong>for</strong>mant AMD flash chips; you may need to adjust these settings on<br />

other boards.<br />

9.1.1. Memory Technology Devices 117


<strong>The</strong> partition layout of the flash devices is contained in the flat device tree <strong>for</strong> the system (see 13.1. Flat<br />

Device Tree).<br />

In<strong>for</strong>mational messages of the MTD subsystem can be found in the <strong>Linux</strong> bootlog, i.e. see section 7.5.1.<br />

<strong>Boot</strong>log of <strong>Linux</strong> kernel with Root Filesystem over NFS.<br />

One can discover this in<strong>for</strong>mation in a running system using the proc filesystem:<br />

-bash-3.2# cat /proc/mtd<br />

dev: size erasesize name<br />

mtd0: 001e0000 00020000 "kernel"<br />

mtd1: 00020000 00020000 "dtb"<br />

mtd2: 00200000 00020000 "root"<br />

mtd3: 03b60000 00020000 "user"<br />

mtd4: 00040000 00020000 "env"<br />

mtd5: 00060000 00020000 "u-boot"<br />

mtd6: 02000000 00004000 "NAND 32MiB 3,3V 8-bit"<br />

mtd7: 00060000 00004000 "u-boot"<br />

mtd8: 00008000 00004000 "env"<br />

mtd9: 01f98000 00004000 "content"<br />

-bash-3.2#<br />

Now we can run some basic tests to verify that the flash driver routines <strong>and</strong> the partitioning works as<br />

expected:<br />

-bash-3.2# xxd /dev/mtd3 | head -4<br />

0000000: 5468 7520 4a61 6e20 2031 2030 313a 3034 Thu Jan 1 01:04<br />

0000010: 3a35 3120 4345 5420 3139 3730 0aff ffff :51 CET 1970....<br />

0000020: ffff ffff ffff ffff ffff ffff ffff ffff ................<br />

0000030: ffff ffff ffff ffff ffff ffff ffff ffff ................<br />

-bash-3.2#<br />

In the hex-dumps of the MTD devices you can identify some strings that verify that we indeed see an U-<strong>Boot</strong><br />

environment, a <strong>Linux</strong> kernel, a ramdisk image <strong>and</strong> an empty partition to play wih.<br />

<strong>The</strong> last output shows the partition to be empty. We can try write some data into it:<br />

-bash-3.2# date > /dev/mtd3<br />

-bash-3.2#<br />

-bash-3.2# head -1 /dev/mtd3<br />

Thu Jan 1 01:04:51 CET 1970<br />

-bash-3.2#<br />

-bash-3.2# date > /dev/mtd3<br />

-bash-3.2#<br />

As you can see it worked the first time. When we tried to write the (new date) again, we got an error. <strong>The</strong><br />

reason is that the date has changed (probably at least the seconds) <strong>and</strong> flash memory cannot be simply<br />

overwritten - it has to be erased first.<br />

You can use the eraseall <strong>Linux</strong> comm<strong>and</strong>s to erase a whole MTD partition:<br />

-bash-3.2# flash_eraseall /dev/mtd3<br />

Erasing 128 Kibyte @ 0 -- 0 % complete.Erasing 128 Kibyte @ 20000 -- 0 % complete.Erasing 128 K<br />

-bash-3.2#<br />

-bash-3.2# date > /dev/mtd3<br />

-bash-3.2#<br />

-bash-3.2# head -1 /dev/mtd3<br />

9.1.1. Memory Technology Devices 118


Thu Jan 1 01:04:51 CET 1970<br />

-bash-3.2#<br />

We have now sufficient proof that the MTD layer is working as expected, so we can try creating a flash<br />

filesystem.<br />

9.1.2. Journalling Flash File System<br />

At the moment it seems that the Journalling Flash File System JFFS is the best choice <strong>for</strong> filesystems in flash<br />

memory of embedded devices. You must enable the following configuration options to get JFFS support in<br />

your system:<br />

CONFIG_JFFS_FS=y<br />

CONFIG_JFFS_FS_VERBOSE=0<br />

If the flash device is erased, we can simply mount it, <strong>and</strong> the creation of the JFFS filesystem is per<strong>for</strong>med<br />

automagically.<br />

Note: For simple accesses like direct read or write operations or erasing you use the character device<br />

interface (/dev/mtd*) of the MTD layer, while <strong>for</strong> filesystem operations like mounting we must use the block<br />

device interface (/dev/mtdblock*).<br />

# eraseall /dev/mtd2<br />

Erased 4096 Kibyte @ 0 -- 100% complete.<br />

# mount -t jffs /dev/mtdblock2 /mnt<br />

# mount<br />

/dev/root on / type nfs (rw,v2,rsize=4096,wsize=4096,hard,udp,nolock,addr=10.0.0.2)<br />

proc on /proc type proc (rw)<br />

devpts on /dev/pts type devpts (rw)<br />

/dev/mtdblock2 on /mnt type jffs (rw)<br />

# df<br />

Filesystem 1k-blocks Used Available Use% Mounted on<br />

/dev/root 2087212 1232060 855152 60% /<br />

/dev/mtdblock2 3584 0 3584 0% /mnt<br />

Now you can access the files in the JFFS filesystem in the /mnt directory.<br />

9.1.3. Second Version of JFFS<br />

Probably even more interesting <strong>for</strong> embedded systems is the second version of JFFS, JFFS2, since it not only<br />

fixes a few design issues with JFFS, but also adds transparent compression, so that you can save a lot of<br />

precious flash memory.<br />

<strong>The</strong> mkfs.jffs2 tool is used to create a JFFS2 filesystem image; it populates the image with files from a<br />

given directory. For instance, to create a JFFS2 image <strong>for</strong> a flash partition of 3 MB total size <strong>and</strong> to populate it<br />

with the files from the /tmp/flashtools directory you would use:<br />

# mkfs.jffs2 --pad=3145728 --eraseblock=262144 \<br />

--root=/tmp/flashtools/ --output image.jffs2<br />

# eraseall /dev/mtd4<br />

Erased 3072 Kibyte @ 0 -- 100% complete.<br />

\# dd if=image.jffs2 of=/dev/mtd4 bs=256k<br />

12+0 records in<br />

12+0 records out<br />

# mount -t jffs2 /dev/mtdblock4 /mnt<br />

# df /mnt<br />

Filesystem 1k-blocks Used Available Use% Mounted on<br />

/dev/mtdblock4 3072 2488 584 81% /mnt<br />

9.1.3. Second Version of JFFS 119


Note: Especially when you are running time-critical applications on your system you should carefully<br />

study if the behaviour of the flash filesystem might have any negative impact on your application. After all, a<br />

flash device is not a normal harddisk. This is especially important when your flash filesystem gets full; JFFS2<br />

acts a bit weird then:<br />

• You will note that an increasing amount of CPU time is spent by the filesystem's garbage collection<br />

kernel thread.<br />

• Access times to the files on the flash filesystem may increase drastically.<br />

• Attempts to truncate a file (to free space) or to rename it may fail:<br />

...<br />

# cp /bin/bash file<br />

cp: writing `file': No space left on device<br />

# >file<br />

bash: file: No space left on device<br />

# mv file foo<br />

mv: cannot create regular file `foo': No space left on device<br />

You will have to use rm to actually delete a file in this situation.<br />

This is especially critical when you are using the flash filesystem to store log files: when your application<br />

detects some abnormal condition <strong>and</strong> produces lots of log messages (which usually are especially important in<br />

this situation) the filesystem may fill up <strong>and</strong> cause extreme long delays - if your system crashes, the most<br />

important messages may never be logged at all.<br />

9.1.4. Compressed ROM Filesystem<br />

In some cases it is sufficent to have read-only access to some files, <strong>and</strong> if the files are big enough it becomes<br />

desirable to use some method of compression. <strong>The</strong> Compressed ROM Filesystem CramFs might be a<br />

solution here.<br />

Please note that CramFs has - beside the fact that it is a read-only filesystem - some severe limitations (like<br />

missing support <strong>for</strong> timestamps, hard links, <strong>and</strong> 16/32 bit uid/gids), but there are many situations in Embedded<br />

Systems where it's still useful.<br />

To create a CramFs filesystem a special tool mkcramfs is used to create a file which contains the CramFs<br />

image. Note that the CramFs filesystem can be written <strong>and</strong> read only by kernels with PAGE_CACHE_SIZE<br />

== 4096, <strong>and</strong> some versions of the mkcramfs program may have other restrictions like that the filesystem<br />

must be written <strong>and</strong> read with architectures of the same endianness. Especially the endianness requirement<br />

makes it impossible to build the CramFs image on x86 PC host when you want to use it on a PowerPC target.<br />

<strong>The</strong> endianness problem has been fixed in the version of mkcramfs that comes with the ELDK.<br />

In some cases you can use a target system running with root filesystem mounted over NFS to create the<br />

CramFs image on the native system <strong>and</strong> store it to flash <strong>for</strong> further use.<br />

Note: <strong>The</strong> normal version of the mkcramfs program tries to initialize some entries in the filesystem's<br />

superblock with r<strong>and</strong>om numbers by reading /dev/r<strong>and</strong>om; this may hang permanently on your target because<br />

there is not enough input (like mouse movement) to the entropy pool. You may want to use a modified<br />

version of mkcramfs which does not depend on /dev/r<strong>and</strong>om.<br />

To create a CramFs image, you put all files you want in the filesystem into one directory, <strong>and</strong> then use the<br />

mkcramfs= program as follows:<br />

9.1.4. Compressed ROM Filesystem 120


$ mkdir /tmp/test<br />

$ cp ... /tmp/test<br />

$ du -sk /tmp/test<br />

64 /tmp/test<br />

$ mkcramfs /tmp/test test.cramfs.img<br />

Super block: 76 bytes<br />

erase<br />

eraseall<br />

mkfs.jffs<br />

lock<br />

unlock<br />

Directory data: 176 bytes<br />

-54.96% (-4784 bytes) erase<br />

-55.46% (-5010 bytes) eraseall<br />

-51.94% (-8863 bytes) mkfs.jffs<br />

-58.76% (-4383 bytes) lock<br />

-59.68% (-4215 bytes) unlock<br />

Everything: 24 kilobytes<br />

$ ls -l test.cramfs.img<br />

-rw-r--r-- 1 wd users 24576 Nov 10 23:44 test.cramfs.img<br />

As you can see, the CramFs image test.cramfs.img takes just 24 kB, while the input directory contained 64 kB<br />

of data. Savings of some 60% like in this case are typical CramFs.<br />

Now we write the CramFs image to a partition in flash <strong>and</strong> test it:<br />

# cp test.cramfs.img /dev/mtd3<br />

# mount -t cramfs /dev/mtdblock3 /mnt<br />

# mount<br />

/dev/root on / type nfs (rw,v2,rsize=4096,wsize=4096,hard,udp,nolock,addr=10.0.0.2)<br />

proc on /proc type proc (rw)<br />

devpts on /dev/pts type devpts (rw)<br />

/dev/mtdblock3 on /mnt type cramfs (rw)<br />

# ls -l /mnt<br />

total 54<br />

-rwxr-xr-x 1 wd users 8704 Jan 9 16:32 erase<br />

-rwxr-xr-x 1 wd users 9034 Jan 1 01:00 eraseall<br />

-rwxr-xr-x 1 wd users 7459 Jan 1 01:00 lock<br />

-rwxr-xr-x 1 wd users 17063 Jan 1 01:00 mkfs.jffs<br />

-rwxr-xr-x 1 wd users 7063 Jan 1 01:00 unlock<br />

Note that all the timestamps in the CramFs filesyste are bogus, <strong>and</strong> so is <strong>for</strong> instance the output of the df<br />

comm<strong>and</strong> <strong>for</strong> such filesystems:<br />

# df /mnt<br />

Filesystem 1k-blocks Used Available Use% Mounted on<br />

/dev/mtdblock3 0 0 0 - /mnt<br />

9.2. <strong>The</strong> TMPFS Virtual Memory Filesystem<br />

<strong>The</strong> tmpfs filesystem, <strong>for</strong>merly known as shmfs, is a filesystem keeping all files in virtual memory.<br />

Everything in tmpfs is temporary in the sense that no files will be created on any device. If you unmount a<br />

tmpfs instance, everything stored therein is lost.<br />

tmpfs puts everything into the kernel internal caches <strong>and</strong> grows <strong>and</strong> shrinks to accommodate the files it<br />

contains <strong>and</strong> is able to swap unneeded pages out to swap space. It has maximum size limits which can be<br />

adjusted on the fly via 'mount -o remount ...'<br />

9.2. <strong>The</strong> TMPFS Virtual Memory Filesystem 121


If you compare it to ramfs (which was the template to create tmpfs) you gain swapping <strong>and</strong> limit checking.<br />

Another similar thing is the RAM disk (/dev/ram*), which simulates a fixed size hard disk in physical RAM,<br />

where you have to create an ordinary filesystem on top. Ramdisks cannot swap <strong>and</strong> you do not have the<br />

possibility to resize them.<br />

9.2.1. Mount Parameters<br />

tmpfs has a couple of mount options:<br />

• size: <strong>The</strong> limit of allocated bytes <strong>for</strong> this tmpfs instance. <strong>The</strong> default is half of your physical RAM<br />

without swap. If you oversize your tmpfs instances the machine will deadlock since the OOM h<strong>and</strong>ler<br />

will not be able to free that memory.<br />

• nr_blocks: <strong>The</strong> same as size, but in blocks of PAGECACHE_SIZE.<br />

• nr_inodes: <strong>The</strong> maximum number of inodes <strong>for</strong> this instance. <strong>The</strong> default is half of the number of<br />

your physical RAM pages.<br />

<strong>The</strong>se parameters accept a suffix k, m or g <strong>for</strong> kilo, mega <strong>and</strong> giga <strong>and</strong> can be changed on remount.<br />

To specify the initial root directory you can use the following mount options:<br />

• mode: <strong>The</strong> permissions as an octal number<br />

• uid: <strong>The</strong> user id<br />

• gid: <strong>The</strong> group id<br />

<strong>The</strong>se options do not have any effect on remount. You can change these parameters with chmod(1),<br />

chown(1) <strong>and</strong> chgrp(1) on a mounted filesystem.<br />

So the following mount comm<strong>and</strong> will give you a tmpfs instance on /mytmpfs which can allocate 12MB of<br />

RAM/SWAP <strong>and</strong> it is only accessible by root.<br />

mount -t tmpfs -o size=12M,mode=700 tmpfs /mytmpfs<br />

9.2.2. Kernel Support <strong>for</strong> tmpfs<br />

In order to use a tmpfs filesystem, the CONFIG_TMPFS option has to be enabled <strong>for</strong> your kernel<br />

configuration. It can be found in the Filesystems configuration group. You can simply check if a running<br />

kernel supports tmpfs by searching the contents of /proc/fileysystems:<br />

bash# grep tmpfs /proc/filesystems<br />

nodev tmpfs<br />

bash#<br />

9.2.3. Usage of tmpfs in Embedded Systems<br />

In embedded systems tmpfs is very well suited to provide read <strong>and</strong> write space (e.g. /tmp <strong>and</strong> /var) <strong>for</strong> a<br />

read-only root file system such as CramFs described in section 9.1.4. Compressed ROM Filesystem. One way<br />

to achieve this is to use symbolic links. <strong>The</strong> following code could be part of the startup file /etc/rc.sh of the<br />

read-only ramdisk:<br />

#!/bin/sh<br />

...<br />

# Won't work on read-only root: mkdir /tmpfs<br />

mount -t tmpfs tmpfs /tmpfs<br />

mkdir /tmpfs/tmp /tmpfs/var<br />

# Won't work on read-only root: ln -sf /tmpfs/tmp /tmpfs/var /<br />

9.2.1. Mount Parameters 122


...<br />

<strong>The</strong> commented out sections will of course fail on a read-only root filesystem, so you have to create the<br />

/tmpfs mount-point <strong>and</strong> the symbolic links in your root filesystem be<strong>for</strong>eh<strong>and</strong> in order to successfully use<br />

this setup.<br />

9.3. Adding Swap Space<br />

If you are running out of system RAM, you can add virtual memory by using swap space. If you reserved a<br />

swap partition on your disk drive, you have to initialize it once using the mkswap comm<strong>and</strong>:<br />

# fdisk -l /dev/hda<br />

Disk /dev/hda: 16 heads, 63 sectors, 1575 cylinders<br />

Units = cylinders of 1008 * 512 bytes<br />

Device <strong>Boot</strong> Start End Blocks Id System<br />

/dev/hda1 1 5 2488+ 83 <strong>Linux</strong><br />

/dev/hda2 6 10 2520 83 <strong>Linux</strong><br />

/dev/hda3 11 141 66024 82 <strong>Linux</strong> swap<br />

/dev/hda4 142 1575 722736 83 <strong>Linux</strong><br />

# mkswap /dev/hda3<br />

Setting up swapspace version 1, size = 67604480 bytes<br />

<strong>The</strong>n, to activate it, you use the swapon comm<strong>and</strong> like this:<br />

# free<br />

total used free shared buffers cached<br />

Mem: 14628 14060 568 8056 100 11664<br />

-/+ buffers/cache: 2296 12332<br />

Swap: 0 0 0<br />

# free<br />

total used free shared buffers cached<br />

Mem: 14628 14060 568 8056 100 11664<br />

-/+ buffers/cache: 2296 12332<br />

Swap: 0 0 0<br />

# swapon /dev/hda3<br />

Adding Swap: 66016k swap-space (priority -2)<br />

# free<br />

total used free shared buffers cached<br />

Mem: 14628 14084 544 8056 100 11648<br />

-/+ buffers/cache: 2336 12292<br />

Swap: 66016 0 66016<br />

If you <strong>for</strong>got to reserve (sufficient) space in a separate partition on your disk, you can still use an ordinary file<br />

<strong>for</strong> swap space. You only have to create a file of appropriate size, <strong>and</strong> initialize it as follows:<br />

# mount /dev/hda4 /mnt<br />

# df<br />

Filesystem 1k-blocks Used Available Use% Mounted on<br />

/dev/root 2087212 1378824 708388 67% /<br />

/dev/hda4 711352 20 675196 1% /mnt<br />

# dd if=/dev/zero of=/mnt/swapfile bs=1024k count=64<br />

64+0 records in<br />

64+0 records out<br />

# mkswap /mnt/swapfile<br />

Setting up swapspace version 1, size = 67104768 bytes<br />

<strong>The</strong>n activate it:<br />

# free<br />

9.3. Adding Swap Space 123


total used free shared buffers cached<br />

Mem: 14628 14084 544 6200 96 11788<br />

-/+ buffers/cache: 2200 12428<br />

Swap: 0 0 0<br />

# swapon /mnt/swapfile<br />

Adding Swap: 65528k swap-space (priority -3)<br />

# free<br />

total used free shared buffers cached<br />

Mem: 14628 14084 544 6200 96 11752<br />

-/+ buffers/cache: 2236 12392<br />

Swap: 65528 0 65528<br />

9.4. Splash Screen Support in <strong>Linux</strong><br />

To complement the U-<strong>Boot</strong> Splash Screen feature the new configuration option<br />

"CONFIG_FB_PRE_INIT_FB" was added to the <strong>Linux</strong> kernel. This allows the <strong>Linux</strong> kernel to skip certain<br />

parts of the framebuffer initialization <strong>and</strong> to reuse the framebuffer contents that was set up by the U-<strong>Boot</strong><br />

firmware. This allows to have an image displayed nearly immediately after power-on, so the delay needed to<br />

boot the <strong>Linux</strong> kernel is masked to the user.<br />

<strong>The</strong> current implementation has some limitations:<br />

• We did not succeed in reusing the previously allocated framebuffer contents directly. Instead, <strong>Linux</strong><br />

will allocate a new framebuffer, copy the contents, <strong>and</strong> then switch the display. This adds a minimal<br />

delay to the boot time, but is otherwise invisible to the user.<br />

• <strong>Linux</strong> manages its own colormap, <strong>and</strong> we considered it too much ef<strong>for</strong>t to keep the same settings as<br />

used by U-<strong>Boot</strong>. Instead we use the "trick" that U-<strong>Boot</strong> will fill the color map table backwards (top<br />

down). This works pretty well <strong>for</strong> images which use no more than 200...255 colors. If the images uses<br />

more colors, a bad color mapping may result.<br />

We strongly recommend to convert all images that will be loaded as <strong>Linux</strong> splash screens to use no<br />

more than 225 colors. <strong>The</strong> "ppmquant" tool can be used <strong>for</strong> this purpose (see Bitmap Support in<br />

U-<strong>Boot</strong> <strong>for</strong> details).<br />

• Usually there will be a <strong>Linux</strong> device driver that is used to adjust the brightness <strong>and</strong> contrast of the<br />

display. When this driver starts, a visible change of brightness will happen if the default settings as<br />

used by U-<strong>Boot</strong> differ.<br />

We recommend to store settings of brightness <strong>and</strong> contrast in U-<strong>Boot</strong> environment variables that<br />

can be shared between U-<strong>Boot</strong> <strong>and</strong> <strong>Linux</strong>. This way it is possible (assuming adequate driver support)<br />

to adjust the display settings correctly already in U-<strong>Boot</strong> <strong>and</strong> thus to avoid any flicker of the display<br />

when <strong>Linux</strong> takes over control.<br />

9.5. Root File System: Design <strong>and</strong> Building<br />

It is not an easy task to design the root file system <strong>for</strong> an embedded system. <strong>The</strong>re are three major problems to<br />

be solved:<br />

1. what to put in it<br />

2. which file system type to use<br />

3. where to store <strong>and</strong> how to boot it<br />

For now we will assume that the contents of the root file system is aready known; <strong>for</strong> example, it is given to<br />

us as a directory tree or a tarball which contains all the required files.<br />

9.5. Root File System: Design <strong>and</strong> Building 124


We will also assume that our system is a typical resource-limited embedded system so we will especially look<br />

<strong>for</strong> solutions where the root file system can be stored on on-board flash memory or other flash memory based<br />

devices like CompactFlash or SD cards, MMC or USB memory sticks.<br />

A widespread approach to build a root file system is to use some <strong>Linux</strong> distribution (like the ELDK) <strong>and</strong> to<br />

remove things not needed. This approach may be pretty common, but it is almost always terribly wrong. You<br />

also don't build a family home by taking a skyscraper <strong>and</strong> removing parts. Like a house, a root file system<br />

should be built bottom up, starting from scratch <strong>and</strong> adding things you know you need. Never add anything<br />

where you don't exactly know what it's needed <strong>for</strong>.<br />

But our focus here is on the second item: the options we have <strong>for</strong> chosing a file system type <strong>and</strong> the<br />

consequences this has.<br />

In all cases we will base our experiments on the same content of the root filesystem; we use the images of the<br />

SELF (Simple Embedded <strong>Linux</strong> Framework) that come with the ELDK. In a first step we will trans<strong>for</strong>m the<br />

SELF images into a tarball to meet the requirements mentioned above:<br />

In a ELDK installation, the SELF images can be found in the /opt/eldk//images/<br />

directory. <strong>The</strong>re is already a compressed ramdisk image in this directory, which we will use<br />

(ramdisk_image.gz):<br />

1. Uncompress ramdisk image:<br />

bash$ gzip -d -c -v /opt/eldk/ppc_8xx/images/ramdisk_image.gz >/tmp/ramdisk_image<br />

/opt/eldk/ppc_8xx/images/ramdisk_image.gz: 61.4%<br />

Note: <strong>The</strong> following steps require root permissions!<br />

2. Mount ramdisk image:<br />

bash# mount -o loop /tmp/ramdisk_image /mnt/tmp<br />

3. Create tarball; to avoid the need <strong>for</strong> root permissions in the following steps we don't include the<br />

device files in our tarball:<br />

bash# cd /mnt/tmp<br />

bash# tar -zc --exclude='dev/*' -f /tmp/rootfs.tar.gz *<br />

4. Instead, we create a separate tarball which contains only the device entries so we can use them when<br />

necessary (with cramfs):<br />

bash# tar -zcf /tmp/devices.tar.gz dev/<br />

bash# cd /tmp<br />

5. Unmount ramdisk image:<br />

bash# umount /mnt/tmp<br />

We will use the /tmp/rootfs.tar.gz tarball as master file in all following experiments.<br />

9.5.1. Root File System on a Ramdisk<br />

Ram disks are used very often to hold the root file system of embedded systems. <strong>The</strong>y have several<br />

advantages:<br />

• well-known<br />

• well-supported by the <strong>Linux</strong> kernel<br />

• simple to build<br />

9.5.1. Root File System on a Ramdisk 125


• simple to use - you can even combine the ramdisk with the <strong>Linux</strong> kernel into a single image file<br />

• RAM based, thus pretty fast<br />

• writable file system<br />

• original state of file system after each reboot = easy recovery from accidental or malicious data<br />

corruption etc.<br />

On the other h<strong>and</strong>, there are several disadvantages, too:<br />

• big memory footprint: you always have to load the complete filesystem into RAM, even if only small<br />

parts of are actually used<br />

• slow boot time: you have to load (<strong>and</strong> uncompress) the whole image be<strong>for</strong>e the first application<br />

process can start<br />

• only the whole image can be replaced (not individual files)<br />

• additional storage needed <strong>for</strong> writable persistent data<br />

Actually there are only very few situations where a ramdisk image is the optimal solution. But because they<br />

are so easy to build <strong>and</strong> use we will discuss them here anyway.<br />

In almost all cases you will use an ext2 file system in your ramdisk image. <strong>The</strong> following steps are needed to<br />

create it:<br />

1.<br />

Create a directory tree with the content of the target root filesystem. We do this by unpacking our<br />

master tarball:<br />

$ mkdir rootfs<br />

$ cd rootfs<br />

$ tar zxf /tmp/rootfs.tar.gz<br />

2. We use the genext2fs tool to create the ramdisk image as this allows to use a simple text file to<br />

describe which devices shall be created in the generated file system image. That means that no root<br />

permissions are required at all. We use the following device table rootfs_devices.tab:<br />

# <br />

/dev d 755 0 0 - - - - -<br />

/dev/console c 640 0 0 5 1 - - -<br />

/dev/fb0 c 640 0 0 29 0 - - -<br />

/dev/full c 640 0 0 1 7 - - -<br />

/dev/hda b 640 0 0 3 0 - - -<br />

/dev/hda b 640 0 0 3 1 1 1 16<br />

/dev/kmem c 640 0 0 1 2 - - -<br />

/dev/mem c 640 0 0 1 1 - - -<br />

/dev/mtd c 640 0 0 90 0 0 2 16<br />

/dev/mtdblock b 640 0 0 31 0 0 1 16<br />

/dev/mtdr c 640 0 0 90 1 0 2 16<br />

/dev/nftla b 640 0 0 93 0 - - -<br />

/dev/nftla b 640 0 0 93 1 1 1 8<br />

/dev/nftlb b 640 0 0 93 16 - - -<br />

/dev/nftlb b 640 0 0 93 17 1 1 8<br />

/dev/null c 640 0 0 1 3 - - -<br />

/dev/ptyp c 640 0 0 2 0 0 1 10<br />

/dev/ptypa c 640 0 0 2 10 - - -<br />

/dev/ptypb c 640 0 0 2 11 - - -<br />

/dev/ptypc c 640 0 0 2 12 - - -<br />

/dev/ptypd c 640 0 0 2 13 - - -<br />

/dev/ptype c 640 0 0 2 14 - - -<br />

/dev/ptypf c 640 0 0 2 15 - - -<br />

/dev/ram b 640 0 0 1 0 0 1 2<br />

/dev/ram b 640 0 0 1 1 - - -<br />

/dev/rtc c 640 0 0 10 135 - - -<br />

/dev/tty c 640 0 0 4 0 0 1 4<br />

/dev/tty c 640 0 0 5 0 - - -<br />

/dev/ttyS c 640 0 0 4 64 0 1 8<br />

9.5.1. Root File System on a Ramdisk 126


3.<br />

4.<br />

/dev/ttyp c 640 0 0 3 0 0 1 10<br />

/dev/ttypa c 640 0 0 3 10 - - -<br />

/dev/ttypb c 640 0 0 3 11 - - -<br />

/dev/ttypc c 640 0 0 3 12 - - -<br />

/dev/ttypd c 640 0 0 3 13 - - -<br />

/dev/ttype c 640 0 0 3 14 - - -<br />

/dev/ttypf c 640 0 0 3 15 - - -<br />

/dev/zero c 640 0 0 1 5 - - -<br />

A description of the <strong>for</strong>mat of this table is part of the manual page <strong>for</strong> the genext2fs tool,<br />

genext2fs(8).<br />

We can now create an ext2 file system image using the genext2fs tool:<br />

$ ROOTFS_DIR=rootfs # directory with root file system content<br />

$ ROOTFS_SIZE=3700 # size of file system image<br />

$ ROOTFS_FREE=100 # free space wanted<br />

$ ROOTFS_INODES=380 # number of inodes<br />

$ ROOTFS_DEVICES=rootfs_devices.tab # device description file<br />

$ ROOTFS_IMAGE=ramdisk.img # generated file system image<br />

$ genext2fs -U \<br />

-d ${ROOTFS_DIR} \<br />

-D ${ROOTFS_DEVICES} \<br />

-b ${ROOTFS_SIZE} \<br />

-r ${ROOTFS_FREE} \<br />

-i ${ROOTFS_INODES} \<br />

${ROOTFS_IMAGE}<br />

Compress the file system image:<br />

$ gzip -v9 ramdisk.img<br />

rootfs.img: 55.6% -- replaced with ramdisk.img.gz<br />

5. Create an U-<strong>Boot</strong> image file from it:<br />

$ mkimage -T ramdisk -C gzip -n 'Test Ramdisk Image' \<br />

> -d ramdisk.img.gz uRamdisk<br />

Image Name: Test Ramdisk Image<br />

Created: Sun Jun 12 16:58:06 2005<br />

Image Type: PowerPC <strong>Linux</strong> RAMDisk Image (gzip compressed)<br />

Data Size: 1618547 Bytes = 1580.61 kB = 1.54 MB<br />

Load Address: 0x00000000<br />

Entry Point: 0x00000000<br />

We now have a root file system image uRamdisk that can be used with U-<strong>Boot</strong>.<br />

9.5.2. Root File System on a JFFS2 File System<br />

JFFS2 (Journalling Flash File System version 2) was specifically designed <strong>for</strong> use on flash memory devices in<br />

embedded systems. It is a log-structured file system which means that it is robust against loss of power,<br />

crashes or other unorderly shutdowns of the system ("robust" means that data that is just being written when<br />

the system goes down may be lost, but the file system itself does not get corrupted <strong>and</strong> the system can be<br />

rebootet without need <strong>for</strong> any kind of file system check).<br />

Some of the advantages of using JFFS2 as root file system in embedded systems are:<br />

• file system uses compression, thus making efficient use of flash memory<br />

• log-structured file system, thus robust against unorderly shutdown<br />

• flash sector wear-leveling<br />

• writable flash file system<br />

Disadvantages are:<br />

9.5.2. Root File System on a JFFS2 File System 127


• long mount times (especially older versions)<br />

• slow when reading: files to be read get uncompressed on the fly which eats CPU cycles <strong>and</strong> takes time<br />

• slow when writing: files to be written get compressed, which eats CPU cycles <strong>and</strong> takes time, but it<br />

may even take much longer until data gets actually stored in flash if the file system becomes full <strong>and</strong><br />

blocks must be erased first or - even worse - if garbage collection becomes necessary<br />

• <strong>The</strong> garbage collector thread may run at any time, consuming CPU cycles <strong>and</strong> blocking accesses to<br />

the file system.<br />

Despite the a<strong>for</strong>ementioned disadvantages, systems using a JFFS2 based root file system are easy to build,<br />

make efficient use of the available resources <strong>and</strong> can run pretty reliably.<br />

To create a JFFS2 based root file system please proceed as follows:<br />

1.<br />

Create a directory tree with the content of the target root filesystem. We do this by unpacking our<br />

master tarball:<br />

$ mkdir rootfs<br />

$ cd rootfs<br />

$ tar zxf /tmp/rootfs.tar.gz<br />

2. We can now create a JFFS2 file system image using the mkfs.jffs2 tool:<br />

$ ROOTFS_DIR=rootfs # directory with root file system content<br />

$ ROOTFS_EBSIZE=0x20000 # erase block size of flash memory<br />

$ ROOTFS_ENDIAN=b # target system is big endian<br />

$ ROOTFS_DEVICES=rootfs_devices.tab # device description file<br />

$ ROOTFS_IMAGE=jffs2.img # generated file system image<br />

$ mkfs.jffs2 -U \<br />

-d ${ROOTFS_DIR} \<br />

-D ${ROOTFS_DEVICES} \<br />

-${ROOTFS_ENDIAN} \<br />

-e ${ROOTFS_EBSIZE} \<br />

-o ${ROOTFS_IMAGE}<br />

mkfs.jffs2: skipping device_table entry '/dev': no parent directory!<br />

Note: When you intend to write the JFFS2 file system image to a NAND flash device, you should also<br />

add the "-n" (or "--no-cleanmarkers") option, as cleanmarkers are not needed then.<br />

When booting the <strong>Linux</strong> kernel prints the following messages showing the default partition map which is used<br />

<strong>for</strong> the flash memory on the TQM8xxL boards:<br />

TQM flash bank 0: Using static image partition definition<br />

Creating 7 MTD partitions on "TQM8xxL0":<br />

0x00000000-0x00040000 : "u-boot"<br />

0x00040000-0x00100000 : "kernel"<br />

0x00100000-0x00200000 : "user"<br />

0x00200000-0x00400000 : "initrd"<br />

0x00400000-0x00600000 : "cramfs"<br />

0x00600000-0x00800000 : "jffs"<br />

0x00400000-0x00800000 : "big_fs"<br />

We use U-<strong>Boot</strong> to load <strong>and</strong> store the JFFS2 image into the last partition <strong>and</strong> set up the <strong>Linux</strong> boot arguments<br />

to use this as root device:<br />

1. Erase flash:<br />

=> era 40400000 407FFFFF<br />

................. done<br />

Erased 35 sectors<br />

9.5.2. Root File System on a JFFS2 File System 128


2. Download JFFS2 image:<br />

=> tftp 100000 /tftpboot/TQM860L/jffs2.img<br />

Using FEC ETHERNET device<br />

TFTP from server 192.168.3.1; our IP address is 192.168.3.80<br />

Filename '/tftpboot/TQM860L/jffs2.img'.<br />

Load address: 0x100000<br />

Loading: #################################################################<br />

#################################################################<br />

#################################################################<br />

#################################################################<br />

#################################################################<br />

#################################################################<br />

########<br />

done<br />

Bytes transferred = 2033888 (1f08e0 hex)<br />

3. Copy image to flash:<br />

=> cp.b 100000 40400000 ${filesize}<br />

Copy to Flash... done<br />

4. set up boot arguments to use flash partition 6 as root device:<br />

=> setenv mtd_args setenv bootargs root=/dev/mtdblock6 rw rootfstype=jffs2<br />

=> printenv addip<br />

addip=setenv bootargs ${bootargs} ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}:${hostna<br />

=> setenv flash_mtd 'run mtd_args addip;bootm ${kernel_addr}'<br />

=> run flash_mtd<br />

Using FEC ETHERNET device<br />

TFTP from server 192.168.3.1; our IP address is 192.168.3.80<br />

Filename '/tftpboot/TQM860L/uImage'.<br />

Load address: 0x200000<br />

Loading: #################################################################<br />

#################################################################<br />

###########<br />

done<br />

Bytes transferred = 719233 (af981 hex)<br />

## <strong>Boot</strong>ing image at 40040000 ...<br />

Image Name: <strong>Linux</strong>-2.4.25<br />

Created: 2005-06-12 16:32:24 UTC<br />

Image Type: PowerPC <strong>Linux</strong> Kernel Image (gzip compressed)<br />

Data Size: 782219 Bytes = 763.9 kB<br />

Load Address: 00000000<br />

Entry Point: 00000000<br />

Verifying Checksum ... OK<br />

Uncompressing Kernel Image ... OK<br />

<strong>Linux</strong> version 2.4.25 (wd@xpert) (gcc version 3.3.3 (<strong>DENX</strong> ELDK 3.1.1 3.3.3-9)) #1 Sun Jun 12<br />

On node 0 totalpages: 4096<br />

zone(0): 4096 pages.<br />

zone(1): 0 pages.<br />

zone(2): 0 pages.<br />

Kernel comm<strong>and</strong> line: root=/dev/mtdblock6 rw rootfstype=jffs2 ip=192.168.3.80:192.168.3.1::2<br />

Decrementer Frequency = 187500000/60<br />

Calibrating delay loop... 49.86 BogoMIPS<br />

...<br />

NET4: Unix domain sockets 1.0/SMP <strong>for</strong> <strong>Linux</strong> NET4.0.<br />

VFS: Mounted root (jffs2 filesystem).<br />

Freeing unused kernel memory: 56k init<br />

BusyBox v0.60.5 (2005.03.07-06:54+0000) Built-in shell (msh)<br />

Enter 'help' <strong>for</strong> a list of built-in comm<strong>and</strong>s.<br />

# ### Application running ...<br />

# mount<br />

rootfs on / type rootfs (rw)<br />

/dev/mtdblock6 on / type jffs2 (rw)<br />

9.5.2. Root File System on a JFFS2 File System 129


proc on /proc type proc (rw)<br />

# df /<br />

Filesystem 1k-blocks Used Available Use% Mounted on<br />

rootfs 4096 2372 1724 58% /<br />

9.5.3. Root File System on a cramfs File System<br />

cramfs is a compressed, read-only file system.<br />

Advantages are:<br />

• file system uses compression, thus making efficient use of flash memory<br />

• Allows <strong>for</strong> quick boot times as only used files get loaded <strong>and</strong> uncompressed<br />

Disadvantages are:<br />

• only the whole image can be replaced (not individual files)<br />

• additional storage needed <strong>for</strong> writable persistent data<br />

• mkcramfs tool does not support device table, so we need root permissions to create the required<br />

device files<br />

To create a cramfs based root file system please proceed as follows:<br />

1.<br />

Create a directory tree with the content of the target root filesystem. We do this by unpacking our<br />

master tarball:<br />

$ mkdir rootfs<br />

$ cd rootfs<br />

$ tar -zxf /tmp/rootfs.tar.gz<br />

2. Create the required device files. We do this here by unpacking a special tarball which holds only the<br />

device file entries. Note: this requires root permissions!<br />

# cd rootfs<br />

# tar -zxf /tmp/devices.tar.gz<br />

3. Many tools require some storage place in a filesystem, so we must provide at least one (small)<br />

writable filesystem. For all data which may be lost when the system goes down, a "tmpfs"<br />

filesystem is the optimal choice. To create such a writable tmpfs filesystem we add the following lines<br />

to the /etc/rc.sh script:<br />

# mount TMPFS because root-fs is readonly<br />

/bin/mount -t tmpfs -o size=2M tmpfs /tmpfs<br />

Some tools require write permissions on some device nodes (<strong>for</strong> example, to change ownership <strong>and</strong><br />

permissions), or dynamically (re-) create such files (<strong>for</strong> example, /dev/log which is usually a Unix<br />

Domain socket). <strong>The</strong> files are placed in a writable filesystem; in the root filesystem symbolic links are<br />

used to point to their new locations:<br />

dev/ptyp0 → /tmpfs/dev/ptyp0 dev/ttyp0 → /tmpfs/dev/ttyp0<br />

dev/ptyp1 → /tmpfs/dev/ptyp1 dev/ttyp1 → /tmpfs/dev/ttyp1<br />

dev/ptyp2 → /tmpfs/dev/ptyp2 dev/ttyp2 → /tmpfs/dev/ttyp2<br />

dev/ptyp3 → /tmpfs/dev/ptyp3 dev/ttyp3 → /tmpfs/dev/ttyp3<br />

dev/ptyp4 → /tmpfs/dev/ptyp4 dev/ttyp4 → /tmpfs/dev/ttyp4<br />

dev/ptyp5 → /tmpfs/dev/ptyp5 dev/ttyp5 → /tmpfs/dev/ttyp5<br />

dev/ptyp6 → /tmpfs/dev/ptyp6 dev/ttyp6 → /tmpfs/dev/ttyp6<br />

9.5.3. Root File System on a cramfs File System 130


4.<br />

dev/ptyp7 → /tmpfs/dev/ptyp7 dev/ttyp7 → /tmpfs/dev/ttyp7<br />

dev/ptyp8 → /tmpfs/dev/ptyp8 dev/ttyp8 → /tmpfs/dev/ttyp8<br />

dev/ptyp9 → /tmpfs/dev/ptyp9 dev/ttyp9 → /tmpfs/dev/ttyp9<br />

dev/ptypa → /tmpfs/dev/ptypa dev/ttypa → /tmpfs/dev/ttypa<br />

dev/ptypb → /tmpfs/dev/ptypb dev/ttypb → /tmpfs/dev/ttypb<br />

dev/ptypc → /tmpfs/dev/ptypc dev/ttypc → /tmpfs/dev/ttypc<br />

dev/ptypd → /tmpfs/dev/ptypd dev/ttypd → /tmpfs/dev/ttypd<br />

dev/ptype → /tmpfs/dev/ptype dev/ttype → /tmpfs/dev/ttype<br />

dev/ptypf → /tmpfs/dev/ptypf dev/ttypf → /tmpfs/dev/ttypf<br />

tmp → /tmpfs/tmp var → /tmpfs/var<br />

dev/log → /var/log/log<br />

In case you use dhclient also:<br />

etc/dhclient.conf → /tmpfs/var/lib/dhclient.conf etc/resolv.conf → /tmpfs/var/lib/resolv.conf<br />

To place the corresponding directories <strong>and</strong> device files in the tmpfs file system, the following code<br />

is added to the /etc/rc.sh script:<br />

mkdir -p /tmpfs/tmp /tmpfs/dev \<br />

/tmpfs/var/lib/dhcp /tmpfs/var/lock /tmpfs/var/run<br />

while read name minor<br />

do<br />

mknod /tmpfs/dev/ptyp$name c 2 $minor<br />

mknod /tmpfs/dev/ttyp$name c 3 $minor<br />

done


Super block: 76 bytes<br />

CRC: c166be6d<br />

warning: gids truncated to 8 bits. (This may be a security concern.)<br />

5. We can use the same setup as be<strong>for</strong>e <strong>for</strong> the JFFS2 filesystem, just changing the bootargument to<br />

"rootfstype=cramfs"<br />

9.5.4. Root File System on a Read-Only ext2 File<br />

System<br />

When storing the root file system in on-board flash memory it seems only natural to look <strong>for</strong> special flash<br />

filesystems like JFFS2, or <strong>for</strong> other file system types that are designed <strong>for</strong> such environments like cramfs. It<br />

seems to be a bad idea to use a st<strong>and</strong>ard ext2 file system because it contains neither any type of wear<br />

leveling which is needed <strong>for</strong> writable file systems in flash memory, nor is it robust against unorderly<br />

shutdowns.<br />

<strong>The</strong> situation changes if we use an ext2 file system which we mount read-only. Such a configuration can be<br />

very useful in some situations.<br />

Advantages:<br />

• very fast<br />

• low RAM memory footprint<br />

Disadvantages:<br />

• high flash memory footprint because no compression<br />

To create an ext2 image that can be used as a read-only root file system the following steps are necessary:<br />

1.<br />

Create a directory tree with the content of the target root filesystem. We do this by unpacking our<br />

master tarball:<br />

$ mkdir rootfs<br />

$ cd rootfs<br />

$ tar -zxf /tmp/rootfs.tar.gz<br />

2. Like with the cramfs root file system, we use "tmpfs" <strong>for</strong> cases where a writable file system is<br />

needed <strong>and</strong> add the following lines to the /etc/rc.sh script:<br />

# mount TMPFS because root-fs is readonly<br />

/bin/mount -t tmpfs -o size=2M tmpfs /tmpfs<br />

We also create the same symbolic links <strong>for</strong> device files that must be placed in a writable filesystem:<br />

dev/ptyp0 → /tmpfs/dev/ptyp0 dev/ttyp0 → /tmpfs/dev/ttyp0<br />

dev/ptyp1 → /tmpfs/dev/ptyp1 dev/ttyp1 → /tmpfs/dev/ttyp1<br />

dev/ptyp2 → /tmpfs/dev/ptyp2 dev/ttyp2 → /tmpfs/dev/ttyp2<br />

dev/ptyp3 → /tmpfs/dev/ptyp3 dev/ttyp3 → /tmpfs/dev/ttyp3<br />

dev/ptyp4 → /tmpfs/dev/ptyp4 dev/ttyp4 → /tmpfs/dev/ttyp4<br />

dev/ptyp5 → /tmpfs/dev/ptyp5 dev/ttyp5 → /tmpfs/dev/ttyp5<br />

dev/ptyp6 → /tmpfs/dev/ptyp6 dev/ttyp6 → /tmpfs/dev/ttyp6<br />

dev/ptyp7 → /tmpfs/dev/ptyp7 dev/ttyp7 → /tmpfs/dev/ttyp7<br />

dev/ptyp8 → /tmpfs/dev/ptyp8 dev/ttyp8 → /tmpfs/dev/ttyp8<br />

9.5.4. Root File System on a Read-Only ext2 File System 132


3.<br />

dev/ptyp9 → /tmpfs/dev/ptyp9 dev/ttyp9 → /tmpfs/dev/ttyp9<br />

dev/ptypa → /tmpfs/dev/ptypa dev/ttypa → /tmpfs/dev/ttypa<br />

dev/ptypb → /tmpfs/dev/ptypb dev/ttypb → /tmpfs/dev/ttypb<br />

dev/ptypc → /tmpfs/dev/ptypc dev/ttypc → /tmpfs/dev/ttypc<br />

dev/ptypd → /tmpfs/dev/ptypd dev/ttypd → /tmpfs/dev/ttypd<br />

dev/ptype → /tmpfs/dev/ptype dev/ttype → /tmpfs/dev/ttype<br />

dev/ptypf → /tmpfs/dev/ptypf dev/ttypf → /tmpfs/dev/ttypf<br />

tmp → /tmpfs/tmp var → /tmpfs/var<br />

dev/log → /var/log/log<br />

In case you use dhclient also:<br />

etc/dhclient.conf → /tmpfs/var/lib/dhclient.conf etc/resolv.conf → /tmpfs/var/lib/resolv.conf<br />

To place the corresponding directories <strong>and</strong> device files in the tmpfs file system, the following code<br />

is added to the /etc/rc.sh script:<br />

mkdir -p /tmpfs/tmp /tmpfs/dev \<br />

/tmpfs/var/lib/dhcp /tmpfs/var/lock /tmpfs/var/run<br />

while read name minor<br />

do<br />

mknod /tmpfs/dev/ptyp$name c 2 $minor<br />

mknod /tmpfs/dev/ttyp$name c 3 $minor<br />

done


change the "rw" argument into "ro" to mount our root file system really read-only:<br />

...<br />

<strong>Linux</strong> version 2.4.25 (wd@xpert) (gcc version 3.3.3 (<strong>DENX</strong> ELDK 3.1.1 3.3.3-9)) #1 Sun Jun 12<br />

On node 0 totalpages: 4096<br />

zone(0): 4096 pages.<br />

zone(1): 0 pages.<br />

zone(2): 0 pages.<br />

Kernel comm<strong>and</strong> line: root=/dev/mtdblock6 ro rootfstype=ext2 ip=192.168.3.80:192.168.3.1::25<br />

Decrementer Frequency = 187500000/60<br />

Calibrating delay loop... 49.86 BogoMIPS<br />

...<br />

9.5.5. Root File System on a Flash Card<br />

Using an ext2 file system on a flash memory card (like CompactFlash, SD, MMC or a USB memory stick)<br />

is st<strong>and</strong>ard technology. To avoid unnecessary flash wear it is a good idea to mount the root file system<br />

read-only, or at least using the "noatime" mount option.<br />

For our test we can use the "ext2.img" file from the previous step without changes:<br />

1.<br />

In this test we use a st<strong>and</strong>ard CompactFlash card which comes with a single partition on it. We use<br />

U-<strong>Boot</strong> to copy the ext2 file system image into this partition:<br />

=> tftp 100000 /tftpboot/TQM860L/ext2.img<br />

Using FEC ETHERNET device<br />

TFTP from server 192.168.3.1; our IP address is 192.168.3.80<br />

Filename '/tftpboot/TQM860L/ext2.img'.<br />

Load address: 0x100000<br />

Loading: #################################################################<br />

#################################################################<br />

#################################################################<br />

#################################################################<br />

#################################################################<br />

#################################################################<br />

#################################################################<br />

#################################################################<br />

#################################################################<br />

#################################################################<br />

#################################################################<br />

##########################<br />

done<br />

Bytes transferred = 3788800 (39d000 hex)<br />

=> ide part<br />

Partition Map <strong>for</strong> IDE device 0 --<br />

Partition Type: DOS<br />

Partition Start Sector Num Sectors Type<br />

1 32 500704 6<br />

=> ide write 100000 20 1ce8<br />

IDE write: device 0 block # 32, count 7400 ... 7400 blocks written: OK<br />

Note that the "ide write" comm<strong>and</strong> takes parameters as hex numbers, <strong>and</strong> the write count is in<br />

terms of disk blocks of 512 bytes each. So we have to use 0x20 <strong>for</strong> the starts sector of the first<br />

partition, <strong>and</strong> 3788800 / 512 = 7400 = 0x1CE8 <strong>for</strong> the block count.<br />

2. We now prepare the <strong>Linux</strong> boot arguments to take this partition as read-only root device:<br />

=> setenv cf_args setenv bootargs root=/dev/hda1 ro<br />

=> setenv flash_cf 'run cf_args addip;bootm ${kernel_addr} - ${fdt_addr}'<br />

9.5.5. Root File System on a Flash Card 134


3.<br />

=> setenv bootcmd run flash_cf<br />

...<strong>and</strong> boot the system:<br />

...<br />

<strong>Linux</strong> version 2.4.25 (wd@xpert) (gcc version 3.3.3 (<strong>DENX</strong> ELDK 3.1.1 3.3.3-9)) #1 Sun Jun 12<br />

On node 0 totalpages: 4096<br />

zone(0): 4096 pages.<br />

zone(1): 0 pages.<br />

zone(2): 0 pages.<br />

Kernel comm<strong>and</strong> line: root=/dev/hda1 ro ip=192.168.3.80:192.168.3.1::255.255.255.0:tqm860l:e<br />

Decrementer Frequency = 187500000/60<br />

Calibrating delay loop... 49.86 BogoMIPS<br />

...<br />

9.5.6. Root File System in a Read-Only File in a<br />

FAT File System<br />

This is a more complicated example that shows that - depending on project requirements - many other<br />

alternatives <strong>for</strong> chosing a root file system <strong>for</strong> your embedded system exist.<br />

<strong>The</strong> scenario is as follows: on your embedded device you use a cheap <strong>and</strong> popular storage medium like<br />

CompactFlash, MMC or SD cards or USB memory sticks to store both the <strong>Linux</strong> kernel <strong>and</strong> your root file<br />

system. You want to distribute software updates over the internet: your customers can download the file from<br />

your web site, or you sent the images by email. Your customers may use any flash card or memory stick they<br />

happen to find, so you have no in<strong>for</strong>mation about br<strong>and</strong> or size of the storage device.<br />

Un<strong>for</strong>tunately most of your customers use Windows systems. And they don't want to be bothered with long<br />

instructions how to create special partitions on the storage device or how to write binary images or things like<br />

that. A simple "copy file" operation is nearly exhausting their capabilities.<br />

What to do Well, if copying a file is all your customers can do we should not ask <strong>for</strong> more. Storage devices<br />

like CompactFlash cards etc. typically come with a single partition on it, which holds a FAT or VFAT file<br />

system. This cannot be used as a <strong>Linux</strong> root file system directly, so we have to use some trickery.<br />

Here is one possible solution: Your software distribution consistes of two files: <strong>The</strong> first file is the <strong>Linux</strong><br />

kernel with a minimal ramdisk image attached (using the multi-file image <strong>for</strong>mat <strong>for</strong> U-<strong>Boot</strong>); U-<strong>Boot</strong> can<br />

load <strong>and</strong> boot such files from a FAT or VFAT file system. <strong>The</strong> second file is your root file system. For<br />

convenience <strong>and</strong> speed we use again an image of an ext2 file system. When <strong>Linux</strong> boots, it will initially use<br />

the attached ramdisk as root file system. <strong>The</strong> programs in this ramdisk will mount the FAT or VFAT file<br />

system - read-only. <strong>The</strong>n we can use a loop device (see losetup(8)) to associate the root file system image with<br />

a block device which can be used as a mount point. And finally we use pivot_root(8) to change the root file<br />

system to our image on the CF card.<br />

This sounds not so complicated, <strong>and</strong> actually it is quite simple once you underst<strong>and</strong> what needs to be done.<br />

Here is a more detailed description:<br />

1. <strong>The</strong> root file system image is easy: as mantioned be<strong>for</strong>e, we will use an ext2 file system image, <strong>and</strong><br />

to avoid wearing the flash storage device we will use it in read-only mode - we did a read-only ext2<br />

root file system image be<strong>for</strong>e, <strong>and</strong> here we can just re-use the existing image file.<br />

2. <strong>The</strong> initial ramdisk image that per<strong>for</strong>ms the pivot_root step must be created from scratch, but we<br />

already know how to create ramdisk images, so we just have to figure out what to put in it.<br />

<strong>The</strong> most important tool here is nash, a script interpreter that was specifically designed <strong>for</strong> such<br />

purposes (see nash(8)). We don't need any additional tools, <strong>and</strong> if we use static linking, then the<br />

9.5.6. Root File System in a Read-Only File in a FAT File System 135


3.<br />

nash binary plus a small script to control it is all we need <strong>for</strong> our initial ramdisk.<br />

To be precise, we need a couple of (empty) directories (bin, dev, etc, lib, loopfs, mnt, proc,<br />

<strong>and</strong> sysroot), the bin/nash binary, the linuxrc script <strong>and</strong> a symbolic link sbin pointing to<br />

bin:<br />

drwxr-xr-x 2 wd users 4096 Apr 13 01:11 bin<br />

-rwxr-xr-x 1 wd users 469512 Apr 11 22:47 bin/nash<br />

drwxr-xr-x 2 wd users 4096 Apr 12 00:04 dev<br />

drwxr-xr-x 2 wd users 4096 Apr 12 00:04 etc<br />

drwxr-xr-x 2 wd users 4096 Apr 12 00:04 lib<br />

-rwxr-xr-x 1 wd users 511 Apr 13 01:28 linuxrc<br />

drwxr-xr-x 2 wd users 4096 Apr 12 00:04 loopfs<br />

drwxr-xr-x 2 wd users 4096 Apr 12 00:09 mnt<br />

drwxr-xr-x 2 wd users 4096 Apr 12 00:04 proc<br />

lrwxrwxrwx 1 wd users 3 Jun 12 18:54 sbin -> bin<br />

drwxr-xr-x 2 wd users 4096 Apr 12 00:04 sysroot<br />

We also need only a minimal device table <strong>for</strong> creating the initial ramdisk:<br />

# <br />

/dev d 755 0 0 - - - - -<br />

/dev/console c 640 0 0 5 1 - - -<br />

/dev/hda b 640 0 0 3 0 - - -<br />

/dev/hda b 640 0 0 3 1 1 1 8<br />

/dev/loop b 640 0 0 7 0 0 1 4<br />

/dev/null c 640 0 0 1 3 - - -<br />

/dev/ram b 640 0 0 1 0 0 1 2<br />

/dev/ram b 640 0 0 1 1 - - -<br />

/dev/tty c 640 0 0 4 0 0 1 4<br />

/dev/tty c 640 0 0 5 0 - - -<br />

/dev/ttyS c 640 0 0 4 64 0 1 4<br />

/dev/zero c 640 0 0 1 5 - - -<br />

4. To create the initial ramdisk we per<strong>for</strong>m the usual steps:<br />

$ INITRD_DIR=initrd<br />

$ INITRD_SIZE=490<br />

$ INITRD_FREE=0<br />

$ INITRD_INODES=54<br />

$ INITRD_DEVICES=initrd_devices.tab<br />

$ INITRD_IMAGE=initrd.img<br />

$ genext2fs -U \<br />

-d ${INITRD_DIR} \<br />

-D ${INITRD_DEVICES} \<br />

-b ${INITRD_SIZE} \<br />

-r ${INITRD_FREE} \<br />

-i ${INITRD_INODES} \<br />

${INITRD_IMAGE}<br />

$ gzip -v9 ${INITRD_IMAGE}<br />

<strong>The</strong> result is a really small (233 kB) compressed ramdisk image.<br />

5. Assuming you already have your <strong>Linux</strong> kernel image, you can now use mkimage to build an U-<strong>Boot</strong><br />

multi-file image that combines the <strong>Linux</strong> kernel <strong>and</strong> the initial ramdisk:<br />

$ LINUX_KERNEL=linuxppc_2_4_devel/arch/ppc/boot/images/vmlinux.gz<br />

$ mkimage -A ppc -O <strong>Linux</strong> -T multi -C gzip \<br />

> -n '<strong>Linux</strong> with Pivot Root Helper' \<br />

> -d ${LINUX_KERNEL}:${INITRD_IMAGE}.gz linux.img<br />

Image Name: <strong>Linux</strong> with Pivot Root Helper<br />

Created: Mon Jun 13 01:48:11 2005<br />

Image Type: PowerPC <strong>Linux</strong> Multi-File Image (gzip compressed)<br />

Data Size: 1020665 Bytes = 996.74 kB = 0.97 MB<br />

Load Address: 0x00000000<br />

9.5.6. Root File System in a Read-Only File in a FAT File System 136


Entry Point: 0x00000000<br />

Contents:<br />

Image 0: 782219 Bytes = 763 kB = 0 MB<br />

Image 1: 238433 Bytes = 232 kB = 0 MB<br />

<strong>The</strong> newly created file linux.img is the second image we have to copy to the CF card.<br />

We are done.<br />

But wait - one essential part was not mentioned yet: the linuxrc script in our initial ramdisk image which<br />

contains all the magic. This script is quite simple:<br />

#!/bin/nash<br />

echo Mounting /proc filesystem<br />

mount -t proc /proc /proc<br />

echo Creating block devices<br />

mkdevices /dev<br />

echo Creating root device<br />

mkrootdev /dev/root<br />

echo 0x0100 > /proc/sys/kernel/real-root-dev<br />

echo Mounting flash card<br />

mount -o noatime -t vfat /dev/hda1 /mnt<br />

echo losetup <strong>for</strong> filesystem image<br />

losetup /dev/loop0 /mnt/rootfs.img<br />

echo Mounting root filesystem image<br />

mount -o defaults --ro -t ext2 /dev/loop0 /sysroot<br />

echo Running pivot_root<br />

pivot_root /sysroot /sysroot/initrd<br />

umount /initrd/proc<br />

Let's go though it step by step:<br />

• <strong>The</strong> first line says that it's a script file <strong>for</strong> the /bin/nash interpreter.<br />

Note: even if this file looks like a shell script it is NOT interpreted by a shell, but by the nash<br />

interpreter. For a complete list of available nash comm<strong>and</strong>s <strong>and</strong> their syntax please refer to the<br />

manual page, nash(8).<br />

• <strong>The</strong> first action is to mount the /proc pseudo file system which is needed to find out some required<br />

in<strong>for</strong>mation.<br />

• <strong>The</strong>n we create block device entries <strong>for</strong> all partitions listed in /proc/partitions (mkdevices<br />

comm<strong>and</strong>).<br />

• In the next step a block device <strong>for</strong> our new root file system is created (mkrootdev comm<strong>and</strong>).<br />

• <strong>The</strong>n we mount the CF card. We assume that there is only a single partition on it (/dev/hda1)<br />

which is of type VFAT (which also will work with FAT file systems). <strong>The</strong>se assumptions work fine<br />

with basicly all memory devices used under Windows.<br />

• We further assume that the file name of the root file system image on the CF card is<br />

"rootfs.img" - this file now gets mounted using a loop device (losetup <strong>and</strong> mount<br />

comm<strong>and</strong>s).<br />

• Our file system image, is now mounted on the /sysroot directory. In the last step we use<br />

pivot_root to make this the new root file system.<br />

• As a final cleanup we unmount the /proc file system which is not needed any more.<br />

<strong>The</strong>re is one tiny flaw in this method: since we mount the CF card on a directory in the ramdisk to be able to<br />

access to root file system image. This means that we cannot unmount the CF card, which in turn prevents us<br />

9.5.6. Root File System in a Read-Only File in a FAT File System 137


from freeing the space <strong>for</strong> the inital ramdisk. <strong>The</strong> consequence is that you permanently lose approx. 450 kB of<br />

RAM <strong>for</strong> the ramdisk. [We could of course re-use this ramdisk space <strong>for</strong> temporary data, but such<br />

optimization is beyond the scope of this document.]<br />

And how does this work on our target<br />

1. First we copy the two images to the CF card; we do this on the target under <strong>Linux</strong>:<br />

bash-2.05b# fdisk -l /dev/hda<br />

Disk /dev/hda: 256 MB, 256376832 bytes<br />

16 heads, 32 sectors/track, 978 cylinders<br />

Units = cylinders of 512 * 512 = 262144 bytes<br />

Device <strong>Boot</strong> Start End Blocks Id System<br />

/dev/hda1 * 1 978 250352 6 FAT16<br />

bash-2.05b# mkfs.vfat /dev/hda1<br />

mkfs.vfat 2.8 (28 Feb 2001)<br />

bash-2.05b# mount -t vfat /dev/hda1 /mnt<br />

bash-2.05b# cp -v linux.img rootfs.img /mnt/<br />

`linux.img' -> `/mnt/linux.img'<br />

`rootfs.img' -> `/mnt/rootfs.img'<br />

bash-2.05b# ls -l /mnt<br />

total 4700<br />

-rwxr--r-- 1 root root 1020729 Jun 14 05:36 linux.img<br />

-rwxr--r-- 1 root root 3788800 Jun 14 05:36 rootfs.img<br />

bash-2.05b# umount /mnt<br />

2. We now prepare U-<strong>Boot</strong> to load the "uMulti" file (combined <strong>Linux</strong> kernel <strong>and</strong> initial ramdisk)<br />

from the CF card <strong>and</strong> boot it:<br />

=> setenv fat_args setenv bootargs rw<br />

=> setenv fat_boot 'run fat_args addip;fatload ide 0:1 200000 linux.img;bootm'<br />

=> setenv bootcmd run fat_boot<br />

3. And finally we try it out:<br />

U-<strong>Boot</strong> 1.1.3 (Jun 13 2005 - 02:24:00)<br />

CPU: XPC86xxxZPnnD4 at 50 MHz: 4 kB I-Cache 4 kB D-Cache FEC present<br />

Board: TQM860LDB0A3-T50.202<br />

DRAM: 16 MB<br />

FLASH: 8 MB<br />

In: serial<br />

Out: serial<br />

Err: serial<br />

Net: SCC ETHERNET, FEC ETHERNET [PRIME]<br />

PCMCIA: 3.3V card found: Transcend 256M<br />

Fixed Disk Card<br />

IDE interface<br />

[silicon] [unique] [single] [sleep] [st<strong>and</strong>by] [idle] [low power]<br />

Bus 0: OK<br />

Device 0: Model: Transcend 256M Firm: 1.1 Ser#: SSSC256M04Z27A25906T<br />

Type: Removable Hard Disk<br />

Capacity: 244.5 MB = 0.2 GB (500736 x 512)<br />

Type "run flash_nfs" to mount root filesystem over NFS<br />

Hit any key to stop autoboot: 0<br />

reading linux.img<br />

1025657 bytes read<br />

## <strong>Boot</strong>ing image at 00200000 ...<br />

Image Name: <strong>Linux</strong> with Pivot Root Helper<br />

Created: 2005-06-13 0:32:41 UTC<br />

Image Type: PowerPC <strong>Linux</strong> Multi-File Image (gzip compressed)<br />

9.5.6. Root File System in a Read-Only File in a FAT File System 138


Data Size: 1025593 Bytes = 1001.6 kB<br />

Load Address: 00000000<br />

Entry Point: 00000000<br />

Contents:<br />

Image 0: 787146 Bytes = 768.7 kB<br />

Image 1: 238433 Bytes = 232.8 kB<br />

Verifying Checksum ... OK<br />

Uncompressing Multi-File Image ... OK<br />

Loading Ramdisk to 00f3d000, end 00f77361 ... OK<br />

<strong>Linux</strong> version 2.4.25 (wd@xpert) (gcc version 3.3.3 (<strong>DENX</strong> ELDK 3.1.1 3.3.3-9)) #1 Mon Jun 13<br />

On node 0 totalpages: 4096<br />

zone(0): 4096 pages.<br />

zone(1): 0 pages.<br />

zone(2): 0 pages.<br />

Kernel comm<strong>and</strong> line: rw ip=192.168.3.80:192.168.3.1::255.255.255.0:tqm860l:eth1:off panic=1<br />

Decrementer Frequency = 187500000/60<br />

Calibrating delay loop... 49.86 BogoMIPS<br />

...<br />

NET4: Unix domain sockets 1.0/SMP <strong>for</strong> <strong>Linux</strong> NET4.0.<br />

RAMDISK: Compressed image found at block 0<br />

Freeing initrd memory: 232k freed<br />

VFS: Mounted root (ext2 filesystem).<br />

Red Hat nash version 4.1.18 starting<br />

Mounting /proc filesystem<br />

Creating block devices<br />

Creating root device<br />

Mounting flash card<br />

hda: hda1<br />

hda: hda1<br />

losetup <strong>for</strong> filesystem image<br />

Mounting root filesystem image<br />

Running pivot_root<br />

Freeing unused kernel memory: 60k init<br />

BusyBox v0.60.5 (2005.03.07-06:54+0000) Built-in shell (msh)<br />

Enter 'help' <strong>for</strong> a list of built-in comm<strong>and</strong>s.<br />

# ### Application running ...<br />

Kernel with a Flattened Device Tree Blob<br />

When booting an arch/powerpc kernel that requires a flattened device tree blob, the above procedure must<br />

be slightly modified. Namely, the multi-image file has to include the blob as the thrid image. Here's an<br />

example of the mkimage comm<strong>and</strong> to create it:<br />

mkimage -A ppc -O <strong>Linux</strong> -T multi -C gzip -n 'Kernel + Pivot Root Helper initrd + FDT blob' -d vml<br />

Image Name: Kernel + Pivot Root Helper initrd + FDT blob<br />

Created: Fri Sep 14 18:24:29 2007<br />

Image Type: PowerPC <strong>Linux</strong> Multi-File Image (gzip compressed)<br />

Data Size: 2894576 Bytes = 2826.73 kB = 2.76 MB<br />

Load Address: 0x00000000<br />

Entry Point: 0x00000000<br />

Contents:<br />

Image 0: 1351205 Bytes = 1319 kB = 1 MB<br />

Image 1: 1531063 Bytes = 1495 kB = 1 MB<br />

Image 2: 12288 Bytes = 12 kB = 0 MB<br />

<strong>The</strong> newly created file kernel+initrd+blob.img needs to be copied to the CF card.<br />

Kernel with a Flattened Device Tree Blob 139


9.6. Root File System Selection<br />

Now we know several options <strong>for</strong> file systems we can use, <strong>and</strong> know how to create the corresponding images.<br />

But how can we decide which one to chose<br />

For practical purposes in embedded systems the following criteria are often essential:<br />

• boot time (i. e. time needed from power on until application code is running)<br />

• flash memory footprint<br />

• RAM memory footprint<br />

• effects on software updates<br />

<strong>The</strong> following data was measured <strong>for</strong> the different configurations. All measurements were per<strong>for</strong>med on the<br />

same TQM860L board (MPC860 CPU at 50 MHz, 16 MB RAM, 8 MB flash, 256 MB CompactFlash card):<br />

File System Type <strong>Boot</strong> Time Free Mem Updates while running<br />

ramdisk 16.3 sec 6.58 MB whole image yes<br />

JFFS2 21.4 sec 10.3 MB per file only non-active files<br />

cramfs 10.8 sec 10.3 MB whole image no<br />

ext2 (ro) 9.1 sec 10.8 MB whole image no<br />

ext2 on CF (ro) 9.3 sec 10.9 MB whole image no<br />

File on FAT fs 11.4 sec 7.8 MB whole image yes<br />

As you can see, the ramdisk solution is the worst of all in terms of RAM memory footprint; also it takes a<br />

pretty long time to boot. However, it is one of the few solutions that allow an in-situ update while the system<br />

is running.<br />

JFFS2 is easy to use as it's a writable file system but it takes a long time to boot.<br />

A read-only ext2 file system shines when boot time <strong>and</strong> RAM memory footprint are important; you pay <strong>for</strong><br />

this with an increased flash memory footprint.<br />

External flash memory devices like CompactFlash cards or USB memory sticks can be cheap <strong>and</strong> efficient<br />

solutions especially when lots of data need to be stored or when easy update procedures are required. -<br />

9.7. Overlay File Systems<br />

Introduction<br />

Overlay File Systems provide an interesting approach to several frequent problems in Embedded Systems. For<br />

example, mini_fo is a virtual kernel file system that can make read-only file systems writable. This is done<br />

by redirecting modifying operations to a writeable location called "storage directory", <strong>and</strong> leaving the original<br />

data in the "base directory" untouched. When reading, the file system merges the modifed <strong>and</strong> original data so<br />

that only the newest versions will appear. This occurs transparently to the user, who can access the data like<br />

on any other read-write file system.<br />

9.7. Overlay File Systems 140


What it is good <strong>for</strong><br />

In embedded systems the main use of mini_fo is to overlay the root file system. This means it is mounted<br />

on top of the regular root file system, thereby allowing applications or users to transparently make<br />

modifications to it but redirecting these to a different location.<br />

Some examples of why this is usefull are explained in the following sections.<br />

Making a read-only root filesystem writeable<br />

Root file systems stored in flash are often read only, such as cramfs or read only ext2. While this offers major<br />

advantages in terms of speed <strong>and</strong> flash memory footprint, it nevertheless is often desireable to be able to<br />

modify the root file system, <strong>for</strong> example to<br />

• apply (small) software updates without having to burn a whole new root file system image to flash<br />

• make modifications during developement when frequent changes to the root file system occur.<br />

This can be achieved by mounting mini_fo on top of the root file system <strong>and</strong> using a (probably small)<br />

writeable partition as the storage file system. This could be either a JFFS2 flash file system, or during<br />

development even an external hard disk. This has the following advantages:<br />

• read-only file systems (fast, small memory footprint) can be used like persistent writable file systems<br />

(in contrast to a ramdisk)<br />

• slow flash journalling file systems with large flash memory footprint can be avoided.<br />

Non persistant changes<br />

Ramdisks are often used when the root file system needs to be modified non-persistantly. This works well, but<br />

downsides are the large RAM memory footprint <strong>and</strong> the time costly operation of copying the ramdisk into<br />

RAM during startup. <strong>The</strong>se can be avoided by overlaying the root file system as in the previous example but<br />

with the difference that the tmpfs file system is used as storage. Thus only modified files are stored in RAM,<br />

<strong>and</strong> can even be swapped out if neccessary. This saves boot time <strong>and</strong> RAM!<br />

Resetable changes<br />

Mini_fo can be easily used to implement a "reset to factory defaults" function by overlaying the default root<br />

file system. When configuration changes are made, these are automatically directed to the storage file system<br />

<strong>and</strong> take precedence over the original files. Now, to restore the system to factory defaults, all that needs to be<br />

done is delete the contents of the storage directory. This will remove all changes made to the root file system<br />

<strong>and</strong> return it to the original state.<br />

Note: Deleting the contents of the storage directory should only be done when the overlay file system is<br />

unmounted.<br />

Examples<br />

Generally, there are two different ways of overlaying the root file system, which both make sense in different<br />

scenarios.<br />

Starting a single application in a chrooted overlayed environment<br />

What it is good <strong>for</strong> 141


This is easy. Let's assume "/" is the read-only root file system <strong>and</strong> /dev/mtdblock5 contains a small JFFS2<br />

flash partition that shall be used to store modifications made by application "/usr/bin/autoPilot":<br />

# mount -t jffs2 /dev/mtdblock5 /tmp/sto<br />

# insmod mini_fo.o<br />

# mount -t mini_fo -o base=/,sto=/tmp/sto/ / /mnt/mini_fo/<br />

# cd /mnt/mini_fo/<br />

# chroot . /usr/bin/autoPilot<br />

<strong>The</strong> mini_fo file system is mounted with "/" as base directory, "/tmp/sto/" as storage directory to the mount<br />

point "/mnt/mini_fo". After that, chroot(1) is used to start the application with the new file system root<br />

"/mnt/mini_fo". All modifications made by the application will be stored to the JFFS2 file system in /tmp/sto.<br />

Starting the whole system system in chrooted overlayed environment<br />

This is more interesting, <strong>and</strong> a bit trickier, as mounting needs to be done during system startup after the root<br />

file system has been mounted, but be<strong>for</strong>e init is started. <strong>The</strong> best way to do this is to have a script that mounts<br />

the mini_fo file system on top of root <strong>and</strong> then starts init in the chrooted overlayed environment. For example<br />

assume the following script "overlay_init", stored in /sbin/:<br />

#!/bin/bash<br />

#<br />

# mount mini_fo overlay file system <strong>and</strong> execute init<br />

#<br />

# make sure these exist in the read-only file system<br />

STORAGE=/tmp/sto<br />

MOUNT_POINT=/mnt/mini_fo/<br />

# mount tmpfs as storage file system with a maximum size of 32MB<br />

mount -t tmpfs -o rw,size=32M none $STORAGE<br />

/sbin/modprobe mini_fo<br />

mount -t mini_fo -o base=/,sto=$STORAGE / $MOUNT_POINT<br />

exec /usr/sbin/chroot $MOUNT_POINT /sbin/init<br />

echo "exec chroot failed, bad!"<br />

exec /bin/sh<br />

exit 1<br />

Now its easy to choose between a mini_fo overlayed <strong>and</strong> the regular non overlayed system just by setting<br />

the "init" kernel parameter in the boot loader to "init=/sbin/overlay_init".<br />

Tips<br />

• pivot_root(1) can be used with chroot if there is need to access the original non overlayed root<br />

file system from the chrooted overlayed environment.<br />

Per<strong>for</strong>mance overhead<br />

<strong>The</strong> mini_fo file system is inserted as an additional layer between the VFS <strong>and</strong> the native file system, <strong>and</strong><br />

thus creates some overhead that varies strongly depending of the operation per<strong>for</strong>med.<br />

1. modifying a regular file <strong>for</strong> the first time<br />

This results in a copy of the original file beeing created in the storage directory, that is then modified.<br />

Overhead depends on the size of the modified file.<br />

Starting a single application in a chrooted overlayed environment 142


2. Reading from files, creating new files, modifying already modified files<br />

<strong>The</strong>se operations are passed directly through to the lower native layer, <strong>and</strong> only impose an overhead<br />

of 1-2%.<br />

Further in<strong>for</strong>mation<br />

This section discusses how the mini_fo overlay file system can be used in embedded systems. More general<br />

in<strong>for</strong>mation is available at the mini_fo project page: http://www.denx.de/wiki/Know/MiniFOHome.<br />

9.8. <strong>The</strong> Persistent RAM File system (PRAMFS)<br />

<strong>The</strong> pramfs file system supports persistent memory devices such as SRAM. Instead of having a block<br />

emulation layer over such a memory area <strong>and</strong> using a normal file system on top of that, pramfs seeks to<br />

induce minimal overhead in this situation. Most important in this respect is that the normal block layer<br />

caching of the <strong>Linux</strong> kernel is circumvented in pramfs.<br />

9.8.1. Mount Parameters<br />

<strong>The</strong> most important parameters <strong>for</strong> normal usage are<br />

• physaddr: <strong>The</strong> physical address of the static memory.<br />

• init: When given, it will initialize the file system to that size.<br />

9.8.2. Example<br />

We will show a sample usage of pramfs in this section using normal DRAM on a board with at least 256MB<br />

of memory. For pramfs we reserve the upper 32MB by appending mem=224M to the kernel comm<strong>and</strong> line.<br />

First off we generate some testdata on a persistent file system (/tmp) to demonstrate that pramfs survives a<br />

reboot (of course with power always applied to keep the DRAM refreshed):<br />

bash-3.00# dd if=/dev/ur<strong>and</strong>om bs=1M count=8 of=/tmp/testdata<br />

8+0 records in<br />

8+0 records out<br />

bash-3.00#<br />

Next we mount the 32MB that we reserved <strong>and</strong> initialize it to be 32MB in size <strong>and</strong> copy the testfile. A final<br />

compare shows that the copy was indeed successful so we can reboot:<br />

bash-3.00# mount -t pramfs -o physaddr=0xe000000,init=0x2000000 none /mnt<br />

bash-3.00# cp /tmp/testdata /mnt<br />

bash-3.00# cmp /tmp/testdata /mnt/testdata<br />

bash-3.00# reboot<br />

Having rebooted (using mem=224M on the kernel comm<strong>and</strong> line again of course) we mount the file system<br />

but this time without the init parameter because it is preinitialized. We then check the contents again:<br />

bash-3.00# mount -t pramfs -o physaddr=0xe000000 none /mnt<br />

bash-3.00# ls /mnt<br />

testdata<br />

bash-3.00# cmp /tmp/testdata /mnt/testdata<br />

bash-3.00#<br />

9.8. <strong>The</strong> Persistent RAM File system (PRAMFS) 143


• 10. Debugging<br />

♦ 10.1. Debugging of U-<strong>Boot</strong><br />

◊ 10.1.1. Debugging of U-<strong>Boot</strong> Be<strong>for</strong>e Relocation<br />

◊ 10.1.2. Debugging of U-<strong>Boot</strong> After Relocation<br />

♦ 10.2. <strong>Linux</strong> Kernel Debugging<br />

◊ 10.2.1. <strong>Linux</strong> Kernel <strong>and</strong> Statically Linked Device Drivers<br />

◊ 10.2.2. Dynamically Loaded Device Drivers (Modules)<br />

◊ 10.2.3. GDB Macros to Simplify Module Loading<br />

♦ 10.3. GDB Startup File <strong>and</strong> Utility Scripts<br />

♦ 10.4. Tips <strong>and</strong> Tricks<br />

♦ 10.5. Application Debugging<br />

◊ 10.5.1. Local Debugging<br />

◊ 10.5.2. Remote Debugging<br />

♦ 10.6. Debugging with Graphical User Interfaces<br />

10. Debugging<br />

<strong>The</strong> purpose of this document is not to provide an introduction into programming <strong>and</strong> debugging in general.<br />

We assume that you know how to use the GNU debugger gdb <strong>and</strong> probably it's graphical frontends like ddd.<br />

We also assume that you have access to adequate tools <strong>for</strong> your work, i. e. a BDI2000 BDM/JTAG debugger.<br />

<strong>The</strong> following discussion assumes that the host name of your BDI2000 is bdi.<br />

Please note that there are several limitations in earlier versions of GDB. <strong>The</strong> version of GDB as distributed<br />

with the ELDK contains several bug fixes <strong>and</strong> extensions. If you find that your GDB behaves differently, have<br />

a look at the GDB sources <strong>and</strong> patches that come with the ELDK source.<br />

10.1. Debugging of U-<strong>Boot</strong><br />

When U-<strong>Boot</strong> starts it is running from ROM space. Running from flash would make it nearly impossible to<br />

read from flash while executing code from flash not to speak of updating the U-<strong>Boot</strong> image in flash itself. To<br />

be able to do just that, U-<strong>Boot</strong> relocates itself to RAM. We there<strong>for</strong>e have two phases with different program<br />

addresses. <strong>The</strong> following sections show how to debug U-<strong>Boot</strong> in both phases.<br />

10.1.1. Debugging of U-<strong>Boot</strong> Be<strong>for</strong>e Relocation<br />

Be<strong>for</strong>e relocation, the addresses in the ELF file can be used without any problems, so debugging U-<strong>Boot</strong> in<br />

this phase with the BDI2000 is quite easy:<br />

bash[0]$ ${CROSS_COMPILE}gdb u-boot<br />

GNU gdb 5.1.1<br />

Copyright 2002 Free Software Foundation, Inc.<br />

GDB is free software, covered by the GNU General Public License, <strong>and</strong> you are<br />

welcome to change it <strong>and</strong>/or distribute copies of it under certain conditions.<br />

Type "show copying" to see the conditions.<br />

<strong>The</strong>re is absolutely no warranty <strong>for</strong> GDB. Type "show warranty" <strong>for</strong> details.<br />

This GDB was configured as "--host=i386-redhat-linux --target=ppc-linux"...<br />

(gdb) target remote bdi:2001<br />

Remote debugging using bdi:2001<br />

0xfffffffc in ()<br />

(gdb) b cpu_init_f<br />

Breakpoint 1 at 0xfffd3310: file cpu_init.c, line 136.<br />

(gdb) c<br />

Continuing.<br />

Breakpoint 1, cpu_init_f () at cpu_init.c:136<br />

10.1. Debugging of U-<strong>Boot</strong> 144


136 asm volatile(" bl 0f" ::: "lr");<br />

(gdb) s<br />

137 asm volatile("0: mflr 3" ::: "r3");<br />

(gdb)<br />

138 asm volatile(" addi 4, 0, 14" ::: "r4");<br />

(gdb)<br />

cpu_init_f is the first C function called from the code in start.C.<br />

10.1.2. Debugging of U-<strong>Boot</strong> After Relocation<br />

For debugging U-<strong>Boot</strong> after relocation we need to know the address to which U-<strong>Boot</strong> relocates itself to. When<br />

no exotic features like PRAM are used, this address usually is - CFG_MONITOR_LEN. In our<br />

example with 16MB RAM <strong>and</strong> CFG_MONITOR_LEN = 192KB this yields the address 0x1000000 -<br />

0x30000 = 0xFD0000.<br />

In other cases, check the source code, <strong>and</strong> apply some common sense. For example, on PowerPC we use "r2"<br />

to hold a pointer to the "global data" structure ("struct global_data"); this structure contains a field<br />

unsigned long reloc_off; /* Relocation Offset */<br />

which is the offset between the image addresses in flash <strong>and</strong> in RAM. You can easily print this value in gdb<br />

like that:<br />

(gdb) print/x ((gd_t *)$r2)->reloc_off<br />

<strong>The</strong>n add this value to the value of TEXT_BASE as defined in your board's config.mk file, <strong>and</strong> you get the<br />

start address of the U-<strong>Boot</strong> image in RAM.<br />

With this knowledge, we can instruct gdb to <strong>for</strong>get the old symbol table <strong>and</strong> reload the symbols with our<br />

calculated offset:<br />

(gdb) symbol-file<br />

Discard symbol table from `/home/dzu/denx/cvs-trees/u-boot/u-boot' (y or n) y<br />

No symbol file now.<br />

(gdb) add-symbol-file u-boot 0xfd0000<br />

add symbol table from file "u-boot" at<br />

.text_addr = 0xfd0000<br />

(y or n) y<br />

Reading symbols from u-boot...done.<br />

(gdb) b board_init_r<br />

Breakpoint 2 at 0xfd99ac: file board.c, line 533.<br />

(gdb) c<br />

Continuing.<br />

Breakpoint 2, board_init_r (id=0xfbb1f0, dest_addr=16495088) at board.c:533<br />

533 {<br />

(gdb)<br />

board_init_r is the first C routine running in the newly relocated C friendly RAM environment.<br />

<strong>The</strong> simple example above relocates the symbols of only one section, .text. Other sections of the<br />

executable image (like .data, .bss, etc.) are not relocated <strong>and</strong> this prevents gdb from accessing static <strong>and</strong><br />

global variables by name. See more sophisticated examples in section 10.3. GDB Startup File <strong>and</strong> Utility<br />

Scripts.<br />

10.1.1. Debugging of U-<strong>Boot</strong> Be<strong>for</strong>e Relocation 145


10.2. <strong>Linux</strong> Kernel Debugging<br />

10.2.1. <strong>Linux</strong> Kernel <strong>and</strong> Statically Linked Device Drivers<br />

10.2.2. Dynamically Loaded Device Drivers (Modules)<br />

First start GDB in the root directory of your <strong>Linux</strong> kernel, using the vmlinux kernel image as file to debug:<br />

bash$ cd <br />

bash$ ${CROSS_COMPILE}gdb vmlinux<br />

GNU gdb 5.1.1<br />

Copyright 2002 Free Software Foundation, Inc.<br />

GDB is free software, covered by the GNU General Public License, <strong>and</strong> you are<br />

welcome to change it <strong>and</strong>/or distribute copies of it under certain conditions.<br />

Type "show copying" to see the conditions.<br />

<strong>The</strong>re is absolutely no warranty <strong>for</strong> GDB. Type "show warranty" <strong>for</strong> details.<br />

This GDB was configured as "--host=i386-redhat-linux --target=ppc-linux".<br />

(gdb)<br />

Now attach to the target <strong>and</strong> start execution with the comm<strong>and</strong>s:<br />

(gdb) target remote bdi:2001<br />

Remote debugging using bdi:2001<br />

0x00000100 in ()<br />

(gdb) c<br />

Continuing.<br />

Now the target should boot <strong>Linux</strong> as usual. Next you need to load your kernel module on the target:<br />

bash# insmod -m ex_sw.o<br />

Sections: Size Address Align<br />

.this 00000060 cf030000 2**2<br />

.text 000002f4 cf030060 2**2<br />

.rodata 00000134 cf030354 2**2<br />

.data 00000000 cf030488 2**0<br />

.sdata 0000000c cf030488 2**2<br />

.kstrtab 00000085 cf030494 2**0<br />

.bss 00000000 cf030519 2**0<br />

.sbss 00000008 cf03051c 2**2<br />

...<br />

<strong>The</strong> option -m prints out the addresses of the various code <strong>and</strong> data segments ( .text, .data, .sdata, .bss, .sbss )<br />

after relocation. GDB needs these addresses to know where all the symbols are located. We now interrupt<br />

GDB to load the symbol table of the module as follows:<br />

(gdb) ^C<br />

Program received signal SIGSTOP, Stopped (signal).<br />

...<br />

(gdb) add-symbol-file /ex_sw.o 0xcf030060\<br />

-s .rodata 0xcf030354\<br />

-s .data 0xcf030488\<br />

-s .sdata 0xcf030488\<br />

-s .bss 0xcf030519\<br />

-s .sbss 0xcf03051c<br />

add symbol table from file "/ex_sw.o" at<br />

.text_addr = 0xcf030060<br />

.rodata_addr = 0xcf030354<br />

.data_addr = 0xcf030488<br />

.sdata_addr = 0xcf030488<br />

.bss_addr = 0xcf030519<br />

10.2. <strong>Linux</strong> Kernel Debugging 146


.sbss_addr = 0xcf03051c<br />

(y or n) y<br />

Reading symbols from /ex_sw.o...done.<br />

Now you can list the source code of the module, set break points or inspect variables as usual:<br />

(gdb) l fun<br />

61 static RT_TASK *thread;<br />

62<br />

63 static int cpu_used[NR_RT_CPUS];<br />

64<br />

65 static void fun(int t)<br />

66 {<br />

67 unsigned int loops = LOOPS;<br />

68 while(loops--) {<br />

69 cpu_used[hard_cpu_id()]++;<br />

70 rt_leds_set_mask(1,t);<br />

(gdb)<br />

(gdb) b ex_sw.c:69<br />

Breakpoint 1 at 0xcf03007c: file ex_sw.c, line 69.<br />

(gdb) c<br />

Continuing.<br />

Breakpoint 1, fun (t=1) at ex_sw.c:69<br />

69 cpu_used[hard_cpu_id()]++;<br />

(gdb) p ntasks<br />

$1 = 16<br />

(gdb) p stack_size<br />

$2 = 3000<br />

<strong>The</strong> next section demonstrates a way to automate the symbol table loading procedure.<br />

10.2.3. GDB Macros to Simplify Module Loading<br />

<strong>The</strong> following GDB macros <strong>and</strong> scripts help you to load kernel modules into GDB in a half-automatic way. It<br />

assumes, that the module on the target has been installed with the comm<strong>and</strong>:<br />

bash# insmod -m my_module.o > my_module.o.map<br />

In your $HOME directory you need the scripts add-symbol-file.sh <strong>and</strong> the GDB startup file .gdbinit, which are<br />

listed in 10.3. GDB Startup File <strong>and</strong> Utility Scripts below.<br />

Now you can include the symbol definition into GDB with:<br />

bash$ ${CROSS_COMPILE}gdb vmlinux<br />

GNU gdb 5.1.1<br />

Copyright 2002 Free Software Foundation, Inc.<br />

GDB is free software, covered by the GNU General Public License, <strong>and</strong> you are<br />

welcome to change it <strong>and</strong>/or distribute copies of it under certain conditions.<br />

Type "show copying" to see the conditions.<br />

<strong>The</strong>re is absolutely no warranty <strong>for</strong> GDB. Type "show warranty" <strong>for</strong> details.<br />

This GDB was configured as "--host=i386-redhat-linux --target=ppc-linux".<br />

0x00000100 in ()<br />

c<br />

Continuing.<br />

^C<br />

Program received signal SIGSTOP, Stopped (signal).<br />

0xcf02a91c in ()<br />

(gdb) add-module rtai4/examples/sw/ex_sw.o<br />

add symbol table from file "/HHL/8xx/target/home/wolf/rtai4/examples/sw/ex_sw.o" at<br />

.text_addr = 0xcf030060<br />

.rodata_addr = 0xcf030340<br />

.data_addr = 0xcf030464<br />

10.2.2. Dynamically Loaded Device Drivers (Modules) 147


.sdata_addr = 0xcf030464<br />

.bss_addr = 0xcf0304f5<br />

.sbss_addr = 0xcf0304f8<br />

(gdb) b ex_sw.c:69<br />

Breakpoint 1 at 0xcf03007c: file ex_sw.c, line 69.<br />

(gdb) c<br />

Continuing.<br />

Breakpoint 1, fun (t=0x1) at ex_sw.c:69<br />

69 cpu_used[hard_cpu_id()]++;<br />

(gdb) p/d loops<br />

$2 = 999986939<br />

(gdb) p t<br />

$3 = 0x1<br />

(gdb) d b<br />

Delete all breakpoints (y or n) y<br />

(gdb) c<br />

Continuing.<br />

10.3. GDB Startup File <strong>and</strong> Utility Scripts<br />

In addition to the add-module macro, the followin example GDB startup file contains a few other useful<br />

settings <strong>and</strong> macros, which you may want to adjust to your local environment:<br />

set output-radix 16<br />

target remote bdi:2001<br />

define reset<br />

detach<br />

target remote bdi:2001<br />

end<br />

define add-module<br />

shell ~/add-symbol-file.sh $arg0<br />

source ~/add-symbol-file.gdb<br />

end<br />

document add-module<br />

Usage: add-module <br />

end<br />

Do add-symbol-file <strong>for</strong> module automatically.<br />

Note: A map file with the extension ".map" must have<br />

been created with "insmod -m > .map"<br />

in advance.<br />

<strong>The</strong> following shell script ~/add-symbol-file.sh is used to run the GDB add-symbol-file comm<strong>and</strong><br />

automatically:<br />

#!/bin/sh<br />

#<br />

# Constructs the GDB "add-symbol-file" comm<strong>and</strong> string<br />

# from the map file of the specified kernel module.<br />

add_sect() {<br />

ADDR=`awk '/^'$1' / {print $3}' $MAPFILE`<br />

if [ "$ADDR" != "" ]; then<br />

echo "-s $1 0x`awk '/^'$1' / {print $3}' $MAPFILE`"<br />

fi<br />

}<br />

[ $# == 1 ] && [ -r "$1" ] || { echo "Usage: $0 " >&2 ; exit 1 ; }<br />

10.3. GDB Startup File <strong>and</strong> Utility Scripts 148


MAPFILE=$1.map<br />

ARGS="0x`awk '/^.text / {print $3}' $MAPFILE`\<br />

`add_sect .rodata`\<br />

`add_sect .data`\<br />

`add_sect .sdata`\<br />

`add_sect .bss`\<br />

`add_sect .sbss`\<br />

"<br />

echo "add-symbol-file $1 $ARGS" > ~/add-symbol-file.gdb<br />

10.4. Tips <strong>and</strong> Tricks<br />

• To prevent GDB from jumping around in the code when trying to single step, i. e. when it seems as if<br />

the code is not executing line by line, you can recompile your code with the following additional<br />

compiler options:<br />

-fno-schedule-insns -fno-schedule-insns2<br />

• On some systems (like the MPC8xx or MPC8260) you can only define one hardware breakpoint.<br />

<strong>The</strong>re<strong>for</strong>e you must delete an existing breakpoint be<strong>for</strong>e you can define a new one:<br />

(gdb) d b<br />

Delete all breakpoints (y or n) y<br />

(gdb) b ex_preempt.c:63<br />

Breakpoint 2 at 0xcf030080: file ex_preempt.c, line 63.<br />

10.5. Application Debugging<br />

10.5.1. Local Debugging<br />

In case there is a native GDB available <strong>for</strong> your target you can use it <strong>for</strong> application debugging as usual:<br />

bash$ gcc -Wall -g -o hello hello.c<br />

bash$ gdb hello<br />

...<br />

(gdb) l<br />

1 #include <br />

2<br />

3 int main(int argc, char* argv[])<br />

4 {<br />

5 printf ("Hello world\n");<br />

6 return 0;<br />

7 }<br />

(gdb) break 5<br />

Breakpoint 1 at 0x8048466: file hello.c, line 5.<br />

(gdb) run<br />

Starting program: /opt/eldk/ppc_8xx/tmp/hello<br />

Breakpoint 1, main (argc=0x1, argv=0xbffff9f4) at hello.c:5<br />

5 printf ("Hello world\n");<br />

(gdb) c<br />

Continuing.<br />

Hello world<br />

Program exited normally.<br />

10.5. Application Debugging 149


10.5.2. Remote Debugging<br />

gdbserver allows you to connect your program with a remote GDB using the "target remote" comm<strong>and</strong>.<br />

On the target machine, you need to have a copy of the program you want to debug. gdbserver does not<br />

need your program's symbol table, so you can strip the program if necessary to save space. GDB on the host<br />

system does all the symbol h<strong>and</strong>ling. Here is an example:<br />

bash$ ${CROSS_COMPILE}gcc -Wall -g -o hello hello.c<br />

bash$ cp -p hello /hello-stripped<br />

bash$ ${CROSS_COMPILE}strip /hello-stripped<br />

To use the server, you must tell it how to communicate with GDB, the name of your program, <strong>and</strong> the<br />

arguments <strong>for</strong> your program. To start a debugging session via network type on the target:<br />

bash$ cd <br />

bash$ gdbserver 192.168.1.1:12345 hello-stripped<br />

Process hello-stripped created; pid = 353<br />

And then on the host:<br />

bash$ ${CROSS_COMPILE}gdb hello<br />

...<br />

(gdb) set solib-absolute-prefix /opt/eldk/$CROSS_COMPILE<br />

(gdb) dir /opt/eldk/$CROSS_COMPILE<br />

Source directories searched:<br />

/opt/eldk/$CROSS_COMPILE:$cdir:$cwd<br />

(gdb) target remote 192.168.1.99:12345<br />

Remote debugging using 192.168.1.99:12345<br />

0x30012748 in ()<br />

...<br />

(gdb) l<br />

1 #include <br />

2<br />

3 int main(int argc, char* argv[])<br />

4 {<br />

5 printf ("Hello world\n");<br />

6 return 0;<br />

7 }<br />

(gdb) break 5<br />

Breakpoint 1 at 0x10000498: file hello.c, line 5.<br />

(gdb) continue<br />

Continuing.<br />

Breakpoint 1, main (argc=1, argv=0x7ffffbe4) at hello.c:5<br />

5 printf ("Hello world\n");<br />

(gdb) p argc<br />

$1 = 1<br />

(gdb) continue<br />

Continuing.<br />

Program exited normally.<br />

If the target program you want to debug is linked against shared libraries, you must tell GDB where the<br />

proper target libraries are located. This is done using the set solib-absolute-prefix GDB<br />

comm<strong>and</strong>. If this comm<strong>and</strong> is omitted, then, apparently, GDB loads the host versions of the libraries <strong>and</strong> gets<br />

crazy because of that.<br />

10.6. Debugging with Graphical User Interfaces<br />

10.6. Debugging with Graphical User Interfaces 150


It is convenient to use DDD, a Graphical User Interface to GDB, <strong>for</strong> debugging as it allows to define <strong>and</strong><br />

execute frequently used comm<strong>and</strong>s via buttons. You can start DDD with the comm<strong>and</strong>:<br />

bash$ ddd --debugger ${CROSS_COMPILE}gdb &<br />

If DDD is not already installed on your <strong>Linux</strong> system, have a look at your distribution media.<br />

11. Simple Embedded <strong>Linux</strong> Framework<br />

12. Books, Mailing Lists, Links, etc.<br />

This section provides references on where to find more in<strong>for</strong>mation<br />

Contents:<br />

• 12. Books, Mailing Lists, Links, etc.<br />

♦ 12.1. Application Notes<br />

♦ 12.2. Further Reading<br />

◊ 12.2.1. <strong>Linux</strong> kernel<br />

◊ 12.2.2. General <strong>Linux</strong> / Unix programming<br />

◊ 12.2.3. Network Programming<br />

◊ 12.2.4. C++ programming<br />

◊ 12.2.5. Java programming<br />

◊ 12.2.6. PowerPC Programming<br />

◊ 12.2.7. Embedded Topics<br />

♦ 12.3. Mailing Lists<br />

♦ 12.4. Links<br />

♦ 12.5. Tools<br />

12.1. Application Notes<br />

A collection of Application Notes relevant <strong>for</strong> embedded computing can be found on the <strong>DENX</strong> web server.<br />

12.2. Further Reading<br />

12.2.1. <strong>Linux</strong> kernel<br />

Books<br />

• Karim Yaghmour, Jon Masters, Gilad Ben-Yossef, Philippe Gerum: "Building Embedded <strong>Linux</strong><br />

Systems 2nd edition",<br />

Paperback: 462 pages, O'Reilly & Associates; (August 2008); ISBN 10: 0-596-52968-6; ISBN 13:<br />

9780596529680 ISBN 059600222X - IMHO the best book about Embedded <strong>Linux</strong> so far. An<br />

absolute must have.<br />

• Greg Kroah-Hartman: "<strong>Linux</strong> Kernel in a Nutshell",<br />

198 pages, O'Reilly ("In Nutshell" series), (December 2006), ISBN 10: 0-596-10079-5; ISBN 13:<br />

9780596100797<br />

- Tarball of PDF files (3 MB):<br />

12.2. Further Reading 151


http://www.kernel.org/pub/linux/kernel/people/gregkh/lkn/lkn_pdf.tar.bz2<br />

- Tarball of DocBook files (1 MB):<br />

http://www.kernel.org/pub/linux/kernel/people/gregkh/lkn/lkn_xml.tar.bz2<br />

• Craig Hollabaugh: "Embedded <strong>Linux</strong>: Hardware, Software, <strong>and</strong> Interfacing",<br />

Paperback: 432 pages; Addison Wesley Professional; (March 7, 2002); ISBN 0672322269<br />

• Christopher Hallinan: "Embedded <strong>Linux</strong> Primer: A Practical Real-World Approach",<br />

576 pages, Prentice Hall, September 2006, ISBN-10: 0-13-167984-8; ISBN-13: 978-0-13-167984-9<br />

• Jonathan Corbet, Aless<strong>and</strong>ro Rubini, Greg Kroah-Hartman: "<strong>Linux</strong> Device Drivers", 3rd Edition<br />

;<br />

Paperback: 636 pages; O'Reilly & Associates; 3rd edition (February 2005); ISBN: 0-596-00590-31 -<br />

<strong>The</strong> reference book <strong>for</strong> writing <strong>Linux</strong> device drivers. An absolute must have. => Read online<br />

• Jürgen Quade, Eva-Katharina Kunst: "<strong>Linux</strong>-Treiber entwickeln"; Broschur: 436 pages;<br />

dpunkt.verlag, Juni 2004; ISBN 3898642380<br />

- focused on kernel 2.6, un<strong>for</strong>tunately German only<br />

- => Read online<br />

• Sreekrishnan Venkateswaran: "Essential <strong>Linux</strong> Device Drivers",<br />

744 pages, Prentice Hall, March 2008, ISBN-10: 0-13-239655-6; ISBN-13: 978-0-13-239655-4<br />

- => Read online<br />

Articles<br />

• <strong>The</strong> <strong>Linux</strong> Kernel - describing most aspects of the <strong>Linux</strong> Kernel. Probably, the first reference <strong>for</strong><br />

beginners. Lots of illustrations explaining data structures use <strong>and</strong> relationships. In short: a must have.<br />

• <strong>Linux</strong> Kernel Module Programming <strong>Guide</strong> - Very nice 92 pages GPL book on the topic of modules<br />

programming. Lots of examples.<br />

• LWN: Porting device drivers to the 2.6 kernel - Series of articles (37) in <strong>Linux</strong> Weekly News:<br />

http://lwn.net/Articles/driver-porting/<br />

• MIPS <strong>Linux</strong> Porting <strong>Guide</strong>: http://linux.junsun.net/porting-howto/porting-howto.html<br />

• Andries Brouwers remarks to the linux kernel: http://www.win.tue.nl/~aeb/linux/lk/lk.html<br />

12.2.2. General <strong>Linux</strong> / Unix programming<br />

Books<br />

• W. Richard Stevens: "Advanced Programming in the UNIX Environment", Addision Wesley, ISBN<br />

0-201-56317-7<br />

• Eric S. Raymond: "<strong>The</strong> Art of Unix Programming", Addision Wesley, ISBN 0131429019 => Read<br />

online<br />

• David R. Butenhof: "Programming with POSIX Threads", Addision Wesley, ISBN 0-201-63392-2.<br />

• Brad<strong>for</strong>d Nichols, Dick Buttlar <strong>and</strong> Jacqueline Proulx Farrell: "Pthreads Programming", O'Reilly<br />

& Associates<br />

Articles<br />

• <strong>The</strong> GNU C Library: http://www.linuxselfhelp.com/gnu/glibc/html_chapter/libc_toc.html<br />

General <strong>Linux</strong> Programming: http://www.linuxselfhelp.com/cats/programming.html<br />

• Multi-Threaded Programming With POSIX Threads:<br />

http://users.actcom.co.il/~choo/lupg/tutorials/multi-thread/multi-thread.html<br />

• Ulrich Drepper : Position Independent Binaries: "Text Relocations"<br />

• Ulrich Drepper : "How to Write Shared Libraries"<br />

• Ulrich Drepper : "What Every Programmer Should Know About Memory"<br />

• David Goldberg : "What Every Computer Scientist Should Know About Floating-Point Arithmetic"<br />

Books 152


• More Ulrich Drepper stuff: http://people.redhat.com/drepper/<br />

• How to optimize DSOs by identifying unused non-exported functions <strong>and</strong> data.<br />

• A quite complete history of the UNIX family can be found here: http://www.levenez.com/unix/<br />

• Unix Manual, first edition, 3 November 1971<br />

• John Graham-Cumming: Debugging Makefiles<br />

St<strong>and</strong>ards:<br />

• <strong>Linux</strong> St<strong>and</strong>ard Base: http://refspecs.freest<strong>and</strong>ards.org/lsb.shtml<br />

• Single UNIX Specification, Version 3 (needs registration even <strong>for</strong> online viewing)<br />

• Single UNIX Specification, Version 2<br />

• PCI Bus Bindings - St<strong>and</strong>ard <strong>for</strong> <strong>Boot</strong> Firmware:<br />

http://playground.sun.com/1275/bindings/pci/pci2_1.pdf<br />

12.2.3. Network Programming<br />

Books<br />

• W. Richard Stevens: "TCP/IP Illustrated, Volume 1 - <strong>The</strong> Protocols", Addision Wesley, ISBN<br />

0-201-63346-9<br />

• Gary R. Wright, W. Richard Stevens: "TCP/IP Illustrated, Volume 2 - <strong>The</strong> Implementation",<br />

Addision Wesley, ISBN 0-201-63354-X<br />

• W. Richard Stevens: "TCP/IP Illustrated, Volume 3 - TCP <strong>for</strong> Transactions", Addision Wesley,<br />

ISBN 0-201-63495-3<br />

• W. Richard Stevens: "UNIX Network Programming, Volume 1 - Networking APIs: Sockets <strong>and</strong><br />

XTI", 2nd ed., Prentice Hall, ISBN-0-13-490012-X<br />

• W. Richard Stevens: "UNIX Network Programming, Volume 2 - Interprocess Communication", 2nd<br />

ed., Prentice Hall, ISBN-0-13-081081-9<br />

Articles<br />

• <strong>Linux</strong> Networking topics (like NAPI, GSO, VLAN, IPsec etc.):<br />

http://linux-net.osdl.org/index.php/Main_Page<br />

12.2.4. C++ programming<br />

Books<br />

• Scott Meyers: "Effective C++: 55 Specific Ways to Improve Your Programs <strong>and</strong> Designs (3rd<br />

Edition)", Addison-Wesley, May 20, 2005, ISBN: 0321334876<br />

12.2.5. Java programming<br />

Books<br />

• Joshua Bloch: "Effective Java -- Programming Language <strong>Guide</strong>", 2001, Addison Wesley, ISBN<br />

0-201-31005-8, 250 pages<br />

Articles 153


12.2.6. PowerPC Programming<br />

Books<br />

• Programming Environments Manual <strong>for</strong> 32-Bit Implementations of the PowerPC architecture:<br />

http://www.freescale.com/files/product/doc/MPCFPE32B.pdf<br />

• IBM PDF file (600+ page book) on PowerPC assembly language:<br />

http://www-3.ibm.com/chips/techlib/techlib.nsf/techdocs/852569B20050FF778525699600719DF2<br />

• Power.org St<strong>and</strong>ard <strong>for</strong> Embedded Power Architecture Plat<strong>for</strong>m Requirements (ePAPR):<br />

http://www.power.org/resources/downloads/Power_ePAPR_APPROVED_v1.0.pdf<br />

Articles<br />

• Introduction to Assembly on the PowerPC:<br />

http://www-106.ibm.com/developerworks/library/l-ppc/t=gr,lnxw09=PowPC<br />

• IBM PDF compiler writers guide on PPC asm tuning etc.:<br />

http://www-3.ibm.com/chips/techlib/techlib.nsf/techdocs/852569B20050FF7785256996007558C6<br />

• A developer's guide to the POWER architecture:<br />

http://www-128.ibm.com/developerworks/linux/library/l-powarch/index.html<br />

• PowerPC EABI Calling Sequence:<br />

ftp://sourceware.redhat.com/pub/binutils/ppc-docs/ppc-eabi-calling-sequence<br />

• PowerPC Embedded Application Binary Interface (32-Bit Implementation):<br />

ftp://sourceware.redhat.com/pub/binutils/ppc-docs/ppc-eabi-1995-01.pdf<br />

• Developing PowerPC Embedded Application Binary Interface (EABI) Compliant Programs<br />

http://www-306.ibm.com/chips/techlib/techlib.nsf/techdocs/852569B20050FF77852569970071B0D6<br />

• System V Application Binary Interface - PowerPC Processor Supplement:<br />

http://refspecs.freest<strong>and</strong>ards.org/elf/elfspec_ppc.pdf<br />

• <strong>Linux</strong> <strong>for</strong> PowerPC Embedded Systems HOWTO (old):<br />

http://penguinppc.org/embedded/howto/PowerPC-Embedded-HOWTO.html<br />

• <strong>Linux</strong> <strong>for</strong> PowerPC Embedded Systems HOWTO (new):<br />

http://www.denx.de/twiki/bin/view/PPCEmbedded<br />

• Underst<strong>and</strong>ing MPC5200 Bestcomm Firmware: Posting on linuxppc-embedded@ozlabs.org mailing<br />

list (see also the mailing list archive entry), source code disasm.c <strong>for</strong> a disassember, <strong>and</strong> "SmartDMA<br />

H<strong>and</strong>-Assembly <strong>Guide</strong>s" document.<br />

12.2.7. Embedded Topics<br />

Articles<br />

• Things you always wanted to know about NAND flash but never dared to ask: Micron Application<br />

Note<br />

• <strong>The</strong> ultimate goal of Embedded C++ is to provide embedded systems programmers with a subset of<br />

C++ that is easy <strong>for</strong> the average C programmer to underst<strong>and</strong> <strong>and</strong> use.<br />

• Our contribution to the Darwin year 2009: Hardware designs that will not replicate: Topic in <strong>DENX</strong><br />

Wiki<br />

12.3. Mailing Lists<br />

<strong>The</strong>se are some mailing lists of interest. If you are new to mailing lists then please take the time to read at<br />

least RFC 1855.<br />

12.3. Mailing Lists 154


• linux-arm-kernel - Communications among developers <strong>and</strong> users of <strong>Linux</strong> on arm boards<br />

• linuxppc-embedded - Communications among developers <strong>and</strong> users of <strong>Linux</strong> on embedded<br />

PowerPC boards<br />

This mailing list has been merged into the linuxppc-dev mailing list below <strong>and</strong> thus does not<br />

exist anymore.<br />

• linuxppc-dev - Communications among active developers of <strong>Linux</strong> on 32 bit PowerPC platt<strong>for</strong>ms.<br />

Not intended <strong>for</strong> user support.<br />

• u-boot - Support <strong>for</strong> "U-<strong>Boot</strong>" Universal <strong>Boot</strong>loader<br />

• ELDK - Support <strong>for</strong> <strong>DENX</strong> Embedded <strong>Linux</strong> Development Kit<br />

12.4. Links<br />

<strong>Linux</strong> Kernel Resources:<br />

• <strong>The</strong> <strong>Linux</strong> Documentation Project : http://www.tldp.org/<br />

• Generic ("official") <strong>Linux</strong> Kernel sources:<br />

git: http://git.kernel.org/p=linux/kernel/git/torvalds/linux-2.6.git;a=tree<br />

FTP: ftp://ftp.kernel.org/pub/linux/kernel/v2.6/<br />

• Full git history of <strong>Linux</strong>: http://thread.gmane.org/gmane.linux.kernel/690811<br />

• Generic kernel sources <strong>for</strong> PowerPC systems: http://penguinppc.org/dev/kernel.shtml<br />

• <strong>DENX</strong> kernel sources: http://git.denx.de/p=linux-2.6-denx.git;a=summary<br />

• Cross-Referencing the Linx Kernel: http://lxr.linux.no/source/a=ppc<br />

• Starting point <strong>for</strong> <strong>Linux</strong> based asm (mostly x86): http://linuxassembly.org/<br />

Realtime, Xenomai, RTAI:<br />

• Xenomai Home Page: http://www.xenomai.org/<br />

• Hackbench, a commonly used system stress tool<br />

• Calibrator, determines cache<br />

• RTAI Home Page: http://www.rtai.org/<br />

• <strong>DENX</strong> RTAI Patches: ftp://ftp.denx.de/pub/RTAI/ sizes at runtime, rendering it another useful system<br />

stress tool<br />

U-<strong>Boot</strong>:<br />

• U-<strong>Boot</strong> Project Page: http://www.denx.de/wiki/U-<strong>Boot</strong>/WebHome.<br />

Note that the old SourceForge page is not maintained anymore.<br />

• <strong>DENX</strong> U-<strong>Boot</strong> <strong>and</strong> <strong>Linux</strong> <strong>Guide</strong>: http://www.denx.de/twiki/bin/view/<strong>DULG</strong><br />

Cross Development Tools:<br />

• <strong>DENX</strong> Embedded <strong>Linux</strong> Development Kit: http://www.denx.de/twiki/bin/view/<strong>DULG</strong>/ELDK<br />

Miscalleneous or unsorted material:<br />

• BDI2000 List of supported Flash Memories: This document not only lists the currently supported<br />

flash chips, but also the required settings in the BDI config file.<br />

• BDI2000 configuration files: ftp://78.31.64.234/bdigdb/config/<br />

12.4. Links 155


12.5. Tools<br />

• http://lxr.linux.no/source/ - Cross-Referencing the <strong>Linux</strong> Kernel - using a versatile hypertext<br />

cross-referencing tool <strong>for</strong> the <strong>Linux</strong> Kernel source tree (the <strong>Linux</strong> Cross-Reference project)<br />

• ftp://ftp.denx.de/pub/tools/backtrace - Decode Stack Backtrace - Perl script to decode the Stack<br />

Backtrace printed by the <strong>Linux</strong> Kernel when it panics<br />

• ftp://ftp.denx.de/pub/tools/clone_tree - "Clone" a Source Tree - Perl script to create a working copy of<br />

a source tree (<strong>for</strong> example the <strong>Linux</strong> Kernel) which contains mainly symbolic links (<strong>and</strong><br />

automagically omits "unwanted" files like CVS repository data, etc.)<br />

• 13. Appendix<br />

♦ 13.1. Flat Device Tree<br />

♦ 13.2. BDI2000 Configuration file<br />

13. Appendix<br />

13.1. Flat Device Tree<br />

/*<br />

* Device Tree Source <strong>for</strong> AMCC Canyonl<strong>and</strong>s (460EX)<br />

*<br />

* Copyright 2008 <strong>DENX</strong> Software Engineering, Stefan Roese <br />

*<br />

* This file is licensed under the terms of the GNU General Public<br />

* License version 2. This program is licensed "as is" without<br />

* any warranty of any kind, whether express or implied.<br />

*/<br />

/ {<br />

#address-cells = ;<br />

#size-cells = ;<br />

model = "amcc,canyonl<strong>and</strong>s";<br />

compatible = "amcc,canyonl<strong>and</strong>s";<br />

dcr-parent = ;<br />

aliases {<br />

ethernet0 = &EMAC0;<br />

ethernet1 = &EMAC1;<br />

serial0 = &UART0;<br />

serial1 = &UART1;<br />

};<br />

cpus {<br />

#address-cells = ;<br />

#size-cells = ;<br />

cpu@0 {<br />

device_type = "cpu";<br />

model = "PowerPC,460EX";<br />

reg = ;<br />

clock-frequency = ; /* Filled in by U-<strong>Boot</strong> */<br />

timebase-frequency = ; /* Filled in by U-<strong>Boot</strong> */<br />

i-cache-line-size = ;<br />

d-cache-line-size = ;<br />

i-cache-size = ;<br />

d-cache-size = ;<br />

dcr-controller;<br />

dcr-access-method = "native";<br />

};<br />

13. Appendix 156


};<br />

memory {<br />

device_type = "memory";<br />

reg = ; /* Filled in by U-<strong>Boot</strong> */<br />

};<br />

UIC0: interrupt-controller0 {<br />

compatible = "ibm,uic-460ex","ibm,uic";<br />

interrupt-controller;<br />

cell-index = ;<br />

dcr-reg = ;<br />

#address-cells = ;<br />

#size-cells = ;<br />

#interrupt-cells = ;<br />

};<br />

UIC1: interrupt-controller1 {<br />

compatible = "ibm,uic-460ex","ibm,uic";<br />

interrupt-controller;<br />

cell-index = ;<br />

dcr-reg = ;<br />

#address-cells = ;<br />

#size-cells = ;<br />

#interrupt-cells = ;<br />

interrupts = ; /* cascade */<br />

interrupt-parent = ;<br />

};<br />

UIC2: interrupt-controller2 {<br />

compatible = "ibm,uic-460ex","ibm,uic";<br />

interrupt-controller;<br />

cell-index = ;<br />

dcr-reg = ;<br />

#address-cells = ;<br />

#size-cells = ;<br />

#interrupt-cells = ;<br />

interrupts = ; /* cascade */<br />

interrupt-parent = ;<br />

};<br />

UIC3: interrupt-controller3 {<br />

compatible = "ibm,uic-460ex","ibm,uic";<br />

interrupt-controller;<br />

cell-index = ;<br />

dcr-reg = ;<br />

#address-cells = ;<br />

#size-cells = ;<br />

#interrupt-cells = ;<br />

interrupts = ; /* cascade */<br />

interrupt-parent = ;<br />

};<br />

SDR0: sdr {<br />

compatible = "ibm,sdr-460ex";<br />

dcr-reg = ;<br />

};<br />

CPR0: cpr {<br />

compatible = "ibm,cpr-460ex";<br />

dcr-reg = ;<br />

};<br />

plb {<br />

compatible = "ibm,plb-460ex", "ibm,plb4";<br />

#address-cells = ;<br />

#size-cells = ;<br />

13.1. Flat Device Tree 157


anges;<br />

clock-frequency = ; /* Filled in by U-<strong>Boot</strong> */<br />

SDRAM0: sdram {<br />

compatible = "ibm,sdram-460ex", "ibm,sdram-405gp";<br />

dcr-reg = ;<br />

};<br />

MAL0: mcmal {<br />

compatible = "ibm,mcmal-460ex", "ibm,mcmal2";<br />

dcr-reg = ;<br />

num-tx-chans = ;<br />

num-rx-chans = ;<br />

#address-cells = ;<br />

#size-cells = ;<br />

interrupt-parent = ;<br />

interrupts = < /*TXEOB*/ 6 4<br />

/*RXEOB*/ 7 4<br />

/*SERR*/ 3 4<br />

/*TXDE*/ 4 4<br />

/*RXDE*/ 5 4>;<br />

};<br />

USB0: ehci@bffd0400 {<br />

compatible = "ibm,usb-ehci-460ex", "usb-ehci";<br />

interrupt-parent = ;<br />

interrupts = ;<br />

reg = ;<br />

};<br />

USB1: usb@bffd0000 {<br />

compatible = "ohci-le";<br />

reg = ;<br />

interrupt-parent = ;<br />

interrupts = ;<br />

};<br />

USBOTG0: usbotg@bff80000 {<br />

compatible = "amcc,usb-otg-460ex";<br />

reg = ;<br />

interrupt-parent = ;<br />

interrupts = ;<br />

#interrupt-cells = ;<br />

#address-cells = ;<br />

#size-cells = ;<br />

interrupt-map = ;<br />

interrupt-map-mask = ;<br />

};<br />

POB0: opb {<br />

compatible = "ibm,opb-460ex", "ibm,opb";<br />

#address-cells = ;<br />

#size-cells = ;<br />

ranges = ;<br />

clock-frequency = ; /* Filled in by U-<strong>Boot</strong> */<br />

EBC0: ebc {<br />

compatible = "ibm,ebc-460ex", "ibm,ebc";<br />

dcr-reg = ;<br />

#address-cells = ;<br />

#size-cells = ;<br />

clock-frequency = ; /* Filled in by U-<strong>Boot</strong> */<br />

/* ranges property is supplied by U-<strong>Boot</strong> */<br />

interrupts = ;<br />

interrupt-parent = ;<br />

13.1. Flat Device Tree 158


};<br />

nor_flash@0,0 {<br />

compatible = "amd,s29gl512n", "cfi-flash";<br />

bank-width = ;<br />

reg = ;<br />

#address-cells = ;<br />

#size-cells = ;<br />

partition@0 {<br />

label = "kernel";<br />

reg = ;<br />

};<br />

partition@1e0000 {<br />

label = "dtb";<br />

reg = ;<br />

};<br />

partition@200000 {<br />

label = "root";<br />

reg = ;<br />

};<br />

partition@400000 {<br />

label = "user";<br />

reg = ;<br />

};<br />

partition@3f60000 {<br />

label = "env";<br />

reg = ;<br />

};<br />

partition@3fa0000 {<br />

label = "u-boot";<br />

reg = ;<br />

};<br />

};<br />

UART0: serial@ef600300 {<br />

device_type = "serial";<br />

compatible = "ns16550";<br />

reg = ;<br />

virtual-reg = ;<br />

clock-frequency = ; /* Filled in by U-<strong>Boot</strong> */<br />

current-speed = ; /* Filled in by U-<strong>Boot</strong> */<br />

interrupt-parent = ;<br />

interrupts = ;<br />

};<br />

UART1: serial@ef600400 {<br />

device_type = "serial";<br />

compatible = "ns16550";<br />

reg = ;<br />

virtual-reg = ;<br />

clock-frequency = ; /* Filled in by U-<strong>Boot</strong> */<br />

current-speed = ; /* Filled in by U-<strong>Boot</strong> */<br />

interrupt-parent = ;<br />

interrupts = ;<br />

};<br />

UART2: serial@ef600500 {<br />

device_type = "serial";<br />

compatible = "ns16550";<br />

reg = ;<br />

virtual-reg = ;<br />

clock-frequency = ; /* Filled in by U-<strong>Boot</strong> */<br />

current-speed = ; /* Filled in by U-<strong>Boot</strong> */<br />

interrupt-parent = ;<br />

interrupts = ;<br />

};<br />

13.1. Flat Device Tree 159


UART3: serial@ef600600 {<br />

device_type = "serial";<br />

compatible = "ns16550";<br />

reg = ;<br />

virtual-reg = ;<br />

clock-frequency = ; /* Filled in by U-<strong>Boot</strong> */<br />

current-speed = ; /* Filled in by U-<strong>Boot</strong> */<br />

interrupt-parent = ;<br />

interrupts = ;<br />

};<br />

IIC0: i2c@ef600700 {<br />

compatible = "ibm,iic-460ex", "ibm,iic";<br />

reg = ;<br />

interrupt-parent = ;<br />

interrupts = ;<br />

};<br />

IIC1: i2c@ef600800 {<br />

compatible = "ibm,iic-460ex", "ibm,iic";<br />

reg = ;<br />

interrupt-parent = ;<br />

interrupts = ;<br />

};<br />

ZMII0: emac-zmii@ef600d00 {<br />

compatible = "ibm,zmii-460ex", "ibm,zmii";<br />

reg = ;<br />

};<br />

RGMII0: emac-rgmii@ef601500 {<br />

compatible = "ibm,rgmii-460ex", "ibm,rgmii";<br />

reg = ;<br />

has-mdio;<br />

};<br />

TAH0: emac-tah@ef601350 {<br />

compatible = "ibm,tah-460ex", "ibm,tah";<br />

reg = ;<br />

};<br />

TAH1: emac-tah@ef601450 {<br />

compatible = "ibm,tah-460ex", "ibm,tah";<br />

reg = ;<br />

};<br />

EMAC0: ethernet@ef600e00 {<br />

device_type = "network";<br />

compatible = "ibm,emac-460ex", "ibm,emac4";<br />

interrupt-parent = ;<br />

interrupts = ;<br />

#interrupt-cells = ;<br />

#address-cells = ;<br />

#size-cells = ;<br />

interrupt-map = ;<br />

reg = ;<br />

local-mac-address = [000000000000]; /* Filled in by U-<strong>Boot</strong> */<br />

mal-device = ;<br />

mal-tx-channel = ;<br />

mal-rx-channel = ;<br />

cell-index = ;<br />

max-frame-size = ;<br />

rx-fifo-size = ;<br />

tx-fifo-size = ;<br />

phy-mode = "rgmii";<br />

phy-map = ;<br />

13.1. Flat Device Tree 160


};<br />

};<br />

rgmii-device = ;<br />

rgmii-channel = ;<br />

tah-device = ;<br />

tah-channel = ;<br />

has-inverted-stacr-oc;<br />

has-new-stacr-staopc;<br />

EMAC1: ethernet@ef600f00 {<br />

device_type = "network";<br />

compatible = "ibm,emac-460ex", "ibm,emac4";<br />

interrupt-parent = ;<br />

interrupts = ;<br />

#interrupt-cells = ;<br />

#address-cells = ;<br />

#size-cells = ;<br />

interrupt-map = ;<br />

reg = ;<br />

local-mac-address = [000000000000]; /* Filled in by U-<strong>Boot</strong> */<br />

mal-device = ;<br />

mal-tx-channel = ;<br />

mal-rx-channel = ;<br />

cell-index = ;<br />

max-frame-size = ;<br />

rx-fifo-size = ;<br />

tx-fifo-size = ;<br />

phy-mode = "rgmii";<br />

phy-map = ;<br />

rgmii-device = ;<br />

rgmii-channel = ;<br />

tah-device = ;<br />

tah-channel = ;<br />

has-inverted-stacr-oc;<br />

has-new-stacr-staopc;<br />

mdio-device = ;<br />

};<br />

PCIX0: pci@c0ec00000 {<br />

device_type = "pci";<br />

#interrupt-cells = ;<br />

#size-cells = ;<br />

#address-cells = ;<br />

compatible = "ibm,plb-pcix-460ex", "ibm,plb-pcix";<br />

primary;<br />

large-inbound-windows;<br />

enable-msi-hole;<br />

reg = ; /* Internal messaging registers */<br />

/* Outbound ranges, one memory <strong>and</strong> one IO,<br />

* later cannot be changed<br />

*/<br />

ranges = ;<br />

/* Inbound 2GB range starting at 0 */<br />

dma-ranges = ;<br />

/* This drives busses 0 to 0x3f */<br />

bus-range = ;<br />

/* All PCI interrupts are routed to ext IRQ 2 -> UIC1-0 */<br />

13.1. Flat Device Tree 161


};<br />

interrupt-map-mask = ;<br />

interrupt-map = < 0000 0 0 0 &UIC1 0 8 >;<br />

PCIE0: pciex@d00000000 {<br />

device_type = "pci";<br />

#interrupt-cells = ;<br />

#size-cells = ;<br />

#address-cells = ;<br />

compatible = "ibm,plb-pciex-460ex", "ibm,plb-pciex";<br />

primary;<br />

port = ; /* port number */<br />

reg = ; /* Registers */<br />

dcr-reg = ;<br />

sdr-base = ;<br />

};<br />

/* Outbound ranges, one memory <strong>and</strong> one IO,<br />

* later cannot be changed<br />

*/<br />

ranges = ;<br />

/* Inbound 2GB range starting at 0 */<br />

dma-ranges = ;<br />

/* This drives busses 40 to 0x7f */<br />

bus-range = ;<br />

/* Legacy interrupts (note the weird polarity, the bridge seems<br />

* to invert PCIe legacy interrupts).<br />

* We are de-swizzling here because the numbers are actually <strong>for</strong><br />

* port of the root complex virtual P2P bridge. But I want<br />

* to avoid putting a node <strong>for</strong> it in the tree, so the numbers<br />

* below are basically de-swizzled numbers.<br />

* <strong>The</strong> real slot is on idsel 0, so the swizzling is 1:1<br />

*/<br />

interrupt-map-mask = ;<br />

interrupt-map = <<br />

0000 0 0 1 &UIC3 c 4 /* swizzled int A */<br />

0000 0 0 2 &UIC3 d 4 /* swizzled int B */<br />

0000 0 0 3 &UIC3 e 4 /* swizzled int C */<br />

0000 0 0 4 &UIC3 f 4 /* swizzled int D */>;<br />

PCIE1: pciex@d20000000 {<br />

device_type = "pci";<br />

#interrupt-cells = ;<br />

#size-cells = ;<br />

#address-cells = ;<br />

compatible = "ibm,plb-pciex-460ex", "ibm,plb-pciex";<br />

primary;<br />

port = ; /* port number */<br />

reg = ; /* Registers */<br />

dcr-reg = ;<br />

sdr-base = ;<br />

/* Outbound ranges, one memory <strong>and</strong> one IO,<br />

* later cannot be changed<br />

*/<br />

ranges = ;<br />

/* Inbound 2GB range starting at 0 */<br />

dma-ranges = ;<br />

13.1. Flat Device Tree 162


};<br />

};<br />

};<br />

/* This drives busses 80 to 0xbf */<br />

bus-range = ;<br />

/* Legacy interrupts (note the weird polarity, the bridge seems<br />

* to invert PCIe legacy interrupts).<br />

* We are de-swizzling here because the numbers are actually <strong>for</strong><br />

* port of the root complex virtual P2P bridge. But I want<br />

* to avoid putting a node <strong>for</strong> it in the tree, so the numbers<br />

* below are basically de-swizzled numbers.<br />

* <strong>The</strong> real slot is on idsel 0, so the swizzling is 1:1<br />

*/<br />

interrupt-map-mask = ;<br />

interrupt-map = <<br />

0000 0 0 1 &UIC3 10 4 /* swizzled int A */<br />

0000 0 0 2 &UIC3 11 4 /* swizzled int B */<br />

0000 0 0 3 &UIC3 12 4 /* swizzled int C */<br />

0000 0 0 4 &UIC3 13 4 /* swizzled int D */>;<br />

13.2. BDI2000 Configuration file<br />

; bdiGDB configuration file <strong>for</strong> AMCC 460EX Evaluation Kit "Canyonl<strong>and</strong>s"<br />

; ---------------------------------------------------------------------<br />

;<br />

;<br />

[INIT]<br />

; Setup TLB<br />

WTLB 0xF0000095 0x4F00003F ;<strong>Boot</strong> Space 256MB<br />

WTLB 0x00000094 0x0000003F ;SDRAM 256MB @ 0x00000000<br />

WTLB 0x90000095 0x4000003F ;ISRAM/OCM<br />

; Setup Peripheral Bus<br />

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;<br />

WDCR 0x12 0x00000010 ;Select EBC0_B0AP<br />

WDCR 0x13 0x10055e00<br />

WDCR 0x12 0x00000000 ;Select EBC0_B0CR<br />

WDCR 0x13 0xfc0da000 ; 64MByte<br />

; OCM<br />

;WDCR 0x20 0x40004580 ;16k<br />

[TARGET]<br />

JTAGCLOCK 1 ;use 8 MHz JTAG clock<br />

CPUTYPE 440 ;the used target CPU type<br />

WAKEUP 500 ;wakeup time after reset<br />

BREAKMODE HARD ;SOFT or HARD, HARD uses PPC hardware breakpoint<br />

STEPMODE HWBP ;JTAG or HWBP, HWBP uses one or two hardware breakpoints<br />

[HOST]<br />

IP 192.168.1.1<br />

FILE /tftpboot/canyonl<strong>and</strong>s/u-boot.bin<br />

FORMAT BIN<br />

DUMP /tftpboot/canyonl<strong>and</strong>s/dump.bin<br />

PROMPT 460EX><br />

[FLASH]<br />

;WORKSPACE 0xe3040000 ;workspace in OCM<br />

;WORKSPACE 0x70000000 ;workspace in OCM<br />

;WORKSPACE 0x90040000 ;workspace in OCM<br />

CHIPTYPE MIRRORX16 ;Flash type<br />

CHIPSIZE 0x1000000 ;<strong>The</strong> size of one flash chip in bytes<br />

13.2. BDI2000 Configuration file 163


BUSWIDTH 16 ;<strong>The</strong> width of the flash memory bus in bits (8 | 16 | 32)<br />

FILE /tftpboot/canyonl<strong>and</strong>s/u-boot.bin<br />

;FORMAT BIN 0xFFF80000<br />

FORMAT BIN 0xFFFA0000<br />

;ERASE 0xFFF80000 ;erase sector 4<br />

ERASE 0xFFFA0000 ;erase sector 4<br />

ERASE 0xFFFC0000 ;erase sector 4<br />

ERASE 0xFFFE0000 ;erase sector 6<br />

[REGS]<br />

FILE<br />

/tftpboot/BDI2000/reg460ex.def<br />

• 14. FAQ - Frequently Asked Questions<br />

♦ 14.1. ELDK<br />

◊ 14.1.1. ELDK Installation under FreeBSD<br />

◊ 14.1.2. ELDK Installation Hangs<br />

◊ 14.1.3. .gvfs: Permission Denied<br />

◊ 14.1.4. Installation on Local Harddisk<br />

◊ 14.1.5. ELDK Include Files Missing<br />

◊ 14.1.6. Using the ELDK on a 64 bit plat<strong>for</strong>m<br />

◊ 14.1.7. GDB Problems with BDI2000/BDI3000 on e500 Cores<br />

♦ 14.2. U-<strong>Boot</strong><br />

◊ 14.2.1. Can U-<strong>Boot</strong> be configured such that it can be started in RAM<br />

◊ 14.2.2. Relocation cannot be done when using -mrelocatable<br />

◊ 14.2.3. U-<strong>Boot</strong> crashes after relocation to RAM<br />

◊ 14.2.4. Warning - bad CRC, using default environment<br />

◊ 14.2.5. Wrong debug symbols after relocation<br />

◊ 14.2.6. Decoding U-<strong>Boot</strong> Crash Dumps<br />

◊ 14.2.7. Porting Problem: cannot move location counter backwards<br />

◊ 14.2.8. U-<strong>Boot</strong> Doesn't Run after Upgrading my Compiler<br />

◊ 14.2.9. How Can I Reduce <strong>The</strong> Image Size<br />

◊ 14.2.10. Erasing Flash Fails<br />

◊ 14.2.11. Ethernet Does Not Work<br />

◊ 14.2.12. Where Can I Get a Valid MAC Address from<br />

◊ 14.2.13. Why do I get TFTP timeouts<br />

◊ 14.2.14. Why is my Ethernet operation not reliable<br />

◊ 14.2.15. How the Comm<strong>and</strong> Line Parsing Works<br />

⋅ 14.2.15.1. Old, simple comm<strong>and</strong> line parser<br />

⋅ 14.2.15.2. Hush shell<br />

⋅ 14.2.15.3. Hush shell scripts<br />

⋅ 14.2.15.4. General rules<br />

◊ 14.2.16. How can I load <strong>and</strong> uncompress a compressed image<br />

◊ 14.2.17. My st<strong>and</strong>alone program does not work<br />

◊ 14.2.18. <strong>Linux</strong> hangs after uncompressing the kernel<br />

♦ 14.3. <strong>Linux</strong><br />

◊ 14.3.1. <strong>Linux</strong> crashes r<strong>and</strong>omly<br />

◊ 14.3.2. <strong>Linux</strong> crashes when uncompressing the kernel<br />

◊ 14.3.3. <strong>Linux</strong> Post Mortem Analysis<br />

◊ 14.3.4. <strong>Linux</strong> kernel register usage<br />

◊ 14.3.5. <strong>Linux</strong> Kernel Ignores my bootargs<br />

◊ 14.3.6. Cannot configure Root Filesystem over NFS<br />

◊ 14.3.7. <strong>Linux</strong> Kernel Panics because "init" process dies<br />

◊ 14.3.8. Unable to open an initial console<br />

13.2. BDI2000 Configuration file 164


◊ 14.3.9. Mounting a Filesystem over NFS hangs <strong>for</strong>ever<br />

◊ 14.3.10. Ethernet does not work in <strong>Linux</strong><br />

◊ 14.3.11. Loopback interface does not work<br />

◊ 14.3.12. <strong>Linux</strong> kernel messages are not printed on the console<br />

◊ 14.3.13. <strong>Linux</strong> ignores input when using the framebuffer driver<br />

◊ 14.3.14. How to switch off the screen saver <strong>and</strong> the blinking cursor<br />

◊ 14.3.15. BogoMIPS Value too low<br />

◊ 14.3.16. <strong>Linux</strong> Kernel crashes when using a ramdisk image<br />

◊ 14.3.17. Ramdisk Greater than 4 MB Causes Problems<br />

◊ 14.3.18. Combining a Kernel <strong>and</strong> a Ramdisk into a Multi-File Image<br />

◊ 14.3.19. Adding Files to Ramdisk is Non Persistent<br />

◊ 14.3.20. Kernel Configuration <strong>for</strong> PCMCIA<br />

◊ 14.3.21. Configure <strong>Linux</strong> <strong>for</strong> PCMCIA Cards using the Card Services package<br />

◊ 14.3.22. Configure <strong>Linux</strong> <strong>for</strong> PCMCIA Cards without the Card Services package<br />

⋅ 14.3.22.1. Using a MacOS Partition Table<br />

⋅ 14.3.22.2. Using a MS-DOS Partition Table<br />

◊ 14.3.23. <strong>Boot</strong>-Time Configuration of MTD Partitions<br />

◊ 14.3.24. Use NTP to synchronize system time against RTC<br />

◊ 14.3.25. Configure <strong>Linux</strong> <strong>for</strong> XIP (Execution In Place)<br />

⋅ 14.3.25.1. XIP Kernel<br />

⋅ 14.3.25.2. Cramfs Filesystem<br />

⋅ 14.3.25.3. Hints <strong>and</strong> Notes<br />

⋅ 14.3.25.4. Space requirements <strong>and</strong> RAM saving, an example<br />

◊ 14.3.26. Use SCC UART with Hardware H<strong>and</strong>shake<br />

◊ 14.3.27. How can I access U-<strong>Boot</strong> environment variables in <strong>Linux</strong><br />

◊ 14.3.28. <strong>The</strong> =appWeb= server hangs *OR* /dev/r<strong>and</strong>om hangs<br />

◊ 14.3.29. Swapping over NFS<br />

♦ 14.4. Self<br />

◊ 14.4.1. How to Add Files to a SELF Ramdisk<br />

◊ 14.4.2. How to Increase the Size of the Ramdisk<br />

♦ 14.5. RTAI<br />

◊ 14.5.1. Conflicts with asm clobber list<br />

♦ 14.6. BDI2000<br />

◊ 14.6.1. Where can I find BDI2000 Configuration Files<br />

◊ 14.6.2. How to Debug <strong>Linux</strong> Exceptions<br />

◊ 14.6.3. How to single step through "RFI" instruction<br />

◊ 14.6.4. Setting a breakpoint doesn't work<br />

♦ 14.7. Motorola LITE5200 Board<br />

◊ 14.7.1. LITE5200 Installation Howto<br />

◊ 14.7.2. USB does not work on Lite5200 board<br />

14. FAQ - Frequently Asked Questions<br />

This is a collection of questions which came up repeatedly. Give me more feedback <strong>and</strong> I will add more stuff<br />

here.<br />

<strong>The</strong> items are categorized whether they concern U-<strong>Boot</strong> itself, the <strong>Linux</strong> kernel or the SELF framework.<br />

14.1. ELDK<br />

14.1. ELDK 165


14.1.1. ELDK Installation under FreeBSD<br />

Question:<br />

How can I install ELDK on a FreeBSD system<br />

Answer:<br />

[Thanks to Rafal Jaworowski <strong>for</strong> these detailed instructions.] This is a short tutorial how to host<br />

ELDK on FreeBSD 5.x <strong>and</strong> 6.x. <strong>The</strong> procedure described below was tested on 5.2.1, 5.3 <strong>and</strong> 6-current<br />

releases; we assume the reader is equipped with the ELDK 3.x CDROM or ISO image <strong>for</strong> installation,<br />

<strong>and</strong> is familiar with FreeBSD basic administration tasks like ports/packages installation.<br />

1. Prerequisites:<br />

1. Install linux_base<br />

2.<br />

<strong>The</strong> first step is to install the <strong>Linux</strong> compatibility layer from ports<br />

/usr/ports/emulators/linux_base/ or packages<br />

ftp://ftp.freebsd.org/pub/FreeBSD/ports/i386/packages/emulators<br />

Please make sure to install version 7.1_5 (linux_base-7.1_5.tbz) or later;<br />

in particular, version 6.1.5 which can also be found in the ports tree does not work<br />

properly!<br />

<strong>The</strong> compatibility layer is activated by<br />

# kldload linux<br />

2. Install bash<br />

Since ELDK <strong>and</strong> <strong>Linux</strong> build scripts are organised around bash while FreeBSD does<br />

not have it in base, this shell needs to be installed either from ports<br />

/usr/ports/shells/bash2/ or packages collection<br />

ftp://ftp.freebsd.org/pub/FreeBSD/ports/i386/packages/shells/<br />

<strong>The</strong> installation puts the bash binary in /usr/local/bin. It is a good idea to<br />

create a symlink in /bin so that hash bang from scripts (#!/bin/bash) works<br />

without modifications:<br />

# cd /bin<br />

# ln -s /usr/local/bin/bash<br />

Prepare ELDK<br />

This step is only needed <strong>for</strong> ELDK release 3.1 <strong>and</strong> older versions.<br />

Copy the install files from the CDROM or ISO image to a writable location. Br<strong>and</strong> the ELDK<br />

installer as <strong>Linux</strong> ELF file:<br />

# cd <br />

# br<strong>and</strong>elf -t <strong>Linux</strong> ./install<br />

Note: <strong>The</strong> following workaround might be a good alternative <strong>for</strong> the tedious copying of<br />

the installation CDROM to a writable location <strong>and</strong> manual br<strong>and</strong>ing: you can set a fallback<br />

br<strong>and</strong>ing in FreeBSD - when the loader cannot recognise the ELF br<strong>and</strong> it will switch to the<br />

last resort defined.<br />

# sysctl -w kern.elf32.fallback_br<strong>and</strong>=3<br />

kern.elf32.fallback_br<strong>and</strong>: -1 -> 3<br />

14.1.1. ELDK Installation under FreeBSD 166


With this setting, the normal ELDK CDROM images should work.<br />

3. Install ELDK normally as described in 3.5.3. Initial Installation<br />

4. Set envrionment variables <strong>and</strong> PATH as needed <strong>for</strong> ELDK (in bash); <strong>for</strong> example:<br />

bash$ export CROSS_COMPILE=ppc_8xxbash$<br />

export PATH=${PATH}:/opt/eldk/bin:/opt/eldk/usr/bin<br />

5. Hints <strong>for</strong> building U-<strong>Boot</strong>:<br />

FreeBSD normally uses BSD-style 'make' in base, but in order to compile U-<strong>Boot</strong><br />

'gmake' (GNU make) has to be used; this is installed as part of the 'linux_base'<br />

package (see above).<br />

U-<strong>Boot</strong> should build according to st<strong>and</strong>ard ELDK instructions, <strong>for</strong> example:<br />

bash$ cd /opt/eldk/ppc_8xx/usr/src/u-boot-1.1.2<br />

bash$ gmake TQM823L_config<br />

bash$ gmake all<br />

6. Hints <strong>for</strong> building <strong>Linux</strong>:<br />

<strong>The</strong>re are three issues with the Makefile in the <strong>Linux</strong> kernel source tree:<br />

⋅ GNU make has to be used.<br />

⋅ <strong>The</strong> 'expr' utility in FreeBSD base behaves differently from the version than is<br />

used in <strong>Linux</strong> so we need to modify the Makefile to explicitly use the <strong>Linux</strong> version<br />

(which is part of the <strong>Linux</strong> compatibility package). This is best achieved with<br />

defining "EXPR = /compat/linux/usr/bin/expr" somewhere at<br />

=Makefile='s beginning <strong>and</strong> replacing all references to 'expr' with the variable<br />

${EXPR).<br />

⋅ Some build steps (like when running 'scripts/mkdep' can generate very long<br />

arguments lists (especially is the <strong>Linux</strong> kernel tree is in a directory with long absolute<br />

filenames). A solution is to use xargs to split such long comm<strong>and</strong>s into several with<br />

shorter argument lists.<br />

<strong>The</strong> <strong>Linux</strong> kernel can then be built following the st<strong>and</strong>ard instructions, <strong>for</strong> example:<br />

bash$ cd /opt/eldk/ppc_8xx/usr/src/linux-2.4.25/<br />

bash$ gmake mrproper<br />

bash$ gmake TQM823L_config<br />

bash$ gmake oldconfig<br />

bash$ gmake dep<br />

bash$ gmake -j6 uImage<br />

ELDK Installation Hangs<br />

Question:<br />

I try to install the ELDK on a <strong>Linux</strong> PC, <strong>and</strong> the installation hangs. It starts fine, but then it freezes<br />

like this:<br />

...<br />

Preparing... ########################################### [100%]<br />

1:db4-devel-ppc_4xx ########################################### [100%]<br />

Preparing... ########################################### [100%]<br />

1:db4-utils-ppc_4xx ########################################### [100%]<br />

Preparing... ########################################### [100%]<br />

1:glib2-ppc_4xx ########################################### [100%]<br />

Preparing... ########################################### [100%]<br />

1:glib2-devel-ppc_4xx ########################################### [100%]<br />

Preparing... ########################################### [100%]<br />

ELDK Installation Hangs 167


Answer:<br />

This is almost certainly a FUTEX problem. To verify this, please wait until the process grinds to a<br />

halt, then use ps to find the pid of the "rpm" process that was started by the "install" program<br />

(use "ps -axf" which gives you a nice hierarchy, look <strong>for</strong> the "install" process, then <strong>for</strong><br />

"rpm") <strong>and</strong> then attach to it with "strace -p". Most probably you will see the something like<br />

this:<br />

# strace -p 21197<br />

Process 21197 attached - interrupt to quit<br />

futex(0x96fe17c, FUTEX_WAIT_PRIVATE, 1, NULL<br />

i. e. the process is hanging in a futex call.<br />

We have seen this more than once with differing <strong>Linux</strong> systems, but un<strong>for</strong>tunately we don't know a<br />

clean <strong>and</strong> reliable way to fix it yet. We suspect that it is a kernel/libc combination problem because it<br />

usually went away usually after changing the exact used kernel version.<br />

<strong>The</strong> only workaround we can recommend so far is to update your host system <strong>and</strong> install more recent<br />

versions of the <strong>Linux</strong> kernel <strong>and</strong>/or the glibc C library (assuming such are available <strong>for</strong> your <strong>Linux</strong><br />

distribution; if not, falling back to a previous kernel version may help, too).<br />

Note: This is only needed <strong>for</strong> the installer, the problem does not happen with the regular use of the<br />

ELDK.<br />

14.1.3. .gvfs: Permission Denied<br />

Question:<br />

When trying to install the ELDK, I get error messages like this <strong>for</strong> each <strong>and</strong> every package that gets<br />

installed:<br />

Preparing... ################### 100%<br />

1: rpm... ################### 100%<br />

Error: Failed to stat /home/wd/.gvfs: Permission Denied<br />

This happens even though I run the installer as root.<br />

Answer:<br />

Even though flagged as an error, these messages are harmless warnings that can be safely ignored.<br />

Be<strong>for</strong>e the RPM tool starts to install a package, it checks if there is sufficient space <strong>for</strong> it in the file<br />

system. Un<strong>for</strong>tunately it is dumb <strong>and</strong> checks all mounted file systems <strong>for</strong> space, but the permissions<br />

of the ".gvfs" directory (the mount point <strong>for</strong> the Gnome Virtual File System) do not permit this.<br />

Note:<br />

Actually the messages are not printed despite the fact that you are running as root, but because you<br />

run as root. You have permissions to check the "$HOME/.gvfs" directory, while root gets an error:<br />

$ df -h /home/wd/.gvfs<br />

Filesystem<br />

Size Used Avail Use% Mounted on<br />

gvfs-fuse-daemon 0 0 0 - /home/wd/.gvfs<br />

$ sudo df -h /home/wd/.gvfs<br />

df: `/home/wd/.gvfs': Permission denied<br />

df: no file systems processed<br />

14.1.4. Installation on Local Harddisk<br />

Question:<br />

14.1.4. Installation on Local Harddisk 168


I have a local harddisk drive connected to my target board. Can I install the ELDK on it <strong>and</strong> run it like<br />

a st<strong>and</strong>ard <strong>Linux</strong> distribution<br />

Answer:<br />

Yes, this is possible. It requires only minor adjustments. <strong>The</strong> following example assumes you are<br />

using a SCSI disk drive, but the same can be done with st<strong>and</strong>ard SATA or PATA drives, too:<br />

1. <strong>Boot</strong> the target with root file system over NFS.<br />

2. Create the necessary partitions on your disk drive: you need at last a swap partition <strong>and</strong> a file<br />

system partition.<br />

bash-3.00# fdisk -l<br />

Disk /dev/sda: 36.9 GB, 36951490048 bytes<br />

64 heads, 32 sectors/track, 35239 cylinders<br />

Units = cylinders of 2048 * 512 = 1048576 bytes<br />

Device <strong>Boot</strong> Start End Blocks Id System<br />

/dev/sda1 1 978 1001456 82 <strong>Linux</strong> swap / Solaris<br />

/dev/sda2 979 12423 11719680 83 <strong>Linux</strong><br />

/dev/sda3 12424 23868 11719680 83 <strong>Linux</strong><br />

/dev/sda4 23869 35239 11643904 83 <strong>Linux</strong><br />

3. Format the partititons:<br />

bash-3.00# mkswap /dev/sda1<br />

bash-3.00# mke2fs -j -m1 /dev/sda2<br />

4. Mount the file system:<br />

bash-3.00# mount /dev/sda2 /mnt<br />

5. Copy the content of the (NFS) root file system into the mounted file system:<br />

bash-3.00# tar --one-file-system -c -f - / | ( cd /mnt ; tar xpf - )<br />

6. Adjust /etc/fstab <strong>for</strong> the disk file system:<br />

bash-3.00# vi /mnt/etc/fstab<br />

bash-3.00# cat /mnt/etc/fstab<br />

/dev/sda2 / ext3 defaults 1 1<br />

/dev/sda1 swap swap defaults 0 0<br />

proc /proc proc defaults 0 0<br />

sysfs /sys sysfs defaults 0 0<br />

7. Adjust /etc/rc.sysinit <strong>for</strong> running from local disk; remove the following comments:<br />

8.<br />

bash-3.00# diff -u /mnt/etc/rc.sysinit.ORIG /mnt/etc/rc.sysinit<br />

--- /mnt/etc/rc.sysinit.ORIG 2007-01-21 04:37:00.000000000 +0100<br />

+++ /mnt/etc/rc.sysinit 2007-03-02 10:58:22.000000000 +0100<br />

@@ -460,9 +460,9 @@<br />

# Remount the root filesystem read-write.<br />

update_boot_stage RCmountfs<br />

-#state=`LC_ALL=C awk '/ \/ / && ($3 !~ /rootfs/) { print $4 }' /proc/mounts`<br />

-#[ "$state" != "rw" -a "$READONLY" != "yes" ] && \<br />

-# action $"Remounting root filesystem in read-write mode: " mount -n -o remount,rw<br />

+state=`LC_ALL=C awk '/ \/ / && ($3 !~ /rootfs/) { print $4 }' /proc/mounts`<br />

+[ "$state" != "rw" -a "$READONLY" != "yes" ] && \<br />

+ action $"Remounting root filesystem in read-write mode: " mount -n -o remount,rw<br />

# Clean up SE<strong>Linux</strong> labels<br />

if [ -n "$SELINUX" ]; then<br />

Unmount disk:<br />

bash-3.00# umount /mnt<br />

9. Reboot, <strong>and</strong> adjust boot arguments to use disk partition as root file system<br />

14.1.4. Installation on Local Harddisk 169


10.<br />

=> setenv diskargs setenv bootargs root=/dev/sda2 ro<br />

=> setenv net_disk 'tftp ${loadaddr} ${bootfile};run diskargs addip addcons;bootm'<br />

=> saveenv<br />

<strong>Boot</strong> with these settings<br />

=> run net_disk<br />

14.1.5. ELDK Include Files Missing<br />

Question:<br />

After configuring <strong>and</strong> compiling a <strong>Linux</strong> kernel in the kernel source tree that comes with the ELDK, I<br />

cannot compile user space programs any more - I get error messages because many #include file like<br />

etc. are missing.<br />

This is with ELDK 4.0 or 4.1.<br />

Answer:<br />

This problem is caused by the way how the ELDK is packaged. At the moment, the ELDK kernel<br />

headers are not packed into a separate "kernel-headers" RPM to avoid duplication, because the kernel<br />

source tree is always installed. Instead, the ELDK "kernel-headers" package is just a set of symlinks.<br />

This worked fine in the past, but fails with the new support <strong>for</strong> ARCH=powerpc systems.<br />

<strong>The</strong> next version of the ELDK will contain a real kernel-headers RPM, which will fix this problem.<br />

As a workaround on current systems, you can install the real kernel include files into the<br />

"include/asm", "include/linux" <strong>and</strong> "include/mtd" directories.<br />

To do this, the following comm<strong>and</strong>s can be used:<br />

bash$ /bin/rpm -e kernel-headers-ppc_<br />

bash$ cd /ppc_<br />

bash$ rm usr/include/asm<br />

bash$ tar -xvzf kernel-headers-powerpc.tar.gz<br />

<strong>The</strong> tarball mentioned above can be downloaded here. It contains the include files that get installed by<br />

running the "make ARCH=powerpc headers_install" comm<strong>and</strong> in the <strong>Linux</strong> kernel tree.<br />

This problem is fixed in ELDK 4.2 <strong>and</strong> later releases.<br />

14.1.6. Using the ELDK on a 64 bit plat<strong>for</strong>m<br />

As the ELDK is compiled <strong>for</strong> 32-bit host systems, a compatibility layer is required on 64-bit systems. This<br />

package is usually called ia32-libs. So on a Debian or Ubuntu system a<br />

sudo apt-get install ia32-libs<br />

should be enough to make the ELDK work.<br />

14.1.7. GDB Problems with BDI2000/BDI3000 on<br />

e500 Cores<br />

Question:<br />

I am using the cross-gdb from ELDK together with the BDI JTAG hardware debugger from Abatron<br />

to debug my e500 based system. When I try to attach to the BDI from within gdb, I get an error<br />

message like this:<br />

14.1.7. GDB Problems with BDI2000/BDI3000 on e500 Cores 170


$ ppc_85xxDP-gdb u-boot<br />

.......<br />

(gdb) target remote bdi14:2001<br />

Remote debugging using bdi14:2001<br />

Remote 'g' packet reply is too long:<br />

000000600fb7bd380fb7bf78e000450000000001000000000ffdd8c00ffd912400001c01000000000ffdd9fc000<br />

(gdb)<br />

Answer:<br />

If you are using at least BDI firmware v1.09 then most probably you <strong>for</strong>got to include the following<br />

directive in the BDI config file:<br />

[TARGET]<br />

REGLIST E500 ;send registers in E500 sequence to GDB<br />

Also be sure that the gdb really thinks that it debugs an e500 core:<br />

(gdb) show architecture<br />

<strong>The</strong> target architecture is set automatically (currently powerpc:e500)<br />

(gdb)<br />

If this is not the case, then fix this problem first. It might just be that you are not using the right cross<br />

debugger in the first place.<br />

14.2. U-<strong>Boot</strong><br />

14.2.1. Can U-<strong>Boot</strong> be configured such that it can<br />

be started in RAM<br />

Question:<br />

I don't want to erase my flash memory because I'm not sure if my new U-<strong>Boot</strong> image will work. Is it<br />

possible to configure U-<strong>Boot</strong> such that I can load it into RAM instead of flash, <strong>and</strong> start it from my<br />

old boot loader<br />

Answer:<br />

No.<br />

Question:<br />

But I've been told it is possible<br />

Answer:<br />

Well, yes. Of course this is possible. This is software, so everything is possible. But it is difficult,<br />

unsupported, <strong>and</strong> fraught with peril. You are on your own if you choose to do it. And it will not help<br />

you to solve your problem.<br />

Question:<br />

Why<br />

Answer:<br />

U-<strong>Boot</strong> expects to see a virgin CPU, i. e. the CPU state must match what you see if the processor<br />

starts executing the first instructions when it comes out of reset. If you want to start U-<strong>Boot</strong> from<br />

another boot loader, you must disable a lot of code, i. e. all initialization parts that already have been<br />

per<strong>for</strong>med by this other boot loader, like setting up the memory controller, initializing the SDRAM,<br />

initializing the serial port, setting up a stack frame etc. Also you must disable the relocation to RAM<br />

14.2.1. Can U-<strong>Boot</strong> be configured such that it can be started in RAM 171


<strong>and</strong> adjust the link addresses etc.<br />

This requires a lot of experience with U-<strong>Boot</strong>, <strong>and</strong> the fact that you had to ask if this can be done<br />

means that you are not in a position to do this.<br />

<strong>The</strong> code you have to disable contains the most critical parts in U-<strong>Boot</strong>, i. e. these are the areas where<br />

99% or more of all errors are located when you port U-<strong>Boot</strong> to a new hardware. In the result, your<br />

RAM image may work, but in the end you will need a full image to program the flash memory with it,<br />

<strong>and</strong> then you will have to enable all this highly critical <strong>and</strong> completely untested code.<br />

You see You cannot use a RAM version of U-<strong>Boot</strong> to avoid testing a flash version, so you can save<br />

all this ef<strong>for</strong>t <strong>and</strong> just burn your image to flash.<br />

Question:<br />

So how can I test an U-<strong>Boot</strong> image <strong>and</strong> recover my system if it doesn't work<br />

Answer:<br />

Attach a BDI2000 to your board, burn the image to flash, <strong>and</strong> debug it in it's natural environment, i. e.<br />

U-<strong>Boot</strong> being the boot loader of the system <strong>and</strong> taking control over the CPU right as it comes out of<br />

reset. If something goes wrong, erase the flash <strong>and</strong> program a new image. This is a routine job using a<br />

BDI2000.<br />

14.2.2. Relocation cannot be done when using<br />

-mrelocatable<br />

Question:<br />

I use ELDK version 3.0. When I build U-<strong>Boot</strong> I get error messages like this:<br />

{st<strong>and</strong>ard input}: Assembler messages:<br />

{st<strong>and</strong>ard input}:4998: Error: Relocation cannot be done when using -mrelocatable<br />

...<br />

Answer:<br />

ELDK 3.0 uses GCC-3.2.2; your U-<strong>Boot</strong> sources are too old <strong>for</strong> this compiler. GCC-3.x requires a<br />

few adaptions which were added in later versions of U-<strong>Boot</strong>. Use <strong>for</strong> example the source tree (1.0.2)<br />

which is included with the ELDK, or download the latest version from CVS.<br />

14.2.3. U-<strong>Boot</strong> crashes after relocation to RAM<br />

Question:<br />

I have ported U-<strong>Boot</strong> to a custom board. It starts OK, but crashes or hangs after relocating itself to<br />

RAM. Why<br />

Answer:<br />

Your SDRAM initialization is bad, <strong>and</strong> the system crashes when it tries to fetch instructions from<br />

RAM. Note that simple read <strong>and</strong> write accesses may still work, it's the burst mode that is failing. This<br />

only shows up when caches are enabled because cache is the primary (or only) user of burst<br />

operations in U-<strong>Boot</strong>. In <strong>Linux</strong>, burst accesses may also result from DMA. For example, it is typical<br />

that a system may crash under heavy network load if the Ethernet controller uses DMA to memory.<br />

It is NOT sufficient to program the memory controller of your CPU; each SDRAM chip also<br />

requires a specific initialization sequence which you must adhere to to the letter - check with the chip<br />

14.2.3. U-<strong>Boot</strong> crashes after relocation to RAM 172


manufacturer's manual.<br />

It has been observed that some operating systems like pSOS+ or VxWorks do not stress the memory<br />

subsystem as much as <strong>Linux</strong> or other UNIX systems like LynxOS do, so just because your board<br />

appears to work running another OS does not mean it is 100% OK.<br />

St<strong>and</strong>ard memory tests are not effective in identifying this type of problem because they do not cause<br />

stressful cache burst read/write operations.<br />

Argument:<br />

But my board ran fine with bootloader XYZ <strong>and</strong>/or operating system ABC.<br />

Answer:<br />

Double-check your configuration that you claim runs properly...<br />

1. Are you sure the SDRAM is initialized using the same init sequence <strong>and</strong> values<br />

2. Are you sure the memory controlling registers are set the same<br />

3. Are you sure your other configuration uses caches <strong>and</strong>/or DMA If it doesn't, it isn't a valid<br />

comparison.<br />

14.2.4. Warning - bad CRC, using default<br />

environment<br />

Question:<br />

I have ported U-<strong>Boot</strong> to a custom board. It seems to boot OK, but it prints:<br />

*** Warning - bad CRC, using default environment<br />

Why<br />

Answer:<br />

Most probably everything is OK. <strong>The</strong> message is printed because the flash sector or ERPROM<br />

containing the environment variables has never been initialized yet. <strong>The</strong> message will go away as<br />

soon as you save the envrionment variables using the saveenv comm<strong>and</strong>.<br />

14.2.5. Wrong debug symbols after relocation<br />

Question:<br />

I want to debug U-<strong>Boot</strong> after relocation to RAM, but it doesn't work since all the symbols are at<br />

wrong addresses now.<br />

Answer:<br />

To debug parts of U-<strong>Boot</strong> that are running from ROM/flash, i. e. be<strong>for</strong>e relocation, just use a<br />

comm<strong>and</strong> like "powerpc-linux-gdb uboot" as usual.<br />

For parts of U-<strong>Boot</strong> that run from RAM, i. e. after relocation, use "powerpc-linux-gdb"<br />

without arguments, <strong>and</strong> use the add-symbol-file comm<strong>and</strong> in GDB to load the symbol table at<br />

the relocation address in RAM. <strong>The</strong> only problem is that you need to know that address, which<br />

depends on RAM size, length reserved <strong>for</strong> U-<strong>Boot</strong>, size of "protected RAM" area, etc. If in doubt,<br />

enable DEBUG mode when building U-<strong>Boot</strong> so it prints the address to the console.<br />

14.2.5. Wrong debug symbols after relocation 173


Hint: I use definitions like these in my .gdbinit file:<br />

define rom<br />

symbol-file<br />

file u-boot<br />

end<br />

define ram<br />

symbol-file<br />

add-symbol-file u-boot 0x01fe0000<br />

end<br />

Note: when you want to switch modes during one debug session (i. e. without restarting GDB) you<br />

can "delete" the current symbol in<strong>for</strong>mation by using the symbol-file comm<strong>and</strong> without<br />

arguments, <strong>and</strong> then either using "symbol-file u-boot" <strong>for</strong> code be<strong>for</strong>e relocation, or<br />

"add-symbol-file u-boot _offset_" <strong>for</strong> code after relocation.<br />

14.2.6. Decoding U-<strong>Boot</strong> Crash Dumps<br />

When you are porting U-<strong>Boot</strong> to new hardware, or implementing extensions, you might run into situations<br />

where U-<strong>Boot</strong> crashes <strong>and</strong> prints a register dump <strong>and</strong> a stack trace, <strong>for</strong> example like this:<br />

Bus Fault @ 0x00f8d70c, fixup 0x00000000<br />

Machine check in kernel mode.<br />

Caused by (from msr): regs 00f52cf8 Unknown values in msr<br />

NIP: 00F8D70C XER: 0000005F LR: 00F8D6F4 REGS: 00f52cf8 TRAP: 0200 DAR: F9F68C00<br />

MSR: 00009002 EE: 1 PR: 0 FP: 0 ME: 1 IR/DR: 00<br />

GPR00: 00016ACC 00F52DE8 00000000 F9F68C00 00FA38EC 00000001 F9F68BF8 0000000B<br />

GPR08: 00000002 00F55470 00000000 00F52D94 44004024 00000000 00FA2F00 C0F75000<br />

GPR16: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000<br />

GPR24: 00000000 00FA38EC 00F553C0 00F55480 00000000 00F52F80 00FA41C0 00000001<br />

Call backtrace:<br />

00000000 00F8F998 00F8FA88 00F8FAF8 00F90B5C 00F90CF8 00F8385C<br />

00F79E6C 00F773B0<br />

machine check<br />

To find out what happened, you can try to decode the stack backtrace (the list of addresses printed after the<br />

"Call backtrace:" line. <strong>The</strong> backtrace tool can be used <strong>for</strong> this purpose. However, there is a little<br />

problem: the addresses printed <strong>for</strong> the stack backtrace are after relocation of the U-<strong>Boot</strong> code to RAM; to use<br />

the backtrace tool you need to know U-<strong>Boot</strong>'s address offset (the difference between the start address of<br />

U-<strong>Boot</strong> in flash <strong>and</strong> its relocation address in RAM).<br />

<strong>The</strong> easiest way to find out the relocation address is to enable debugging <strong>for</strong> the U-<strong>Boot</strong> source file<br />

lib_*/board.c - U-<strong>Boot</strong> will then print some debug messages<br />

...<br />

Now running in RAM - U-<strong>Boot</strong> at: 00f75000<br />

...<br />

Now you have to calculate the address offset between your link address (<strong>The</strong> value of the TEXT_BASE<br />

definition in your board//config.mk file). In our case this value is 0x40000000, so the address offset<br />

is 0x40000000 - 0x00f75000 = 0x3f08b000<br />

Now we use the backtrace script with the System.map file in the U-<strong>Boot</strong> source tree <strong>and</strong> this address<br />

offset:<br />

-> backtrace System.map 0x3f08b000<br />

14.2.6. Decoding U-<strong>Boot</strong> Crash Dumps 174


Reading symbols from System.map<br />

Using Address Offset 0x3f08b000<br />

0x3f08b000 -- unknown address<br />

0x4001a998 -- 0x4001a8d0 + 0x00c8<br />

0x4001aa88 -- 0x4001aa2c + 0x005c<br />

0x4001aaf8 -- 0x4001aad0 + 0x0028<br />

0x4001bb5c -- 0x4001ba68 + 0x00f4<br />

0x4001bcf8 -- 0x4001bcd8 + 0x0020<br />

0x4000e85c -- 0x4000e6f8 + 0x0164<br />

0x40004e6c -- 0x40004b9c + 0x02d0<br />

0x400023b0 -- 0x400023b0 + 0x0000<br />

free_pipe<br />

free_pipe_list<br />

run_list<br />

parse_stream_outer<br />

parse_file_outer<br />

main_loop<br />

board_init_r<br />

trap_init<br />

In this case the last "good" entry on the stack was in free_pipe...<br />

14.2.7. Porting Problem: cannot move location<br />

counter backwards<br />

Question:<br />

I'm trying to port U-<strong>Boot</strong> to a new board <strong>and</strong> the linker throws an error message like this:<br />

board//u-boot.lds:75 cannot move location counter backwards (from 00000000b0008<br />

Answer:<br />

Check your linker script board/your_board/u-boot.lds which controls how the object files<br />

are linked together to build the U-<strong>Boot</strong> image.<br />

It looks as if your board uses an "embedded" environment, i. e. the flash sector containing the<br />

environment variables is surrounded by code. <strong>The</strong> u-boot.lds tries to collect as many as possible<br />

code in the first part, making the gap between this first part <strong>and</strong> the environment sector as small as<br />

possible. Everything that does not fit is then placed in the second part, after the environment sector.<br />

Some your modifications caused the code that was put in this first part to grow, so that the linker finds<br />

that it would have to overwrite space that is already used.<br />

Try commenting out one (or more) line(s) be<strong>for</strong>e the line containing the<br />

"common/environment.o" statement. [ "lib_generic/zlib.o" is usually a good<br />

c<strong>and</strong>idate <strong>for</strong> testing as it's big ]. Once you get U-<strong>Boot</strong> linked, you can check in the u-boot.map<br />

file how big the gap is, <strong>and</strong> which object files could be used to fill it up again.<br />

14.2.8. U-<strong>Boot</strong> Doesn't Run after Upgrading my<br />

Compiler<br />

Question:<br />

I encountered a big problem that U-<strong>Boot</strong> 1.1.4 compiled by ELDK 4.1 <strong>for</strong> MPC82xx crashed.<br />

But if I build it using gcc-3.4.6 based cross tools, U-<strong>Boot</strong> on my board boots correctly.<br />

<strong>The</strong> same U-<strong>Boot</strong> code built by ELDK 4.1 (gcc-4.0) failed, nothing occurs on the serial port.<br />

Answer:<br />

This is often a missing volatile attribute on shared variable references, particularly hardware<br />

registers. Newer compiler versions optimize more aggressively, making missing volatile<br />

14.2.8. U-<strong>Boot</strong> Doesn't Run after Upgrading my Compiler 175


attributes visible.<br />

If you use -O0 (no optimization) does it fix the problem<br />

If it does, it most likely is an optimization/volatile issue. <strong>The</strong> hard part is figuring out where. Device<br />

h<strong>and</strong>ling <strong>and</strong> board-specific code is the place to start.<br />

14.2.9. How Can I Reduce <strong>The</strong> Image Size<br />

Question:<br />

I am trying to reduce the size of the u-boot.bin file so that it fits into 256 KB. I disabled all the drivers<br />

that I didn't need but the binary size is still 512KB, it seems to be a hard number coded in somewhere.<br />

Where can the image size be altered from<br />

Answer:<br />

Some processors have a fixed reset vector address at 0xFFFFFFFC, so the U-<strong>Boot</strong> image has to<br />

include that address, i. e. it covers the full range from the start address to the end of the 32 bit address<br />

space. In such a case, the start address must be changed - check the setting of TEXT_BASE in your<br />

board//config.mk file.<br />

14.2.10. Erasing Flash Fails<br />

Question:<br />

I tried to erase the flash memory like<br />

erase 40050000 40050100<br />

It fails. What am I doing wrong<br />

Answer:<br />

Remember that flash memory cannot be erased in arbitrary areas, but only in so called "erase regions"<br />

or "sectors". If you have U-<strong>Boot</strong> running you can use the flinfo (Flash in<strong>for</strong>mation, short fli)<br />

comm<strong>and</strong> to print in<strong>for</strong>mation about the flash memory on your board, <strong>for</strong> instance:<br />

=> fli<br />

Bank # 1: AMD AM29LV160B (16 Mbit, bottom boot sect)<br />

Size: 4 MB in 35 Sectors<br />

Sector Start Addresses:<br />

40000000 (RO) 40008000 (RO) 4000C000 (RO) 40010000 (RO) 40020000 (RO)<br />

40040000 40060000 40080000 400A0000 400C0000<br />

400E0000 40100000 40120000 40140000 40160000<br />

40180000 401A0000 401C0000 401E0000 40200000<br />

40220000 40240000 40260000 40280000 402A0000<br />

402C0000 402E0000 40300000 40320000 40340000<br />

40360000 40380000 403A0000 403C0000 403E0000<br />

In the example above, the area 40050000 ... 40050100 lies right in the middle of a erase unit<br />

(40040000 ... 4005FFFF), so you cannot erase it without erasing the whole sector, i. e. you have to<br />

type<br />

=> erase 40040000 4005FFFF<br />

Also note that there are some sectors marked as read-only ((RO)); you cannot erase or overwrite<br />

14.2.10. Erasing Flash Fails 176


these sectors without un-protecting the sectors first (see the U-<strong>Boot</strong> protect comm<strong>and</strong>).<br />

14.2.11. Ethernet Does Not Work<br />

Question:<br />

Ethernet does not work on my board.<br />

Answer:<br />

Maybe you <strong>for</strong>got to set a MAC address Check if the "ethaddr" environment variable is defined,<br />

<strong>and</strong> if it has a sane value. If there are more than one Ethernet interfaces on your board, you may also<br />

have to check the MAC addresses <strong>for</strong> these, i. e. check the "eth1addr", "eth2addr", etc.<br />

variables, too.<br />

Question:<br />

I have configured a MAC address of 01:02:03:04:05:06, <strong>and</strong> I can see that an ARP packet is sent by<br />

U-<strong>Boot</strong>, <strong>and</strong> that an ARP reply is sent by the server, but U-<strong>Boot</strong> never receives any packets. What's<br />

wrong<br />

Answer:<br />

You have chosen a MAC address which, according to the ANSI/IEEE 802-1990 st<strong>and</strong>ard, has the<br />

multicast bit set. Under normal conditions a network interface discards such packets, <strong>and</strong> this is what<br />

U-<strong>Boot</strong> is doing. This is not a bug, but correct behaviour.<br />

Please use only valid MAC addresses that were assigned to you.<br />

For bring-up testing in the lab you can also use so-called locally administered ethernet addresses.<br />

<strong>The</strong>se are addresses that have the 2nd LSB in the most significant byte of MAC address set. <strong>The</strong><br />

gen_eth_addr tool that comes with U-<strong>Boot</strong> (see "tools/gen_eth_addr" ) can be used to<br />

generate r<strong>and</strong>om addresses from this pool.<br />

14.2.12. Where Can I Get a Valid MAC Address<br />

from<br />

Question:<br />

Where can I get a valid MAC address from<br />

Answer:<br />

You have to buy a block of 4096 MAC addresses (IAB = Individual Address Block) or a block of<br />

16M MAC addresses (OUI = Organizationally Unique Identifier, also referred to as 'company id')<br />

from IEEE Registration Authority. <strong>The</strong> current cost of an IAB is $550.00, the cost of an OUI is<br />

$1,650.00. See http://st<strong>and</strong>ards.ieee.org/regauth/oui/index.shtml<br />

You can buy Eproms containing MAC addresses from: Maxim or Microchip.<br />

You can set the "locally administered" bit to make your own MAC address (no guarantee of<br />

uniqueness, but pretty good odds if you don't do something dumb). Ref: Wikipedia<br />

Universally administered <strong>and</strong> locally administered addresses are distinguished by<br />

setting the second least significant bit of the most significant byte of the address. If<br />

the bit is 0, the address is universally administered. If it is 1, the address is locally<br />

14.2.12. Where Can I Get a Valid MAC Address from 177


administered. <strong>The</strong> bit is 0 in all OUIs. For example, 02-00-00-00-00-01. <strong>The</strong> most<br />

significant byte is 02h. <strong>The</strong> binary is 00000010 <strong>and</strong> the second least significant bit is<br />

1. <strong>The</strong>re<strong>for</strong>e, it is a locally administered address.<br />

14.2.13. Why do I get TFTP timeouts<br />

Question 1:: When trying to download a file from the TFTP server I always get timeouts like these:<br />

...<br />

Loading: #######T ##################################T###################T ####T ##T #<br />

###T #T #########T ########T #############T ##T #############T ########T #############T<br />

#####T ###T ######T #######T #######T #############T ##T ##############T ###########<br />

###########<br />

done<br />

If the target is connected directly to the host PC (i. e. without a switch inbetween) the problem goes away or is<br />

at least less incisive.<br />

What's wrong<br />

Answer 1:: Most probably you have a full duplex/half duplex problem. Verify that U-<strong>Boot</strong> is setting the<br />

ethernet interface on your board to the proper duplex mode (full/half). I'm guessing your board is half duplex<br />

but your switch is full (typical of a switch ;-).<br />

<strong>The</strong> switch sends traffic to your board while your board is transmitting... that is a collision (late collision at<br />

that) to your board but is OK to the switch. This doesn't happen nearly as much with a direct link to your PC<br />

since then you have a dedicated link without much asynchronous traffic.<br />

<strong>The</strong> software (U-<strong>Boot</strong>/<strong>Linux</strong>) needs to poll the PHY chip <strong>for</strong> duplex mode <strong>and</strong> then (re)configure the MAC<br />

chip (separate or built into the CPU) to match. If the poll isn't happening or has a bug, you have problems like<br />

described above.<br />

Question 2:: When I use tftp, there are some problems. My terminal always displays "Loading: T T T T T T T<br />

T T T T T T T T T T T T T". <strong>The</strong> whole in<strong>for</strong>mation as follows:<br />

U-<strong>Boot</strong> 1.1.4_XT (Jun 6 2006 - 17:36:18)<br />

U-<strong>Boot</strong> code: 0C300000 -> 0C31AD70 BSS: -> 0C31EF98<br />

RAM Configuration:<br />

Bank #0: 0c000000 8 MB<br />

Bank #1: 0c800000 8 MB<br />

Flash: 2 MB<br />

*** Warning - bad CRC, using default environment<br />

In: serial<br />

Out: serial<br />

Err: serial<br />

Hit any key to stop autoboot: 0<br />

XT=> help tftp<br />

tftpboot [loadAddress] [bootfilename]<br />

XT=> tftpboot 0x0c700000 image.bin<br />

TFTP from server 192.168.0.23; our IP address is 192.168.0.70<br />

Filename 'image.bin'.<br />

Load address: 0xc700000<br />

Loading: T T T T T T T T T T T T T T T T T T T T<br />

Retry count exceeded; starting again<br />

TFTP from server 192.168.0.23; our IP address is 192.168.0.70<br />

Would someone give me some suggestions<br />

14.2.13. Why do I get TFTP timeouts 178


Answer 2:: (1) Verify your TFTP server is working. On a machine (not the TFTP server nor your<br />

development board) use tftp to read the target file.<br />

$ tftp 192.168.0.23 get image.bin<br />

If this doesn't work, fix your TFTP server configuration <strong>and</strong> make sure it is running.<br />

(2) If your TFTP server is working, run ethereal (or equivalent ethernet sniffing) to see what ethernet packets<br />

are being sent by your development board. It usually works best to run ethereal on your TFTP server (if you<br />

run it on a different machine <strong>and</strong> you use an ethernet switch, the third machine likely won't see the tftp<br />

packets).<br />

14.2.14. Why is my Ethernet operation not reliable<br />

Question:<br />

My ethernet connection is not working reliable. On one switch it works fine, but on another one it<br />

doesn't.<br />

or:<br />

Question:<br />

I always see transmit errors or timeouts <strong>for</strong> the first packet of a download, but then it works well.<br />

or:<br />

Question:<br />

I cannot mount the <strong>Linux</strong> root file system over NFS; especially not with recent <strong>Linux</strong> kernel versions<br />

(older kernel versions work better). Specifying "proto=tcp" as mount option greatly improves the<br />

situation.<br />

etc.<br />

Answer:<br />

<strong>The</strong>re are many possible explanations <strong>for</strong> such problems. After eliminating the obvious sources (like<br />

broken cables etc.) you should check the configuration of your Ethernet PHY. One common cause of<br />

problems is if your PHY is hard configured in duplex mode (<strong>for</strong> example 100baseTX Full Duplex or<br />

10baseT Full Duplex). If such a setup is combined with a autonegotiating switch, then trouble is<br />

ahead.<br />

Jerry Van Baren explained this as follows:<br />

Ignoring the configuration where both ends are (presumably correctly)<br />

manually configured, you end up with five cases, two of them<br />

misconfigured <strong>and</strong> WRONG:<br />

1) Autonegotiation autonegotiation - reliable.<br />

2) 10bT half duplex autonegotiation - reliable.<br />

3) 100bT half duplex autonegotiation - reliable.<br />

4) 10bT *FULL* duplex autonegotiation - *UNreliable*.<br />

5) 100bT *FULL* duplex autonegotiation - *UNreliable*.<br />

<strong>The</strong> problem that I've observed is that the *humans* (the weak links)<br />

that do the manual configuration don't underst<strong>and</strong> that "parallel<br />

detection" *must be* half duplex by definition in the spec (it is hard<br />

to define a reliable algorithm to detect full duplex capability so the<br />

spec writers punted). As a result, the human invariably picks "full<br />

duplex" because everybody knows full duplex is better... <strong>and</strong> end up as<br />

case (4) or (5). <strong>The</strong>y inadvertently end up with a slower unreliable<br />

link (lots of "collisions" resulting in runt packets) rather than the<br />

14.2.14. Why is my Ethernet operation not reliable 179


faster better link they thought they were picking (d'oh!). <strong>The</strong> really<br />

bad thing is that the network works fine in testing on an isolated LAN<br />

with no traffic <strong>and</strong> absolutely craps its pants when it hits the real<br />

world.<br />

Rule:<br />

That is my reasoning behind my statement that we can generally ignore<br />

the autonegotiation fixed configuration case because the odds of it<br />

working properly are poor anyway.<br />

Always try to set up your PHY <strong>for</strong> autonegotiation.<br />

If you must use some fixed setting, then set it to half duplex mode.<br />

If you really must use a fixed full-duplex setting, then you absolutley must make sure that the link<br />

partner is configured exactly the same.<br />

14.2.15. How the Comm<strong>and</strong> Line Parsing Works<br />

<strong>The</strong>re are two different comm<strong>and</strong> line parsers available with U-<strong>Boot</strong>: the old "simple" one, <strong>and</strong> the much<br />

more powerful "hush" shell:<br />

14.2.15.1. Old, simple comm<strong>and</strong> line parser<br />

• supports environment variables (through setenv / saveenv comm<strong>and</strong>s)<br />

• several comm<strong>and</strong>s on one line, separated by ';'<br />

• variable substitution using "... ${_variablename_} ..." syntax<br />

NOTE: Older versions of U-<strong>Boot</strong> used "$(...)" <strong>for</strong> variable substitution. Support <strong>for</strong> this<br />

syntax is still present in current versions, but will be removed soon. Please use "${...}" instead,<br />

which has the additional benefit that your environment definitions are compatible with the Hush shell,<br />

too.<br />

• special characters ('$', ';') can be escaped by prefixing with '\', <strong>for</strong> example:<br />

setenv bootcmd bootm \${address}<br />

• You can also escape text by enclosing in single apostrophes, <strong>for</strong> example:<br />

setenv addip 'setenv bootargs ${bootargs} ip=${ipaddr}:${serverip}:${gatewayip}:${n<br />

14.2.15.2. Hush shell<br />

• similar to Bourne shell, with control structures like if...then...else...fi,<br />

<strong>for</strong>...do...done, while...do...done, until...do...done, ...<br />

• supports environment ("global") variables (through setenv / saveenv comm<strong>and</strong>s) <strong>and</strong> local shell<br />

variables (through st<strong>and</strong>ard shell syntax name=value ); only environment variables can be used<br />

with the run comm<strong>and</strong>, especially as the variable to run (i. e. the first argument).<br />

• In the current implementation, the local variables space <strong>and</strong> global environment variables space are<br />

separated. Local variables are those you define by simply typing like name=value. To access a<br />

local variable later on, you have to write '$name' or '${name}'; to execute the contents of a<br />

variable directly you can type '$name' at the comm<strong>and</strong> prompt. Note that local variables can only<br />

be used <strong>for</strong> simple comm<strong>and</strong>s, not <strong>for</strong> compound comm<strong>and</strong>s etc.<br />

• Global environment variables are those you can set <strong>and</strong> print using setenv <strong>and</strong> printenv. To run<br />

a comm<strong>and</strong> stored in such a variable, you need to use the run comm<strong>and</strong>, <strong>and</strong> you must not use the '$'<br />

sign to access them.<br />

• To store comm<strong>and</strong>s <strong>and</strong> special characters in a variable, use single quotation marks surrounding the<br />

whole text of the variable, instead of the backslashes be<strong>for</strong>e semicolons <strong>and</strong> special symbols.<br />

• Be careful when using the hash ('#') character - like with a "real" Bourne shell it is the comment<br />

14.2.15. How the Comm<strong>and</strong> Line Parsing Works 180


Examples:<br />

character, so you have to escape it when you use it in the value of a variable.<br />

setenv bootcmd bootm \$address<br />

setenv addip 'setenv bootargs $bootargs ip=$ipaddr:$serverip:$gatewayip:$netmask:$hostnam<br />

14.2.15.3. Hush shell scripts<br />

Here are a few examples <strong>for</strong> the use of the advanced capabilities of the hush shell in U-<strong>Boot</strong> environment<br />

variables or scripts:<br />

Example:<br />

Example:<br />

=> setenv check 'if imi $addr; then echo Image OK; else echo Image corrupted!!; fi'<br />

=> print check<br />

check=if imi $addr; then echo Image OK; else echo Image corrupted!!; fi<br />

=> addr=0 ; run check<br />

## Checking Image at 00000000 ...<br />

Bad Magic Number<br />

Image corrupted!!<br />

=> addr=40000 ;run check<br />

## Checking Image at 00040000 ...<br />

Image Name: ARM <strong>Linux</strong>-2.4.18<br />

Created: 2003-06-02 14:10:54 UTC<br />

Image Type: ARM <strong>Linux</strong> Kernel Image (gzip compressed)<br />

Data Size: 801609 Bytes = 782.8 kB<br />

Load Address: 0c008000<br />

Entry Point: 0c008000<br />

Verifying Checksum ... OK<br />

Image OK<br />

Instead of "echo Image OK" there could be a comm<strong>and</strong> (sequence) to boot or otherwise deal with<br />

the correct image; instead of the "echo Image corrupted!!" there could be a comm<strong>and</strong><br />

(sequence) to (load <strong>and</strong>) boot an alternative image, etc.<br />

=> addr1=0<br />

=> addr2=10<br />

=> bootm $addr1 || bootm $addr2 || tftpboot $loadaddr $loadfile && bootm<br />

## <strong>Boot</strong>ing image at 00000000 ...<br />

Bad Magic Number<br />

## <strong>Boot</strong>ing image at 00000010 ...<br />

Bad Magic Number<br />

TFTP from server 192.168.3.1; our IP address is 192.168.3.68<br />

Filename '/tftpboot/TRAB/uImage'.<br />

Load address: 0xc400000<br />

Loading: #################################################################<br />

#################################################################<br />

###########################<br />

done<br />

Bytes transferred = 801673 (c3b89 hex)<br />

## <strong>Boot</strong>ing image at 0c400000 ...<br />

Image Name: ARM <strong>Linux</strong>-2.4.18<br />

14.2.15.2. Hush shell 181


This will check if the image at (flash) address "addr1" is ok <strong>and</strong> boot it; if the image is not ok, the<br />

alternative image at address "addr2" will be checked <strong>and</strong> booted if it is found to be OK. If both<br />

images are missing or corrupted, a new image will be loaded over TFTP <strong>and</strong> booted.<br />

14.2.15.4. General rules<br />

1. If a comm<strong>and</strong> line (or an environment variable executed by a run comm<strong>and</strong>) contains several<br />

comm<strong>and</strong>s separated by semicolons, <strong>and</strong> one of these comm<strong>and</strong>s fails, the remaining comm<strong>and</strong>s will<br />

still be executed.<br />

2. If you execute several variables with one call to run (i. e. calling run with a list of variables as<br />

arguments), any failing comm<strong>and</strong> will cause run to terminate, i. e. the remaining variables are not<br />

executed.<br />

14.2.16. How can I load <strong>and</strong> uncompress a<br />

compressed image<br />

Question:<br />

Can I use U-<strong>Boot</strong> to load <strong>and</strong> uncompress a compressed image from flash into RAM And can I<br />

choose whether I want to automatically run it at that time, or wait until later<br />

Answer:<br />

Yes to both questions. First, you should generate your image as type "st<strong>and</strong>alone" (using "mkimage<br />

... -T st<strong>and</strong>alone ..."). When you use the bootm comm<strong>and</strong> <strong>for</strong> such an image, U-<strong>Boot</strong><br />

will automatically uncompress the code while it is storing it at that image's load address in RAM<br />

(given by the -a option to the mkimage comm<strong>and</strong>).<br />

As to the second question, by default, unless you say differently, U-<strong>Boot</strong> will automatically start the<br />

image by jumping to its entry point (given by the -e option to mkimage) after loading it. If you want<br />

to prevent automatic execution, just set the environment variable "autostart" to "no"<br />

("setenv autostart no") be<strong>for</strong>e running bootm.<br />

14.2.17. My st<strong>and</strong>alone program does not work<br />

Question:<br />

I tried adding some new code to the hellow_world.c demo program. This works well as soon as I<br />

only add code to the existing hello_world() function, but as soon as I add some functions of my own,<br />

things go all haywire: the code of the hello_world() function does not get executed correctly, <strong>and</strong> my<br />

new function gets called with unexpected arguments. What's wrong<br />

Answer:<br />

You probably failed to notice that any code you add to the example program may shift the entry point<br />

address. You should check this using the nm program:<br />

$ ${CROSS_COMPILE}nm -n examples/hello_world<br />

0000000000040004 T testfunc<br />

0000000000040058 T hello_world<br />

000000000004016c t dummy<br />

...<br />

As you can see, the entry point (function hello_world()) is no longer at 0x40004 as it was be<strong>for</strong>e <strong>and</strong><br />

14.2.17. My st<strong>and</strong>alone program does not work 182


as it's documented. Instead, it is now at 0x40058. So you have to start your st<strong>and</strong>alone program at this<br />

address, <strong>and</strong> everything should work well.<br />

14.2.18. <strong>Linux</strong> hangs after uncompressing the<br />

kernel<br />

Question:<br />

I am using U-<strong>Boot</strong> with a <strong>Linux</strong> kernel version Y (Y < 2.4.5-pre5), but the last message I see is<br />

Uncompressing Kernel Image ... OK<br />

<strong>The</strong>n the system hangs.<br />

Answer:<br />

Most probably you pass bad parameters to the <strong>Linux</strong> kernel.<br />

<strong>The</strong>re are several possible reasons:<br />

◊ Bad device tree; <strong>for</strong> example, check that the memory map set up by the boot loader (like<br />

mapping of IMMR, PCI addresses etc.) is consistent with what is encoded in your device tree<br />

specification.<br />

Here some possible reasons <strong>for</strong> older <strong>Linux</strong> kernel versions:<br />

<strong>Linux</strong>:<br />

arch/ppc:<br />

◊ arch/ppc: Bad definition of the bd_info structure<br />

You must make sure that your machine specific header file (<strong>for</strong> instance<br />

include/asm-ppc/tqm8xx.h) includes the same definition of the Board In<strong>for</strong>mation structure as<br />

we define in include/ppcboot.h, <strong>and</strong> make sure that your definition of IMAP_ADDR uses the<br />

same value as your U-<strong>Boot</strong> configuration in CFG_IMMR.<br />

◊ Bad clock in<strong>for</strong>mation<br />

Be<strong>for</strong>e kernel version 2.4.5-pre5 (BitKeeper Patch 1.1.1.6, 22MAY2001) the kernel expected<br />

the clock in<strong>for</strong>mation in MHz, but recent kernels expect it in Hz instead. U-<strong>Boot</strong> passes the<br />

clock in<strong>for</strong>mation in Hz by default. To switch to the old behaviour, you can set the<br />

environment variable "clocks_in_mhz" in U-<strong>Boot</strong>:<br />

=> setenv clocks_in_mhz 1<br />

=> saveenv<br />

For recent kernel the "clocks_in_mhz" variable must not be set. If it is present in your environment, you<br />

can delete it as follows:<br />

=> setenv clocks_in_mhz<br />

=> saveenv<br />

A common error is to try "setenv clocks_in_mhz 0" or to some other value - this will not work,<br />

as the value of the variable is not important at all. It is the existence of the variable that will be checked.<br />

•<br />

♦ Inconsistent memory map<br />

Some boards may need corrct mappings <strong>for</strong> some special hardware devices like BCSR (Board<br />

Control <strong>and</strong> Status Registers) etc. Verify that the mappings expected by <strong>Linux</strong> match those<br />

created by U-<strong>Boot</strong>.<br />

14.2.18. <strong>Linux</strong> hangs after uncompressing the kernel 183


14.3. <strong>Linux</strong><br />

14.3.1. <strong>Linux</strong> crashes r<strong>and</strong>omly<br />

Question:<br />

On my board, <strong>Linux</strong> crashes r<strong>and</strong>omly or has r<strong>and</strong>om exceptions (especially floating point exceptions<br />

if it is a PowerPC processor). Why<br />

Answer:<br />

Quite likely your SDRAM initialization is bad. See U<strong>Boot</strong>CrashAfterRelocation <strong>for</strong> more<br />

in<strong>for</strong>mation.<br />

On a PowerPC, the instructions beginning with 0xFF are floating point instructions. When your<br />

memory subsystem fails, the PowerPC is reading bad values (0xFF) <strong>and</strong> thus executing illegal<br />

floating point instructions.<br />

14.3.2. <strong>Linux</strong> crashes when uncompressing the<br />

kernel<br />

Question:<br />

When I try to boot <strong>Linux</strong>, it crashes during uncompressing the kernel image:<br />

=> bootm 100000<br />

## <strong>Boot</strong>ing image at 00100000 ...<br />

Image Name: <strong>Linux</strong>-2.4.25<br />

Image Type: PowerPC <strong>Linux</strong> Kernel Image (gzip compressed)<br />

Data Size: 1003065 Bytes = 979.6 kB<br />

Load Address: 00000000<br />

Entry Point: 00000000<br />

Verifying Checksum ... OK<br />

Uncompressing Kernel Image ... Error: inflate() returned -3<br />

GUNZIP ERROR - must RESET board to recover<br />

Answer:<br />

Your kernel image is quite big - nearly 1 MB compressed; when it gets uncompressed it will need 2.5<br />

... 3 MB, starting at address 0x0000. But your compressed image was stored at 1 MB (0x100000), so<br />

the uncompressed code will overwrite the (remaining) compressed image. <strong>The</strong> solution is thus simple:<br />

just use a higher address to download the compressed image into RAM. For example, try:<br />

=> bootm 400000<br />

14.3.3. <strong>Linux</strong> Post Mortem Analysis<br />

You may find yourself in a situation where the <strong>Linux</strong> kernel crashes or hangs without any output on the<br />

console. <strong>The</strong> first attempt to get more in<strong>for</strong>mation in such a situation is a Post Mortem dump of the log buffer<br />

- often the <strong>Linux</strong> kernel has already collected useful in<strong>for</strong>mation in its console I/O buffer which just does not<br />

get printed because the kernel does not run until successful initialization of the console port.<br />

Proceed as follows:<br />

14.3.3. <strong>Linux</strong> Post Mortem Analysis 184


1.<br />

Find out the virtual address of the log buffer; For 2.4 <strong>Linux</strong> kernels search <strong>for</strong> "log_buf":<br />

2.4 <strong>Linux</strong>:<br />

bash$ grep log_buf System.map<br />

c0182f54 b log_buf<br />

Here the virtual address of the buffer is 0xC0182F54<br />

For 2.6 kernels "__log_buf" must be used:<br />

bash$ grep __log_buf System.map<br />

c02124c4 b __log_buf<br />

Here the virtual address of the buffer is 0xC02124C4<br />

2. Convert to physical address: on PowerPC systems, the kernel is usually configured <strong>for</strong> a virtual<br />

address of kernel base (CONFIG_KERNEL_START) of 0xC0000000. Just subtract this value from<br />

the address you found. In our case we get:<br />

physical address = 0xC0182F54 - 0xC0000000 = 0x00182F54<br />

3. Reset your board - do not power-cycle it!<br />

4. Use your boot loader (you're running U-<strong>Boot</strong>, right) to print a memory dump of that memory area:<br />

=> md 0x00182F54<br />

This whole operation is based on the assumption that your boot loader does not overwrite the RAM contents -<br />

U-<strong>Boot</strong> will take care not to destroy such valuable in<strong>for</strong>mation.<br />

14.3.4. <strong>Linux</strong> kernel register usage<br />

For the PowerPC architecture, the <strong>Linux</strong> kernel uses the following registers:<br />

R1:<br />

stack pointer<br />

R2:<br />

pointer to task_struct <strong>for</strong> the current task<br />

R3-R4:<br />

parameter passing <strong>and</strong> return values<br />

R5-R10:<br />

parameter passing<br />

R13:<br />

small data area pointer<br />

R30:<br />

GOT pointer<br />

R31:<br />

frame pointer<br />

A function can use r0 <strong>and</strong> r3 - r12 without saving <strong>and</strong> restoring them. r13 - r31 have to be preserved so<br />

they must be saved <strong>and</strong> restored when you want to use them. Also, cr2 - cr4 must be preserved, while cr0,<br />

cr1, cr5 - cr7, lr, ctr <strong>and</strong> xer can be used without saving & restoring them. [ Posted Tue, 15 Jul 2003<br />

by Paul Mackerras to linuxppc-embedded@lists.linuxppc.org ].<br />

See also the (E)ABI specifications <strong>for</strong> the PowerPC architecture, Developing PowerPC Embedded<br />

Application Binary Interface (EABI) Compliant Programs<br />

14.3.4. <strong>Linux</strong> kernel register usage 185


14.3.5. <strong>Linux</strong> Kernel Ignores my bootargs<br />

Question:<br />

Why doesn't the kernel use the comm<strong>and</strong>-line options I set in the "bootargs" environment variable in<br />

U-<strong>Boot</strong> when I boot my target system<br />

Answer:<br />

This problem is typical <strong>for</strong> ARM systems only. <strong>The</strong> following discussion is ARM-centric:<br />

First, check to ensure that you have configured your U-<strong>Boot</strong> build so that CONFIG_CMDLINE_TAG<br />

is enabled. (Other tags like CONFIG_SETUP_MEMORY_TAGS or CONFIG_INITRD_TAG may be<br />

needed, too.) This ensures that u-boot will boot the kernel with a comm<strong>and</strong>-line tag that incorporates<br />

the kernel options you set in the "bootargs" environment variable.<br />

If you have the CONFIG_CMDLINE_TAG option configured, the problem is almost certainly with<br />

your kernel build. You have to instruct the kernel to pick up the boot tags at a certain address. This is<br />

done in the machine descriptor macros, which are found in the processor start-up C code <strong>for</strong> your<br />

architecture. For the Intel DBPXA250 "Lubbock" development board, the machine descriptor<br />

macros are located at the bottom of the file arch/arm/mach-pxa/lubbock.c, <strong>and</strong> they look<br />

like this:<br />

MACHINE_START(LUBBOCK, "Intel DBPXA250 Development Plat<strong>for</strong>m")<br />

MAINTAINER("MontaVista Software Inc.")<br />

BOOT_MEM(0xa0000000, 0x40000000, io_p2v(0x40000000))<br />

FIXUP(fixup_lubbock)<br />

MAPIO(lubbock_map_io)<br />

INITIRQ(lubbock_init_irq)<br />

MACHINE_END<br />

<strong>The</strong> machine descriptor macros <strong>for</strong> your machine will be located in a similar file in your kernel source<br />

tree. Having located your machine descriptor macros, the next step is to find out where U-<strong>Boot</strong> puts<br />

the kernel boot tags in memory <strong>for</strong> your architecture. On the Lubbock, this address turns out to be the<br />

start of physical RAM plus 0x100, or 0xa0000100. Add the "BOOT_PARAMS" macro with this<br />

address to your machine descriptor macros; the result should look something like this:<br />

MACHINE_START(LUBBOCK, "Intel DBPXA250 Development Plat<strong>for</strong>m")<br />

MAINTAINER("MontaVista Software Inc.")<br />

BOOT_PARAMS(0xa0000100)<br />

BOOT_MEM(0xa0000000, 0x40000000, io_p2v(0x40000000))<br />

FIXUP(fixup_lubbock)<br />

MAPIO(lubbock_map_io)<br />

INITIRQ(lubbock_init_irq)<br />

MACHINE_END<br />

If there is already a BOOT_PARAMS macro in your machine descriptor macros, modify it so that it<br />

has the correct address. <strong>The</strong>n, rebuild your kernel <strong>and</strong> re-install it on your target. Now the kernel<br />

should be able to pick up the kernel options you have set in the "bootargs" environment variable.<br />

14.3.6. Cannot configure Root Filesystem over NFS<br />

Question:<br />

I want to configure my system with root filesystem over NFS, but I cannot find any such<br />

configuration option.<br />

Answer:<br />

14.3.6. Cannot configure Root Filesystem over NFS 186


What you are looking <strong>for</strong> is the CONFIG_ROOT_NFS configuration option, which depends on<br />

CONFIG_IP_PNP.<br />

To enable root filesystem over NFS you must enable the "IP: kernel level<br />

autoconfiguration" option in the "Networking options" menu first.<br />

14.3.7. <strong>Linux</strong> Kernel Panics because "init" process<br />

dies<br />

Question:<br />

I once had a running system but suddenly, without any changes, the <strong>Linux</strong> kernel started crashing<br />

because the "init" process was dying each time I tried to boot the system, <strong>for</strong> example like that:<br />

...<br />

VFS: Mounted root (nfs filesystem).<br />

Freeing unused kernel memory: 140k init<br />

init has generated signal 11 but has no h<strong>and</strong>ler <strong>for</strong> it<br />

Kernel panic - not syncing: Attempted to kill init!<br />

Answer:<br />

You probably run your system with the root file system mounted over NFS. Change into the root<br />

directory of your target file system, <strong>and</strong> remove the file "etc/ld.so.cache". That should fix this<br />

problem:<br />

# cd /opt/eldk/ppc_6xx/<br />

# rm -f etc/ld.so.cache<br />

Explanation:<br />

Normally, the file "etc/ld.so.cache" contains a compiled list of system libraries. This file is<br />

used by the dynamic linker/loader ld.so to cache library in<strong>for</strong>mation. If it does not exist, rebuilt<br />

automatically. For some reason, a corrupted or partial file was written to your root file system. This<br />

corrupt file then confused the dynamic linker so that it crashed when trying to start the init process.<br />

14.3.8. Unable to open an initial console<br />

Question:<br />

<strong>The</strong> <strong>Linux</strong> kernel boots, but then hangs after printing: "Warning: unable to open an initial console".<br />

Answer:<br />

Most probably you have one or missing entries in the /dev directory in your root filesystem. If you<br />

are using the ELDK's root filesystem over NFS, you probably <strong>for</strong>got to run the ELDK_MAKEDEV <strong>and</strong><br />

ELDK_FIXOWNER scripts as described in 3.7. Mounting Target Components via NFS.<br />

14.3.9. Mounting a Filesystem over NFS hangs<br />

<strong>for</strong>ever<br />

Question:<br />

We use the SELF ramdisk image that comes with the ELDK. When we try to mount a filesystem over<br />

NFS from the server, <strong>for</strong> example:<br />

# mount -t nfs 192.168.1.1:/target/home /home<br />

14.3.9. Mounting a Filesystem over NFS hangs <strong>for</strong>ever 187


the comm<strong>and</strong> waits nearly 5 minutes in uninterruptable sleep. <strong>The</strong>n the mount finally succeeds.<br />

What's wrong<br />

Answer:<br />

<strong>The</strong> default configuration of the SELF was not designed to mount additional filesystems with file<br />

locking over NFS, so no portmap deamon is running, which is causing your problems. <strong>The</strong>re are two<br />

solutions <strong>for</strong> the problem:<br />

1. Add the portmap deamon (/sbin/portmap) to the target filesystem <strong>and</strong> start it as part of<br />

the init scripts.<br />

2. Tell the "mount" program <strong>and</strong> the kernel that you don't need file locking by passing the<br />

"nolock" option to the mount call, i. e. use<br />

# mount -o nolock -t nfs 192.168.1.1:/target/home /home<br />

Explanation:<br />

If you call the mount comm<strong>and</strong> like above (i. e. without the "nolock" option) an RPC call to the<br />

"portmap" deamon will be attempted which is required to start a lockd kernel thread which is<br />

necessary if you want to use file locking on the NFS filesystem. This call will fail only after a very<br />

long timeout.<br />

14.3.10. Ethernet does not work in <strong>Linux</strong><br />

Question:<br />

Ethernet does not work on my board. But everything is fine when I use the ethernet interface in<br />

U-<strong>Boot</strong> (<strong>for</strong> example by per<strong>for</strong>ming a TFTP download). This is a bug in U-<strong>Boot</strong>, right<br />

Answer:<br />

No. It's a bug in the <strong>Linux</strong> ethernet driver.<br />

In some cases the <strong>Linux</strong> driver fails to set the MAC address. That's a buggy driver then - <strong>Linux</strong><br />

ethernet drivers are supposed to read the MAC address at startup. On ->open, they are supposed to<br />

reprogram the MAC address back into the chip (but not the EEPROM, if any) whether or not the<br />

address has been changed.<br />

In general, a <strong>Linux</strong> driver shall not make any assumptions about any initialization being done (or not<br />

done) by a boot loader; instead, that driver is responsible <strong>for</strong> per<strong>for</strong>ming all of the necessary<br />

initialization itself.<br />

And U-<strong>Boot</strong> shall not touch any hardware it does not access itself. If you don't use the ethernet<br />

interface in U-<strong>Boot</strong>, it won't be initialized by U-<strong>Boot</strong>.<br />

A pretty extensive discussion of this issue can be found in the thread ATAG <strong>for</strong> MAC address on the<br />

ARM <strong>Linux</strong> mailing list. archive 1 archive 2<br />

Some current methods <strong>for</strong> h<strong>and</strong>ling the MAC address programming:<br />

• use custom ATAGs (ARM systems)<br />

• use a Flattened Device Tree (if your arch/port supports it)<br />

• parse the U-<strong>Boot</strong> environment directly<br />

• pass it via the comm<strong>and</strong> line<br />

If your device driver does not support one of these sources directly, then do it yourself:<br />

14.3.10. Ethernet does not work in <strong>Linux</strong> 188


• add an init board hook<br />

• program it from user space (`ifconfig hw ...`)<br />

• <strong>for</strong> people who need to do NFS root or similar, then use initramfs -- this is what it was designed <strong>for</strong> !<br />

14.3.11. Loopback interface does not work<br />

Question:<br />

When I boot <strong>Linux</strong> I get a "socket: Address family not supported by protocol"<br />

error message when I try to configure the loopback interface. What's wrong<br />

Answer:<br />

This is most probably a problem with your kernel configuration. Make sure that the<br />

CONFIG_PACKET option is selected.<br />

14.3.12. <strong>Linux</strong> kernel messages are not printed on<br />

the console<br />

Question:<br />

I expect to see some <strong>Linux</strong> kernel messages on the console, but there aren't any.<br />

Answer:<br />

This is absolutely normal when using the ELDK with root filesystem over NFS. <strong>The</strong> ELDK startup<br />

routines will start the syslog daemon, which will collect all kernel messages <strong>and</strong> write them into a<br />

logfile ( /var/log/messages ).<br />

If you want to see the messages at the console, either run "tail -f /var/log/messages &"<br />

on the console window, or stop the syslog daemon by issuing a "/etc/rc.d/init.d/syslog<br />

stop" comm<strong>and</strong>. Another alternative is to increase the console_loglevel of the kernel (any<br />

message with log level less than console_loglevel will be printed to the console). With the<br />

following comm<strong>and</strong> the console_loglevel could be set at runtime: "echo 8 ><br />

/proc/sys/kernel/printk". Now all messages are displayed on the console.<br />

14.3.13. <strong>Linux</strong> ignores input when using the<br />

framebuffer driver<br />

Question:<br />

When using the framebuffer driver the console output goes to the LCD display, but I cannot input<br />

anything. What's wrong<br />

Answer:<br />

You can define "console devices" using the console= boot argument. Add something like this to your<br />

bootargs setting:<br />

... console=tty0 console=ttyS0,${baudrate} ...<br />

This will ensure that the boot messages are displayed on both the framebuffer (/dev/tty0) <strong>and</strong> the serial<br />

console (/dev/ttyS0); the last device named in a console= option will be the one that takes input,<br />

too, so with the settings above you can use the serial console to enter comm<strong>and</strong>s etc. For a more<br />

14.3.13. <strong>Linux</strong> ignores input when using the framebuffer driver 189


detailed description see<br />

http://www.tldp.org/HOWTO/Remote-Serial-Console-HOWTO/configure-kernel.html<br />

14.3.14. How to switch off the screen saver <strong>and</strong> the<br />

blinking cursor<br />

Question:<br />

I'm using a splash screen on my frame buffer display, but it is disturbed by a blinking cursor, <strong>and</strong> after<br />

a while the screen is blanked. How can I prevent this<br />

Answer:<br />

Screen saver <strong>and</strong> blinking cursor can be turned off (<strong>and</strong> on) using escape sequences.<br />

To turn off the screen saver, send the sequence "\E[9;0]" to the terminal ="/dev/tty1". For<br />

example, output the content of file "/etc/blank_off" in one of your init scripts:<br />

# cat /etc/blank_off<br />

To turn off the blinking cursor, send the sequence "\E[25l\E[1c" to the terminal. For<br />

example, copy the content of file "/etc/init_tty" to the terminal:<br />

# cat /etc/init_tty<br />

For details, please see "man 4 console_codes" .<br />

14.3.15. BogoMIPS Value too low<br />

Question:<br />

We are only seeing 263.78 bogomips on a MPC5200 running at 396 MHz.<br />

Doesn't this seem way to low With a 603e core I'd expect 1 bogomip per MHz or better.<br />

Answer:<br />

No, the values you see is correct. Please keep in mind that there is a good reason <strong>for</strong> the name<br />

BogoMIPS.<br />

On PowerPC, the bogomips calculation is measuring the speed of a dbnz instruction. On some<br />

processors like the MPC8xx it takes 2 clocks per dbnz instruction, <strong>and</strong> you get 1 BogoMIP/MHz.<br />

<strong>The</strong> MPC5200 takes 3 clocks per dbnz in this loop, so you get .67 BogoMIP/MHz.<br />

See also <strong>The</strong> frequently asked questions about BogoMips.<br />

14.3.16. <strong>Linux</strong> Kernel crashes when using a<br />

ramdisk image<br />

Question:<br />

I have a PowerPC board with 1 GiB of RAM (or more). It works fine with root file system over NFS,<br />

but it will crash when I try to use a ramdisk.<br />

Answer:<br />

14.3.16. <strong>Linux</strong> Kernel crashes when using a ramdisk image 190


Check where your ramdisk image gets loaded to. In the st<strong>and</strong>ard configuration, the <strong>Linux</strong> kernel can<br />

access only 768 MiB of RAM, so your ramdisk image must be loaded below this limit. Check your<br />

boot messages. You are hit by this problem when U-<strong>Boot</strong> reports something like this:<br />

Loading Ramdisk to 3fdab000, end 3ff2ff9d ... OK<br />

<strong>and</strong> then <strong>Linux</strong> shows a message like this:<br />

mem_pieces_remove: [3fdab000,3ff2ff9d) not in any region<br />

To fix, just tell U-<strong>Boot</strong> to load the ramdisk image below the 768 MB limit:<br />

=> setenv initrd_high 30000000<br />

14.3.17. Ramdisk Greater than 4 MB Causes<br />

Problems<br />

Question:<br />

I built a ramdisk image which is bigger than 4 MB. I run into problems when I try to boot <strong>Linux</strong> with<br />

this image, while other (smaller) ramdisk images work fine.<br />

Answer:<br />

<strong>The</strong> <strong>Linux</strong> kernel has a default maximum ramdisk size of 4096 kB. To boot with a bigger ramdisk<br />

image, you must raise this value. <strong>The</strong>re are two methods:<br />

◊ Dynamical adjustment using boot arguments:<br />

You can pass a boot argument ramdisk_size= to the <strong>Linux</strong> kernel to<br />

overwrite the configured maximum. Note that this argument needs to be be<strong>for</strong>e any root<br />

argument. A flexible way to to this is using U-<strong>Boot</strong> environment variables. For instance, to<br />

boot with a ramdisk image of 6 MB (6144 kB), you can define:<br />

=> setenv rd_size 6144<br />

=> setenv bootargs ... ramdisk_size=\${rd_size} ...<br />

=> saveenv<br />

If you later find out that you need an even bigger ramdisk image, or that a smaller one is sufficient, all that<br />

needs changing is the value of the "rd_size" environment variable.<br />

•<br />

♦ Increasing the <strong>Linux</strong> kernel default value:<br />

When configuring your <strong>Linux</strong> kernel, adjust the value of the<br />

CONFIG_BLK_DEV_RAM_SIZE parameter so that it contains a number equal or larger than<br />

your ramdisk (in kB). (In the 2.4 kernel series, you'll find this setting under the "Block<br />

devices" menu choice while, in the 2.6 series, it will be under "Device drivers" -> "Block<br />

devices".)<br />

14.3.18. Combining a Kernel <strong>and</strong> a Ramdisk into a<br />

Multi-File Image<br />

Question:<br />

I used to build a zImage.initrd file which combined the <strong>Linux</strong> kernel with a ramdisk image. Can<br />

14.3.18. Combining a Kernel <strong>and</strong> a Ramdisk into a Multi-File Image 191


I do something similar with U-<strong>Boot</strong><br />

Answer:<br />

Yes, you can create "Multi-File Images" which contain several images, typically an OS (<strong>Linux</strong>) kernel<br />

image <strong>and</strong> one or more data images like RAMDisks. This construct is useful <strong>for</strong> instance when you<br />

want to boot over the network using BOOTP etc., where the boot server provides just a single image<br />

file, but you want to get <strong>for</strong> instance an OS kernel <strong>and</strong> a RAMDisk image.<br />

<strong>The</strong> typical way to build such an image is:<br />

bash$ mkimage -A ppc -O <strong>Linux</strong> -T multi -C gzip \<br />

-n '<strong>Linux</strong> Multiboot-Image' -e 0 -a 0 \<br />

-d vmlinux.gz:ramdisk_image.gz pMulti<br />

See also the usage message you get when you call "mkimage" without arguments.<br />

14.3.19. Adding Files to Ramdisk is Non Persistent<br />

Quetsion:<br />

I want to add some files to my ramdisk, but every time I reboot I lose all my changes. What can I do<br />

Answer:<br />

To add your files or modifications permanently, you have to rebuild the ramdisk image. You may<br />

check out the sources of our SELF package (Simple Embedded <strong>Linux</strong> Framework) to see how this can<br />

be done, see <strong>for</strong> example ftp://ftp.denx.de/pub/<strong>Linux</strong>PPC/usr/src/SELF/ or check out the sources <strong>for</strong><br />

ELDK (module eldk_build from our CVS server, see http://www.denx.de/re/linux.html.<br />

See also section 14.4.1. How to Add Files to a SELF Ramdisk <strong>for</strong> another way to change the ramdisk<br />

image.<br />

For further hints about the creation <strong>and</strong> use of initial ramdisk images see also the file<br />

Documentation/initrd.txt in your <strong>Linux</strong> kernel source directory.<br />

14.3.20. Kernel Configuration <strong>for</strong> PCMCIA<br />

Question:<br />

Which kernel configuration options are relevant to support PCMCIA cards under <strong>Linux</strong><br />

Answer:<br />

<strong>The</strong> following kernel configuration options are required to support miscellaneous PCMCIA card types<br />

with <strong>Linux</strong> <strong>and</strong> the PCMCIA CS package:<br />

◊ PCMCIA IDE cards (CF <strong>and</strong> true-IDE)<br />

To support the IDE CardService client, the kernel has to be configured with general ATA IDE<br />

support. <strong>The</strong> MPC8xx IDE support (CONFIG_BLK_DEV_MPC8XX_IDE flag) must be<br />

turned off.<br />

◊ PCMCIA modem cards<br />

<strong>The</strong> kernel has to be configured with st<strong>and</strong>ard serial port support (CONFIG_SERIAL flag).<br />

After the kernel bootup the following preparation is needed:<br />

bash# mknod /dev/ttySp0 c 240 64<br />

This creates a new special device <strong>for</strong> the modem card; please note that /dev/ttyS0 ... S4 <strong>and</strong><br />

TTY_MAJOR 4 are already used by the st<strong>and</strong>ard 8xx UART driver). /dev/ttySp0 becomes<br />

14.3.20. Kernel Configuration <strong>for</strong> PCMCIA 192


available <strong>for</strong> use as soon as the CardServices detect <strong>and</strong> initialize the PCMCIA modem card.<br />

◊ PCMCIA Wireless LAN cards<br />

Enable the "Network device support" --> "Wireless LAN (non-hamradio)" --> "Wireless<br />

LAN (non-hamradio)" option in the kernel configuration (CONFIG_NET_RADIO flag).<br />

14.3.21. Configure <strong>Linux</strong> <strong>for</strong> PCMCIA Cards using<br />

the Card Services package<br />

<strong>The</strong> following kernel configuration options are required to support miscellaneous PCMCIA card types with<br />

<strong>Linux</strong> <strong>and</strong> the PCMCIA CS package:<br />

1. PCMCIA IDE cards (CompactFlash <strong>and</strong> true-IDE)<br />

General setup -> Support <strong>for</strong> hot-pluggable devices (enable: Y) -> PCMCIA/CardBus support -><br />

PCMCIA/CardBus support (enable: M) -> MPC8XX PCMCIA host bridge support (select)<br />

2. PCMCIA Modem Cards<br />

3. PCMCIA Network Cards<br />

4. PCMCIA WLAN Cards<br />

Build <strong>and</strong> install modules in target root filesystem, shared over NFS:<br />

bash$ make modules modules_install INSTALL_MOD_PATH=/opt/eldk/ppc_8xx<br />

Adjust PCMCIA configuration file (/opt/eldk/ppc_8xx/etc/sysconfig/pcmcia):<br />

PCMCIA=yes<br />

PCIC=m8xx_pcmcia<br />

PCIC_OPTS=<br />

CORE_OPTS=<br />

CARDMGR_OPTS=<br />

Start PCMCIA Card Services:<br />

bash-2.05# sh /etc/rc.d/init.d/pcmcia start<br />

14.3.22. Configure <strong>Linux</strong> <strong>for</strong> PCMCIA Cards without<br />

the Card Services package<br />

For "disk" type PC Cards (FlashDisks, CompactFlash, Hard Disk Adapters - basically anything that looks like<br />

an ordinary IDE drive), an alternative solution is available: direct support within the <strong>Linux</strong> kernel. This has<br />

the big advantage of minimal memory footprint, but of course it comes with a couple of disadvantages, too:<br />

• It works only with "disk" type PC Cards - no support <strong>for</strong> modems, network cards, etc; <strong>for</strong> these you<br />

still need the PCMCIA Card Services package.<br />

• <strong>The</strong>re is no support <strong>for</strong> "hot plug", i. e. you cannot insert or remove the card while <strong>Linux</strong> is running.<br />

(Well, of course you can do this, but either you will not be able to access any card inserted, or when<br />

you remove a card you will most likely crash the system. Don't do it - you have been warned!)<br />

• <strong>The</strong> code relies on initialization of the PCMCIA controller by the firmware (of course U-<strong>Boot</strong> will do<br />

exactly what's required).<br />

On the other h<strong>and</strong> these are no real restrictions <strong>for</strong> use in an Embedded System.<br />

14.3.22. Configure <strong>Linux</strong> <strong>for</strong> PCMCIA Cards without the Card Services package 193


To enable the "direct IDE support" you have to select the following <strong>Linux</strong> kernel configuration options:<br />

CONFIG_IDE=y<br />

CONFIG_BLK_DEV_IDE=y<br />

CONFIG_BLK_DEV_IDEDISK=y<br />

CONFIG_IDEDISK_MULTI_MODE=y<br />

CONFIG_BLK_DEV_MPC8xx_IDE=y<br />

CONFIG_BLK_DEV_IDE_MODES=y<br />

<strong>and</strong>, depending on which partition types <strong>and</strong> languages you want to support:<br />

CONFIG_PARTITION_ADVANCED=y<br />

CONFIG_MAC_PARTITION=y<br />

CONFIG_MSDOS_PARTITION=y<br />

CONFIG_NLS=y<br />

CONFIG_NLS_DEFAULT="y"<br />

CONFIG_NLS_ISO8859_1=y<br />

CONFIG_NLS_ISO8859_15=y<br />

With these options you will see messages like the following when you boot the <strong>Linux</strong> kernel:<br />

...<br />

Uni<strong>for</strong>m Multi-Plat<strong>for</strong>m E-IDE driver Revision: 6.31<br />

ide: Assuming 50MHz system bus speed <strong>for</strong> PIO modes; override with idebus=xx<br />

PCMCIA slot B: phys mem e0000000...ec000000 (size 0c000000)<br />

Card ID: CF 128MB CH<br />

Fixed Disk Card<br />

IDE interface<br />

[silicon] [unique] [single] [sleep] [st<strong>and</strong>by] [idle] [low power]<br />

hda: probing with STATUS(0x50) instead of ALTSTATUS(0x41)<br />

hda: CF 128MB, ATA DISK drive<br />

ide0 at 0xc7000320-0xc7000327,0xc3000106 on irq 13<br />

hda: 250368 sectors (128 MB) w/16KiB Cache, CHS=978/8/32<br />

Partition check:<br />

hda: hda1 hda2 hda3 hda4<br />

...<br />

You can now access your PC Card "disk" like any normal IDE drive. If you start with a new drive, you have<br />

to start by creating a new partition table. For PowerPC systems, there are two commonly used options:<br />

14.3.22.1. Using a MacOS Partition Table<br />

A MacOS partition table is the "native" partition table <strong>for</strong>mat on PowerPC systems; most desktop PowerPC<br />

systems use it, so you may prefer it when you have PowerPC development systems around.<br />

To <strong>for</strong>mat your "disk" drive with a MacOS partition table you can use the pdisk comm<strong>and</strong>:<br />

We start printing the help menu, re-initializing the partition table <strong>and</strong> then printing the new, empty partition<br />

table so that we know the block numbers when we want to create new partitions:<br />

# pdisk /dev/hda<br />

Edit /dev/hda -<br />

Comm<strong>and</strong> ( <strong>for</strong> help): <br />

Notes:<br />

Base <strong>and</strong> length fields are blocks, which vary in size between media.<br />

<strong>The</strong> base field can be p; i.e. use the base of the nth partition.<br />

<strong>The</strong> length field can be a length followed by k, m, g or t to indicate<br />

kilo, mega, giga, or tera bytes; also the length can be p; i.e. use<br />

the length of the nth partition.<br />

<strong>The</strong> name of a partition is descriptive text.<br />

Comm<strong>and</strong>s are:<br />

14.3.22.1. Using a MacOS Partition Table 194


h help<br />

p print the partition table<br />

P (print ordered by base address)<br />

i initialize partition map<br />

s change size of partition map<br />

c create new partition (st<strong>and</strong>ard Mk<strong>Linux</strong> type)<br />

C (create with type also specified)<br />

n (re)name a partition<br />

d delete a partition<br />

r reorder partition entry in map<br />

w write the partition table<br />

q quit editing (don't save changes)<br />

Comm<strong>and</strong> ( <strong>for</strong> help): i<br />

map already exists<br />

do you want to reinit [n/y]: y<br />

Comm<strong>and</strong> ( <strong>for</strong> help): p<br />

Partition map (with 512 byte blocks) on '/dev/hda'<br />

#: type name length base ( size )<br />

1: Apple_partition_map Apple 63 @ 1<br />

2: Apple_Free Extra 1587536 @ 64 (775.2M)<br />

Device block size=512, Number of Blocks=1587600 (775.2M)<br />

DeviceType=0x0, DeviceId=0x0<br />

At first we create two small partitions that will be used to store a <strong>Linux</strong> boot image; a compressed <strong>Linux</strong><br />

kernel is typically around 400 ... 500 kB, so chosing a partition size of 2 MB is more than generous. 2 MB<br />

coresponds to 4096 disk blocks of 512 bytes each, so we enter:<br />

Comm<strong>and</strong> ( <strong>for</strong> help): C<br />

First block: 64<br />

Length in blocks: 4096<br />

Name of partition: boot0<br />

Type of partition: PPC<strong>Boot</strong><br />

Comm<strong>and</strong> ( <strong>for</strong> help): p<br />

Partition map (with 512 byte blocks) on '/dev/hda'<br />

#: type name length base ( size )<br />

1: Apple_partition_map Apple 63 @ 1<br />

2: PPC<strong>Boot</strong> boot0 4096 @ 64 ( 2.0M)<br />

3: Apple_Free Extra 1583440 @ 4160 (773.2M)<br />

Device block size=512, Number of Blocks=1587600 (775.2M)<br />

DeviceType=0x0, DeviceId=0x0<br />

To be able to select between two kernel images (<strong>for</strong> instance when we want to do a field upgrade of the <strong>Linux</strong><br />

kernel) we create a second boot partition of exactly the same size:<br />

Comm<strong>and</strong> ( <strong>for</strong> help): C<br />

First block: 4160<br />

Length in blocks: 4096<br />

Name of partition: boot1<br />

Type of partition: PPC<strong>Boot</strong><br />

Comm<strong>and</strong> ( <strong>for</strong> help): p<br />

Partition map (with 512 byte blocks) on '/dev/hda'<br />

#: type name length base ( size )<br />

1: Apple_partition_map Apple 63 @ 1<br />

2: PPC<strong>Boot</strong> boot0 4096 @ 64 ( 2.0M)<br />

3: PPC<strong>Boot</strong> boot1 4096 @ 4160 ( 2.0M)<br />

4: Apple_Free Extra 1579344 @ 8256 (771.2M)<br />

Device block size=512, Number of Blocks=1587600 (775.2M)<br />

DeviceType=0x0, DeviceId=0x0<br />

Now we create a swap partition - 64 MB should be more than sufficient <strong>for</strong> our Embedded System; 64 MB<br />

means 64*1024*2 = 131072 disk blocks of 512 bytes:<br />

Comm<strong>and</strong> ( <strong>for</strong> help): C<br />

First block: 8256<br />

14.3.22.1. Using a MacOS Partition Table 195


Length in blocks: 131072<br />

Name of partition: swap<br />

Type of partition: swap<br />

Comm<strong>and</strong> ( <strong>for</strong> help): p<br />

Partition map (with 512 byte blocks) on '/dev/hda'<br />

#: type name length base ( size )<br />

1: Apple_partition_map Apple 63 @ 1<br />

2: PPC<strong>Boot</strong> boot0 4096 @ 64 ( 2.0M)<br />

3: PPC<strong>Boot</strong> boot1 4096 @ 4160 ( 2.0M)<br />

4: swap swap 131072 @ 8256 ( 64.0M)<br />

5: Apple_Free Extra 1448272 @ 139328 (707.2M)<br />

Device block size=512, Number of Blocks=1587600 (775.2M)<br />

DeviceType=0x0, DeviceId=0x0<br />

Finally, we dedicate all the remaining space to the root partition:<br />

Comm<strong>and</strong> ( <strong>for</strong> help): C<br />

First block: 139328<br />

Length in blocks: 1448272<br />

Name of partition: root<br />

Type of partition: <strong>Linux</strong><br />

Comm<strong>and</strong> ( <strong>for</strong> help): p<br />

Partition map (with 512 byte blocks) on '/dev/hda'<br />

#: type name length base ( size )<br />

1: Apple_partition_map Apple 63 @ 1<br />

2: PPC<strong>Boot</strong> boot0 4096 @ 64 ( 2.0M)<br />

3: PPC<strong>Boot</strong> boot1 4096 @ 4160 ( 2.0M)<br />

4: swap swap 131072 @ 8256 ( 64.0M)<br />

5: <strong>Linux</strong> root 1448272 @ 139328 (707.2M)<br />

Device block size=512, Number of Blocks=1587600 (775.2M)<br />

DeviceType=0x0, DeviceId=0x0<br />

To make our changes permanent we must write the new partition table to the disk, be<strong>for</strong>e we quit the pdisk<br />

program:<br />

Comm<strong>and</strong> ( <strong>for</strong> help): w<br />

Writing the map destroys what was there be<strong>for</strong>e. Is that okay [n/y]: y<br />

hda: [mac] hda1 hda2 hda3 hda4 hda5<br />

hda: [mac] hda1 hda2 hda3 hda4 hda5<br />

Comm<strong>and</strong> ( <strong>for</strong> help): q<br />

Now we can initialize the swap space <strong>and</strong> the filesystem:<br />

# mkswap /dev/hda4<br />

Setting up swapspace version 1, size = 67104768 bytes<br />

# mke2fs /dev/hda5<br />

mke2fs 1.19, 13-Jul-2000 <strong>for</strong> EXT2 FS 0.5b, 95/08/09<br />

Filesystem label=<br />

OS type: <strong>Linux</strong><br />

Block size=4096 (log=2)<br />

Fragment size=4096 (log=2)<br />

90624 inodes, 181034 blocks<br />

9051 blocks (5.00%) reserved <strong>for</strong> the super user<br />

First data block=0<br />

6 block groups<br />

32768 blocks per group, 32768 fragments per group<br />

15104 inodes per group<br />

Superblock backups stored on blocks:<br />

32768, 98304, 163840<br />

Writing inode tables: done<br />

Writing superblocks <strong>and</strong> filesystem accounting in<strong>for</strong>mation: done<br />

14.3.22.1. Using a MacOS Partition Table 196


14.3.22.2. Using a MS-DOS Partition Table<br />

<strong>The</strong> MS-DOS partition table is especially common on PC type computers, which these days means nearly<br />

everywhere. You will prefer this <strong>for</strong>mat if you want to exchange your "disk" media with any PC type host<br />

system.<br />

<strong>The</strong> fdisk comm<strong>and</strong> is used to create MS-DOS type partition tables; to create the same partitioning scheme as<br />

above you would use the following comm<strong>and</strong>s:<br />

# fdisk /dev/hda<br />

Device contains neither a valid DOS partition table, nor Sun, SGI or OSF disklabel<br />

Building a new DOS disklabel. Changes will remain in memory only,<br />

until you decide to write them. After that, of course, the previous<br />

content won't be recoverable.<br />

<strong>The</strong> number of cylinders <strong>for</strong> this disk is set to 1575.<br />

<strong>The</strong>re is nothing wrong with that, but this is larger than 1024,<br />

<strong>and</strong> could in certain setups cause problems with:<br />

1) software that runs at boot time (e.g., old versions of LILO)<br />

2) booting <strong>and</strong> partitioning software from other OSs<br />

(e.g., DOS FDISK, OS/2 FDISK)<br />

Comm<strong>and</strong> (m <strong>for</strong> help): m<br />

Comm<strong>and</strong> action<br />

a toggle a bootable flag<br />

b edit bsd disklabel<br />

c toggle the dos compatibility flag<br />

d delete a partition<br />

l list known partition types<br />

m print this menu<br />

n add a new partition<br />

o create a new empty DOS partition table<br />

p print the partition table<br />

q quit without saving changes<br />

s create a new empty Sun disklabel<br />

t change a partition's system id<br />

u change display/entry units<br />

v verify the partition table<br />

w write table to disk <strong>and</strong> exit<br />

x extra functionality (experts only)<br />

Comm<strong>and</strong> (m <strong>for</strong> help): n<br />

Comm<strong>and</strong> action<br />

e extended<br />

p primary partition (1-4)<br />

p<br />

Partition number (1-4): 1<br />

First cylinder (1-1575, default 1):<br />

Using default value 1<br />

Last cylinder or +size or +sizeM or +sizeK (1-1575, default 1575): +2M<br />

Comm<strong>and</strong> (m <strong>for</strong> help): p<br />

Disk /dev/hda: 16 heads, 63 sectors, 1575 cylinders<br />

Units = cylinders of 1008 * 512 bytes<br />

Device <strong>Boot</strong> Start End Blocks Id System<br />

/dev/hda1 1 5 2488+ 83 <strong>Linux</strong><br />

Comm<strong>and</strong> (m <strong>for</strong> help): n<br />

Comm<strong>and</strong> action<br />

e extended<br />

p primary partition (1-4)<br />

p<br />

Partition number (1-4): 2<br />

First cylinder (6-1575, default 6):<br />

Using default value 6<br />

Last cylinder or +size or +sizeM or +sizeK (6-1575, default 1575): +2M<br />

Comm<strong>and</strong> (m <strong>for</strong> help): p<br />

14.3.22.2. Using a MS-DOS Partition Table 197


Disk /dev/hda: 16 heads, 63 sectors, 1575 cylinders<br />

Units = cylinders of 1008 * 512 bytes<br />

Device <strong>Boot</strong> Start End Blocks Id System<br />

/dev/hda1 1 5 2488+ 83 <strong>Linux</strong><br />

/dev/hda2 6 10 2520 83 <strong>Linux</strong><br />

Comm<strong>and</strong> (m <strong>for</strong> help): n<br />

Comm<strong>and</strong> action<br />

e extended<br />

p primary partition (1-4)<br />

p<br />

Partition number (1-4): 3<br />

First cylinder (11-1575, default 11):<br />

Using default value 11<br />

Last cylinder or +size or +sizeM or +sizeK (11-1575, default 1575): +64M<br />

Comm<strong>and</strong> (m <strong>for</strong> help): t<br />

Partition number (1-4): 3<br />

Hex code (type L to list codes): 82<br />

Changed system type of partition 3 to 82 (<strong>Linux</strong> swap)<br />

Comm<strong>and</strong> (m <strong>for</strong> help): p<br />

Disk /dev/hda: 16 heads, 63 sectors, 1575 cylinders<br />

Units = cylinders of 1008 * 512 bytes<br />

Device <strong>Boot</strong> Start End Blocks Id System<br />

/dev/hda1 1 5 2488+ 83 <strong>Linux</strong><br />

/dev/hda2 6 10 2520 83 <strong>Linux</strong><br />

/dev/hda3 11 141 66024 82 <strong>Linux</strong> swap<br />

Note that we had to use the t comm<strong>and</strong> to mark this partition as swap space.<br />

Comm<strong>and</strong> (m <strong>for</strong> help): n<br />

Comm<strong>and</strong> action<br />

e extended<br />

p primary partition (1-4)<br />

p<br />

Partition number (1-4): 4<br />

First cylinder (142-1575, default 142):<br />

Using default value 142<br />

Last cylinder or +size or +sizeM or +sizeK (142-1575, default 1575):<br />

Using default value 1575<br />

Comm<strong>and</strong> (m <strong>for</strong> help): p<br />

Disk /dev/hda: 16 heads, 63 sectors, 1575 cylinders<br />

Units = cylinders of 1008 * 512 bytes<br />

Device <strong>Boot</strong> Start End Blocks Id System<br />

/dev/hda1 1 5 2488+ 83 <strong>Linux</strong><br />

/dev/hda2 6 10 2520 83 <strong>Linux</strong><br />

/dev/hda3 11 141 66024 82 <strong>Linux</strong> swap<br />

/dev/hda4 142 1575 722736 83 <strong>Linux</strong><br />

Comm<strong>and</strong> (m <strong>for</strong> help): w<br />

<strong>The</strong> partition table has been altered!<br />

Calling ioctl() to re-read partition table.<br />

hda: hda1 hda2 hda3 hda4<br />

hda: hda1 hda2 hda3 hda4<br />

WARNING: If you have created or modified any DOS 6.x<br />

partitions, please see the fdisk manual page <strong>for</strong> additional<br />

in<strong>for</strong>mation.<br />

Syncing disks.<br />

Now we are ready to initialize the partitions:<br />

# mkswap /dev/hda3<br />

Setting up swapspace version 1, size = 67604480 bytes<br />

# mke2fs /dev/hda4<br />

mke2fs 1.19, 13-Jul-2000 <strong>for</strong> EXT2 FS 0.5b, 95/08/09<br />

Filesystem label=<br />

OS type: <strong>Linux</strong><br />

14.3.22.2. Using a MS-DOS Partition Table 198


Block size=4096 (log=2)<br />

Fragment size=4096 (log=2)<br />

90432 inodes, 180684 blocks<br />

9034 blocks (5.00%) reserved <strong>for</strong> the super user<br />

First data block=0<br />

6 block groups<br />

32768 blocks per group, 32768 fragments per group<br />

15072 inodes per group<br />

Superblock backups stored on blocks:<br />

32768, 98304, 163840<br />

Writing inode tables: done<br />

Writing superblocks <strong>and</strong> filesystem accounting in<strong>for</strong>mation: done<br />

14.3.23. <strong>Boot</strong>-Time Configuration of MTD Partitions<br />

Instead of defining a static partition map as described in section Memory Technology Devices you can define<br />

the partitions <strong>for</strong> your flash memory at boot time using comm<strong>and</strong> line arguments. To do that you have to<br />

enable the CONFIG_MTD_CMDLINE_PARTS kernel configuration option. With this option enabled, the<br />

kernel will recognize a comm<strong>and</strong> line argument mtdparts <strong>and</strong> decode it as follows:<br />

mtdparts=[;


server 127.127.1.0 # local clock<br />

fudge 127.127.1.0 stratum 10<br />

by<br />

server 127.127.43.0<br />

# st<strong>and</strong>ard <strong>Linux</strong> RTC<br />

<strong>The</strong>n make sure to start the NTP daemon on your target by adding it to the corresponding init scripts <strong>and</strong><br />

restart it if it is already running.<br />

<strong>The</strong> "address" of the RTC (127.127.43.0 in the example above) is not an IP address, but actually used<br />

as an index into an internal array of supported reference clocks in the NTP daemon code. You may need to<br />

check with your ntpd implementation if the example above does not work as expected.<br />

14.3.25. Configure <strong>Linux</strong> <strong>for</strong> XIP (Execution In<br />

Place)<br />

This document describes how to setup <strong>and</strong> use XIP in the kernel <strong>and</strong> the cramfs filesystem. (A patch to add<br />

XIP support to your kernel can be found at the bottom of this page.)<br />

14.3.25.1. XIP Kernel<br />

To select XIP you must enable the CONFIG_XIP option:<br />

$ cd <br />

$ make menuconfig<br />

...<br />

MPC8xx CPM Options ---><br />

[*] Make a XIP (eXecute in Place) kernel<br />

(40100000) Physical XIP kernel address<br />

(c1100000) Virtual XIP kernel address<br />

(64) Image header size e.g. 64 bytes <strong>for</strong> PPC<strong>Boot</strong><br />

<strong>The</strong> physical <strong>and</strong> virtual address of the flash memory used <strong>for</strong> XIP must be defined statically with the macros<br />

CONFIG_XIP_PHYS_ADDR <strong>and</strong> CONFIG_XIP_VIRT_ADDR. <strong>The</strong> virtual address usually points to the end<br />

of the kernel virtual address of the system memory. <strong>The</strong> physical <strong>and</strong> virtual address must be aligned relative<br />

to an 8 MB boundary:<br />

CONFIG_XIP_PHYS_ADDR = FLASH-base-address + offset-in-FLASH<br />

CONFIG_XIP_VIRT_ADDR = 0xc0000000 + DRAM-size + offset-in-FLASH<br />

<strong>The</strong> default configuration parameters shown above are <strong>for</strong> a system with 16MB of DRAM <strong>and</strong> the XIP kernel<br />

image located at the physical address 0x40100000 in flash memory.<br />

Note that the FLASH <strong>and</strong> MTD driver must be disabled.<br />

You can then build the "uImage", copy it to CONFIG_XIP_PHYS_ADDR in flash memory <strong>and</strong> boot it from<br />

CONFIG_XIP_PHYS_ADDR as usual.<br />

14.3.25.2. Cramfs Filesystem<br />

<strong>The</strong> cramfs filesystem enhancements:<br />

14.3.25. Configure <strong>Linux</strong> <strong>for</strong> XIP (Execution In Place) 200


• <strong>The</strong>y allow cramfs optional direct access to a cramfs image in memory (ram, rom, flash). It eliminates<br />

the unnecessary step of passing data through an intermediate buffer, as compared to accessing the<br />

same image through a memory block device like mtdblock.<br />

• <strong>The</strong>y allow optional cramfs linear root support. This eliminates the requirement of having to provide a<br />

block device to use a linear cramfs image as the root filesystem.<br />

• <strong>The</strong>y provide optional XIP. It extends mkcramfs to store files marked "+t" uncompressed <strong>and</strong><br />

page-aligned. <strong>Linux</strong> can then mmap those files <strong>and</strong> execute them in-place without copying them<br />

entirely to ram first.<br />

Note: the current implementation can only be used together with a XIP kernel, which provides the appropriate<br />

XIP memory (FLASH) mapping.<br />

To configure a root file system on linear cramfs with XIP select:<br />

$ cd <br />

$ make menuconfig<br />

...<br />

File systems --->"<br />

...<br />

Compressed ROM file system support<br />

[*] Use linear addressing <strong>for</strong> cramfs<br />

(40400000) Physical address of linear cramfs<br />

[*] Support XIP on linear cramfs<br />

[*] Root file system on linear cramfs<br />

This defines a cramfs filesystem located at the physical address 0x40400000 in FLASH memory.<br />

After building the kernel image "pImage" as usual, you will want to build a filesystem using the mkcramfs<br />

executable (it's located in /scripts/cramfs). If you do not already have a reasonable sized disk directory tree<br />

you will need to make one. <strong>The</strong> ramdisk directory of SELF (the Simple Embedded <strong>Linux</strong> Framework from<br />

<strong>DENX</strong> at ftp.denx.de) is a good starting point. Be<strong>for</strong>e you build your cramfs image you must mark the binary<br />

files to be executed in place later on with the "t" permission:<br />

$ mkcramfs -r ramdisk cramfs.img<br />

<strong>and</strong> copy it to the defined place in FLASH memory.<br />

You can then boot the XIP kernel with the cramfs root filesystem using the boot argument:<br />

$ setenv bootargs root=/dev/cramfs ...<br />

Be aware that cramfs is a read-only filesystem.<br />

14.3.25.3. Hints <strong>and</strong> Notes<br />

• XIP conserves RAM at the expense of flash. This might be useful if you have a big flash memory <strong>and</strong><br />

little RAM.<br />

• Flash memory used <strong>for</strong> XIP must be readable all the time e.g. this excludes installation <strong>and</strong> usage the<br />

character device or MTD flash drivers, because they do device probing, sector erase etc.<br />

• <strong>The</strong> XIP extension is currently only available <strong>for</strong> PowerPC 8xx but can easily be extended to other<br />

architectures.<br />

• Currently only up to 8 MB of ROM/Flash are supported.<br />

• <strong>The</strong> original work was done <strong>for</strong> the am<strong>and</strong>a system.<br />

• Special thanks goes to David Petersen <strong>for</strong> collecting the availible XIP extension sources <strong>and</strong><br />

highlighting how to put all the pieces together.<br />

14.3.25.2. Cramfs Filesystem 201


14.3.25.4. Space requirements <strong>and</strong> RAM saving, an example<br />

For ppc 8xx, all figures are in bytes:<br />

• Normal kernel + linear cramfs (patched):<br />

pImage: 538062<br />

cramfs: 1081344<br />

total: used: free: shared: buffers: cached:<br />

Mem: 14921728 3866624 11055104 2781184 0 2240512<br />

• XIP kernel + linear cramfs:<br />

pImage: 1395952<br />

cramfs: 1081344<br />

total: used: free: shared: buffers: cached:<br />

Mem: 16175104 3940352 12234752 2822144 0 2240512<br />

• XIP kernel + XIP cramfs (chmod +t: busybox, initd, libc):<br />

pImage: 1395952<br />

cramfs: 1871872<br />

total: used: free: shared: buffers: cached:<br />

Mem: 16175104 2367488 13807616 610304 0 671744<br />

<strong>The</strong> actual RAM saving is here approximately 1.1MB + 1.5M = 2.6 MB.<br />

Have fun with XIP.<br />

Wolfgang Gr<strong>and</strong>egger (wg@denx.de)<br />

• linux-2.4.4-2002-03-21-xip.patch.gz: <strong>Linux</strong> patches <strong>for</strong> XIP on MPC8xx<br />

14.3.26. Use SCC UART with Hardware H<strong>and</strong>shake<br />

Question:<br />

I am using a SCC port of a MPC8xx / MPC82xx as UART; <strong>for</strong> the <strong>Linux</strong> UART driver I have<br />

configured support <strong>for</strong> hardware h<strong>and</strong>shake. <strong>The</strong>n I used a null-modem cable to connect the port to<br />

the serial port of my PC. But this does not work. What am I doing wrong<br />

Answer:<br />

<strong>The</strong>re is absolutely no way to connect a MPC8xx / MPC82xx SCC port to any DTE <strong>and</strong> use RS-232<br />

st<strong>and</strong>ard hardware flow control.<br />

Explanation:<br />

<strong>The</strong> serial interface of the SCC ports in MPC8xx / MPC82xx processors is designed as a DTE<br />

circuitry <strong>and</strong> the RS-232 st<strong>and</strong>ard hardware flow control can not be used in the DTE to DTE<br />

connection with the null-modem cable (with crossed RTS/CTS signals).<br />

<strong>The</strong> RS-232 st<strong>and</strong>ard specifies a DTE to DCE connection <strong>and</strong> its hardware h<strong>and</strong>shaking is designed<br />

<strong>for</strong> this specific task. <strong>The</strong> hardware flow control signals in the PC (<strong>and</strong> similar equipment) are<br />

implemented as software readable/writable bits in a control register <strong>and</strong> there<strong>for</strong>e may be arbitrary<br />

14.3.26. Use SCC UART with Hardware H<strong>and</strong>shake 202


treated. Unlike that, in the 8xx/82xx the h<strong>and</strong>shake protocol is h<strong>and</strong>led by the CPM microcode. <strong>The</strong><br />

meaning of the signals is fixed <strong>for</strong> the RS-232 st<strong>and</strong>ard with no way <strong>for</strong> user to change it.<br />

In widely spread DTE-to-DTE connections over the so called 'null-modem' cable with the hardware<br />

flow control lines the meaning of the h<strong>and</strong>shake signals is changed with respect to the RS-232<br />

st<strong>and</strong>ard. <strong>The</strong>re<strong>for</strong>e this approach may not be used with the 8xx/82xx.<br />

Question:<br />

I succeeded in activating hardware h<strong>and</strong>shake on the transmit side of the SCC using the CTS signal.<br />

However I have problems in the receive direction.<br />

Answer:<br />

This is caused by the semantics of the RTS signal as implemented on the SCC controllers: the CPM<br />

will assert this signal when it wants to send out data. This means you cannot use RTS to enable the<br />

transmitter on the other side, because it will be enabled only when the SCC is sending data itself.<br />

Conclusions:<br />

If you want to use 8xx/82xx based equipment in combination with RS-232 hardware control protocol,<br />

you must have a DCE device (modem, plotter, printer, etc) on the other end.<br />

Hardware flow control on a SCC works only in transmit direction; when receiving data the driver has<br />

to be fast enough to prevent data overrun conditions (normally this is no problem though).<br />

14.3.27. How can I access U-<strong>Boot</strong> environment<br />

variables in <strong>Linux</strong><br />

Question:<br />

I would like to access U-<strong>Boot</strong>'s environment variables from my <strong>Linux</strong> application. Is this possible<br />

Answer:<br />

Yes, you can. <strong>The</strong> environment variables must be stored in flash memory, <strong>and</strong> your <strong>Linux</strong> kernel must<br />

support flash access through the MTD layer. In the U-<strong>Boot</strong> source tree you can find the environment<br />

tools in the directory tools/env, which can be built with comm<strong>and</strong>:<br />

make env<br />

For building against older versions of the MTD headers (meaning be<strong>for</strong>e v2.6.8-rc1) it is required to pass the<br />

argument "MTD_VERSION=old" to make:<br />

make MTD_VERSION=old env<br />

<strong>The</strong> resulting binary is called fw_printenv, but actually includes support <strong>for</strong> setting environment variables<br />

too. To achieve this, the binary behaves according to the name it is invoked as, so you will have to create a<br />

link called fw_setenv to fw_printenv.<br />

<strong>The</strong>se tools work exactly like the U-<strong>Boot</strong> comm<strong>and</strong>s printenv resp. setenv You can either build these<br />

tools with a fixed configuration selected at compile time, or you can configure the tools using the<br />

/etc/fw_env.config configuration file in your target root filesystem. Here is an example configuration<br />

file:<br />

# Configuration file <strong>for</strong> fw_(printenv/saveenv) utility.<br />

# Up to two entries are valid, in this case the redund<strong>and</strong><br />

# environment sector is assumed present.<br />

14.3.27. How can I access U-<strong>Boot</strong> environment variables in <strong>Linux</strong> 203


#########################################################################<br />

# For TQM8xxL modules:<br />

#########################################################################<br />

# MTD device name Device offset Env. size Flash sector size<br />

/dev/mtd0 0x8000 0x4000 0x4000<br />

/dev/mtd0 0xC000 0x4000 0x4000<br />

#########################################################################<br />

# For NSCU:<br />

#########################################################################<br />

# MTD device name Device offset Env. size Flash sector size<br />

#/dev/mtd1 0x0000 0x8000 0x20000<br />

#/dev/mtd2 0x0000 0x8000 0x20000<br />

#########################################################################<br />

# For LWMON<br />

#########################################################################<br />

# MTD device name Device offset Env. size Flash sector size<br />

#/dev/mtd1 0x0000 0x2000 0x40000<br />

14.3.28. <strong>The</strong> appWeb server hangs OR /dev/r<strong>and</strong>om<br />

hangs<br />

Question:<br />

I try to run the appWeb server, but it hangs, because read accesses to /dev/r<strong>and</strong>om hang <strong>for</strong>ever.<br />

What's wrong<br />

Answer:<br />

Your configuration of the <strong>Linux</strong> kernel does not contain drivers that feed enough entropy <strong>for</strong><br />

/dev/r<strong>and</strong>om. Often mouse or keyboard drivers are used <strong>for</strong> this purpose, so on an embedded<br />

system without such devices /dev/r<strong>and</strong>om may not provide enough r<strong>and</strong>om numbers <strong>for</strong> your<br />

application.<br />

Workaround:<br />

As a quick workaround you can use /dev/ur<strong>and</strong>om instead; i. e. try the following comm<strong>and</strong>s on<br />

your system:<br />

# cd /dev<br />

# rm -f r<strong>and</strong>om<br />

# ln -s ur<strong>and</strong>om r<strong>and</strong>om<br />

Solution:<br />

<strong>The</strong> correct solution <strong>for</strong> the problem is of course to feed sufficient entropy into /dev/r<strong>and</strong>om. To<br />

do so you can modify one or more appropriate device drivers on your system; <strong>for</strong> example if you<br />

know that there is sufficient traffic on network or on a serial port than adding SA_SAMPLE_RANDOM<br />

to the 3rd argument when calling the request_irq() function in your ethernet <strong>and</strong>/or serial<br />

driver(s) will cause the inter-interrupt times to be used to build up entropy <strong>for</strong> /dev/r<strong>and</strong>om.<br />

14.3.29. Swapping over NFS<br />

In case that the available memory is not sufficient, i.e. <strong>for</strong> compiling the X.org server, <strong>and</strong> no hard-drive can<br />

be attached to the system it is possible to swap over NFS, although it is not quite straight<strong>for</strong>ward.<br />

14.3.29. Swapping over NFS 204


Usually one would create a blank file, mkswap it <strong>and</strong> simply do a swapon swapfile. Doing this on a filesystem<br />

mounted over NFS, i.e. the ELDK root filesystem, fails however.<br />

With one level of indirection we can trick the kernel into doing it anyway. First we create a filesystem image<br />

(ext2 will do) on the NFS filesystem <strong>and</strong> mount it with the aid of the loopback device. <strong>The</strong>n we create a blank<br />

swapfile inside of this filesystem <strong>and</strong> turn on swapping:<br />

bash-2.05b# mount<br />

/dev/nfs on / type nfs (rw)<br />

none on /proc type proc (rw)<br />

bash-2.05b# cd /tmp<br />

bash-2.05b# dd if=/dev/zero of=ext2.img bs=1M count=66<br />

66+0 records in<br />

66+0 records out<br />

bash-2.05b# mkfs.ext2 ext2.img<br />

mke2fs 1.27 (8-Mar-2002)<br />

ext2.img is not a block special device.<br />

Proceed anyway (y,n) y<br />

Filesystem label=<br />

OS type: <strong>Linux</strong><br />

Block size=1024 (log=0)<br />

Fragment size=1024 (log=0)<br />

16920 inodes, 67584 blocks<br />

3379 blocks (5.00%) reserved <strong>for</strong> the super user<br />

First data block=1<br />

9 block groups<br />

8192 blocks per group, 8192 fragments per group<br />

1880 inodes per group<br />

Superblock backups stored on blocks:<br />

8193, 24577, 40961, 57345<br />

Writing inode tables: done<br />

Writing superblocks <strong>and</strong> filesystem accounting in<strong>for</strong>mation: done<br />

This filesystem will be automatically checked every 26 mounts or<br />

180 days, whichever comes first. Use tune2fs -c or -i to override.<br />

bash-2.05b# <strong>for</strong> i in `seq 0 9` ; do mknod /dev/loop$i b 7 $i ; done<br />

bash-2.05b# mkdir /mnt2<br />

bash-2.05b# mount -o loop ext2.img /mnt2<br />

bash-2.05b# cd /mnt2<br />

bash-2.05b# dd if=/dev/zero of=swapfile bs=1M count=62<br />

62+0 records in<br />

62+0 records out<br />

bash-2.05b# mkswap swapfile<br />

Setting up swapspace version 1, size = 65007 kB<br />

bash-2.05b# free<br />

total used free shared buffers cached<br />

Mem: 14556 14260 296 0 772 9116<br />

-/+ buffers/cache: 4372 10184<br />

Swap: 0 0 0<br />

bash-2.05b# swapon swapfile<br />

bash-2.05b# free<br />

total used free shared buffers cached<br />

Mem: 14556 14172 384 0 784 9020<br />

-/+ buffers/cache: 4368 10188<br />

Swap: 63480 0 63480<br />

bash-2.05b#<br />

Because the ELDK right now has no device nodes <strong>for</strong> the loopback driver we create them along the way. It<br />

goes without saying that the loop driver has to be included in the kernel configuration. You can check this by<br />

looking <strong>for</strong> a driver <strong>for</strong> major number 7 (block devices) in /proc/devices.<br />

14.3.29. Swapping over NFS 205


14.4. Self<br />

14.4.1. How to Add Files to a SELF Ramdisk<br />

It is not always necessary to rebuild a SELF based ramdisk image if you want to modify or to extend it.<br />

Especially during development it is often eaiser to unpack it, modify it, <strong>and</strong> re-pack it again. To do so, you<br />

have to underst<strong>and</strong> the internal structure of the uRamdisk (resp. pRamdisk) images files as used with the<br />

U-<strong>Boot</strong> (old: PPC<strong>Boot</strong>) boot loader:<br />

<strong>The</strong> uRamdisk image contains two parts:<br />

• a 64 byte U-<strong>Boot</strong> header<br />

• a (usually gzip compressed) ramdisk image<br />

To modify the contents you have to extract, uncompress <strong>and</strong> mount the ramdisk image. This can be done as<br />

follows:<br />

1. Extract compressed ramdisk image (ramdisk.gz)<br />

bash$ dd if=uRamdisk bs=64 skip=1 of=ramdisk.gz<br />

21876+1 records in<br />

21876+1 records out<br />

2. Uncompress ramdisk image (if it was a compressed one)<br />

bash$ gunzip -v ramdisk.gz<br />

ramdisk.gz: 66.6% -- replaced with ramdisk<br />

3. Mount ramdisk image<br />

bash# mount -o loop ramdisk /mnt/tmp<br />

Now you can add, remove, or modify files in the /mnt/tmp directory. If you are done, you can re-pack the<br />

ramdisk into a U-<strong>Boot</strong> image:<br />

1. Unmount ramdisk image:<br />

bash# umount /mnt/tmp<br />

2. Compress ramdisk image<br />

bash$ gzip -v9 ramdisk<br />

ramdisk:<br />

66.6% -- replaced with ramdisk.gz<br />

3. Create new U-<strong>Boot</strong> image (new-uRamdisk)<br />

bash$ mkimage -T ramdisk -C gzip -n 'Simple Embedded <strong>Linux</strong> Framework' \<br />

> -d ramdisk.gz new-uRamdisk<br />

Image Name: Simple Embedded <strong>Linux</strong> Framework<br />

Created: Sun May 4 13:23:48 2003<br />

Image Type: PowerPC <strong>Linux</strong> RAMDisk Image (gzip compressed)<br />

Data Size: 1400121 Bytes = 1367.31 kB = 1.34 MB<br />

Load Address: 0x00000000<br />

Entry Point: 0x00000000<br />

Instead of re-packing into a U-boot ramdisk image you can of course also just extract the contents of the<br />

SELF image <strong>and</strong> re-use it as base of a (known to be working) root filesystem.<br />

14.4.1. How to Add Files to a SELF Ramdisk 206


• For example, you can create a JFFS2 filesystem using the mkfs.jffs2 comm<strong>and</strong> that comes with<br />

the MTD Tools:<br />

bash# mkfs.jffs2 -r /mnt/tmp -e 0x10000 -o image.jffs2<br />

• Or you can create a CramFS filesystem with mkcramfs:<br />

bash# mkcramfs -r /mnt/tmp image.cramfs<br />

Swapping filesystem endian-ness<br />

...<br />

Everything: 1656 kilobytes<br />

Super block: 76 bytes<br />

CRC: 7f34cae4<br />

14.4.2. How to Increase the Size of the Ramdisk<br />

1. Extract compressed ramdisk image (ramdisk.gz) from U-<strong>Boot</strong> image:<br />

bash$ dd if=uRamdisk bs=64 skip=1 of=ramdisk.gz<br />

21876+1 records in<br />

21876+1 records out<br />

2. Uncompress ramdisk image<br />

bash$ gunzip -v ramdisk.gz<br />

ramdisk.gz: 66.6% -- replaced with ramdisk<br />

3. Mount ramdisk image<br />

As root:<br />

bash# mkdir -p /mnt/tmp<br />

bash# mount -o loop ramdisk /mnt/tmp<br />

4. Create new ramdisk image, say 8 MB big:<br />

bash$ dd if=/dev/zero of=new_ramdisk bs=1024k count=8<br />

bash$ /sbin/mke2fs -F -m0 new_ramdisk<br />

bash$ /sbin/tune2fs -c 0 -i 0 new_ramdisk<br />

As root:<br />

bash# mkdir -p /mnt/new<br />

bash# mount -o loop new_ramdisk /mnt/new<br />

5. Copy files from old ramdisk to new ramdisk:<br />

As root:<br />

bash# cd /mnt/tmp<br />

bash# find . -depth -print | cpio -VBpdum /mnt/new<br />

Now you can add, remove, or modify files in the /mnt/new directory. If you are done, you can re-pack<br />

the ramdisk into a U-<strong>Boot</strong> image:<br />

6. Unmount ramdisk images:<br />

As root:<br />

bash# umount /mnt/tmp<br />

bash# umount /mnt/new<br />

7. Compress new ramdisk image<br />

bash$ gzip -v9 new_ramdisk<br />

ramdisk:<br />

66.6% -- replaced with new_ramdisk.gz<br />

14.4.2. How to Increase the Size of the Ramdisk 207


8. Create new U-<strong>Boot</strong> image (new-uRamdisk)<br />

bash$ mkimage -T ramdisk -C gzip -n 'New Simple Embedded <strong>Linux</strong> Framework' \<br />

> -d new_ramdisk.gz new_uRamdisk<br />

Image Name: Simple Embedded <strong>Linux</strong> Framework<br />

Created: Sun May 4 13:23:48 2003<br />

Image Type: PowerPC <strong>Linux</strong> RAMDisk Image (gzip compressed)<br />

Data Size: 1400121 Bytes = 1367.31 kB = 1.34 MB<br />

Load Address: 0x00000000<br />

Entry Point: 0x00000000<br />

Remember that <strong>Linux</strong> by default supports only ramdisks up to a size of 4 MB. For bigger ramdisks, you<br />

have to either modify your LInux kernel configuration (parameter CONFIG_BLK_DEV_RAM_SIZE in the<br />

"Block devices" menue), or pass a "ramdisk_size=" boot argument to the <strong>Linux</strong> kernel.<br />

14.5. RTAI<br />

14.5.1. Conflicts with asm clobber list<br />

Question:<br />

When I try to compile my LInux kernel after applying the RTAI patch, I get a strange "asm-specifier<br />

<strong>for</strong> variable `__sc_3' conflicts with asm clobber list" error message. What does that mean<br />

Answer:<br />

You are using an old version of the <strong>Linux</strong> kernel / RTAI patch in combination with a more recent<br />

version of the cross compiler. Please use a recent kernel tree (<strong>and</strong> the corresponding RTAI patch), or<br />

apply the attached patch to fix this problem.<br />

See: http://www.denx.de/wiki/pub/<strong>DULG</strong>/ConflictsWithAsmClobberList/patch<br />

14.6. BDI2000<br />

14.6.1. Where can I find BDI2000 Configuration<br />

Files<br />

<strong>The</strong> configuration files provided by Abatrron can be found here: ftp://78.31.64.234/bdigdb/config/<br />

A collection of configuration files <strong>for</strong> the BDI2000 BDM/JTAG debugger by Abatron can be found at<br />

ftp://ftp.denx.de/pub/BDI2000/<br />

A list of FAQ (with answers) can be found at http://www.ultsol.com/faqs.htm<br />

A list of supported flash chips (<strong>and</strong> the needed matching entries <strong>for</strong> the config file) can be found at<br />

http://www.abatron.ch/fileadmin/user_upload/products/pdf/flashsupp.pdf<br />

14.6.1. Where can I find BDI2000 Configuration Files 208


14.6.2. How to Debug <strong>Linux</strong> Exceptions<br />

Question:<br />

I am trying to single step into a <strong>Linux</strong> exception h<strong>and</strong>ler. This does not seem to work. Setting a<br />

breakpoint does not work either.<br />

Answer:<br />

<strong>The</strong> problem is bit complex on a MPC8xx target. Debug mode entry is like an exception <strong>and</strong> there<strong>for</strong>e<br />

only safe at locations in the code where an exception does not lead to an unrecoverable state. Another<br />

exception can only be accepted if SRR0 <strong>and</strong> SRR1 are saved. <strong>The</strong> MSR[RI] should indicate if<br />

currently an exception is safe. MSR[RI] is cleared automatically at exception entry.<br />

<strong>The</strong> MPC8xx hardware breakpoints do only trigger if MSR[RI] is set in order to prevent<br />

non-recoverable state.<br />

<strong>The</strong> problem is that the <strong>Linux</strong> exception h<strong>and</strong>ler does not take all this into account. First priority has<br />

speed, there<strong>for</strong>e neither SRR0 nor SRR1 are saved immediately. Only after EXCEPTION_PROLOG<br />

this registers are saved. Also <strong>Linux</strong> does not h<strong>and</strong>le the MSR[RI] bit.<br />

Hint: Use STEPMODE HWBP when debugging <strong>Linux</strong>. This allows the TLB Miss Exception<br />

h<strong>and</strong>ler to update the TLB while you are single stepping.<br />

Conclusion:<br />

You cannot debug <strong>Linux</strong> exception entry <strong>and</strong> exit code. Because of speed, DataStoreTLBMiss does<br />

not even make use of EXCEPTION_PROLOG, <strong>and</strong> SRR0/SRR1 are never saved. <strong>The</strong>re<strong>for</strong>e you<br />

cannot debug DataStoreTLBMiss unless you change it's code (save SRR0/SRR1, set MSR[RI].<br />

14.6.3. How to single step through "RFI"<br />

instruction<br />

Question:<br />

I am trying to debug <strong>Linux</strong> on an IBM 405GP processor. <strong>Linux</strong> boots fine <strong>and</strong> I can step through the<br />

code until the "rfi" instruction in head_4xx.S; then I get the following:<br />

- TARGET: target has entered debug mode<br />

Target state : debug mode<br />

Debug entry cause : JTAG stop request<br />

Current PC : 0x00000700<br />

Current CR : 0x28004088<br />

Current MSR : 0x00000000<br />

Current LR : 0x000007a8<br />

# Step timeout detected<br />

Answer:<br />

Your single step problem most likely comes from the fact that GDB accesses some non-existent<br />

memory (at least some versions do/did in the past). This exception is stored in some way within the<br />

405 <strong>and</strong> when you step "rfi" it triggers. This is because some instructions like "rfi" are always<br />

stepped using a hardware breakpoint <strong>and</strong> not with the JTAG single step feature.<br />

Probably you can step over the "rfi" instruction when using the BDI2000's telnet comm<strong>and</strong><br />

interface instead of GDB.<br />

14.6.3. How to single step through "RFI" instruction 209


Similar problems have also been reported when stepping through "mtmsr" or "mfmsr" during<br />

initial boot code. <strong>The</strong> problem comes also from the fact that GDB accesses non-existent memory<br />

(maybe it tries to read a non-existent stack frame).<br />

To debug the <strong>Linux</strong> kernel, I recommend that you run to a point where the MMU is on be<strong>for</strong>e you<br />

connect with GDB.<br />

To debug boot code where the MMU is off I recommend to use the MMAP feature of the BDI to<br />

prevent illegal memory accesses from GDB.<br />

14.6.4. Setting a breakpoint doesn't work<br />

Question:<br />

I am trying to set a breakpoint using the BDI2000 telnet interface. However, the code does not<br />

stop at the breakpoint.<br />

Answer:<br />

Make sure that the CPU has been stopped be<strong>for</strong>e setting the breakpoint. You can verify this by issuing<br />

the "info" comm<strong>and</strong> be<strong>for</strong>e setting the breakpoint. If the target state is "running" you must use<br />

the "halt" comm<strong>and</strong> to stop the CPU be<strong>for</strong>e you can successfully set the breakpoint.<br />

14.7. Motorola LITE5200 Board<br />

14.7.1. LITE5200 Installation Howto<br />

A nice "Application Note: Installing Embedded <strong>Linux</strong> on the Motorola MPC5200 Lite Evaluation Board"<br />

which covers the installation of U-<strong>Boot</strong> <strong>and</strong> <strong>Linux</strong> can be found at:<br />

http://emsys.denayer.wenk.be/emcam/<strong>Linux</strong>_on_MPC5200_(UK).pdf<br />

14.7.2. USB does not work on Lite5200 board<br />

Question:<br />

USB does not work on my Lite5200 board. Also, the green LED behind the USB connector remains<br />

always off. Why<br />

Answer:<br />

This is a hardware problem. <strong>The</strong> green LED must be on as soon as you power on the Lite5200 board.<br />

As a workaround you can short-circuit resistor R164 (bottom side of the board, close to the USB<br />

connector). Please note that you will probably lose all warranty <strong>and</strong>/or may ruin the board. You have<br />

been warned.<br />

15. Glossary<br />

15. Glossary 210


ABI<br />

- Application Binary Interface<br />

<strong>The</strong> convention <strong>for</strong> register usage <strong>and</strong> C linkage commonly used on desktop PowerPC machines. Similar, but<br />

not identical to the EABI.<br />

Includes binding specific ppc registers to certain fixed purposes, even though there may be no technical<br />

reason to en<strong>for</strong>ce such binding, simplifying the process of linking together two separate sets of object code.<br />

e.g the ABI states that r1 shall be the stack pointer.<br />

BANK<br />

- also "memory bank"<br />

A bank of memory (flash or RAM) consists of all those memory chips on your system that are controlled by<br />

the same chip select signal.<br />

For example, a system might consist of one flash chip with a 8 bit bus interface, which is attached to the CS0<br />

chip select signal, 2 flash chips with a 16 bit bus interface, which are attached to the CS1 chip select signal,<br />

<strong>and</strong> 2 SDRAM chips with a 16 bit bus interface, which are attached to the CS2 chip select signal.<br />

This setup results in a system with 3 banks of memory:<br />

BDM<br />

• 1 bank of flash, 8 bit wide (CS0)<br />

• 1 bank of flash, 32 bit wide (CS1)<br />

• 1 bank of SDRAM, 32 bit wide (CS2)<br />

- Background Debug Mode<br />

An on-chip debug interface supported by a special hardware port on some processors. It allows to take full<br />

control over the CPU with minimal external hardware, in many cases eliminationg the need <strong>for</strong> expensive<br />

tools like In-Circuit-Emulators.<br />

BOOTP<br />

- <strong>Boot</strong> Protocol<br />

A network protocol which can be used to inquire a server about in<strong>for</strong>mation <strong>for</strong> the intended system<br />

configuration (like IP address, host name, netmask, name server, routing, name of a boot image, address of<br />

NFS server, etc.<br />

CFI<br />

- Common Flash Interface<br />

CFI is a st<strong>and</strong>ard <strong>for</strong> flash chips that allows to create device independend drivers <strong>for</strong> such chips.<br />

ABI 211


CPM<br />

- Communications Processor Module<br />

<strong>The</strong> magic communications co-processor in Motorola PowerQUICC devices. It contains SCCs <strong>and</strong> SMCs, <strong>and</strong><br />

per<strong>for</strong>ms SDMA <strong>and</strong> IDMA.<br />

CPU<br />

- Central Processor Unit<br />

Depending on the context, this may refer to the PowerPC core itself, or the physical processor device<br />

(including CPM, SIU, packaging etc) as a single unit.<br />

CramFs<br />

- Compressed ROM File System<br />

Cramfs is designed to be a simple, small, <strong>and</strong> compressed file system <strong>for</strong> ROM based embedded systems.<br />

CramFs is read-only, limited to 256MB file systems (with 16MB files), <strong>and</strong> doesn't support 16/32 bits uid/gid,<br />

hard links <strong>and</strong> timestamps.<br />

CVS<br />

- Concurrent Versions System<br />

CVS is a version control system; it can be used to record the history of files, so that it is <strong>for</strong> instance possible<br />

to retrieve specific versions of a source tree.<br />

DHCP<br />

- Dynamic Host Configuration Protocol<br />

A network protocol which can be used to inquire a server about in<strong>for</strong>mation <strong>for</strong> the intended system<br />

configuration (like IP address, host name, netmask, name server, routing, name of a boot image, address of<br />

NFS server, etc.). Sucessor of BOOTP<br />

DMA<br />

- Direct Memory Access<br />

A <strong>for</strong>m a data transfer directly between memory <strong>and</strong> a peripheral or between memory <strong>and</strong> memory, without<br />

normal program intervention.<br />

EABI<br />

- Embedded Application Binary Interface<br />

<strong>The</strong> convention <strong>for</strong> register usage <strong>and</strong> C linkage commonly used on embedded PowerPC machines, derived<br />

from the ABI.<br />

CPM 212


ELDK<br />

- Embedded <strong>Linux</strong> Development Kit<br />

A package which contains everything you need to get startet with an Embedded <strong>Linux</strong> project on your<br />

hardware:<br />

FEC<br />

• cross development tools (like compiler, assembler, linker etc.) that are running on a Host system<br />

while generating code <strong>for</strong> a Target system<br />

• native tools <strong>and</strong> libraries that can be use to build a system running on the target; they can also be<br />

exported on a NFS server <strong>and</strong> used as root filesystem <strong>for</strong> the target<br />

• source code <strong>and</strong> binary images <strong>for</strong> PPC<strong>Boot</strong> <strong>and</strong> <strong>Linux</strong><br />

• Our SELF package as example configuration <strong>for</strong> an embedded system.<br />

- Fast Ethernet Controller<br />

<strong>The</strong> 100 Mbps (100Base) Ethernet controller, present on 'T' devices such as the 860T <strong>and</strong> 855T.<br />

FTP<br />

- File Transfer Protocol<br />

A protocol that can be used to transfer files over a network.<br />

GPL<br />

/ LGPL - GNU General Public License/Lesser General Public License<br />

<strong>The</strong> full license text can be found at http://www.gnu.org/copyleft/gpl.html.<br />

<strong>The</strong> licenses under which the <strong>Linux</strong> kernel <strong>and</strong> much of the utility <strong>and</strong> library code necessary to build a<br />

complete system may be copied, distributed <strong>and</strong> modified. Each portion of the software is copyright by its<br />

respected copyright holder, <strong>and</strong> you must comply with the terms of the license in order to legally copy (<strong>and</strong><br />

hence use) it. One significant requirement is that you freely redistribute any modifications you make; if you<br />

can't cope with this, embedded <strong>Linux</strong> isn't <strong>for</strong> you.<br />

Host<br />

<strong>The</strong> computer system which is used <strong>for</strong> software development. For instance it is used to run the tools of the<br />

ELDK to build software packages.<br />

IDMA<br />

- Independent DMA<br />

ELDK 213


A general purpose DMA engine with relatively limited throughput provided by the microcoded CPM, <strong>for</strong> use<br />

with external peripherals or memory-to-memory transfers.<br />

JFFS<br />

- Journalling Flash File System<br />

JFFS (developed by Axis Communicartion AB, Sweden) is a log-based filesystem on top of the MTD layer; it<br />

promises to keep your filesystem <strong>and</strong> data in a consistent state even in cases of sudden power-down or system<br />

crashes. That's why it is especially useful <strong>for</strong> embedded devices where a regular shutdown procedure cannot<br />

always be guaranteed.<br />

JFFS2<br />

- Second version of the Journalling Flash File System<br />

Like JFFS this is a journalling flash filesystem that is based on the MTD layer; it fixes some design problems<br />

of JFFS <strong>and</strong> adds transparent compression.<br />

JTAG<br />

- Joint Test Action Group<br />

A st<strong>and</strong>ard (see "IEEE St<strong>and</strong>ard 1149.1") that defines how to control the pins of JTAG compliant devices.<br />

Here: An on-chip debug interface supported by a special hardware port on some processors. It allows to take<br />

full control over the CPU with minimal external hardware, in many cases eliminationg the need <strong>for</strong> expensive<br />

tools like In-Circuit-Emulators.<br />

MII<br />

- Media Independent Interface<br />

<strong>The</strong> IEEE Ethernet st<strong>and</strong>ard control interface used to communicate between the Ethernet controller (MAC)<br />

<strong>and</strong> the external PHY.<br />

MMU<br />

- Memory Management Unit<br />

CPU component which maps kernel- <strong>and</strong> user-space virtual addresses to physical addresses, <strong>and</strong> is an integral<br />

part of <strong>Linux</strong> kernel operation.<br />

MTD<br />

- Memory Technology Devices<br />

<strong>The</strong> MTD functions in <strong>Linux</strong> support memory devices like flash or Disk-On-Chip in a device-independend<br />

way so that the higher software layers (like filesystem code) need no knowledge about the actual hardware<br />

properties.<br />

IDMA 214


PC<br />

Card<br />

PC Cards are self-contained extension cards especially <strong>for</strong> laptops <strong>and</strong> other types of portable computers. In<br />

just about the size of a credit card they provide functions like LAN cards (including wireless LAN), modems,<br />

ISDN cards, or hard disk drives - often "solid-state" disks based on flash chips.<br />

<strong>The</strong> PC Card technology has been has been developed <strong>and</strong> st<strong>and</strong>ardized by the Personal Computer Memory<br />

Card International Association (PCMCIA), see http://www.pcmcia.org/pccard.htm .<br />

PCMCIA<br />

- Personal Computer Memory Card International Association<br />

PCMCIA is an abbreviation that can st<strong>and</strong> <strong>for</strong> several things: the association which defines the st<strong>and</strong>ard, the<br />

specification itself, or the devices. <strong>The</strong> official term <strong>for</strong> the devices is PC-Card.<br />

PHY<br />

- Physical Interface<br />

<strong>The</strong> physical layer transceiver which implements the IEEE Ethernet st<strong>and</strong>ard interface between the ethernet<br />

wires (twisted pair, 50 ohm coax, etc.) <strong>and</strong> the ethernet controller (MAC). PHYs are often external<br />

transceivers but may be integrated in the MAC chip or in the CPU.<br />

<strong>The</strong> PHY is controlled more or less transparently to software via the MII.<br />

RTOS<br />

- Real-Time Operating System<br />

SCC<br />

- Serial Communications Controller<br />

<strong>The</strong> high per<strong>for</strong>mance module(s) within the CPM which implement the lowest layer of various serial<br />

protocols, such as Asynchronous serial (UART), 10 Mbps Ethernet, HDLC etc.<br />

SDMA<br />

- Serial DMA<br />

DMA used to transfer data to <strong>and</strong> from the SCCs.<br />

SELF<br />

- Simple Embedded <strong>Linux</strong> Framework<br />

A simple default configuration <strong>for</strong> Embedded <strong>Linux</strong> systems that is suitable as starting point <strong>for</strong> building your<br />

own systems. It is based on BusyBox to provide an init process, shell, <strong>and</strong> many common tools (from cat<br />

PC 215


<strong>and</strong> ls to vi), plus some other tools to provide network connectivity, allowing to access the system over the<br />

internet using telnet <strong>and</strong> FTP services.<br />

SIU<br />

- System Interface Unit<br />

Provides much of the external interfacing logic. It's the other major module on Motorola PowerQUICC<br />

devices alongside the CPU core <strong>and</strong> CPM.<br />

SMC<br />

- Serial Management Controller<br />

A lower per<strong>for</strong>mance version of the SCCs with more limited functionality, particularly useful <strong>for</strong> serial debug<br />

ports <strong>and</strong> low throughput serial protocols.<br />

SPI<br />

- Serial Peripheral Interface<br />

A relatively simple synchronous serial interface <strong>for</strong> connecting low speed external devices using minimal<br />

wires.<br />

S-Record<br />

- Motorola S-Record Format<br />

Motorola S-records are an industry-st<strong>and</strong>ard <strong>for</strong>mat <strong>for</strong> transmitting binary files to target systems <strong>and</strong> PROM<br />

programmers.<br />

See also: http://pmon.groupbsd.org/Info/srec.htm<br />

Target<br />

<strong>The</strong> computer system which will be used later in you application environment, <strong>for</strong> instance an Embedded<br />

System. In many cases it has a different architecture <strong>and</strong> much more limited resoucres than a typical Host<br />

system, so it is often not possible to develop the software directly (native) on this system.<br />

TFTP<br />

- Trivial File Transfer Protocol<br />

A simple network protocol <strong>for</strong> file transfer; used in combination with BOOTP or DHCP to load boot images<br />

etc. over the network.<br />

UART<br />

- Universal Asynchronous Receiver Transmitter<br />

SELF 216


Generically, this refers to any device capable of implementing a variety of asynchronous serial protocols, such<br />

as RS-232, HDLC <strong>and</strong> SDLC. In this context, it refers to the operating mode of the SCCs which provides this<br />

functionality.<br />

UPM<br />

- User Programmable Machine<br />

A highly flexible bus interfacing machine unit allowing external peripherals with an extremely wide variety of<br />

interfacing requirements to be connected directly to the CPU.<br />

YellowDog<br />

More in<strong>for</strong>mation about the YellowDog GNU/<strong>Linux</strong> distribution <strong>for</strong> PowerPC systems can be found at<br />

http://www.yellowdoglinux.com.<br />

UART 217

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!