Go to the first, previous, next, last section, table of contents.
Using the Developer's Kit in one of the cross-development configurations
usually requires some attention to setting up the target environment.
(A cross-development configuration is used for developing software to
run on a different machine (the target) from the development tools
themselves (which run on the host)---for example, you might use a
SPARCstation to generate and debug code for an AMD 29K-based
board.)
To allow our tools to work with your target environment (except for
real-time operating systems, which provide full operating system
support), you need to set up:
-
the C run-time environment (described below).
-
stubs, or minimal versions of operating system subroutines for the
C subroutine library. See section `System Calls' in The Cygnus C Support Library.
-
a connection to the debugger. See section `Remote Debugging' in Debugging with GDB.
The C Run-Time Environment (crt0
)
To link and run C or C++ programs, you need to define a small module
(usually written in assembler as `crt0.s') that makes sure the
hardware is initialized for C conventions before calling main
.
There are some examples of `crt0.s' code (along with examples of
system call stub code) available in the source code for your Developer's
Kit. Look in the directories under:
installdir/progressive-95q4/src/newlib/libc/sys
(installdir refers to your installation directory, by default
`/usr/cygnus'.) For example, look in `.../sys/h8300hms'
for Hitachi H8/300 bare boards, or in `.../sys/sparclite'
for the Fujitsu SPARClite board. More examples are available under
the directory:
installdir/progressive-95q4/src/newlib/stub
To write your own `crt0.s', you need this information about
your target:
-
A memory map. What memory is available, and where?
-
Which way does the stack grow?
-
What output format do you use?
At a minimum, your `crt0.s' must do these things:
-
Define the symbol
start
(`_start' in assembler code).
Execution begins at this symbol.
-
Set up the stack pointer `sp'. It is largely up to you to choose
where to store your stack within the constraints of your target's memory
map. Perhaps the simplest choice is to choose a fixed-size area
somewhere in the uninitialized-data section (often called `bss').
Remember that whether you choose the low address or the high address in
this area depends on the direction your stack grows.
-
Initialize all memory in the uninitialized-data (`bss') section to
zero. The easiest way to do this is with the help of a linker script
(see section `Command Language' in Using LD; the GNU linker).
Use a linker script 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
`crt0.s'.
-
Call
main
. Nothing else will!
A more complete `crt0.s' might also do the following:
-
Define an `_exit' subroutine (this is the C name; in your assembler
code, use the label `__exit', with two leading underbars). Its
precise behavior depends on the details of your system, and on your
choice. Possibilities include trapping back to the boot monitor, if
there is one; or to the loader, if there is no monitor; or even back to
the symbol
start
.
-
If your target has no monitor to mediate communications with the
debugger, you must set up the hardware exception handler in
`crt0.s'. See section `The GDB remote serial protocol' in Debugging with GDB, for details on how to use the
GDB generic remote-target facilities for this purpose.
-
Perform other hardware-dependent initialization; for example,
initializing an MMU or an auxiliary floating-point chip.
-
Define low-level input and output subroutines. For example, `crt0.s'
is a convenient place to define the minimal assembly-level routines
described in section `System Calls' in The Cygnus C Support Library.
Go to the first, previous, next, last section, table of contents.