close

參考來源
http://www.denx.de/wiki/publish/DULG/DULG-tqm8xxl.html

 

 

14. FAQ - Frequently Asked Questions

This is a collection of questions which came up repeatedly. Give me more feedback and I will add more stuff here.

The items are categorized whether they concern UBoot itself, the Linux kernel or the SELF framework.

14.1. ELDK

14.1.1. ELDK Installation under FreeBSD

 

Question:
How can I install ELDK on a FreeBSD system?

 

Answer:
[Thanks to Rafal Jaworowski for these detailed instructions.] This is a short tutorial how to host ELDK on FreeBSD 5.x and 6.x. The procedure described below was tested on 5.2.1, 5.3 and 6-current releases; we assume the reader is equipped with the ELDK 3.x CDROM or ISO image for installation, and is familiar with FreeBSD basic administration tasks like ports/packages installation.
  1. Prerequisites:
    1. Install linux_base

      The first step is to install the Linux compatibility layer from ports /usr/ports/emulators/linux_base/ or packages ftp://ftp.freebsd.org/pub/FreeBSD/ports/i386/packages/emulators/

      ALERT! Please make sure to install version 7.1_5 (linux_base-7.1_5.tbz) or later; in particular, version 6.1.5 which can also be found in the ports tree does not work properly!

      The compatibility layer is activated by
      # kldload linux
      
    2. Install bash

      Since ELDK and Linux build scripts are organised around bash while FreeBSD does not have it in base, this shell needs to be installed either from ports /usr/ports/shells/bash2/ or packages collection ftp://ftp.freebsd.org/pub/FreeBSD/ports/i386/packages/shells/

      The installation puts the bash binary in /usr/local/bin. It is a good idea to create a symlink in /bin so that hash bang from scripts (#!/bin/bash) works without modifications:
      # cd /bin 
      # ln -s /usr/local/bin/bash
      
  2. Prepare ELDK

    ALERT! This step is only needed for ELDK release 3.1 and older versions.

    Copy the install files from the CDROM or ISO image to a writable location. Brand the ELDK installer as Linux ELF file:
    # cd <elkd_install_dir>
    # brandelf -t Linux ./install
    
    TIP Note: The following workaround might be a good alternative for the tedious copying of the installation CDROM to a writable location and manual branding: you can set a fallback branding in FreeBSD - when the loader cannot recognise the ELF brand it will switch to the last resort defined.
    # sysctl -w kern.elf32.fallback_brand=3
    kern.elf32.fallback_brand: -1 -> 3
    
    With this setting, the normal ELDK CDROM images should work.
  3. Install ELDK normally as described in 3.4.3. Initial Installation
  4. Set envrionment variables and PATH as needed for ELDK (in bash); for example:
    bash$ export CROSS_COMPILE=ppc_8xx-
    bash$ export PATH=${PATH}:/opt/eldk/bin:/opt/eldk/usr/bin
    
  5. Hints for building U-Boot:

    FreeBSD normally uses BSD-style 'make' in base, but in order to compile U-Boot 'gmake' (GNU make) has to be used; this is installed as part of the 'linux_base' package (see above).

    U-Boot should build according to standard ELDK instructions, for example:
    bash$ cd /opt/eldk/ppc_8xx/usr/src/u-boot-1.1.2
    bash$ gmake TQM823L_config
    bash$ gmake all
    
  6. Hints for building Linux:

    There are three issues with the Makefile in the Linux kernel source tree:
    • GNU make has to be used.
    • The 'expr' utility in FreeBSD base behaves differently from the version than is used in Linux so we need to modify the Makefile to explicitly use the Linux version (which is part of the Linux compatibility package). This is best achieved with defining "EXPR = /compat/linux/usr/bin/expr" somewhere at =Makefile='s beginning and replacing all references to 'expr' with the variable ${EXPR).
    • Some build steps (like when running 'scripts/mkdep' can generate very long arguments lists (especially is the Linux kernel tree is in a directory with long absolute filenames). A solution is to use xargs to split such long commands into several with shorter argument lists.

      The Linux kernel can then be built following the standard instructions, for example:
      bash$ cd /opt/eldk/ppc_8xx/usr/src/linux-2.4.25/
      bash$ gmake mrproper
      bash$ gmake TQM823L_config
      bash$ gmake oldconfig
      bash$ gmake dep
      bash$ gmake -j6 uImage
      

14.1.2. ELDK Installation Aborts

 

Question:
I tried to install ELDK version 2.x on a SuSE 8.2 / SuSE 9 / RedHat-9 Linux host but failed - it terminated without installing any packages. Why?

 

Answer:
Newer Linux distributions use libraries that are incompatible to those used by the ELDK's installation tools. This problem was fixed in later releases of the ELDK (version 3.0 and later). It is therefore recommended to use a more recent version of the ELDK. If you really want to install an old version, the following back-port is available:

Please download the file ftp://ftp.denx.de/pub/tmp/ELDK-update-2.2.0.tar.bz2

Then change into the source tree with the ELDK files and perform the following operations:
bash$ rm RPMS/rpm-4.0.3-1.03b_2.i386.rpm \
    RPMS/rpm-build-4.0.3-1.03b_2.i386.rpm \
    RPMS/rpm-devel-4.0.3-1.03b_2.i386.rpm \
    tools/usr/lib/rpm/rpmpopt-4.0.3
bash$ tar jxf /tmp/ELDK-update-2.2.0.tar.bz2
Then build the ISO image as documented, and try again.

14.1.3. Installation on Local Harddisk

 

Question:
I have a local harddisk drive connected to my target board. Can I install the ELDK on it and run it like a standard Linux distribution?

 

Answer:
Yes, this is possible. It requires only minor adjustments. The following example assumes you are using a SCSI disk drive, but the same can be done with standard SATA or PATA drives, too:
  1. Boot the target with root file system over NFS.
  2. Create the necessary partitions on your disk drive: you need at last a swap partition and a file system partition.
    bash-3.00# fdisk -l 
    
    Disk /dev/sda: 36.9 GB, 36951490048 bytes
    64 heads, 32 sectors/track, 35239 cylinders
    Units = cylinders of 2048 * 512 = 1048576 bytes
    
       Device Boot      Start         End      Blocks   Id  System
    /dev/sda1               1         978     1001456   82  Linux swap / Solaris
    /dev/sda2             979       12423    11719680   83  Linux
    /dev/sda3           12424       23868    11719680   83  Linux
    /dev/sda4           23869       35239    11643904   83  Linux
    
  3. Format the partititons:
    bash-3.00# mkswap /dev/sda1
    bash-3.00# mke2fs -j -m1 /dev/sda2
    
  4. Mount the file system:
    bash-3.00# mount /dev/sda2 /mnt
    
  5. Copy the content of the (NFS) root file system into the mounted file system:
    bash-3.00# tar --one-file-system -c -f - / | ( cd /mnt ; tar xpf - )
    
  6. Adjust /etc/fstab for the disk file system:
    bash-3.00# vi /mnt/etc/fstab
    bash-3.00# cat /mnt/etc/fstab
    /dev/sda2       /               ext3    defaults        1 1
    /dev/sda1       swap            swap    defaults        0 0
    proc            /proc           proc    defaults        0 0
    sysfs           /sys            sysfs   defaults        0 0
    
  7. Adjust /etc/rc.sysinit for running from local disk; remove the following comments:
    bash-3.00# diff -u /mnt/etc/rc.sysinit.ORIG /mnt/etc/rc.sysinit
    --- /mnt/etc/rc.sysinit.ORIG    2007-01-21 04:37:00.000000000 +0100
    +++ /mnt/etc/rc.sysinit 2007-03-02 10:58:22.000000000 +0100
    @@ -460,9 +460,9 @@
     
     # Remount the root filesystem read-write.
     update_boot_stage RCmountfs
    -#state=`LC_ALL=C awk '/ \/ / && ($3 !~ /rootfs/) { print $4 }' /proc/mounts`
    -#[ "$state" != "rw" -a "$READONLY" != "yes" ] && \
    -#  action $"Remounting root filesystem in read-write mode: " mount -n -o remount,rw /
    +state=`LC_ALL=C awk '/ \/ / && ($3 !~ /rootfs/) { print $4 }' /proc/mounts`
    +[ "$state" != "rw" -a "$READONLY" != "yes" ] && \
    +  action $"Remounting root filesystem in read-write mode: " mount -n -o remount,rw /
     
     # Clean up SELinux labels
     if [ -n "$SELINUX" ]; then
    
  8. Unmount disk:
    bash-3.00# umount /mnt
    
  9. Reboot, and adjust boot arguments to use disk partition as root file system
    => setenv diskargs setenv bootargs root=/dev/sda2 ro
    => setenv net_disk 'tftp ${loadaddr} ${bootfile};run diskargs addip addcons;bootm'
    => saveenv
    
  10. Boot with these settings
    => run net_disk
    

14.1.4. ELDK Include Files Missing

 

Question:
After configuring and compiling a Linux kernel in the kernel source tree that comes with the ELDK, I cannot compile user space programs any more - I get error messages because many #include file like <errno.h> etc. are missing.
This is with ELDK 4.0 or 4.1.
Answer:
This problem is caused by the way how the ELDK is packaged. At the moment, the ELDK kernel headers are not packed into a separate "kernel-headers" RPM to avoid duplication, because the kernel source tree is always installed. Instead, the ELDK "kernel-headers" package is just a set of symlinks. This worked fine in the past, but fails with the new support for ARCH=powerpc systems.
The next version of the ELDK will contain a real kernel-headers RPM, which will fix this problem.
As a workaround on current systems, you can install the real kernel include files into the "include/asm", "include/linux" and "include/mtd" directories.
To do this, the following commands can be used:
bash$ <eldkroot>/bin/rpm -e kernel-headers-ppc_<target>
bash$ cd <eldkroot>/ppc_<target>
bash$ rm usr/include/asm
bash$ tar -xvzf kernel-headers-powerpc.tar.gz
The tarball mentioned above can be downloaded here. It contains the include files that get installed by running the "make ARCH=powerpc headers_install" command in the Linux kernel tree.

This problem is fixed in ELDK 4.2 and later releases.

14.2. U-Boot

14.2.1. Can UBoot be configured such that it can be started in RAM?

 

Question:
I don't want to erase my flash memory because I'm not sure if my new U-Boot image will work. Is it possible to configure U-Boot such that I can load it into RAM instead of flash, and start it from my old boot loader?
Answer:
No.

 

Question:
But I've been told it is possible??
Answer:
Well, yes. Of course this is possible. This is software, so everything is possible. But it is difficult, unsupported, and fraught with peril. You are on your own if you choose to do it. And it will not help you to solve your problem.

 

Question:
Why?
Answer:
U-Boot expects to see a virgin CPU, i. e. the CPU state must match what you see if the processor starts executing the first instructions when it comes out of reset. If you want to start U-Boot from another boot loader, you must disable a lot of code, i. e. all initialization parts that already have been performed by this other boot loader, like setting up the memory controller, initializing the SDRAM, initializing the serial port, setting up a stack frame etc. Also you must disable the relocation to RAM and adjust the link addresses etc.

This requires a lot of experience with U-Boot, and the fact that you had to ask if this can be done means that you are not in a position to do this.

The code you have to disable contains the most critical parts in U-Boot, i. e. these are the areas where 99% or more of all errors are located when you port U-Boot to a new hardware. In the result, your RAM image may work, but in the end you will need a full image to program the flash memory with it, and then you will have to enable all this highly critical and completely untested code.

You see? You cannot use a RAM version of U-Boot to avoid testing a flash version, so you can save all this effort and just burn your image to flash.

 

Question:
So how can I test an U-Boot image and recover my system if it doesn't work?
Answer:
Attach a BDI2000 to your board, burn the image to flash, and debug it in it's natural environment, i. e. U-Boot being the boot loader of the system and taking control over the CPU right as it comes out of reset. If something goes wrong, erase the flash and program a new image. This is a routine job using a BDI2000.

14.2.2. Relocation cannot be done when using -mrelocatable

Question:
I use ELDK version 3.0. When I build U-Boot I get error messages like this:
{standard input}: Assembler messages:
{standard input}:4998: Error: Relocation cannot be done when using -mrelocatable
...

 

Answer:
ELDK 3.0 uses GCC-3.2.2; your U-Boot sources are too old for this compiler. GCC-3.x requires a few adaptions which were added in later versions of U-Boot. Use for example the source tree (1.0.2) which is included with the ELDK, or download the latest version from CVS.

14.2.3. U-Boot crashes after relocation to RAM

 

Question:
I have ported U-Boot to a custom board. It starts OK, but crashes or hangs after relocating itself to RAM. Why?

 

Answer:
Your SDRAM initialization is bad, and the system crashes when it tries to fetch instructions from RAM. Note that simple read and write accesses may still work, it's the burst mode that is failing. This only shows up when caches are enabled because cache is the primary (or only) user of burst operations in U-Boot. In Linux, burst accesses may also result from DMA. For example, it is typical that a system may crash under heavy network load if the Ethernet controller uses DMA to memory.

 

ALERT! It is NOT sufficient to program the memory controller of your CPU; each SDRAM chip also requires a specific initialization sequence which you must adhere to to the letter - check with the chip manufacturer's manual.

 

It has been observed that some operating systems like pSOS+ or VxWorks do not stress the memory subsystem as much as Linux or other UNIX systems like LynxOS do, so just because your board appears to work running another OS does not mean it is 100% OK.

 

Standard memory tests are not effective in identifying this type of problem because they do not cause stressful cache burst read/write operations.

 

Argument:
But my board ran fine with bootloader XYZ and/or operating system ABC.

 

Answer:
Double-check your configuration that you claim runs properly...

 

  1. Are you sure the SDRAM is initialized using the same init sequence and values?
  2. Are you sure the memory controlling registers are set the same?
  3. Are you sure your other configuration uses caches and/or DMA? If it doesn't, it isn't a valid comparison.

14.2.4. Warning - bad CRC, using default environment

 

 

Question:
I have ported U-Boot to a custom board. It seems to boot OK, but it prints:
*** Warning - bad CRC, using default environment
Why?

 

Answer:
Most probably everything is OK. The message is printed because the flash sector or ERPROM containing the environment variables has never been initialized yet. The message will go away as soon as you save the envrionment variables using the saveenv command.

14.2.5. Wrong debug symbols after relocation

 

Question:
I want to debug U-Boot after relocation to RAM, but it doesn't work since all the symbols are at wrong addresses now.

 

Answer:
To debug parts of U-Boot that are running from ROM/flash, i. e. before relocation, just use a command like "powerpc-linux-gdb uboot" as usual.

 

For parts of U-Boot that run from RAM, i. e. after relocation, use "powerpc-linux-gdb" without arguments, and use the add-symbol-file command in GDB to load the symbol table at the relocation address in RAM. The only problem is that you need to know that address, which depends on RAM size, length reserved for U-Boot, size of "protected RAM" area, etc. If in doubt, enable DEBUG mode when building U-Boot so it prints the address to the console.

 

TIP Hint: I use definitions like these in my .gdbinit file:
define rom
        symbol-file
        file u-boot
end
                                                                                
define ram
        symbol-file
        add-symbol-file u-boot  0x01fe0000
end

 

Note: when you want to switch modes during one debug session (i. e. without restarting GDB) you can "delete" the current symbol information by using the symbol-file command without arguments, and then either using "symbol-file u-boot" for code before relocation, or "add-symbol-file u-boot _offset_" for code after relocation.

14.2.6. Linux hangs after uncompressing the kernel

 

Question:
I am using U-Boot with a Linux kernel version Y (Y < 2.4.5-pre5), but the last message I see is
Uncompressing Kernel Image ... OK
Then the system hangs.

 

Answer:
Most probably you pass bad parameters to the Linux kernel.
There are several possible reasons:
  • Bad definition of the bd_info structure
    You must make sure that your machine specific header file (for instance include/asm-ppc/tqm8xx.h) includes the same definition of the Board Information structure as we define in include/ppcboot.h, and make sure that your definition of IMAP_ADDR uses the same value as your U-Boot configuration in CFG_IMMR.
  • Bad clock information
    Before kernel version 2.4.5-pre5 (BitKeeper Patch 1.1.1.6, 22MAY2001) the kernel expected the clock information in MHz, but recent kernels expect it in Hz instead. U-Boot passes the clock information in Hz by default. To switch to the old behaviour, you can set the environment variable "clocks_in_mhz" in U-Boot:
                                                                         
=> setenv clocks_in_mhz 1
=> saveenv
       

For recent kernel the "clocks_in_mhz" variable must not be set. If it is present in your environment, you can delete it as follows:

                                                                         
=> setenv clocks_in_mhz
=> saveenv
       

ALERT! A common error is to try "setenv clocks_in_mhz 0" or to some other value - this will not work, as the value of the variable is not important at all. It is the existence of the variable that will be checked.

    • Inconsistent memory map
      Some boards may need corrct mappings for some special hardware devices like BCSR (Board Control and Status Registers) etc. Verify that the mappings expected by Linux match those created by U-Boot.

14.2.7. Erasing Flash Fails

 

Question:
I tried to erase the flash memory like
erase 40050000 40050100
It fails. What am I doing wrong?

 

Answer:
Remember that flash memory cannot be erased in arbitrary areas, but only in so called "erase regions" or "sectors". If you have U-Boot running you can use the flinfo (Flash information, short fli) command to print information about the flash memory on your board, for instance:
=> fli
                                                                                
Bank # 1: AMD AM29LV160B (16 Mbit, bottom boot sect)
  Size: 4 MB in 35 Sectors
  Sector Start Addresses:
    40000000 (RO) 40008000 (RO) 4000C000 (RO) 40010000 (RO) 40020000 (RO)
    40040000      40060000      40080000      400A0000      400C0000
    400E0000      40100000      40120000      40140000      40160000
    40180000      401A0000      401C0000      401E0000      40200000
    40220000      40240000      40260000      40280000      402A0000
    402C0000      402E0000      40300000      40320000      40340000
    40360000      40380000      403A0000      403C0000      403E0000
In the example above, the area 40050000 ... 40050100 lies right in the middle of a erase unit (40040000 ... 4005FFFF), so you cannot erase it without erasing the whole sector, i. e. you have to type
=> erase 40040000 4005FFFF
Also note that there are some sectors marked as read-only ((RO)); you cannot erase or overwrite these sectors without un-protecting the sectors first (see the U-Boot protect command).

 

14.2.8. Ethernet Does Not Work

 

Question:
Ethernet does not work on my board. I have configured a MAC address of 01:02:03:04:05:06, and I can see that an ARP packet is sent by U-Boot, and that an ARP reply is sent by the server, but U-Boot never receives any packets. What's wrong?

 

Answer:
You have chosen a MAC address which, according to the ANSI/IEEE 802-1990 standard, has the multicast bit set. Under normal conditions a network interface discards such packets, and this is what U-Boot is doing. This is not a bug, but correct behaviour.

 

Please use only valid MAC addresses that were assigned to you.

 

For bring-up testing in the lab you can also use so-called locally administered ethernet addresses. These are addresses that have the 2nd LSB in the most significant byte of MAC address set. The gen_eth_addr tool that comes with U-Boot (see "tools/gen_eth_addr" ) can be used to generate random addresses from this pool.

14.2.9. Where Can I Get a Valid MAC Address from?

 

Question:
Where can I get a valid MAC address from?

 

Answer:
You have to buy a block of 4096 MAC addresses (IAB = Individual Address Block) or a block of 16M MAC addresses (OUI = Organizationally Unique Identifier, also referred to as 'company id') from IEEE Registration Authority. The current cost of an IAB is $550.00, the cost of an OUI is $1,650.00. See http://standards.ieee.org/regauth/oui/index.shtml

 

You can set the "locally administered" bit to make your own MAC address (no guarantee of uniqueness, but pretty good odds if you don't do something dumb). Ref: Wikipedia

 

Universally administered and locally administered addresses are distinguished by setting the second least significant bit of the most significant byte of the address. If the bit is 0, the address is universally administered. If it is 1, the address is locally administered. The bit is 0 in all OUIs. For example, 02-00-00-00-00-01. The most significant byte is 02h. The binary is 00000010 and the second least significant bit is 1. Therefore, it is a locally administered address.

14.2.10. Why do I get TFTP timeouts?

Question 1:: When trying to download a file from the TFTP server I always get timeouts like these:

...
Loading: #######T ##################################T###################T ####T ##T #
       ###T #T #########T ########T #############T ##T #############T ########T #############T
       #####T ###T ######T #######T #######T #############T ##T ##############T ###########
       ###########
done

If the target is connected directly to the host PC (i. e. without a switch inbetween) the problem goes away or is at least less incisive.

What's wrong?

Answer 1:: Most probably you have a full duplex/half duplex problem. Verify that U-Boot is setting the ethernet interface on your board to the proper duplex mode (full/half). I'm guessing your board is half duplex but your switch is full (typical of a switch ;-).

The switch sends traffic to your board while your board is transmitting... that is a collision (late collision at that) to your board but is OK to the switch. This doesn't happen nearly as much with a direct link to your PC since then you have a dedicated link without much asynchronous traffic.

The software (U-Boot/Linux) needs to poll the PHY chip for duplex mode and then (re)configure the MAC chip (separate or built into the CPU) to match. If the poll isn't happening or has a bug, you have problems like described above.

Question 2:: When I use tftp, there are some problems. My terminal always displays "Loading: T T T T T T T T T T T T T T T T T T T T". The whole information as follows:

U-Boot 1.1.4_XT (Jun  6 2006 - 17:36:18)
U-Boot code: 0C300000 -> 0C31AD70  BSS: -> 0C31EF98
RAM Configuration:
Bank #0: 0c000000  8 MB
Bank #1: 0c800000  8 MB
Flash:  2 MB
*** Warning - bad CRC, using default environment
In:    serial
Out:   serial
Err:   serial
Hit any key to stop autoboot:  0
XT=>  help tftp
tftpboot [loadAddress] [bootfilename]
XT=>  tftpboot 0x0c700000 image.bin
TFTP from server 192.168.0.23; our IP address is 192.168.0.70
Filename 'image.bin'.
Load address: 0xc700000
Loading: T T T T T T T T T T T T T T T T T T T T
Retry count exceeded; starting again
TFTP from server 192.168.0.23; our IP address is 192.168.0.70

Would someone give me some suggestions?

Answer 2:: (1) Verify your TFTP server is working. On a machine (not the TFTP server nor your development board) use tftp to read the target file.

$ tftp 192.168.0.23 get image.bin

If this doesn't work, fix your TFTP server configuration and make sure it is running.
(2) If your TFTP server is working, run ethereal (or equivalent ethernet sniffing) to see what ethernet packets are being sent by your development board. It usually works best to run ethereal on your TFTP server (if you run it on a different machine and you use an ethernet switch, the third machine likely won't see the tftp packets).

14.2.11. How the Command Line Parsing Works

There are two different command line parsers available with U-Boot: the old "simple" one, and the much more powerful "hush" shell:

 

14.2.11.1. Old, simple command line parser

 

  • supports environment variables (through setenv / saveenv commands)
  • several commands on one line, separated by ';'
  • variable substitution using "... ${_variablename_} ..." syntax
    ALERT! NOTE: Older versions of U-Boot used "$(...)" for variable substitution. Support for this syntax is still present in current versions, but will be removed soon. Please use "${...}" instead, which has the additional benefit that your environment definitions are compatible with the Hush shell, too.
  • special characters ('$', ';') can be escaped by prefixing with '\', for example:
            setenv bootcmd bootm \${address}
    
  • You can also escape text by enclosing in single apostrophes, for example:
            setenv addip 'setenv bootargs ${bootargs} ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}:${hostname}:${netdev}:off'
    

 

14.2.11.2. Hush shell

 

  • similar to Bourne shell, with control structures like if...then...else...fi, for...do...done, while...do...done, until...do...done, ...
  • supports environment ("global") variables (through setenv / saveenv commands) and local shell variables (through standard shell syntax name=value ); only environment variables can be used with the run command, especially as the variable to run (i. e. the first argument).
  • In the current implementation, the local variables space and global environment variables space are separated. Local variables are those you define by simply typing like name=value. To access a local variable later on, you have to write '$name' or '${name}'; to execute the contents of a variable directly you can type '$name' at the command prompt. Note that local variables can only be used for simple commands, not for compound commands etc.
  • Global environment variables are those you can set and print using setenv and printenv. To run a command stored in such a variable, you need to use the run command, and you must not use the '$' sign to access them.
  • To store commands and special characters in a variable, use single quotation marks surrounding the whole text of the variable, instead of the backslashes before semicolons and special symbols.
  • Be careful when using the hash ('#') character - like with a "real" Bourne shell it is the comment character, so you have to escape it when you use it in the value of a variable.

Examples:

 

        setenv bootcmd bootm \$address
        setenv addip 'setenv bootargs $bootargs ip=$ipaddr:$serverip:$gatewayip:$netmask:$hostname:$netdev:off'

 

14.2.11.3. Hush shell scripts

Here are a few examples for the use of the advanced capabilities of the hush shell in U-Boot environment variables or scripts:

 

Example:
 
=> setenv check 'if imi $addr; then echo Image OK; else echo Image corrupted!!; fi'
=> print check
check=if imi $addr; then echo Image OK; else echo Image corrupted!!; fi
=> addr=0 ; run check

## Checking Image at 00000000 ...
   Bad Magic Number
Image corrupted!!
=> addr=40000 ;run check

## Checking Image at 00040000 ...
   Image Name:   ARM Linux-2.4.18
   Created:      2003-06-02  14:10:54 UTC
   Image Type:   ARM Linux Kernel Image (gzip compressed)
   Data Size:    801609 Bytes = 782.8 kB
   Load Address: 0c008000
   Entry Point:  0c008000
   Verifying Checksum ... OK
Image OK
Instead of "echo Image OK" there could be a command (sequence) to boot or otherwise deal with the correct image; instead of the "echo Image corrupted!!" there could be a command (sequence) to (load and) boot an alternative image, etc.

Example:
 
=> addr1=0
=> addr2=10
=> bootm $addr1 || bootm $addr2 || tftpboot $loadaddr $loadfile && bootm
## Booting image at 00000000 ...
Bad Magic Number
## Booting image at 00000010 ...
Bad Magic Number
TFTP from server 192.168.3.1; our IP address is 192.168.3.68
Filename '/tftpboot/TRAB/uImage'.
Load address: 0xc400000
Loading: #################################################################
         #################################################################
         ###########################
done
Bytes transferred = 801673 (c3b89 hex)
## Booting image at 0c400000 ...
   Image Name:   ARM Linux-2.4.18
This will check if the image at (flash?) address "addr1" is ok and boot it; if the image is not ok, the alternative image at address "addr2" will be checked and booted if it is found to be OK. If both images are missing or corrupted, a new image will be loaded over TFTP and booted.

 

 

14.2.11.4. General rules

 

  1. If a command line (or an environment variable executed by a run command) contains several commands separated by semicolons, and one of these commands fails, the remaining commands will still be executed.
  2. If you execute several variables with one call to run (i. e. calling run with a list of variables as arguments), any failing command will cause run to terminate, i. e. the remaining variables are not executed.

14.2.12. Decoding U-Boot Crash Dumps

When you are porting U-Boot to new hardware, or implementing extensions, you might run into situations where U-Boot crashes and prints a register dump and a stack trace, for example like this:

 

Bus Fault @ 0x00f8d70c, fixup 0x00000000
Machine check in kernel mode.
Caused by (from msr): regs 00f52cf8 Unknown values in msr
NIP: 00F8D70C XER: 0000005F LR: 00F8D6F4 REGS: 00f52cf8 TRAP: 0200 DAR: F9F68C00
MSR: 00009002 EE: 1 PR: 0 FP: 0 ME: 1 IR/DR: 00

GPR00: 00016ACC 00F52DE8 00000000 F9F68C00 00FA38EC 00000001 F9F68BF8 0000000B 
GPR08: 00000002 00F55470 00000000 00F52D94 44004024 00000000 00FA2F00 C0F75000 
GPR16: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
GPR24: 00000000 00FA38EC 00F553C0 00F55480 00000000 00F52F80 00FA41C0 00000001 
Call backtrace: 
00000000 00F8F998 00F8FA88 00F8FAF8 00F90B5C 00F90CF8 00F8385C 
00F79E6C 00F773B0 
machine check

To find out what happened, you can try to decode the stack backtrace (the list of addresses printed after the "Call backtrace:" line. The backtrace tool can be used for this purpose. However, there is a little problem: the addresses printed for the stack backtrace are after relocation of the U-Boot code to RAM; to use the backtrace tool you need to know U-Boot's address offset (the difference between the start address of U-Boot in flash and its relocation address in RAM).

The easiest way to find out the relocation address is to enable debugging for the U-Boot source file lib_*/board.c - U-Boot will then print some debug messages

 

...
Now running in RAM - U-Boot at: 00f75000
...

Now you have to calculate the address offset between your link address (The value of the TEXT_BASE definition in your board/?/config.mk file). In our case this value is 0x40000000, so the address offset is 0x40000000 - 0x00f75000 = 0x3f08b000

Now we use the backtrace script with the System.map file in the U-Boot source tree and this address offset:

 

-> backtrace System.map 0x3f08b000
Reading symbols from System.map
Using Address Offset 0x3f08b000
0x3f08b000 -- unknown address
0x4001a998 -- 0x4001a8d0 + 0x00c8   free_pipe
0x4001aa88 -- 0x4001aa2c + 0x005c   free_pipe_list
0x4001aaf8 -- 0x4001aad0 + 0x0028   run_list
0x4001bb5c -- 0x4001ba68 + 0x00f4   parse_stream_outer
0x4001bcf8 -- 0x4001bcd8 + 0x0020   parse_file_outer
0x4000e85c -- 0x4000e6f8 + 0x0164   main_loop
0x40004e6c -- 0x40004b9c + 0x02d0   board_init_r
0x400023b0 -- 0x400023b0 + 0x0000   trap_init

In this case the last "good" entry on the stack was in free_pipe...

14.2.13. Porting Problem: cannot move location counter backwards

 

Question:
I'm trying to port U-Boot to a new board and the linker throws an error message like this:
board/<your_board>/u-boot.lds:75 cannot move location counter backwards (from 00000000b0008010 to 00000000b0008000)

 

Answer:
Check your linker script board/your_board/u-boot.lds which controls how the object files are linked together to build the U-Boot image.

It looks as if your board uses an "embedded" environment, i. e. the flash sector containing the environment variables is surrounded by code. The u-boot.lds tries to collect as many as possible code in the first part, making the gap between this first part and the environment sector as small as possible. Everything that does not fit is then placed in the second part, after the environment sector.

Some your modifications caused the code that was put in this first part to grow, so that the linker finds that it would have to overwrite space that is already used.

Try commenting out one (or more) line(s) before the line containing the "common/environment.o" statement. [ "lib_generic/zlib.o" is usually a good candidate for testing as it's big ]. Once you get U-Boot linked, you can check in the u-boot.map file how big the gap is, and which object files could be used to fill it up again.

14.2.14. How can I load and uncompress a compressed image

 

Question:
Can I use U-Boot to load and uncompress a compressed image from flash into RAM? And can I choose whether I want to automatically run it at that time, or wait until later?

 

Answer:
Yes to both questions. First, you should generate your image as type "standalone" (using "mkimage ... -T standalone ..."). When you use the bootm command for such an image, U-Boot will automatically uncompress the code while it is storing it at that image's load address in RAM (given by the -a option to the mkimage command).

As to the second question, by default, unless you say differently, U-Boot will automatically start the image by jumping to its entry point (given by the -e option to mkimage) after loading it. If you want to prevent automatic execution, just set the environment variable "autostart" to "no" ("setenv autostart no") before running bootm.

14.2.15. My standalone program does not work

 

 

Question:
I tried adding some new code to the hellow_world.c demo program. This works well as soon as I only add code to the existing hello_world() function, but as soon as I add some functions of my own, things go all haywire: the code of the hello_world() function does not get executed correctly, and my new function gets calles with unexpected arguments. What's wrong?

 

Answer:
You probably failed to notice that any code you add to the example program may shift the entry point address. You should check this using the nm program:
$ ${CROSS_COMPILE}nm -n examples/hello_world
0000000000040004 T testfunc
0000000000040058 T hello_world
000000000004016c t dummy
...
As you can see, the entry point (function hello_world()) is no longer at 0x40004 as it was before, but at 0x40058. Just start your standalone program at this address, and everything should work well.

14.2.16. U-Boot Doesn't Run after Upgrading my Compiler

 

Question:
I encountered a big problem that U-Boot 1.1.4 compiled by ELDK 4.1 for MPC82xx crashed.

But if I build it using gcc-3.4.6 based cross tools, U-Boot on my board boots correctly.

The same U-Boot code built by ELDK 4.1 (gcc-4.0) failed, nothing occurs on the serial port.

 

Answer:
This is often a missing volatile attribute on shared variable references, particularly hardware registers. Newer compiler versions optimize more aggressively, making missing volatile attributes visible.

If you use -O0 (no optimization) does it fix the problem?
If it does, it most likely is an optimization/volatile issue. The hard part figuring out where. Device handling and board-specific code is the place to start.

14.3. Linux

14.3.1. Linux crashes randomly

 

Question:
On my board, Linux crashes randomly or has random exceptions (especially floating point exceptions if it is a PowerPC processor). Why?

 

Answer:
Quite likely your SDRAM initialization is bad. See UBootCrashAfterRelocation for more information.

 

On a PowerPC, the instructions beginning with 0xFF are floating point instructions. When your memory subsystem fails, the PowerPC is reading bad values (0xFF) and thus executing illegal floating point instructions.

14.3.2. Linux crashes when uncompressing the kernel

 

Question:
When I try to boot Linux, it crashes during uncompressing the kernel image:
=> bootm 100000
## Booting image at 00100000 ...
Image Name: Linux-2.4.25
Image Type: PowerPC Linux Kernel Image (gzip compressed)
Data Size: 1003065 Bytes = 979.6 kB
Load Address: 00000000
Entry Point: 00000000
Verifying Checksum ... OK
Uncompressing Kernel Image ... Error: inflate() returned -3
GUNZIP ERROR - must RESET board to recover

 

Answer:
Your kernel image is quite big - nearly 1 MB compressed; when it gets uncompressed it will need 2.5 ... 3 MB, starting at address 0x0000. But your compressed image was stored at 1 MB (0x100000), so the uncompressed code will overwrite the (remaining) compressed image. The solution is thus simple: just use a higher address to download the compressed image into RAM. For example, try:
=> bootm 400000

14.3.3. Linux Post Mortem Analysis

You may find yourself in a situation where the Linux kernel crashes or hangs without any output on the console. The first attempt to get more information in such a situation is a Post Mortem dump of the log buffer - often the Linux kernel has already collected useful information in its console I/O buffer which just does not get printed because the kernel does not run until successful initialization of the console port.

Proceed as follows:

 

  1. Find out the virtual address of the log buffer; For 2.4 Linux kernels search for "log_buf":
    2.4 Linux:
    bash$ grep log_buf System.map
    c0182f54 b log_buf
    
    Here the virtual address of the buffer is 0xC0182F54
    For 2.6 kernels "__log_buf" must be used:
    bash$ grep __log_buf System.map
    c02124c4 b __log_buf
    
    Here the virtual address of the buffer is 0xC02124C4  
  2. Convert to physical address: on PowerPC systems, the kernel is usually configured for a virtual address of kernel base (CONFIG_KERNEL_START) of 0xC0000000. Just subtract this value from the address you found. In our case we get:
    physical address = 0xC0182F54 - 0xC0000000 = 0x00182F54
    
  3. Reset your board - do not power-cycle it!
     
  4. Use your boot loader (you're running U-Boot, right?) to print a memory dump of that memory area:
    => md 0x00182F54
    

This whole operation is based on the assumption that your boot loader does not overwrite the RAM contents - U-Boot will take care not to destroy such valuable information.

14.3.4. Linux kernel register usage

For the PowerPC architecture, the Linux kernel uses the following registers:

 

R1:
stack pointer
R2:
pointer to task_struct for the current task
R3-R4:
parameter passing and return values
R5-R10:
parameter passing
R13:
small data area pointer
R30:
GOT pointer
R31:
frame pointer

A function can use r0 and r3 - r12 without saving and restoring them. r13 - r31 have to be preserved so they must be saved and restored when you want to use them. Also, cr2 - cr4 must be preserved, while cr0, cr1, cr5 - cr7, lr, ctr and xer can be used without saving & restoring them. [ Posted Tue, 15 Jul 2003 by Paul Mackerras to linuxppc-embedded@lists.linuxppc.org ].

See also the (E)ABI specifications for the PowerPC architecture, Developing PowerPC Embedded Application Binary Interface (EABI) Compliant Programs

14.3.5. Linux Kernel Ignores my bootargs

 

Question:
Why doesn't the kernel use the command-line options I set in the "bootargs" environment variable in U-Boot when I boot my target system?

 

Answer:
This problem is typical for ARM systems only. The following discussion is ARM-centric:

First, check to ensure that you have configured your U-Boot build so that CONFIG_CMDLINE_TAG is enabled. (Other tags like CONFIG_SETUP_MEMORY_TAGS or CONFIG_INITRD_TAG may be needed, too.) This ensures that u-boot will boot the kernel with a command-line tag that incorporates the kernel options you set in the "bootargs" environment variable.

If you have the CONFIG_CMDLINE_TAG option configured, the problem is almost certainly with your kernel build. You have to instruct the kernel to pick up the boot tags at a certain address. This is done in the machine descriptor macros, which are found in the processor start-up C code for your architecture. For the Intel DBPXA250 "Lubbock" development board, the machine descriptor macros are located at the bottom of the file arch/arm/mach-pxa/lubbock.c, and they look like this:
MACHINE_START(LUBBOCK, "Intel DBPXA250 Development Platform")
   MAINTAINER("MontaVista Software Inc.")
   BOOT_MEM(0xa0000000, 0x40000000, io_p2v(0x40000000))
   FIXUP(fixup_lubbock)
   MAPIO(lubbock_map_io)
   INITIRQ(lubbock_init_irq)
MACHINE_END
The machine descriptor macros for your machine will be located in a similar file in your kernel source tree. Having located your machine descriptor macros, the next step is to find out where U-Boot puts the kernel boot tags in memory for your architecture. On the Lubbock, this address turns out to be the start of physical RAM plus 0x100, or 0xa0000100. Add the "BOOT_PARAMS" macro with this address to your machine descriptor macros; the result should look something like this:
MACHINE_START(LUBBOCK, "Intel DBPXA250 Development Platform")
   MAINTAINER("MontaVista Software Inc.")
        BOOT_PARAMS(0xa0000100)
   BOOT_MEM(0xa0000000, 0x40000000, io_p2v(0x40000000))
   FIXUP(fixup_lubbock)
   MAPIO(lubbock_map_io)
   INITIRQ(lubbock_init_irq)
MACHINE_END
If there is already a BOOT_PARAMS macro in your machine descriptor macros, modify it so that it has the correct address. Then, rebuild your kernel and re-install it on your target. Now the kernel should be able to pick up the kernel options you have set in the "bootargs" environment variable.

14.3.6. Cannot configure Root Filesystem over NFS

 

Question:
I want to configure my system with root filesystem over NFS, but I cannot find any such configuration option.

 

Answer:
What you are looking for is the CONFIG_ROOT_NFS configuration option, which depends on CONFIG_IP_PNP.
To enable root filesystem over NFS you must enable the "IP: kernel level autoconfiguration" option in the "Networking options" menu first.

14.3.7. Linux Kernel Panics because "init" process dies

 

Question:
I once had a running system but suddenly, without any changes, the Linux kernel started crashing because the "init" process was dying each time I tried to boot the system, for example like that:
...
VFS: Mounted root (nfs filesystem).
Freeing unused kernel memory: 140k init
init has generated signal 11 but has no handler for it
Kernel panic - not syncing: Attempted to kill init!
Answer:
You probably run your system with the root file system mounted over NFS. Change into the root directory of your target file system, and remove the file "etc/ld.so.cache". That should fix this problem:
# cd /opt/eldk/ppc_6xx/
# rm -f etc/ld.so.cache
Explanation:
Normally, the file "etc/ld.so.cache" contains a compiled list of system libraries. This file is used by the dynamic linker/loader ld.so to cache library information. If it does not exist, rebuilt automatically. For some reason, a corrupted or partial file was written to your root file system. This corrupt file then confused the dynamic linker so that it crashed when trying to start the init process.

14.3.8. Unable to open an initial console

 

Question:
The Linux kernel boots, but then hangs after printing: "Warning: unable to open an initial console".

 

Answer:
Most probably you have one or missing entries in the /dev directory in your root filesystem. If you are using the ELDK's root filesystem over NFS, you probably forgot to run the ELDK_MAKEDEV and ELDK_FIXOWNER scripts as described in 3.6. Mounting Target Components via NFS.

14.3.9. Mounting a Filesystem over NFS hangs forever

 

Question:
We use the SELF ramdisk image that comes with the ELDK. When we try to mount a filesystem over NFS from the server, for example:

# mount -t nfs 192.168.1.1:/target/home /home

the command waits nearly 5 minutes in uninterruptable sleep. Then the mount finally succeeds. What's wrong?

 

Answer:
The default configuration of the SELF was not designed to mount additional filesystems with file locking over NFS, so no portmap deamon is running, which is causing your problems. There are two solutions for the problem:
  1. Add the portmap deamon (/sbin/portmap) to the target filesystem and start it as part of the init scripts.
  2. Tell the "mount" program and the kernel that you don't need file locking by passing the "nolock" option to the mount call, i. e. use

    # mount -o nolock -t nfs 192.168.1.1:/target/home /home

 

Explanation:
If you call the mount command like above (i. e. without the "nolock" option) an RPC call to the "portmap" deamon will be attempted which is required to start a lockd kernel thread which is necessary if you want to use file locking on the NFS filesystem. This call will fail only after a very long timeout.

14.3.10. Ethernet does not work in Linux

 

Question:
Ethernet does not work on my board. But everything is fine when I use the ethernet interface in U-Boot (for example by performing a TFTP download). This is a bug in U-Boot, right?

 

Answer:
No. It's a bug in the Linux ethernet driver.

In some cases the Linux driver fails to set the MAC address. That's a buggy driver then - Linux ethernet drivers are supposed to read the MAC address at startup. On ->open, they are supposed to reprogram the MAC address back into the chip (but not the EEPROM, if any) whether or not the address has been changed.

In general, a Linux driver shall not make any assumptions about any initialization being done (or not done) by a boot loader; instead, that driver is responsible for performing all of the necessary initialization itself.

And U-Boot shall not touch any hardware it does not access itself. If you don't use the ethernet interface in U-Boot, it won't be initialized by U-Boot.

A pretty extensive discussion of this issue can be found in the thread ATAG for MAC address on the ARM Linux mailing list. archive 1 archive 2

14.3.11. Loopback interface does not work

 

Question:
When I boot Linux I get a "socket: Address family not supported by protocol" error message when I try to configure the loopback interface. What's wrong?

 

Answer:
This is most probably a problem with your kernel configuration. Make sure that the CONFIG_PACKET option is selected.

14.3.12. Linux kernel messages are not printed on the console

 

Question:
I expect to see some Linux kernel messages on the console, but there aren't any.

 

Answer:
This is absolutely normal when using the ELDK with root filesystem over NFS. The ELDK startup routines will start the syslog daemon, which will collect all kernel messages and write them into a logfile ( /var/log/messages ).

 

If you want to see the messages at the console, either run "tail -f /var/log/messages &" on the console window, or stop the syslog daemon by issuing a "/etc/rc.d/init.d/syslog stop" command. Another alternative is to increase the console_loglevel of the kernel (any message with log level less than console_loglevel will be printed to the console). With the following command the console_loglevel could be set at runtime: "echo 8 > /proc/sys/kernel/printk". Now all messages are displayed on the console.

14.3.13. Linux ignores input when using the framebuffer driver

 

Question:
When using the framebuffer driver the console output goes to the LCD display, but I cannot input anything. What's wrong?

 

Answer:
You can define "console devices" using the console= boot argument. Add something like this to your bootargs setting:
... console=tty0 console=ttyS0,${baudrate} ...
This will ensure that the boot messages are displayed on both the framebuffer (/dev/tty0) and the serial console (/dev/ttyS0); the last device named in a console= option will be the one that takes input, too, so with the settings above you can use the serial console to enter commands etc. For a more detailed description see http://www.tldp.org/HOWTO/Remote-Serial-Console-HOWTO/configure-kernel.html

14.3.14. BogoMIPS Value too low

 

Question:
We are only seeing 263.78 bogomips on a MPC5200 running at 396 MHz.
Doesn't this seem way to low ?? With a 603e core I'd expect 1 bogomip per MHz or better.

 

Answer:
No, the values you see is correct. Please keep in mind that there is a good reason for the name BogoMIPS.

On PowerPC, the bogomips calculation is measuring the speed of a dbnz instruction. On some processors like the MPC8xx it takes 2 clocks per dbnz instruction, and you get 1 BogoMIP/MHz. The MPC5200 takes 3 clocks per dbnz in this loop, so you get .67 BogoMIP/MHz.

See also The frequently asked questions about BogoMips.

14.3.15. Linux Kernel crashes when using a ramdisk image

 

 

Question:
I have a PowerPC board with 1 GiB of RAM (or more). It works fine with root file system over NFS, but it will crash when I try to use a ramdisk.

 

Answer:
Check where your ramdisk image gets loaded to. In the standard configuration, the Linux kernel can access only 768 MiB of RAM, so your ramdisk image must be loaded below this limit. Check your boot messages. You are hit by this problem when U-Boot reports something like this:
Loading Ramdisk to 3fdab000, end 3ff2ff9d ... OK
and then Linux shows a message like this:
mem_pieces_remove: [3fdab000,3ff2ff9d) not in any region
To fix, just tell U-Boot to load the ramdisk image below the 768 MB limit:
=> setenv initrd_high 30000000

14.3.16. Ramdisk Greater than 4 MB Causes Problems

 

Question:
I built a ramdisk image which is bigger than 4 MB. I run into problems when I try to boot Linux with this image, while other (smaller) ramdisk images work fine.

 

Answer:
The Linux kernel has a default maximum ramdisk size of 4096 kB. To boot with a bigger ramdisk image, you must raise this value. There are two methods:
  • Dynamical adjustment using boot arguments:
    You can pass a boot argument ramdisk_size=<size-in-kB> to the Linux kernel to overwrite the configured maximum. Note that this argument needs to be before any root argument. A flexible way to to this is using U-Boot environment variables. For instance, to boot with a ramdisk image of 6 MB (6144 kB), you can define:
=> setenv rd_size 6144
=> setenv bootargs ... ramdisk_size=\${rd_size} ...
=> saveenv
       

If you later find out that you need an even bigger ramdisk image, or that a smaller one is sufficient, all that needs changing is the value of the "rd_size" environment variable.

    • Increasing the Linux kernel default value:
      When configuring your Linux kernel, adjust the value of the CONFIG_BLK_DEV_RAM_SIZE parameter so that it contains a number equal or larger than your ramdisk (in kB). (In the 2.4 kernel series, you'll find this setting under the "Block devices" menu choice while, in the 2.6 series, it will be under "Device drivers" -> "Block devices".)

 

14.3.17. Combining a Kernel and a Ramdisk into a Multi-File Image

 

Question:
I used to build a zImage.initrd file which combined the Linux kernel with a ramdisk image. Can I do something similar with U-Boot?

 

Answer:
Yes, you can create "Multi-File Images" which contain several images, typically an OS (Linux) kernel image and one or more data images like RAMDisks. This construct is useful for instance when you want to boot over the network using BOOTP etc., where the boot server provides just a single image file, but you want to get for instance an OS kernel and a RAMDisk image.
The typical way to build such an image is:
bash$ mkimage -A ppc -O Linux -T multi -C gzip \
-n 'Linux Multiboot-Image' -e 0 -a 0 \
-d vmlinux.gz:ramdisk_image.gz pMulti
See also the usage message you get when you call "mkimage" without arguments.

14.3.18. Adding Files to Ramdisk is Non Persistent

 

Quetsion:
I want to add some files to my ramdisk, but every time I reboot I lose all my changes. What can I do?

 

Answer:
To add your files or modifications permanently, you have to rebuild the ramdisk image. You may check out the sources of our SELF package (Simple Embedded Linux Framework) to see how this can be done, see for example ftp://ftp.denx.de/pub/LinuxPPC/usr/src/SELF/ or check out the sources for ELDK (module eldk_build from our CVS server, see http://www.denx.de/re/linux.html.

 

See also section 14.4.1. How to Add Files to a SELF Ramdisk for another way to change the ramdisk image.

 

For further hints about the creation and use of initial ramdisk images see also the file Documentation/initrd.txt in your Linux kernel source directory.

14.3.19. Kernel Configuration for PCMCIA

 

Question:
Which kernel configuration options are relevant to support PCMCIA cards under Linux?

 

Answer:
The following kernel configuration options are required to support miscellaneous PCMCIA card types with Linux and the PCMCIA CS package:
  • PCMCIA IDE cards (CF and true-IDE)
    To support the IDE CardService client, the kernel has to be configured with general ATA IDE support. The MPC8xx IDE support (CONFIG_BLK_DEV_MPC8XX_IDE flag) must be turned off.
  • PCMCIA modem cards
    The kernel has to be configured with standard serial port support (CONFIG_SERIAL flag). After the kernel bootup the following preparation is needed:
    bash# mknod /dev/ttySp0 c 240 64
    
    This creates a new special device for the modem card; please note that /dev/ttyS0 ... S4 and TTY_MAJOR 4 are already used by the standard 8xx UART driver). /dev/ttySp0 becomes available for use as soon as the CardServices detect and initialize the PCMCIA modem card.
  • PCMCIA Wireless LAN cards
    Enable the "Network device support" --> "Wireless LAN (non-hamradio)" --> "Wireless LAN (non-hamradio)" option in the kernel configuration (CONFIG_NET_RADIO flag).

14.3.20. Configure Linux for PCMCIA Cards using the Card Services package

The following kernel configuration options are required to support miscellaneous PCMCIA card types with Linux and the PCMCIA CS package:

 

  1. PCMCIA IDE cards (CompactFlash and true-IDE)
    General setup -> Support for hot-pluggable devices (enable: Y) -> PCMCIA/CardBus support -> PCMCIA/CardBus support (enable: M) -> MPC8XX PCMCIA host bridge support (select)
  2. PCMCIA Modem Cards
  3. PCMCIA Network Cards
  4. PCMCIA WLAN Cards

Build and install modules in target root filesystem, shared over NFS:

bash$ make modules modules_install INSTALL_MOD_PATH=/opt/eldk/ppc_8xx

Adjust PCMCIA configuration file (/opt/eldk/ppc_8xx/etc/sysconfig/pcmcia):

PCMCIA=yes
PCIC=m8xx_pcmcia
PCIC_OPTS=
CORE_OPTS=
CARDMGR_OPTS=

Start PCMCIA Card Services:

bash-2.05# sh /etc/rc.d/init.d/pcmcia start

14.3.21. Configure Linux for PCMCIA Cards without the Card Services package

For "disk" type PC Cards (FlashDisks, CompactFlash, Hard Disk Adapters - basically anything that looks like an ordinary IDE drive), an alternative solution is available: direct support within the Linux kernel. This has the big advantage of minimal memory footprint, but of course it comes with a couple of disadvantages, too:

 

  • It works only with "disk" type PC Cards - no support for modems, network cards, etc; for these you still need the PCMCIA Card Services package.
  • There is no support for "hot plug", i. e. you cannot insert or remove the card while Linux is running. (Well, of course you can do this, but either you will not be able to access any card inserted, or when you remove a card you will most likely crash the system. Don't do it - you have been warned!)
  • The code relies on initialization of the PCMCIA controller by the firmware (of course U-Boot will do exactly what's required).

On the other hand these are no real restrictions for use in an Embedded System.

To enable the "direct IDE support" you have to select the following Linux kernel configuration options:

 

CONFIG_IDE=y
CONFIG_BLK_DEV_IDE=y
CONFIG_BLK_DEV_IDEDISK=y
CONFIG_IDEDISK_MULTI_MODE=y
CONFIG_BLK_DEV_MPC8xx_IDE=y
CONFIG_BLK_DEV_IDE_MODES=y

and, depending on which partition types and languages you want to support:

CONFIG_PARTITION_ADVANCED=y
CONFIG_MAC_PARTITION=y
CONFIG_MSDOS_PARTITION=y
CONFIG_NLS=y
CONFIG_NLS_DEFAULT="y"
CONFIG_NLS_ISO8859_1=y
CONFIG_NLS_ISO8859_15=y

With these options you will see messages like the following when you boot the Linux kernel:

 

...
Uniform Multi-Platform E-IDE driver Revision: 6.31
ide: Assuming 50MHz system bus speed for PIO modes; override with idebus=xx
PCMCIA slot B: phys mem e0000000...ec000000 (size 0c000000)
Card ID:   CF 128MB CH
 Fixed Disk Card
 IDE interface
 [silicon] [unique] [single] [sleep] [standby] [idle] [low power]
hda: probing with STATUS(0x50) instead of ALTSTATUS(0x41)
hda: CF 128MB, ATA DISK drive
ide0 at 0xc7000320-0xc7000327,0xc3000106 on irq 13
hda: 250368 sectors (128 MB) w/16KiB Cache, CHS=978/8/32
Partition check:
 hda: hda1 hda2 hda3 hda4
...

You can now access your PC Card "disk" like any normal IDE drive. If you start with a new drive, you have to start by creating a new partition table. For PowerPC systems, there are two commonly used options:

 

14.3.21.1. Using a MacOS Partition Table

A MacOS partition table is the "native" partition table format on PowerPC systems; most desktop PowerPC systems use it, so you may prefer it when you have PowerPC development systems around.

To format your "disk" drive with a MacOS partition table you can use the pdisk command:

We start printing the help menu, re-initializing the partition table and then printing the new, empty partition table so that we know the block numbers when we want to create new partitions:

 

# pdisk /dev/hda
Edit /dev/hda -
Command (? for help): ?
Notes:
  Base and length fields are blocks, which vary in size between media.
  The base field can be <nth>p; i.e. use the base of the nth partition.
  The length field can be a length followed by k, m, g or t to indicate
  kilo, mega, giga, or tera bytes; also the length can be <nth>p; i.e. use
  the length of the nth partition.
  The name of a partition is descriptive text.
Commands are:
  h    help
  p    print the partition table
  P    (print ordered by base address)
  i    initialize partition map
  s    change size of partition map
  c    create new partition (standard MkLinux type)
  C    (create with type also specified)
  n    (re)name a partition
  d    delete a partition
  r    reorder partition entry in map
  w    write the partition table
  q    quit editing (don't save changes)
Command (? for help): i
map already exists
do you want to reinit? [n/y]: y
Command (? for help): p
Partition map (with 512 byte blocks) on '/dev/hda'
 #:                type name    length   base    ( size )
 1: Apple_partition_map Apple       63 @ 1
 2:          Apple_Free Extra  1587536 @ 64      (775.2M)
Device block size=512, Number of Blocks=1587600 (775.2M)
DeviceType=0x0, DeviceId=0x0

At first we create two small partitions that will be used to store a Linux boot image; a compressed Linux kernel is typically around 400 ... 500 kB, so chosing a partition size of 2 MB is more than generous. 2 MB coresponds to 4096 disk blocks of 512 bytes each, so we enter:

 

Command (? for help): C
First block: 64
Length in blocks: 4096
Name of partition: boot0
Type of partition: PPCBoot
Command (? for help): p
Partition map (with 512 byte blocks) on '/dev/hda'
 #:                type name    length   base    ( size )
 1: Apple_partition_map Apple       63 @ 1
 2:             PPCBoot boot0     4096 @ 64      (  2.0M)
 3:          Apple_Free Extra  1583440 @ 4160    (773.2M)
Device block size=512, Number of Blocks=1587600 (775.2M)
DeviceType=0x0, DeviceId=0x0

To be able to select between two kernel images (for instance when we want to do a field upgrade of the Linux kernel) we create a second boot partition of exactly the same size:

Command (? for help): C
First block: 4160
Length in blocks: 4096
Name of partition: boot1
Type of partition: PPCBoot
Command (? for help): p
Partition map (with 512 byte blocks) on '/dev/hda'
 #:                type name    length   base    ( size )
 1: Apple_partition_map Apple       63 @ 1
 2:             PPCBoot boot0     4096 @ 64      (  2.0M)
 3:             PPCBoot boot1     4096 @ 4160    (  2.0M)
 4:          Apple_Free Extra  1579344 @ 8256    (771.2M)
Device block size=512, Number of Blocks=1587600 (775.2M)
DeviceType=0x0, DeviceId=0x0

Now we create a swap partition - 64 MB should be more than sufficient for our Embedded System; 64 MB means 64*1024*2 = 131072 disk blocks of 512 bytes:

Command (? for help): C
First block: 8256
Length in blocks: 131072
Name of partition: swap
Type of partition: swap
Command (? for help): p
Partition map (with 512 byte blocks) on '/dev/hda'
 #:                type name    length   base    ( size )
 1: Apple_partition_map Apple       63 @ 1
 2:             PPCBoot boot0     4096 @ 64      (  2.0M)
 3:             PPCBoot boot1     4096 @ 4160    (  2.0M)
 4:                swap swap    131072 @ 8256    ( 64.0M)
 5:          Apple_Free Extra  1448272 @ 139328  (707.2M)
Device block size=512, Number of Blocks=1587600 (775.2M)
DeviceType=0x0, DeviceId=0x0

Finally, we dedicate all the remaining space to the root partition:

Command (? for help): C
First block: 139328
Length in blocks: 1448272
Name of partition: root
Type of partition: Linux
Command (? for help): p
Partition map (with 512 byte blocks) on '/dev/hda'
 #:                type name    length   base    ( size )
 1: Apple_partition_map Apple       63 @ 1
 2:             PPCBoot boot0     4096 @ 64      (  2.0M)
 3:             PPCBoot boot1     4096 @ 4160    (  2.0M)
 4:                swap swap    131072 @ 8256    ( 64.0M)
 5:               Linux root   1448272 @ 139328  (707.2M)
Device block size=512, Number of Blocks=1587600 (775.2M)
DeviceType=0x0, DeviceId=0x0

To make our changes permanent we must write the new partition table to the disk, before we quit the pdisk program:

Command (? for help): w
Writing the map destroys what was there before. Is that okay? [n/y]: y
 hda: [mac] hda1 hda2 hda3 hda4 hda5
 hda: [mac] hda1 hda2 hda3 hda4 hda5
Command (? for help): q

Now we can initialize the swap space and the filesystem:

# mkswap /dev/hda4
Setting up swapspace version 1, size = 67104768 bytes
# mke2fs /dev/hda5
mke2fs 1.19, 13-Jul-2000 for EXT2 FS 0.5b, 95/08/09
Filesystem label=
OS type: Linux
Block size=4096 (log=2)
Fragment size=4096 (log=2)
90624 inodes, 181034 blocks
9051 blocks (5.00%) reserved for the super user
First data block=0
6 block groups
32768 blocks per group, 32768 fragments per group
15104 inodes per group
Superblock backups stored on blocks:
        32768, 98304, 163840
Writing inode tables: done
Writing superblocks and filesystem accounting information: done

 

14.3.21.2. Using a MS-DOS Partition Table

The MS-DOS partition table is especially common on PC type computers, which these days means nearly everywhere. You will prefer this format if you want to exchange your "disk" media with any PC type host system.

The fdisk command is used to create MS-DOS type partition tables; to create the same partitioning scheme as above you would use the following commands:

# fdisk /dev/hda
Device contains neither a valid DOS partition table, nor Sun, SGI or OSF disklabel
Building a new DOS disklabel. Changes will remain in memory only,
until you decide to write them. After that, of course, the previous
content won't be recoverable.
The number of cylinders for this disk is set to 1575.
There is nothing wrong with that, but this is larger than 1024,
and could in certain setups cause problems with:
1) software that runs at boot time (e.g., old versions of LILO)
2) booting and partitioning software from other OSs
   (e.g., DOS FDISK, OS/2 FDISK)
Command (m for help): m
Command action
   a   toggle a bootable flag
   b   edit bsd disklabel
   c   toggle the dos compatibility flag
   d   delete a partition
   l   list known partition types
   m   print this menu
   n   add a new partition
   o   create a new empty DOS partition table
   p   print the partition table
   q   quit without saving changes
   s   create a new empty Sun disklabel
   t   change a partition's system id
   u   change display/entry units
   v   verify the partition table
   w   write table to disk and exit
   x   extra functionality (experts only)

Command (m for help): n
Command action
   e   extended
   p   primary partition (1-4)
p
Partition number (1-4): 1
First cylinder (1-1575, default 1):
Using default value 1
Last cylinder or +size or +sizeM or +sizeK (1-1575, default 1575): +2M
Command (m for help): p
Disk /dev/hda: 16 heads, 63 sectors, 1575 cylinders
Units = cylinders of 1008 * 512 bytes
   Device Boot    Start       End    Blocks   Id  System
/dev/hda1             1         5      2488+  83  Linux

Command (m for help): n
Command action
   e   extended
   p   primary partition (1-4)
p
Partition number (1-4): 2
First cylinder (6-1575, default 6):
Using default value 6
Last cylinder or +size or +sizeM or +sizeK (6-1575, default 1575): +2M
Command (m for help): p
Disk /dev/hda: 16 heads, 63 sectors, 1575 cylinders
Units = cylinders of 1008 * 512 bytes
   Device Boot    Start       End    Blocks   Id  System
/dev/hda1             1         5      2488+  83  Linux
/dev/hda2             6        10      2520   83  Linux

Command (m for help): n
Command action
   e   extended
   p   primary partition (1-4)
p
Partition number (1-4): 3
First cylinder (11-1575, default 11):
Using default value 11
Last cylinder or +size or +sizeM or +sizeK (11-1575, default 1575): +64M
Command (m for help): t
Partition number (1-4): 3
Hex code (type L to list codes): 82
Changed system type of partition 3 to 82 (Linux swap)
Command (m for help): p
Disk /dev/hda: 16 heads, 63 sectors, 1575 cylinders
Units = cylinders of 1008 * 512 bytes
   Device Boot    Start       End    Blocks   Id  System
/dev/hda1             1         5      2488+  83  Linux
/dev/hda2             6        10      2520   83  Linux
/dev/hda3            11       141     66024   82  Linux swap

Note that we had to use the t command to mark this partition as swap space.

Command (m for help): n
Command action
   e   extended
   p   primary partition (1-4)
p
Partition number (1-4): 4
First cylinder (142-1575, default 142):
Using default value 142
Last cylinder or +size or +sizeM or +sizeK (142-1575, default 1575):
Using default value 1575
Command (m for help): p
Disk /dev/hda: 16 heads, 63 sectors, 1575 cylinders
Units = cylinders of 1008 * 512 bytes
   Device Boot    Start       End    Blocks   Id  System
/dev/hda1             1         5      2488+  83  Linux
/dev/hda2             6        10      2520   83  Linux
/dev/hda3            11       141     66024   82  Linux swap
/dev/hda4           142      1575    722736   83  Linux

Command (m for help): w
The partition table has been altered!
Calling ioctl() to re-read partition table.
 hda: hda1 hda2 hda3 hda4
 hda: hda1 hda2 hda3 hda4
WARNING: If you have created or modified any DOS 6.x
partitions, please see the fdisk manual page for additional
information.
Syncing disks.

Now we are ready to initialize the partitions:

# mkswap /dev/hda3
Setting up swapspace version 1, size = 67604480 bytes
# mke2fs /dev/hda4
mke2fs 1.19, 13-Jul-2000 for EXT2 FS 0.5b, 95/08/09
Filesystem label=
OS type: Linux
Block size=4096 (log=2)
Fragment size=4096 (log=2)
90432 inodes, 180684 blocks
9034 blocks (5.00%) reserved for the super user
First data block=0
6 block groups
32768 blocks per group, 32768 fragments per group
15072 inodes per group
Superblock backups stored on blocks:
        32768, 98304, 163840
Writing inode tables: done
Writing superblocks and filesystem accounting information: done

14.3.22. Boot-Time Configuration of MTD Partitions

Instead of defining a static partition map as described in section Memory Technology Devices you can define the partitions for your flash memory at boot time using command line arguments. To do that you have to enable the CONFIG_MTD_CMDLINE_PARTS kernel configuration option. With this option enabled, the kernel will recognize a command line argument mtdparts and decode it as follows:

mtdparts=<mtddef>[;<mtddef]
<mtddef>  := <mtd-id>:<partdef>[,<partdef>]
<partdef> := <size>[@offset][<name>][ro]
<mtd-id>  := unique id used in mapping driver/device (number of flash bank)
<size>    := standard linux memsize OR "-" to denote all remaining space
<name>    := '(' NAME ')'

For example, instead of using a static partition map like this:

0x00000000-0x00060000 : "U-Boot"
0x00060000-0x00080000 : "Environment 1"
0x00080000-0x000A0000 : "Environment 2"
0x000A0000-0x000C0000 : "ASIC Images"
0x000C0000-0x001C0000 : "Linux Kernel"
0x001C0000-0x005C0000 : "Ramdisk Image"
0x005C0000-0x01000000 : "User Data"

you can pass a command line argument as follows:

mtdparts=0:384k(U-Boot),128k(Env1),128k(Env2),128k(ASIC),1M(Linux),4M(Ramdisk),-(User_Data)

14.3.23. Use NTP to synchronize system time against RTC

If a system has a real-time clock (RTC) this is often used only to initialize the system time when the system boots. From then, the system time is running independently. The RTC will probably only be used again at shutdown to save the current system time. Such a configuration is used in many workstation configurations. It is useful if time is not really critical, or if the system time is synchronized against some external reference clock like when using the Network Time Protocol (NTP) to access time servers on the network.

But some systems provide a high-accuracy real-time clock (RTC) while the system clocks are not as accurate, and sometimes permanent access to the net is not possible or wanted. In such systems it makes more sense to use the RTC as reference clock (Stratum 1 NTP server - cf. http://www.ntp.org/). To enable this mode of operation you must edit the NTP daemon's configuration file /etc/ntp.conf in your target's root file system. Replace the lines

        server  127.127.1.0     # local clock
        fudge   127.127.1.0 stratum 10 

by

        server 127.127.43.0     # standard Linux RTC

Then make sure to start the NTP daemon on your target by adding it to the corresponding init scripts and restart it if it is already running.

ALERT! The "address" of the RTC (127.127.43.0 in the example above) is not an IP address, but actually used as an index into an internal array of supported reference clocks in the NTP daemon code. You may need to check with your ntpd implementation if the example above does not work as expected.

14.3.24. Configure Linux for XIP (Execution In Place)

This document describes how to setup and use XIP in the kernel and the cramfs filesystem. (A patch to add XIP support to your kernel can be found at the bottom of this page.)

 

14.3.24.1. XIP Kernel

To select XIP you must enable the CONFIG_XIP option:

  $ cd <xip-linux-root>
  $ make menuconfig
  ...
    MPC8xx CPM Options  --->
      [*] Make a XIP (eXecute in Place) kernel
      (40100000) Physical XIP kernel address
      (c1100000) Virtual  XIP kernel address
      (64) Image header size e.g. 64 bytes for PPCBoot

The physical and virtual address of the flash memory used for XIP must be defined statically with the macros CONFIG_XIP_PHYS_ADDR and CONFIG_XIP_VIRT_ADDR. The virtual address usually points to the end of the kernel virtual address of the system memory. The physical and virtual address must be aligned relative to an 8 MB boundary:

  CONFIG_XIP_PHYS_ADDR = FLASH-base-address + offset-in-FLASH
  CONFIG_XIP_VIRT_ADDR = 0xc0000000 + DRAM-size + offset-in-FLASH

The default configuration parameters shown above are for a system with 16MB of DRAM and the XIP kernel image located at the physical address 0x40100000 in flash memory.

Note that the FLASH and MTD driver must be disabled.

You can then build the "uImage", copy it to CONFIG_XIP_PHYS_ADDR in flash memory and boot it from CONFIG_XIP_PHYS_ADDR as usual.

 

14.3.24.2. Cramfs Filesystem

The cramfs filesystem enhancements:

 

  • They allow cramfs optional direct access to a cramfs image in memory (ram, rom, flash). It eliminates the unnecessary step of passing data through an intermediate buffer, as compared to accessing the same image through a memory block device like mtdblock.
  • They allow optional cramfs linear root support. This eliminates the requirement of having to provide a block device to use a linear cramfs image as the root filesystem.
  • They provide optional XIP. It extends mkcramfs to store files marked "+t" uncompressed and page-aligned. Linux can then mmap those files and execute them in-place without copying them entirely to ram first.

Note: the current implementation can only be used together with a XIP kernel, which provides the appropriate XIP memory (FLASH) mapping.

To configure a root file system on linear cramfs with XIP select:

  $ cd <xip-linux-root>
  $ make menuconfig
  ...
    File systems  --->"
    ...
    <*> Compressed ROM file system support
    [*]   Use linear addressing for cramfs
    (40400000) Physical address of linear cramfs
    [*]     Support XIP on linear cramfs
    [*]     Root file system on linear cramfs

This defines a cramfs filesystem located at the physical address 0x40400000 in FLASH memory.

After building the kernel image "pImage" as usual, you will want to build a filesystem using the mkcramfs executable (it's located in /scripts/cramfs). If you do not already have a reasonable sized disk directory tree you will need to make one. The ramdisk directory of SELF (the Simple Embedded Linux Framework from DENX at ftp.denx.de) is a good starting point. Before you build your cramfs image you must mark the binary files to be executed in place later on with the "t" permission:

  $ mkcramfs -r ramdisk cramfs.img

and copy it to the defined place in FLASH memory.

You can then boot the XIP kernel with the cramfs root filesystem using the boot argument:

  $ setenv bootargs root=/dev/cramfs ...

Be aware that cramfs is a read-only filesystem.

 

14.3.24.3. Hints and Notes

 

  • XIP conserves RAM at the expense of flash. This might be useful if you have a big flash memory and little RAM.
  • Flash memory used for XIP must be readable all the time e.g. this excludes installation and usage the character device or MTD flash drivers, because they do device probing, sector erase etc.
  • The XIP extension is currently only available for PowerPC 8xx but can easily be extended to other architectures.
  • Currently only up to 8 MB of ROM/Flash are supported.
  • The original work was done for the amanda system.
  • Special thanks goes to David Petersen for collecting the availible XIP extension sources and highlighting how to put all the pieces together.

 

14.3.24.4. Space requirements and RAM saving, an example

For ppc 8xx, all figures are in bytes:

 

  • Normal kernel + linear cramfs (patched):
        pImage:  538062
        cramfs: 1081344
      
                total:    used:    free:  shared: buffers:  cached:
        Mem:  14921728  3866624 11055104  2781184        0  2240512
    

 

  • XIP kernel + linear cramfs:
        pImage: 1395952
        cramfs: 1081344
      
                total:    used:    free:  shared: buffers:  cached:
        Mem:  16175104  3940352 12234752  2822144        0  2240512
    

 

  • XIP kernel + XIP cramfs (chmod +t: busybox, initd, libc):
        pImage: 1395952
        cramfs: 1871872
      
                total:    used:    free:  shared: buffers:  cached:
        Mem:  16175104  2367488 13807616   610304        0   671744
    

The actual RAM saving is here approximately 1.1MB + 1.5M = 2.6 MB.

Have fun with XIP.

Wolfgang Grandegger (wg@denx.de)

14.3.25. Use SCC UART with Hardware Handshake

 

Question:
I am using a SCC port of a MPC8xx / MPC82xx as UART; for the Linux UART driver I have configured support for hardware handshake. Then I used a null-modem cable to connect the port to the serial port of my PC. But this does not work. What am I doing wrong?

 

Answer:
There is absolutely no way to connect a MPC8xx / MPC82xx SCC port to any DTE and use RS-232 standard hardware flow control.

 

Explanation:
The serial interface of the SCC ports in MPC8xx / MPC82xx processors is designed as a DTE circuitry and the RS-232 standard hardware flow control can not be used in the DTE to DTE connection with the null-modem cable (with crossed RTS/CTS signals).

 

The RS-232 standard specifies a DTE to DCE connection and its hardware handshaking is designed for this specific task. The hardware flow control signals in the PC (and similar equipment) are implemented as software readable/writable bits in a control register and therefore may be arbitrary treated. Unlike that, in the 8xx/82xx the handshake protocol is handled by the CPM microcode. The meaning of the signals is fixed for the RS-232 standard with no way for user to change it.

 

In widely spread DTE-to-DTE connections over the so called 'null-modem' cable with the hardware flow control lines the meaning of the handshake signals is changed with respect to the RS-232 standard. Therefore this approach may not be used with the 8xx/82xx.

 

Question:
I succeeded in activating hardware handshake on the transmit side of the SCC using the CTS signal. However I have problems in the receive direction.

 

Answer:
This is caused by the semantics of the RTS signal as implemented on the SCC controllers: the CPM will assert this signal when it wants to send out data. This means you cannot use RTS to enable the transmitter on the other side, because it will be enabled only when the SCC is sending data itself.

 

Conclusions:
If you want to use 8xx/82xx based equipment in combination with RS-232 hardware control protocol, you must have a DCE device (modem, plotter, printer, etc) on the other end.

 

Hardware flow control on a SCC works only in transmit direction; when receiving data the driver has to be fast enough to prevent data overrun conditions (normally this is no problem though).

14.3.26. How can I access U-Boot environment variables in Linux?

 

Question:
I would like to access U-Boot's environment variables from my Linux application. Is this possible?

 

Answer:
Yes, you can. The environment variables must be stored in flash memory, and your Linux kernel must support flash access through the MTD layer. In the U-Boot source tree you can find the environment tools in the directory tools/env, which can be built with command:

 

make env

For building against older versions of the MTD headers (meaning before v2.6.8-rc1) it is required to pass the argument "MTD_VERSION=old" to make:

 

make MTD_VERSION=old env

The resulting binary is called fw_printenv, but actually includes support for setting environment variables too. To achieve this, the binary behaves according to the name it is invoked as, so you will have to create a link called fw_setenv to fw_printenv.

These tools work exactly like the U-Boot commands printenv resp. setenv You can either build these tools with a fixed configuration selected at compile time, or you can configure the tools using the /etc/fw_env.config configuration file in your target root filesystem. Here is an example configuration file:

 

# Configuration file for fw_(printenv/saveenv) utility.
# Up to two entries are valid, in this case the redundand
# environment sector is assumed present.

#########################################################################
# For TQM8xxL modules:
#########################################################################
# MTD device name       Device offset   Env. size       Flash sector size
/dev/mtd0            0x8000          0x4000          0x4000
/dev/mtd0            0xC000          0x4000          0x4000

#########################################################################
# For NSCU:
#########################################################################
# MTD device name       Device offset   Env. size       Flash sector size
#/dev/mtd1              0x0000          0x8000          0x20000
#/dev/mtd2              0x0000          0x8000          0x20000


#########################################################################
# For LWMON
#########################################################################
# MTD device name       Device offset   Env. size       Flash sector size
#/dev/mtd1               0x0000          0x2000          0x40000

14.3.27. The appWeb server hangs OR /dev/random hangs

 

Question:
I try to run the appWeb server, but it hangs, because read accesses to /dev/random hang forever. What's wrong?

 

Answer:
Your configuration of the Linux kernel does not contain drivers that feed enough entropy for /dev/random. Often mouse or keyboard drivers are used for this purpose, so on an embedded system without such devices /dev/random may not provide enough random numbers for your application.

 

Workaround:
As a quick workaround you can use /dev/urandom instead; i. e. try the following commands on your system:
   # cd /dev
   # rm -f random
   # ln -s urandom random

 

Solution:
The correct solution for the problem is of course to feed sufficient entropy into /dev/random. To do so you can modify one or more appropriate device drivers on your system; for example if you know that there is sufficient traffic on network or on a serial port than adding SA_SAMPLE_RANDOM to the 3rd argument when calling the request_irq() function in your ethernet and/or serial driver(s) will cause the inter-interrupt times to be used to build up entropy for /dev/random.

14.3.28. Swapping over NFS

In case that the available memory is not sufficient, i.e. for compiling the X.org server, and no hard-drive can be attached to the system it is possible to swap over NFS, although it is not quite straightforward.

Usually one would create a blank file, mkswap it and simply do a swapon swapfile. Doing this on a filesystem mounted over NFS, i.e. the ELDK root filesystem, fails however.

With one level of indirection we can trick the kernel into doing it anyway. First we create a filesystem image (ext2 will do) on the NFS filesystem and mount it with the aid of the loopback device. Then we create a blank swapfile inside of this filesystem and turn on swapping:

 

bash-2.05b# mount
/dev/nfs on / type nfs (rw)
none on /proc type proc (rw)
bash-2.05b# cd /tmp
bash-2.05b# dd if=/dev/zero of=ext2.img bs=1M count=66
66+0 records in
66+0 records out
bash-2.05b# mkfs.ext2 ext2.img
mke2fs 1.27 (8-Mar-2002)
ext2.img is not a block special device.
Proceed anyway? (y,n) y
Filesystem label=
OS type: Linux
Block size=1024 (log=0)
Fragment size=1024 (log=0)
16920 inodes, 67584 blocks
3379 blocks (5.00%) reserved for the super user
First data block=1
9 block groups
8192 blocks per group, 8192 fragments per group
1880 inodes per group
Superblock backups stored on blocks:
        8193, 24577, 40961, 57345

Writing inode tables: done
Writing superblocks and filesystem accounting information: done

This filesystem will be automatically checked every 26 mounts or
180 days, whichever comes first.  Use tune2fs -c or -i to override.
bash-2.05b# for i in `seq 0 9` ; do mknod /dev/loop$i b 7 $i ; done
bash-2.05b# mkdir /mnt2
bash-2.05b# mount -o loop ext2.img /mnt2
bash-2.05b# cd /mnt2
bash-2.05b# dd if=/dev/zero of=swapfile bs=1M count=62
62+0 records in
62+0 records out
bash-2.05b# mkswap swapfile
Setting up swapspace version 1, size = 65007 kB
bash-2.05b# free
             total       used       free     shared    buffers     cached
Mem:         14556      14260        296          0        772       9116
-/+ buffers/cache:       4372      10184
Swap:            0          0          0
bash-2.05b# swapon swapfile
bash-2.05b# free
             total       used       free     shared    buffers     cached
Mem:         14556      14172        384          0        784       9020
-/+ buffers/cache:       4368      10188
Swap:        63480          0      63480
bash-2.05b# 

Because the ELDK right now has no device nodes for the loopback driver we create them along the way. It goes without saying that the loop driver has to be included in the kernel configuration. You can check this by looking for a driver for major number 7 (block devices) in /proc/devices.

14.4. Self

14.4.1. How to Add Files to a SELF Ramdisk

It is not always necessary to rebuild a SELF based ramdisk image if you want to modify or to extend it. Especially during development it is often eaiser to unpack it, modify it, and re-pack it again. To do so, you have to understand the internal structure of the uRamdisk (resp. pRamdisk) images files as used with the U-Boot (old: PPCBoot) boot loader:

The uRamdisk image contains two parts:

 

  • a 64 byte U-Boot header
  • a (usually gzip compressed) ramdisk image

To modify the contents you have to extract, uncompress and mount the ramdisk image. This can be done as follows:

 

  1. Extract compressed ramdisk image (ramdisk.gz)
    bash$ dd if=uRamdisk bs=64 skip=1 of=ramdisk.gz
    21876+1 records in
    21876+1 records out
    
  2. Uncompress ramdisk image (if it was a compressed one)
    bash$ gunzip -v ramdisk.gz
    ramdisk.gz:      66.6% -- replaced with ramdisk
    
  3. Mount ramdisk image
    bash# mount -o loop ramdisk /mnt/tmp
    

Now you can add, remove, or modify files in the /mnt/tmp directory. If you are done, you can re-pack the ramdisk into a U-Boot image:

 

  1. Unmount ramdisk image:
    bash# umount /mnt/tmp
    
  2. Compress ramdisk image
    bash$ gzip -v9 ramdisk
    ramdisk:         66.6% -- replaced with ramdisk.gz
    
  3. Create new U-Boot image (new-uRamdisk)
    bash$ mkimage -T ramdisk -C gzip -n 'Simple Embedded Linux Framework' \
    > -d ramdisk.gz new-uRamdisk
    Image Name:   Simple Embedded Linux Framework
    Created:      Sun May  4 13:23:48 2003
    Image Type:   PowerPC Linux RAMDisk Image (gzip compressed)
    Data Size:    1400121 Bytes = 1367.31 kB = 1.34 MB
    Load Address: 0x00000000
    Entry Point:  0x00000000
    

Instead of re-packing into a U-boot ramdisk image you can of course also just extract the contents of the SELF image and re-use it as base of a (known to be working) root filesystem.

 

  • For example, you can create a JFFS2 filesystem using the mkfs.jffs2 command that comes with the MTD Tools:
    bash# mkfs.jffs2 -r /mnt/tmp -e 0x10000 -o image.jffs2 -b
    

 

 

  • Or you can create a CramFS filesystem with mkcramfs:
    bash# mkcramfs -r /mnt/tmp image.cramfs
    Swapping filesystem endian-ness
    ...
    Everything: 1656 kilobytes
    Super block: 76 bytes
    CRC: 7f34cae4
    

14.4.2. How to Increase the Size of the Ramdisk

 

  1. Extract compressed ramdisk image (ramdisk.gz) from U-Boot image:
    bash$ dd if=uRamdisk bs=64 skip=1 of=ramdisk.gz
    21876+1 records in
    21876+1 records out
    
  2. Uncompress ramdisk image
    bash$ gunzip -v ramdisk.gz
    ramdisk.gz:      66.6% -- replaced with ramdisk
    
  3. Mount ramdisk image
    As root:
    bash# mkdir -p /mnt/tmp
    bash# mount -o loop ramdisk /mnt/tmp
    
  4. Create new ramdisk image, say 8 MB big:
    bash$ dd if=/dev/zero of=new_ramdisk bs=1024k count=8
    bash$ /sbin/mke2fs -F -m0 new_ramdisk
    bash$ /sbin/tune2fs -c 0 -i 0 new_ramdisk
    
    As root:
    bash# mkdir -p /mnt/new
    bash# mount -o loop new_ramdisk /mnt/new
    
  5. Copy files from old ramdisk to new ramdisk:
    As root:
    bash# cd /mnt/tmp
    bash# find . -depth -print | cpio -VBpdum /mnt/new
    
    Now you can add, remove, or modify files in the /mnt/new directory. If you are done, you can re-pack the ramdisk into a U-Boot image:
  6. Unmount ramdisk images:
    As root:
    bash# umount /mnt/tmp
    bash# umount /mnt/new
    
  7. Compress new ramdisk image
    bash$ gzip -v9 new_ramdisk
    ramdisk:         66.6% -- replaced with new_ramdisk.gz
    
  8. Create new U-Boot image (new-uRamdisk)
    bash$ mkimage -T ramdisk -C gzip -n 'New Simple Embedded Linux Framework' \
    > -d new_ramdisk.gz new_uRamdisk
    Image Name:   Simple Embedded Linux Framework
    Created:      Sun May  4 13:23:48 2003
    Image Type:   PowerPC Linux RAMDisk Image (gzip compressed)
    Data Size:    1400121 Bytes = 1367.31 kB = 1.34 MB
    Load Address: 0x00000000
    Entry Point:  0x00000000
    

TIP Remember that Linux by default supports only ramdisks up to a size of 4 MB. For bigger ramdisks, you have to either modify your LInux kernel configuration (parameter CONFIG_BLK_DEV_RAM_SIZE in the "Block devices" menue), or pass a "ramdisk_size=" boot argument to the Linux kernel.

14.5. RTAI

14.5.1. Conflicts with asm clobber list

 

Question:
When I try to compile my LInux kernel after applying the RTAI patch, I get a strange "asm-specifier for variable `__sc_3' conflicts with asm clobber list" error message. What does that mean?
Answer:
You are using an old version of the Linux kernel / RTAI patch in combination with a more recent version of the cross compiler. Please use a recent kernel tree (and the corresponding RTAI patch), or apply the attached patch to fix this problem.
See: http://h623653.serverkompetenz.net/wiki/pub/DULG/ConflictsWithAsmClobberList/patch

14.6. BDI2000

14.6.1. Where can I find BDI2000 Configuration Files?

A collection of configuration files for the BDI2000 BDM/JTAG debugger by Abatron can be found at ftp://ftp.denx.de/pub/BDI2000/

14.6.2. How to Debug Linux Exceptions

Question:
I am trying to single step into a Linux exception handler. This does not seem to work. Setting a breakpoint does not work either.
Answer:
The problem is bit complex on a MPC8xx target. Debug mode entry is like an exception and therefore only safe at locations in the code where an exception does not lead to an unrecoverable state. Another exception can only be accepted if SRR0 and SRR1 are saved. The MSR[RI] should indicate if currently an exception is safe. MSR[RI] is cleared automatically at exception entry.
The MPC8xx hardware breakpoints do only trigger if MSR[RI] is set in order to prevent non-recoverable state. The problem is that the Linux exception handler does not take all this into account. First priority has speed, therefore neither SRR0 nor SRR1 are saved immediately. Only after EXCEPTION_PROLOG this registers are saved. Also Linux does not handle the MSR[RI] bit. 
Hint: Use STEPMODE HWBP when debugging Linux. This allows the TLB Miss Exception handler to update the TLB while you are single stepping.
Conclusion:
You cannot debug Linux exception entry and exit code. Because of speed, DataStoreTLBMiss does not even make use of EXCEPTION_PROLOG, and SRR0/SRR1 are never saved. Therefore you cannot debug DataStoreTLBMiss unless you change it's code (save SRR0/SRR1, set MSR[RI].

14.6.3. How to single step through "RFI" instruction

Question:
I am trying to debug Linux on an IBM 405GP processor. Linux boots fine and I can step through the code until the "rfi" instruction in head_4xx.S; then I get the following:
- TARGET: target has entered debug mode
    Target state      : debug mode
    Debug entry cause : JTAG stop request
    Current PC        : 0x00000700
    Current CR        : 0x28004088
    Current MSR       : 0x00000000
    Current LR        : 0x000007a8
# Step timeout detected
Answer:
Your single step problem most likely comes from the fact that GDB accesses some non-existent memory (at least some versions do/did in the past). This exception is stored in some way within the 405 and when you step "rfi" it triggers. This is because some instructions like "rfi" are always stepped using a hardware breakpoint and not with the JTAG single step feature. Probably you can step over the "rfi" instruction when using the BDI2000's telnet command interface instead of GDB.
 
Similar problems have also been reported when stepping through "mtmsr" or "mfmsr" during initial boot code. The problem comes also from the fact that GDB accesses non-existent memory (maybe it tries to read a non-existent stack frame).

To debug the Linux kernel, I recommend that you run to a point where the MMU is on before you connect with GDB. To debug boot code where the MMU is off I recommend to use the MMAP feature of the BDI to prevent illegal memory accesses from GDB.

14.6.4. Setting a breakpoint doesn't work

 

Question:
I am trying to set a breakpoint using the BDI2000 telnet interface. However, the code does not stop at the breakpoint.
Answer:
Make sure that the CPU has been stopped before setting the breakpoint. You can verify this by issuing the "info" command before setting the breakpoint. If the target state is "running" you must use the "halt" command to stop the CPU before you can successfully set the breakpoint.

14.7. Motorola LITE5200 Board

14.7.1. LITE5200 Installation Howto

A nice "Application Note: Installing Embedded Linux on the Motorola MPC5200 Lite Evaluation Board" which covers the installation of U-Boot and Linux can be found at:

http://emsys.denayer.wenk.be/emcam/Linux_on_MPC5200_(UK).pdf

14.7.2. USB does not work on Lite5200 board

Question:
USB does not work on my Lite5200 board. Also, the green LED behind the USB connector remains always off. Why?
Answer:
This is a hardware problem. The green LED must be on as soon as you power on the Lite5200 board. As a workaround you can short-circuit resistor R164 (bottom side of the board, close to the USB connector). Please note that you will probably lose all warranty and/or may ruin the board. You have been warned.

14.8. TQM Boards

14.8.1. Using a PCMCIA WLAN Card with a TQM8xxL Board

Question:
What is needed to get a PCMCIA WLAN card running on a TQM8xxL system?
Answer:
You need ELDK version 2.0.2 or later; this includes (1) the Linux kernel source with the required extensions, the PCMCIA Card Service package with extensions for MPC8xx systems, and the wireless tools package to control the PCMCIA devices.
 
To bring up the WLAN card for network operations, the following actions should be performed (the example output shows card configuration for a WLAN network controlled by the Access Point ("managed" mode):
  1. Starting CardServices on the target:
    bash# /etc/rc.d/init.d/pcmcia start
    
  2. Assign the IP address of the WLAN network segment to the WLAN interface:
    bash# ifconfig eth1 192.168.2.3
    
  3. Assign the Network (or Domain) Name to the WLAN interface:
    bash# iwconfig eth1 essid "DENX"
    
  4. At this point the Acess Point station MAC address should appear on the iwconfig output:
    bash# iwconfig eth1
    eth1      IEEE 802.11-DS  ESSID:"DENX"  Nickname:"Prism  I"
              Mode:Managed  Frequency:2.462GHz  Access Point: 00:02:2D:03:A5:15
              Bit Rate:2Mb/s   Tx-Power=15 dBm   Sensitivity:1/3
              Retry min limit:8   RTS thr:off   Fragment thr:off
              Encryption key:off
              Power Management:off
              Link Quality:28/92  Signal level:151/153  Noise level:107/153
              Rx invalid nwid:0  invalid crypt:0  invalid misc:0
The card is now ready for normal network operations.

14.8.2. Ethernet Problems on TQM8xxL boards

Question:
I am using a TQM8xxL module on a STK8xxL Starter Kit board. Everything is fine, but Ethernet does not work - neither in U-Boot nor in Linux.
Answer:
The TQM855L/M, TQM860L/M and TQM862L/M modules use SCC1 for the Ethernet interface. Make sure that jumpers are set on connectors labeled X.12, X.13 and X.14 on the STK8xxL board on the positions 1-3 and 2-4; also make sure to remove the jumpers from positions 7-8, 9-10 and 11-12 on X.30. For the TQM823L and TQM850L modules SCC2 is used for Ethernet. Here jumpers must be set on connectors X.12, X.13 and X.14 on the positions 3-5 and 4-6; X.30 is used for USB configuration on these boards - if you don't use USB it's safe to remove the jumpers from positions 7-8, 9-10 and 11-12 on X.30.

15. Glossary

ABI

- Application Binary Interface

The convention for register usage and C linkage commonly used on desktop PowerPC machines. Similar, but not identical to the EABI.

Includes binding specific ppc registers to certain fixed purposes, even though there may be no technical reason to enforce such binding, simplifying the process of linking together two separate sets of object code. e.g the ABI states that r1 shall be the stack pointer.

BANK

- also "memory bank"

A bank of memory (flash or RAM) consists of all those memory chips on your system that are controlled by the same chip select signal.

For example, a system might consist of one flash chip with a 8 bit bus interface, which is attached to the CS0 chip select signal, 2 flash chips with a 16 bit bus interface, which are attached to the CS1 chip select signal, and 2 SDRAM chips with a 16 bit bus interface, which are attached to the CS2 chip select signal.

This setup results in a system with 3 banks of memory:

  • 1 bank of flash, 8 bit wide (CS0)
  • 1 bank of flash, 32 bit wide (CS1)
  • 1 bank of SDRAM, 32 bit wide (CS2)

BDM

- Background Debug Mode

An on-chip debug interface supported by a special hardware port on some processors. It allows to take full control over the CPU with minimal external hardware, in many cases eliminationg the need for expensive tools like In-Circuit-Emulators.

BOOTP

- Boot Protocol

A network protocol which can be used to inquire a server about information for the intended system configuration (like IP address, host name, netmask, name server, routing, name of a boot image, address of NFS server, etc.

CFI

- Common Flash Interface

CFI is a standard for flash chips that allows to create device independend drivers for such chips.

CPM

- Communications Processor Module

The magic communications co-processor in Motorola PowerQUICC devices. It contains SCCs and SMCs, and performs SDMA and IDMA.

CPU

- Central Processor Unit

Depending on the context, this may refer to the PowerPC core itself, or the physical processor device (including CPM, SIU, packaging etc) as a single unit.

CramFs

- Compressed ROM File System

Cramfs is designed to be a simple, small, and compressed file system for ROM based embedded systems. CramFs is read-only, limited to 256MB file systems (with 16MB files), and doesn't support 16/32 bits uid/gid, hard links and timestamps.

CVS

- Concurrent Versions System

CVS is a version control system; it can be used to record the history of files, so that it is for instance possible to retrieve specific versions of a source tree.

DHCP

- Dynamic Host Configuration Protocol

A network protocol which can be used to inquire a server about information for the intended system configuration (like IP address, host name, netmask, name server, routing, name of a boot image, address of NFS server, etc.). Sucessor of BOOTP

DMA

- Direct Memory Access

A form a data transfer directly between memory and a peripheral or between memory and memory, without normal program intervention.

EABI

- Embedded Application Binary Interface

The convention for register usage and C linkage commonly used on embedded PowerPC machines, derived from the ABI.

ELDK

- Embedded Linux Development Kit

A package which contains everything you need to get startet with an Embedded Linux project on your hardware:

  • cross development tools (like compiler, assembler, linker etc.) that are running on a Host system while generating code for a Target system
  • native tools and libraries that can be use to build a system running on the target; they can also be exported on a NFS server and used as root filesystem for the target
  • source code and binary images for PPCBoot and Linux
  • Our SELF package as example configuration for an embedded system.

FEC

- Fast Ethernet Controller

The 100 Mbps (100Base) Ethernet controller, present on 'T' devices such as the 860T and 855T.

FTP

- File Transfer Protocol

A protocol that can be used to transfer files over a network.

GPL

/ LGPL - GNU General Public License/Lesser General Public License

The full license text can be found at http://www.gnu.org/copyleft/gpl.html.

The licenses under which the Linux kernel and much of the utility and library code necessary to build a complete system may be copied, distributed and modified. Each portion of the software is copyright by its respected copyright holder, and you must comply with the terms of the license in order to legally copy (and hence use) it. One significant requirement is that you freely redistribute any modifications you make; if you can't cope with this, embedded Linux isn't for you.

Host

The computer system which is used for software development. For instance it is used to run the tools of the ELDK to build software packages.

IDMA

- Independent DMA

A general purpose DMA engine with relatively limited throughput provided by the microcoded CPM, for use with external peripherals or memory-to-memory transfers.

JFFS

- Journalling Flash File System

JFFS (developed by Axis Communicartion AB, Sweden) is a log-based filesystem on top of the MTD layer; it promises to keep your filesystem and data in a consistent state even in cases of sudden power-down or system crashes. That's why it is especially useful for embedded devices where a regular shutdown procedure cannot always be guaranteed.

JFFS2

- Second version of the Journalling Flash File System

Like JFFS this is a journalling flash filesystem that is based on the MTD layer; it fixes some design problems of JFFS and adds transparent compression.

JTAG

- Joint Test Action Group

A standard (see "IEEE Standard 1149.1") that defines how to control the pins of JTAG compliant devices.

Here: An on-chip debug interface supported by a special hardware port on some processors. It allows to take full control over the CPU with minimal external hardware, in many cases eliminationg the need for expensive tools like In-Circuit-Emulators.

MII

- Media Independent Interface

The IEEE Ethernet standard control interface used to communicate between the Ethernet controller (MAC) and the external PHY.

MMU

- Memory Management Unit

CPU component which maps kernel- and user-space virtual addresses to physical addresses, and is an integral part of Linux kernel operation.

MTD

- Memory Technology Devices

The MTD functions in Linux support memory devices like flash or Disk-On-Chip in a device-independend way so that the higher software layers (like filesystem code) need no knowledge about the actual hardware properties.

PC

Card

PC Cards are self-contained extension cards especially for laptops and other types of portable computers. In just about the size of a credit card they provide functions like LAN cards (including wireless LAN), modems, ISDN cards, or hard disk drives - often "solid-state" disks based on flash chips.

The PC Card technology has been has been developed and standardized by the Personal Computer Memory Card International Association (PCMCIA), see http://www.pcmcia.org/pccard.htm .

PCMCIA

- Personal Computer Memory Card International Association

PCMCIA is an abbreviation that can stand for several things: the association which defines the standard, the specification itself, or the devices. The official term for the devices is PC-Card.

PHY

- Physical Interface

The physical layer transceiver which implements the IEEE Ethernet standard interface between the ethernet wires (twisted pair, 50 ohm coax, etc.) and the ethernet controller (MAC). PHYs are often external transceivers but may be integrated in the MAC chip or in the CPU.

The PHY is controlled more or less transparently to software via the MII.

RTOS

- Real-Time Operating System

SCC

- Serial Communications Controller

The high performance module(s) within the CPM which implement the lowest layer of various serial protocols, such as Asynchronous serial (UART), 10 Mbps Ethernet, HDLC etc.

SDMA

- Serial DMA

DMA used to transfer data to and from the SCCs.

SELF

- Simple Embedded Linux Framework

A simple default configuration for Embedded Linux systems that is suitable as starting point for building your own systems. It is based on BusyBox to provide an init process, shell, and many common tools (from cat and ls to vi), plus some other tools to provide network connectivity, allowing to access the system over the internet using telnet and FTP services.

SIU

- System Interface Unit

Provides much of the external interfacing logic. It's the other major module on Motorola PowerQUICC devices alongside the CPU core and CPM.

SMC

- Serial Management Controller

A lower performance version of the SCCs with more limited functionality, particularly useful for serial debug ports and low throughput serial protocols.

SPI

- Serial Peripheral Interface

A relatively simple synchronous serial interface for connecting low speed external devices using minimal wires.

S-Record

- Motorola S-Record Format

Motorola S-records are an industry-standard format for transmitting binary files to target systems and PROM programmers.

See also: http://pmon.groupbsd.org/Info/srec.htm

Target

The computer system which will be used later in you application environment, for instance an Embedded System. In many cases it has a different architecture and much more limited resoucres than a typical Host system, so it is often not possible to develop the software directly (native) on this system.

TFTP

- Trivial File Transfer Protocol

A simple network protocol for file transfer; used in combination with BOOTP or DHCP to load boot images etc. over the network.

UART

- Universal Asynchronous Receiver Transmitter

Generically, this refers to any device capable of implementing a variety of asynchronous serial protocols, such as RS-232, HDLC and SDLC. In this context, it refers to the operating mode of the SCCs which provides this functionality.

UPM

- User Programmable Machine

A highly flexible bus interfacing machine unit allowing external peripherals with an extremely wide variety of interfacing requirements to be connected directly to the CPU.

YellowDog

More information about the YellowDog GNU/Linux distribution for PowerPC systems can be found at http://www.yellowdoglinux.com.

arrow
arrow
    全站熱搜

    BB 發表在 痞客邦 留言(0) 人氣()