210 likes | 343 Vues
Real-Time System Design. Developing a Cross Compiler and libraries for a target system. Why port a cross compiler?. In real-time and embedded systems you will frequently come across new hardware for which there either isn’t a compiler or the current compiler doesn’t meet your specifications
E N D
Real-Time System Design Developing a Cross Compiler and libraries for a target system
Why port a cross compiler? • In real-time and embedded systems you will frequently come across new hardware for which there either isn’t a compiler or the current compiler doesn’t meet your specifications • In this situation one way forward is to port a compiler for this new board
What compiler to select? • Short of writing a new compiler yourself you will probably want to port an existing compiler • Selection of the base compiler is important • The target hardware might force a choice • If it is only supported by one compiler • If it runs an OS that is close to a particular compiler
Selection Criteria • There are a number of criteria that can be used • Mature compiler • Portable • Widely used/known • Large tool set • Runs on same/compatible hardware • Variety of OS/RTOS interfaces • Good library support • Supports a number of languages • Good documentation • Open source/open standard
Hardware considerations • If your selected compiler does not have support for the processor you will have to • Write a back end for the compiler to generate the correct assembler code • Port many low level startup and compiler routines • Write linker scripts and library files
Operating System considerations • If your compiler is not supported by the target OS then you will have to • Write initialisation routines – crt0.o for example • Port library routines • Port some compiler startup routines • Frequently boards have very minimal OS/monitors
Using GCC as an example • GCC scores very highly on many of the points in slide four • I will use it as an example • Although the name implies the C compiler and this is what I will concentrate on, it does support a number of other languages – Ada, C++, Java, etc
Building a cross compiler • Firstly select the host machine, although it can help if it is the same processor and OS, it is frequently the case that neither are supported on the host machine • However it is very useful that the cross compiler runs in native mode on your host machine • i.e. you can compiler at least some of your cross compiler with the host’s native compiler • The link between GNU and Linux is obvious therefore I will use a GNU i686 Linux platform
Cross compiler tools • Aside from the compiler itself you will require a number of tools. Key ones are • A cross linker – gas in GNU • A cross assembler – gld in GNU • A downloader – will depend upon the target • Others that will be very useful are • A librarian – ranlib in GNU • An object copier – objcopy in GNU • A debugger – GDB in GNU • A symbol table dumper – nm in GNU
Building the cross utilities • The GNU suite comes with a set of compiler utilities that are bundled together called binutils. • You must build binutils before building the cross compiler. • It is possible to use other tools with the compiler – it may be required by an on-board OS for example, however GNU does work well with its own tools. • You must check compatibility issues between the GCC release and binutils
Building the cross compiler #1 • The first pass of the cross compiler must be built with the native compiler • This will be a i686 program that generates target output • There are a variety of target outputs to configure GNU with • The standard is • CPU-VENDOR-OS – i.e. • m68k-sun-bsd4.2 • arm-unknown-elf • m88k-unknown-a.out
Using a GNU template • Selecting the correct template is important • Firstly • Select the correct processor and check that the exact family is supported – i.e. m68k and 68040. This means that GCC can generate the correct assembler code • Then • If you have the correct manufacturer and OS life is simple, Otherwise, • Go for the nearest (or unknown) and at least get the code format correct – coff, elf and so on • In the later option you will have to do some porting and interfacing.
Creating a GNU template • GCC is built with portability in mind. • It is possible to create new assembler and OS interfaces for GNU • This requires learning BDF to create binary definition files for the new target • You may have to write a version of gas, the GNU assembler. • This is non-trivial, and first off try to use what already exists.
Building the cross compiler #2 • As stated earlier, most of the cross compiler will be generated in native mode • However GNU will need to generate target code and some of this may be difficult or impossible for the native compiler • The code generation may require extra (target) library code that it can’t generate • For example, the m68k -68000 option only has 16 bit multiple and divide instructions (mulu/s and divs/u) and the compiler requires 32 bit library functions. These must be created by either a 68000 compiler or assembler.
Building the cross compiler #2 • The compiler itself requires some special startup functions written in target code • The compiler has some functions _exit for example • These can be suppressed using the –nostdfunc option • All of the above cannot be generate by the native compiler. They may have to be hand coded or stubbed out if not required.
Includes and libraries • The standard include files - /usr/include – will probably not work with the target and a minimal set must generated • Much is standard and can be copied, so can be taken from the target OS • GCC, like most C compilers, requires a minimal, standard library, libc.a. Again this will have to be created.
Startup files • The cross compiler will generate all the target code from your program code and the linker will load in any library code, in the correct format. • However there is an initialisation file that is required to initialise and execute the target code • This is crt0.o on GNU – cstart on Crossware and OS9