[ previous ] [ Abstract ] [ Copyright Notice ] [ Contents ] [ next ]

Free H8 development environment under Linux
Chapter 3 Linker Script


3.1 What is a "linker script"?

A linker script is a script file to specify how programs are loaded to memory. In case of PC application programming, there is no need to know about physical memory address, because it is managed by OS. But in embedded application with no OS, developpers must consider where programs are loaded to.

The linker script must be made each target memory configuration, which depends on external memories of target CPU. If you will use H8 CPU only with internal memory, you may use the sample linker script. If your target CPU boards have external ROM or RAM, the linker script must be modified.

By a linker script, you must specify:

In the following document, we'll explain:


3.2 H8-specific consideration for memory mapping

In H8, there are some choices for memory mapping.

There are 7 operating modes by combining these choices. Here we don't consider for initial bus mode, which is not affected to memory mapping.

In mode 7, external memory bus is disabled. We think it is the most frequently used mode, we explain it for example.

Here is a memory map of this mode.

     H'00000 +-------------+
             |Vector       |
             +-------------+
             |On-chip ROM  |
     H'1FFFF +-------------+
     
     H'FEF10 +-------------+
             |On-chip RAM  |
     H'FFF0F +-------------+
     H'FFF1C +-------------+
             |I/O Registers|
     H'FFFFF +-------------+


3.3 H8 boot mode

H8 boot mode is a mode to load programs from serial I/O. For boards without external memory, this mode is the only method to execute programs in target hardware. Normally, programs to load main program to the internal flash memory is executed in this mode. We provide this program with this document.

In H8 boot mode, the program is loaded to on-chip RAM, while main programs are loaded to ROM. Different linker scripts must be used for boot mode and ROM mode.


3.4 Other H8 consideration

Interrupt vector is a table of memory address where to go when an interrupt is occured. Interrupt vector must be placed from memory address H'00000, the top of memory.

Note that the vector resides in on-chip ROM when on-chip ROM is enabled. For this reason, the interrupt vector may not be modified while application program is running. The interrupt vector must be specified in advance, in the linker script.

For H8 have no I/O address space, I/O registers are also mapped in memory. They may be specified by the linker script, but in common in C, they are accessed by coercing absolute address to pointer like the following example.

     aValue = *(char *)0xfffd6;


3.5 ROMization and initial value

Here, we consider about initial value of global variables. In PC, global variables are initialized by OS program loader, but in embedded application, we must provide routines to initialize global variable. The easiest way is to initialize variables in main routine explicitly, but there is a good way to do this without affecting application programs.

In common, initialization is achieved by the following way.

To do this, a linker script and bootstrap routines must be modified.


3.6 A sample linker script

In this section, a sample linker script named h8rom.x and some explanations are shown. Refer ld documents for full explanation of linker scripts.

     OUTPUT_FORMAT("coff-h8300")
     OUTPUT_ARCH(h8300h)

In the head of the script, default options are specified. Here, they specifies default object format to COFF, and architecture to H8/300H. For this reason, -mh options must be specified for GCC with this script.

     ENTRY("_start")

Next, ENTRY command specifies where the program starts. The `_start' label is defined in crt0, the C startup routine.

     MEMORY
     {
     	vectors(r) : o = 0x0000, l = 0xff
     	rom(rx) : o = 0x100, l = 0x1ff00
     	ram(rwx) : o = 0xfef10, l = 0x1000
     	/* The top of main RAM, which the stack starts. */
     	topram(rw) : o = 0xffefc, l = 0x4
     }

MEMORY command defines physical memory map. In this command, 4 memory block, `vectors' (interrupt vectors), `rom', `ram', and `topram' ( address for stack top ) are defined. Each line contains a memory block name, the start address by `o' (abbreviation of `origin'), and the size by `l' (abbreviation of `length').

     SECTIONS
     {
     .vectors : {
     	LONG(ABSOLUTE(_start))		/*  0 Reset vector */
     	LONG(ABSOLUTE(_start))		/*    Reserved */
     ......
             FILL(0xff)
             } > vectors

Next, SECTIONS command specifies how the data are stored in physical memories. First entry in the sample is an interrupt vector table. In this way, memory labels can be stored to specific location of memory.

     .text : {
     	*(.text) 				
     	*(.strings)
     	*(.rodata) 				
        	 _etext = . ; 
     	} > rom
     .tors : {
     ...
     }

Here, code and constant data are mapped to ROM. text, .string, and rodata are the default section name used by GCC. Program code, string data, and constant data are stored to them.

A label _etext is defined as a next address of .rodata. This lable can be used in the program, perhaps in startup routine.

.tors maps C++ constructor (.ctors) and desctuctor (.dtors) to ROM.

     .data : AT ( ADDR(.tors) + SIZEOF(.tors) ){
     	___data = . ;
     	*(.data)
     	*(.tiny)
     	 _edata = .;
     	} > ram

.data section has initialized data. They are assigned in ROM at loading, and copied to RAM at startup procedure.

     .bss : {
     	 _bss_start = . ;
     	*(.bss)
     	*(COMMON)
     	 _end = . ;  
     	}  >ram
     .stack : {
     	 _stack = . ; 
     	*(.stack)
     	}  > topram

.bss and .stack section have uninitialized data. They are placed in RAM, and not in ROM.


[ previous ] [ Abstract ] [ Copyright Notice ] [ Contents ] [ next ]
Free H8 development environment under Linux
version 1.0, 24 Nov 1999
Muneyuki IWATA kp9m-iwt@asahi-net.or.jp