參考來源
http://www.denx.de/wiki/publish/DULG/DULG-tqm8xxl.html
- 14. FAQ - Frequently Asked Questions
- 14.1. ELDK
- 14.2. U-Boot
- 14.2.1. Can UBoot be configured such that it can be started in RAM?
- 14.2.2. Relocation cannot be done when using -mrelocatable
- 14.2.3. U-Boot crashes after relocation to RAM
- 14.2.4. Warning - bad CRC, using default environment
- 14.2.5. Wrong debug symbols after relocation
- 14.2.6. Linux hangs after uncompressing the kernel
- 14.2.7. Erasing Flash Fails
- 14.2.8. Ethernet Does Not Work
- 14.2.9. Where Can I Get a Valid MAC Address from?
- 14.2.10. Why do I get TFTP timeouts?
- 14.2.11. How the Command Line Parsing Works
- 14.2.12. Decoding U-Boot Crash Dumps
- 14.2.13. Porting Problem: cannot move location counter backwards
- 14.2.14. How can I load and uncompress a compressed image
- 14.2.15. My standalone program does not work
- 14.2.16. U-Boot Doesn't Run after Upgrading my Compiler
- 14.3. Linux
- 14.3.1. Linux crashes randomly
- 14.3.2. Linux crashes when uncompressing the kernel
- 14.3.3. Linux Post Mortem Analysis
- 14.3.4. Linux kernel register usage
- 14.3.5. Linux Kernel Ignores my bootargs
- 14.3.6. Cannot configure Root Filesystem over NFS
- 14.3.7. Linux Kernel Panics because "init" process dies
- 14.3.8. Unable to open an initial console
- 14.3.9. Mounting a Filesystem over NFS hangs forever
- 14.3.10. Ethernet does not work in Linux
- 14.3.11. Loopback interface does not work
- 14.3.12. Linux kernel messages are not printed on the console
- 14.3.13. Linux ignores input when using the framebuffer driver
- 14.3.14. BogoMIPS Value too low
- 14.3.15. Linux Kernel crashes when using a ramdisk image
- 14.3.16. Ramdisk Greater than 4 MB Causes Problems
- 14.3.17. Combining a Kernel and a Ramdisk into a Multi-File Image
- 14.3.18. Adding Files to Ramdisk is Non Persistent
- 14.3.19. Kernel Configuration for PCMCIA
- 14.3.20. Configure Linux for PCMCIA Cards using the Card Services package
- 14.3.21. Configure Linux for PCMCIA Cards without the Card Services package
- 14.3.22. Boot-Time Configuration of MTD Partitions
- 14.3.23. Use NTP to synchronize system time against RTC
- 14.3.24. Configure Linux for XIP (Execution In Place)
- 14.3.25. Use SCC UART with Hardware Handshake
- 14.3.26. How can I access U-Boot environment variables in Linux?
- 14.3.27. The =appWeb= server hangs *OR* /dev/random hangs
- 14.3.28. Swapping over NFS
- 14.4. Self
- 14.5. RTAI
- 14.6. BDI2000
- 14.7. Motorola LITE5200 Board
- 14.8. TQM Boards
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
- 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.
- Prerequisites:
- Install
linux_base
The first step is to install the Linux compatibility layer from ports/usr/ports/emulators/linux_base/
or packagesftp://ftp.freebsd.org/pub/FreeBSD/ports/i386/packages/emulators/
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
- Install
bash
Since ELDK and Linux build scripts are organised aroundbash
while FreeBSD does not have it in base, this shell needs to be installed either from ports/usr/ports/shells/bash2/
or packages collectionftp://ftp.freebsd.org/pub/FreeBSD/ports/i386/packages/shells/
The installation puts thebash
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
- Install
- Prepare ELDK
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
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. - Install ELDK normally as described in 3.4.3. Initial Installation
- 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
- 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
- Hints for building Linux:
There are three issues with theMakefile
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 usexargs
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
- GNU
- Prerequisites:
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:
- Boot the target with root file system over NFS.
- 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
- Format the partititons:
bash-3.00# mkswap /dev/sda1 bash-3.00# mke2fs -j -m1 /dev/sda2
- Mount the file system:
bash-3.00# mount /dev/sda2 /mnt
- 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 - )
- 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
- 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
- Unmount disk:
bash-3.00# umount /mnt
- 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
- 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.
- Argument:
- But my board ran fine with bootloader XYZ and/or operating system ABC.
- Answer:
- Double-check your configuration that you claim runs properly...
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."powerpc-linux-gdb"
without arguments, and use theadd-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.
define rom symbol-file file u-boot end define ram symbol-file add-symbol-file u-boot 0x01fe0000 end
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 isUncompressing 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 ofIMAP_ADDR
uses the same value as your U-Boot configuration inCFG_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:
- Bad definition of the
=> 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
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.
- Inconsistent memory map
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, shortfli
) 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-Bootprotect
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.
"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
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 syntaxname=value
); only environment variables can be used with therun
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
andprintenv
. To run a command stored in such a variable, you need to use therun
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
- 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. - If you execute several variables with one call to
run
(i. e. callingrun
with a list of variables as arguments), any failing command will causerun
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. Theu-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 theu-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 thebootm
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 themkimage
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 tomkimage
) after loading it. If you want to prevent automatic execution, just set the environment variable"autostart"
to"no"
("setenv autostart no"
) before runningbootm
.
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 missingvolatile
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.
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:
- 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 is0xC0182F54
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 is0xC02124C4
- Convert to physical address: on PowerPC systems, the kernel is usually configured for a virtual address of kernel base (
CONFIG_KERNEL_START
) of0xC0000000
. Just subtract this value from the address you found. In our case we get:physical address = 0xC0182F54 - 0xC0000000 = 0x00182F54
- Reset your board - do not power-cycle it!
- 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 thatCONFIG_CMDLINE_TAG
is enabled. (Other tags likeCONFIG_SETUP_MEMORY_TAGS
orCONFIG_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 theCONFIG_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 filearch/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 onCONFIG_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/loaderld.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 theinit
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 theELDK_MAKEDEV
andELDK_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:
- Add the portmap deamon (
/sbin/portmap
) to the target filesystem and start it as part of the init scripts. - 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
- Add the portmap deamon (
- 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
)."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 theconsole_loglevel
of the kernel (any message with log level less thanconsole_loglevel
will be printed to the console). With the following command theconsole_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 aconsole=
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 adbnz
instruction. On some processors like the MPC8xx it takes 2 clocks perdbnz
instruction, and you get 1 BogoMIP/MHz. The MPC5200 takes 3 clocks perdbnz
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 argumentramdisk_size=<size-in-kB>
to the Linux kernel to overwrite the configured maximum. Note that this argument needs to be before anyroot
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:
- Dynamical adjustment using boot arguments:
=> 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 theCONFIG_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".)
- Increasing the Linux kernel default value:
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.
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).
- PCMCIA IDE cards (CF and true-IDE)
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:
- 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) - PCMCIA Modem Cards
- PCMCIA Network Cards
- 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.
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)
- linux-2.4.4-2002-03-21-xip.patch.gz: Linux patches for XIP on MPC8xx
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).
- 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.
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 addingSA_SAMPLE_RANDOM
to the 3rd argument when calling therequest_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:
- 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
- Uncompress ramdisk image (if it was a compressed one)
bash$ gunzip -v ramdisk.gz ramdisk.gz: 66.6% -- replaced with ramdisk
- 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:
- Unmount ramdisk image:
bash# umount /mnt/tmp
- Compress ramdisk image
bash$ gzip -v9 ramdisk ramdisk: 66.6% -- replaced with ramdisk.gz
- 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
- 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
- Uncompress ramdisk image
bash$ gunzip -v ramdisk.gz ramdisk.gz: 66.6% -- replaced with ramdisk
- Mount ramdisk image
As root:bash# mkdir -p /mnt/tmp bash# mount -o loop ramdisk /mnt/tmp
- 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
- 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: - Unmount ramdisk images:
As root:bash# umount /mnt/tmp bash# umount /mnt/new
- Compress new ramdisk image
bash$ gzip -v9 new_ramdisk ramdisk: 66.6% -- replaced with new_ramdisk.gz
- 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
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 inhead_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'stelnet
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):
- Starting CardServices on the target:
bash# /etc/rc.d/init.d/pcmcia start
- Assign the IP address of the WLAN network segment to the WLAN interface:
bash# ifconfig eth1 192.168.2.3
- Assign the Network (or Domain) Name to the WLAN interface:
bash# iwconfig eth1 essid "DENX"
- 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
- Starting CardServices on the target:
- 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.
留言列表