| Red Hat Docs > Manuals > GNUPro Toolkit Manuals > |
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Use the following tutorials for standard native development with the tools.
Use the following tutorials for use of the tools with your cross-configuration, using processes known as advanced embedded development.
See http://www.redhat.com/docs/manuals/gnupro/ for details about the tools.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
To start, create the following sample source code file and save it as `hello.c'. The following sections will show you how to compile this file to form an executable, and how to run it. This will also help to verify that the tools have been installed correctly.
#include <stdio.h>
int a, c;
static void
foo (int b)
{
c = a + b;
printf ("%d + %d = %d\n", a, b, c);
}
int
main (void)
{
int b;
a = 3;
b = 4;
printf ("Hello, world!\n");
foo (b);
return 0;
}
|
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
To compile the code to run on a stand-alone simulator, use the following command:
TOOLPREFIX-gcc -g hello.c -o hello |
Note that TOOLPREFIX is the name of compiler's target and file format. So for example if that target were an ARM and the file format was ELF then TOOLPREFIX would be "arm-elf" and the command run would be:
arm-elf-gcc -g hello.c -o hello |
The `-g' option generates debugging information and `-o' specifies the name of the executable to be produced. Both of these can be omitted if you wish. Other useful options include `-O' to enable standard optimizations, and `-O2' for extensive optimizations. If no `-O' is specified, GCC will not optimize.
See Using GCC in GNUPro Compiler Tools for more basic compiler information.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
To run the program on the stand-alone simulator, use the following example:
TOOLPREFIX-run hello |
The program generates:
hello world! 3 + 4 = 7 |
The simulator executes the program, and returns when the program exits.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
To start GDB, use the following commands:
TOOLPREFIX-gdb -nw hello |
`-nw' is used to select the command line interface to
GDB (the Insight interface is the default; see Debugging with Insight); the `-nw' option is useful when you wish to
report a problem you have with GDB, since a sequence of
commands is simpler to reproduce. After the initial copyright and
configuration information, GDB returns its own prompt,
(gdb). The following is a sample debugging session using the
target sim command to specify the simulator as the target.
sim
simulator), type:
target sim |
The following output displays:
Connected to the simulator. |
load |
This will produce some output describing the sections of the program as they are loaded into (simulated) memory. eg:
Loading section .init, size 0x10 lma 0x0
Loading section .text, size 0xad6e lma 0x10
Loading section .fini, size 0x8 lma 0xad7e
Loading section .rodata, size 0x372 lma 0xad88
Loading section .data, size 0x3d6 lma 0xb0fc
Loading section .ctors, size 0x4 lma 0xb4d2
Loading section .dtors, size 0x4 lma 0xb4d6
Loading section .eh_frame, size 0x1054 lma 0xff04
Start address 0x10
Transfer rate: 403792 bits in <1 sec.
|
break main |
The following output displays:
Breakpoint 1 at 0x132: file hello.c, line 15. |
Note the exact address and line number may vary, depending upon the target architecture being simulated and the exact layout of the C code in the `hello.c' file.
run |
The following output displays (when the program stops at a breakpoint):
Starting program: hello
Breakpoint 1, main () at hello.c:15
15 a = 3;
|
Again note that the exact line number and instruction displayed will be dependent upon the target architecture and source code layout.
a, type:
print a |
The following output displays:
$1 = 0 |
next:
next |
The following output displays:
16 b = 4; |
print a |
$2 = 3 |
list |
12 int
13 main (void)
14 {
15 int b;
16
17 a = 3;
18 b = 4;
19
20 printf ("Hello, world!\n");
21
22 foo (b);
23
24 return 0;
25 }
|
list foo |
1 #include <stdio.h>
2
3 int a, c;
4
5 static void
6 foo (int b)
7 {
8 c = a + b;
9 printf ("%d + %d = %d\n", a, b, c);
10 }
|
break 8 |
Breakpoint 2 at 0xf4: file hello.c, line 8. |
continue |
Continuing.
Hello, world!
Breakpoint 2, foo (b=4) at hello.c:8
8 c = a + b;
|
step |
The following output displays:
9 printf ("%d + %d = %d\n", a, b, c);
|
print c |
$3 = 7 |
backtrace |
#0 foo (b=4) at hello.c:9
#1 0x15c in main () at hello.c:18
|
quit |
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
The compiler normally turns a text based source file into a binary object file. It is possible however to instruct it to just convert the source code into assembler and stop there. The `-S' option does this. It also possible to instruct the compiler to produce an assembler listing as well as an object file. That can be done as follows:
TOOLPREFIX-gcc -c -O2 -Wa,-al hello.c |
`-c' tells GCC to compile or assemble source files, but not to link them. `-O2' produces more fully optimized code. These are both optional. `-Wa' tells the compiler to pass the comma-separated list of options which follows it on to the assembler. Hence the `-al' option is an assembler option to request an assembler listing.
This example shows a partial excerpt of an assembler listing for a MIPS based target.
38 .align 2 39 .globl main 40 .type main,@function 41 main: 42 004c 9421FFF8 stwu 1,-8(1) 43 0050 7C0802A6 mflr 0 44 0054 9001000C stw 0,12(1) 45 0058 48000001 bl __eabi 46 005c 3D200000 lis 9,a@ha 47 0060 3C600000 lis 3,.LC1@ha 48 0064 38000003 li 0,3 49 0068 38630010 la 3,.LC1@l(3) 50 006c 90090000 stw 0,a@l(9) 51 0070 48000001 bl puts |
For some targets (but not all) it also possible to produce an assembler listing which intermixes the original input source code with the assembler instructions produced by the compiler. This can help track down bugs, discover how the compiler handles certain language constructs (such as function calls) and to learn more about assembly language. To do this, just add an h to the assembler option like this:
TOOLPREFIX-gcc -c -O2 -Wa,-alh hello.c |
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
The objdump tool can be used to to produce an disassembly of an
object or executable file. It is used like this:
TOOLPREFIX-objdump -d hello.o |
You could also use the `-D' option to produce a dissassembly of all of the sections in an object file, not just those that have been marked as containing instructions, and @option {-z} to tell objdump to disassemble instructions whoes value is zero. (Normally such instructions are just skipped).
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
In order to execute C and C++ programs it is necessary to run some special code at the very beginning of execution, before main is called. This code initialises system hardware, sets up any structures needed by the libraries, eg to handle calls to atexit(), and also calls any C++ global constructors.
The file containing this startup code is often called crt0.o.
It is usually written in assembler as crt0.s and then turned
into an object file for linking. The startup code defines a special
start symbol which is the default startup address for your
application.
Although the tools do come with an already assembled crt0.o file, for embedded targets it is often necessary to write your own crt0.s. Especially if the hardware you are using does not match that hardware that the crt0.s was written for. To write your own crt0.s module, you need the following information about your target.
There are some examples available in the sources of GNUPro Toolkit for
crt0.s code (along with examples of system calls with
subroutines); look in the
installdir/src/libgloss/TARGET directory
(installdir refers to your installation directory).
Your crt0.s module must at least do the following in order for
it to be useful:
start symbol. This is often called _start.
Execution begins with it.
Choose where to store your stack within the constraints of your target s
memory map, the simplest choice being a fixed-size area somewhere in the
uninitialized data section (often bss). Whether you choose a low
address or a high address in this area depends on the direction your
stack grows.
bss section to
zero.
Use a linker script (see Linker Scripts,
and, also, see Linker Scripts in Using ld in GNUPro
Development Tools) to define symbols such as bss_start and
bss_end to record the boundaries of this section; then you can
use a for loop to initialize all memory between them in the
crt0.s module.
main. Nothing else will.
A more complete crt0.s module might also do the following:
main returns. The exact behaviour
depends upon your system. There might be functions registered with
atexit to be run. There might be a system monitor that can be
called, or the code could just enter an infinite loop.
crt0.s
module. See The GDB Remote Serial Protocol in
Debugging with GDB in GNUPro Debugging Tools
for details for using the generic remote-target facilities for this
purpose.
MMU or an auxiliary floating-point chip).
crt0.s module is a convenient place to define the minimal
assembly-level routines; see System Calls in GNUPro C Library in
GNUPro Libraries).
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
In the `install-prefix/<host>/<target>/lib/ldscripts/'
directory you can find the default scripts used by the
linker. (install-prefix signifies the top level directory where
the tools are installed. <host> signifies your host
configuration and <target> signifies your target configuration).
In that directory there will be files with the extensions .x,
.xbn, .xn, .xr, .xs, and .xu. The
basic script is the one with the .x extension. The others are
used when certain linker command line options are used. .xr is
used when linking without relocating (`-r'), .xu is used
when when linking without relocating, but when constructors are built
(`-Ur'), .xn is used when page boundaries are not being
used (`-n'), .xbn is used when page boundaries are not
used and the .text section is writable (`-N') and .xs is
used when generating a shared library (`--shared').
The linker script does the following:
Different processors and different operating systems make different areas of memory available to an application. The linker script describes the layout of this memory, so that the linker can choose where to place the application's instructions and data.
The linker script's format and syntax are described in the linker documentation which is normally in the form of an info file @emph (ld.info) in the installed toolchain's filespace. The following is small selections of fragments taken from a fictional linker script. They serve to demonstrate the general flavour of linker scripts.
A memory map is specified using the MEMORY command like this:
MEMORY
{
ram : ORIGIN = 0x10000, LENGTH = 2M
rom (rx): ORIGIN = 0xff0000, LENGTH = 1M
}
|
This map describes a region called ram which is 2 megabytes long starting at address 0x10000 and a region called rom which is only one megabyte long and which starts at address 0xff0000. This second region also has the attributes read-only and execute whereas the ram region does not have any attributes.
Memory region attributes are used when the linker decides where to place input sections which have not been explicitly assigned to a memory region. The linker will attempt to match the attributes of the input section to the attributes of each memory region in turn, going for the best match.
Input sections are mapped to output sections using the SECTIONS
command:
SECTIONS
{
.text :
{
*(.text)
} > rom
.data
{
*(.data)
*(.sdata)
__edata = .;
} > ram
.bss
{
*(.bss)
}
/DISCARD/
{
*(.dwarf*)
}
}
|
This example shows that any section @emph(.text) in any input file will be mapped to a section called @emph(.text) in the output file. The sections will be appended one after another in the order in which they occur on the linker's command line. The resulting combined input sections will be placed in the output file at address that lie within the rom memory section.
Any input section called .data or .sdata will be mapped to an output section called {.data}, which will be placed within the ram memory region. The linker will also create a variable called __edata whoes value will be the address just after the end of the .data section in the output file.
Any input section called .bss will be mapped to a section also called .bss in the output file, and the memory region chosen will depend upon the attributes of the input .bss sections.
Any input section whose name starts with the string .dwarf will be thrown away. Any other input section, not explicitly matched by any of the above rules, will be mapped to sections matching their own names, and placed after all other sections in the output file.
For more information on linking, see Using ld in
GNUPro Development Tools.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
When you use GNUPro tools, you typically use a standard convention for calling each tool with a toolchain name. For cross-compilers, where the code produced by the compiler does not run on the same machine as the compiler, but is instead copied over to a different machine with a different architecture, the convention is to use the host name followed by the target name as a prefix to the tool.
The tables that follow provide the specific host and target names that you require. If you are not already familiar with the names of specific tools, review See Compiler and Development Tools.
| Target | Name |
| ARM |
i686-pc-cygwin-x-arm-elf
|
| MIPS |
i686-pc-cygwin-x-mips-elf
|
| MIPS 64 |
i686-pc-cygwin-x-mips64-elf
|
| MIPS ISA32 |
i686-pc-cygwin-x-mipsisa32-elf
|
| PowerPC |
i686-pc-cygwin-x-powerpc-eabi
|
| Target | Name |
| ARM |
i686-pc-linux-gnulibc2.2-x-arm-elf
|
i686-pc-linux-gnulibc2.3-x-arm-elf
| |
| MIPS |
i686-pc-linux-gnulibc2.2-x-mips-elf
|
i686-pc-linux-gnulibc2.3-x-mips-elf
| |
| MIPS 64 |
i686-pc-linux-gnulibc2.2-x-mips64-elf
|
i686-pc-linux-gnulibc2.3-x-mips64-elf
| |
| MIPS ISA32 |
i686-pc-linux-gnulibc2.2-x-mipsisa32-elf
|
i686-pc-linux-gnulibc2.3-x-mipsisa32-elf
| |
| PowerPC |
i686-pc-linux-gnulibc2.2-x-powerpc-eabi
|
i686-pc-linux-gnulibc2.3-x-powerpc-eabi
|
| Target | Name |
| StrongARM |
sparc-sun-solaris2.6-arm-elf
|
| MIPS |
sparc-sun-solaris2.6-x-mips-elf
|
| MIPS 64 |
sparc-sun-solaris2.6-x-mips64-elf
|
| MIPS ISA32 |
sparc-sun-solaris2.6-x-mipsisa32-elf
|
| PowerPC | sparc-sun-solaris2.6-x-powerpc-eabi |
| [ << ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |