Frequently Asked Questions
rev 1.5
| Q: How large should a FLASH/ROM part be? | ||||||||||||
|
A: Normally, we recommend a minimum size of 4MByte. About 0.8Kbyte to 1.2MByte of flash storage is required for the kernel and bootloader (depending upon the size of the kernel and the FLASH memory losses do to the alignment of erase blocks). The rest of the flash is used to hold a file system. However, using some compression technologies a 2MByte flash part can also be used successfully if:
|
||||||||||||
| Q: What are the BSP limitations compared with desktop Linux? | ||||||||||||
|
A: The embedded device has significantly less hardware, thus limiting what is possible compared to a desktop computer. The other big difference is the BSP comes with uClinux (instead of Linux) and uClibc (instead of glibc). The set of applications is much smaller as well. The main difference between uClinux used in the BSP and desktop Linux is uClinux is designed to work with processors that do not have memory management unit (MMU) support. This hardware limitation means one process can write to memory "owned" by another process, or even owned by the Linux kernel. There is no processor hardware to memory access violations. No MMU support also means other features, like fork() are not supported (but vfork() is supported). uClibc supports a subset of the functionality supported by glibc. The differences can be found on the uClibc website. |
||||||||||||
| Q: At what address does the rrload bootloader store downloaded data? | ||||||||||||
|
A: The rrload bootloader stores the downloaded data, either bootloader, kernel or file system data, at the address specified in the file being downloaded. Normally the rrbin format is used since it the most compact format. The rrbin format consists of 3 ASCII text lines followed by the contents of the data being downloaded in binary format. The 3 ASCII text lines provide information to rrload about where to store the downloaded data, the size of the downloaded data, and the starting execution address if the downloaded data is an ARM7 executable file. Given an rrbin file, say linux.rr, you can see the 3 ASCII lines using the following command: $ head -3 linux.rr>LoadAddr :0x02A00000 >EntryAddr:0x02A0B000 >NumBytes :0x000DFF58 The value of the LoadAddr indicates where in memory the downloaded will be stored. This value overrides the destination you specify when using the rrload copy command in command line mode. |
||||||||||||
| Q: What block drivers do each of the file systems require? | ||||||||||||
|
A: The following table lists which block driver is required for a file system.
|
||||||||||||
| Q: Why won't my file compile with xflat-gcc? | ||||||||||||
|
A: What you are seeing may be normal (if somewhat less than desirable) behavior of xflat-gcc. This is usually the consequence of attempting to access global variables that are normally exported from shared libraries. The technical approach to MMU-less shared library support used by the XFLAT shared libraries without an MMU has some limitations that shared library support with an MMU does not. In particular, you cannot access global variables across shared library boundaries. This is not so much a consequence of the shared library implementation as it is a consequence of the GOT-less implementation that is the standard for embedded ARM binaries: The absence of a GOT and the limitations of the FLAT/XFLAT binary formats do not support the indirection that you would need to relocate the data references. Consider the following trivial code example:
extern char *optarg; This will not compile under xflat-gcc even though the code usage is consistent with the getopt() man page. In order to explain why this will not compile, we'll have to dig a little deeper "under the hood:" The global variable optarg is defined in the libc shared library. So you will never be able to able to access it directly from your code using extern char * optarg; given the limitations on the access of global variables. But why does this cause a compilation error? The Cadenux tool change retains the header files that you use under a directory path something like: /opt/Cadenux/[processor]/[kernel]/crossdev/arm-uclinux/include. If you look at unistd.h in that include directory, you will see that it includes getopt.h (at least under the version of uClibc current used in the toolchain). And if you look at getopt.h in that same directory, you will see that it already contains extern char *optarg;. So what is happening? xflat-gcc is described here. Note that xflat-gcc is not really a compiler; it is a wrapper around the real compiler, arm-uclinux-gcc. The main thing that xflat-gcc does is to redirect the source of all of the compiler's include files. When you "#include <unistd.h>," you don't get the header file from the /opt/Cadenux/[processor]/[kernel]/crossdev/arm-uclinux/include directory. Rather, xflac-gcc will take the unistd.h header file from /opt/Cadenux/[processor]/[kernel]/crossdev/arm-uclinux/include/xflat! Similarly, when unistd.h includes getopt.h, that header file will also come from the xflat header file subdirectory. Now, look at this .../xflat/optarg.h. It is tiny, it contains little more than: #include_next <getopt.h> #undef optarg So, when you reference the variable optarg, you don't actually reference the variable, you actually dereference a function that returns a pointer to the variable. Because of this definition, the extern char *optarg; declaration in your C code will not compile. You could #undef optarg before the extern, but then you build would only fail at link time (or worse yet, maybe at run time!). The solution: Just remove the extern char * optarg;; you don't need it. xflat-gcc performs this same trick on numerous other variables exported from libc such as errno, stdout, etc. and it does this without any special knowledge or code changes in the user code. But a few exported variables, like optarg, optind, and environ are more troublesome, primarily because the man page usages suggests that they be explicitly externed. You can see the full list of such variables at ..include/xflat/xflat_accessors.h. Should I be concerned with the performance implications of these data accessors? Read on. |
||||||||||||
| Q: Are there any performance issues caused by the XFLAT data accessors? | ||||||||||||
|
A: As described above and elsewhere, the global variables cannot be shared between your program code and shared libraries. Instead, the xflat-gcc tool inserts data accessor functions to manage access to global variables across such module boundaries: When you reference such a global variable, you don't actually reference the variable, you actually dereference a function that returns a pointer to the variable. Typical dereferencing in this manner should not cause an measurable performance degradation if it is infrequent. However, such dereferencing could be a performance issue if such a variable is referenced at a high duty, say, in a "tight" loop. Then the small amount of processing required to access the variable could become a performance issue. In this case, you might want to save a pointer to the variable reference so that you do not call the accessor function at a high rate. For example, instead of: #include <stdio.h>
Try something like: #include <stdio.h>
Then, the stderr accessor function is called only once and outside of the "tight" loop. Using such accessor functions has been a common practice with uClibc (stdout, stderr, etc. were already really function calls). XFLAT just required that this practice be extended. |
||||||||||||
| Q: How do I create my own XFLAT data accessor? | ||||||||||||
|
A: Suppose your shared library exports a global variable something like: foo_t foo; Where foo_t would be any type and foo could be any name. The you write an accessor function like: foo_t *get_foo(void) { return &foo; } You would build this into your shared library. It is now an exported function that can be called across shared library boundaries. Then, in your program, change code like: foo_t *foo = &foo; to: foo_t *foo = get_foo(); Notice that in every case except for the first, the following macro will do the job with no code changes: /* Instead of extern foo_t foo, use */ |
||||||||||||
| Q: What software do I need to provide to my customers if they request the source code? | ||||||||||||
|
A: The GPL and LGPL licenses state under what conditions the source code must be provided to person receiving a device containing Open Source software licensed using either the GPL or LGPL license. You only need to provide the Open Source software bundle to a person receiving a device containing the Open Source software if the person requests the source code. Refer to the license applicable to the software in question to determine if you need to include the software in the source code bundle. For a device using embedded Linux, the software in the device will be in one of five categories:
The above information is intended to provide an overview. Refer to the appropriate licenses to determine what software needs to be included in the source code bundle for your specific case. | ||||||||||||
| Q: Why doesn't uClinux support fork() and how do I use vfork() in its place? | ||||||||||||
|
A: The fork() system call requires that the system duplicate the data segment if the child process writes to it. This behavior can not be emulated without memory management unit (MMU) support. Use the following steps when converting an application from using fork() to using vfork(). These steps were derived from an email sent by Joe deBlaquiere on Tue, 21 Nov 2000 to the uclinux-dev@uClinux.org list.
|
||||||||||||
| Q: How do I add a SD RAM part or flash part to the BSP configuration tool? | ||||||||||||
|
A: There are three BSP configuration utility files that need to be modified, along with any source code files that will use the newly defined part. The two BSP configuration utility files to be modified are:
|
||||||||||||
| Q: What real-time extensions does your BSP support? | ||||||||||||
|
A: DSPLinux supports real-time extensions derived from the MontaVista real-time extensions. DSPLinux supports a preemptable kernel and a real-time scheduler. Lock-breaking logic is also supported. In addition, kernel instrumentation has been added to monitor interrupt latency and preemption latency. Real-time configuration:
|
||||||||||||
| Q:What causes the rrload error "can not handle out-of-order tftp blocks" when downloading the kernel or filesystem? | ||||||||||||
|
A: If you use rrload TFTP network download and interrupt the download before it completes, then a TFTP process continues to run on the machine hosting the TFTP server (usually your Linux workstation). If you again download using TFTP, then multiple TFTP processes attempt to send the data to your target hardware. The processes use different TFTP packet numbering and rrload detects the incorrect numbering and generates the out-of-order message. An easy way to see if a TFTP process is running is to use the BSP check configuration utility. In the top level development directory, type "make chkconfig". If extra TFTP processes are running, an error message is printed showing the process ID number. You can use "sudo kill -9 <process ID>" to kill the unwanted TFTP processes. |
||||||||||||
| Q:The Cadenux BSPs for the ARM7 chips use uClinux. What applications have been ported to uClinux? | ||||||||||||
|
A: Many Open Source applications have been ported to uClinux. There is a uClinux CVS server which contains the ported source code. You can browse the CVS server here. |
||||||||||||
| Q:What books are avaiable to learn more about the Linux kernel? | ||||||||||||
|
A: For the Linux 2.4 kernel Understanding the Linux Kernel, 2nd EditionBy Daniel P. Bovet, Marco Cesati 2nd Edition December 2002 ISBN: 0-596-00213-0 For the Linux 2.6 kernel: Linux Kernel Development, 2nd EditionBy Robert Love ISBN: 0672327201 Copyright: 2005 For Linux driver development: Linux Device Drivers, 3rd EditionBy Jonathan Corbet, Alessandro Rubini, Greg Kroah-Hartman 3rd Edition February 2005 ISBN: 0-596-00590-3 |
||||||||||||
| Q:What extra packages are necessary for using our BSP's on Fedora Core 4 | ||||||||||||
|
A:
1. Using yum install:
sudo yum install gcc glibc-headers glibc-kernheaders glibc-devel.i386 If you don't have yum configured
here you will find a clear guide to configure it.
2. Disable SELinux so the command mkfs can be used
(necessary for build the BSP's fs image)
You can know if SELinux is active by running sestatus on a terminal. If
it says: SELinux is already disabled, otherwise you can disable it by editing the
file /etc/sysconfig/selinux and set SELINUX=disabled. You will need to reboot
your machine to apply the cahnges. |
||||||||||||
| Q: How do I use VFAT long filenames with UTF characters? | ||||||||||||
|
A:
You need to make sure the kernel has the necessary codepages supported and you need to provide
additional parameters when mounting a VFAT file system.
$ cd # mount -t vfat -o codepage=950 iocharset=utf8 /dev/mmca1 /mnt/mmc |
||||||||||||
| Q: | ||||||||||||
|
A: |
Copyright 2002, 2003, 2004, 2005 Cadenux. All rights reserved.