Cross gcc Mailing List Archive

[Prev][Next][Index][Thread]

Re: [laire@basis.owl.de: How to generate a Rom Binary ?]




Ralph Schmidt <laire@basis.owl.de> said:
> Does anybody know how i can create a rom binary with objcopy where 
> the instructions with reloc informations are changed to a rom 
> address. 

You're in luck, I do this sort of thing with GNU tools all the time,
for boards that my company designs. The example files below come from
the O/S for one such board, the ISE board.

I use a linker script to arrange for text to go into ROM, .data and
.bss into DRAM and the .data copied into the ROM after the .text.
The example linker script is included below.

I define the memory regions first. That is obvious. There is DRAM
and there is a FLASH memory. The IBR (a data structure required by
the CPU) has a specific memory address so I give it a region.

The SECTIONS part arranges for the sections to be dispatched into
various regions of memory. What this does is also pretty obvious. The
output sections (.text, .bss, etc) are filled from sections of the
input file. The magic for making a ROM image is in the AT() operator.

	.text : AT(0) { ...

This causes the output .text section to be assigned a LOAD address of
zero, in other words the beginning of memory. The LINK address will
be in the flash memory. COFF files keep seperate link and load addresses
for sections.

	.data : AT( SIZEOF(.text) ) {

This bit of magic causes the .data section to be loaded directly after
the .text in the flash image, yet it will be linked as it if goes in
the DRAM. The startup code knows that this is happening and copies
the image to DRAM before calling main.

  i960-coff-objcopy --remove-section=.comment --output-target=srec a.out a.srec

All that is left for the objcopy command is to make an image that the
PROM programmer can understand. The above works nicely, and makes
S-Records and sets the addresses in the image to the LOAD addresses for
the sections. You can also make binary images by changing the output-target.

Pretty nifty, eh?

(P.S. The copyrighted code below is included WITH PERMISSION. GPL applies.)

/*
 * Copyright (c) 1996 Picture Elements, Inc.
 *    Stephen Williams
 *
 * $Id: bootprom.ld,v 1.2 1996/10/11 00:23:17 steve Exp $
 *
 * $Log: bootprom.ld,v $
 * Revision 1.2  1996/10/11 00:23:17  steve
 *  Rearrange the memory map to reflect the theory of
 *  operation for the ISE board.
 *
 * Revision 1.1  1996/10/08 03:28:47  steve
 *  Add the ISE bootstrap prom.
 *
 */

/*
 * The memory map for the linked result places the text and IBR in the
 * flash memory, and the data and bss sections into the dram. The image
 * is delivered to the board by stuffing everything in the flash memory.
 * To get this affect, I use the AT() options for each output section to
 * LINK it in the ram or whatever but LOAD it into the given location
 * relative to the beginning of flash memory.
 *
 * When the flash memory is programmed and stuffed on the board, the
 * .text and IBR sections are at the right address. The startup code is
 * then smart enough to copy the .data image from the flash into DRAM.
 *
 * Note that I restrict myself to the high 1Meg of DRAM because the
 * program that runs out of flash is expected to load a real program
 * into DRAM. By using only a little bit of the end of DRAM, I can use
 * beginning for the sub-program's text and data, and then upon reset
 * the DRAM that I've been using goes to the heap of the child.
 */

MEMORY
{
	/* Put DRAM in region 2_3. */
	dram  : org = 0xa0000000 + 3M, len = 1M

	  /* FLASH memory is fixed in hardware to be 512K bytes,
	     and we want it at the end so we can put the IMI there,
	     especially the initial boot record. */
	flash : org = 0xff000000 - 512K, len = 512K
	IBR   : org = 0xfeffff30,  len = 208
}

	  /* The ISE board has a couple little registers for controlling
	     the few non-PCI devices on the local bus. */

__ISE_STATUS  = 0xb0000000;
__ISE_CONTROL = 0xb0000000;


ENTRY(start)
STARTUP(locore.o)

SECTIONS
{
	  /* Executable code, constants, and the constructor table
	     go in the beginning of the flash memory. */

	.text : AT(0) {
		*(.text)
		. = ALIGN(4);
		___CTOR_TABLE__ = .;
		*(.ctors)
		LONG(0);
		___DTOR_TABLE__ = .;
		*(.dtors)
		LONG(0);
		_etext = .;
	} > flash


	  /* Initialized data goes into the DRAM. Load load an image
	     of this section in the FLASH after the .text section so
	     the startup code can find it and copy it in place. */

	.data : AT( SIZEOF(.text) ) {
		. = ALIGN(16); _bdata = .;
		*(.data)
		*(COMMON)
		_edata = .;
	} > dram


	  /* The .bss section is uninitialized data. I need to link
	     to it, but it doesn't get loaded. */
	.bss (NOLOAD) : {
		*(.bss)
		_end = .;
	}  >dram

	_end_heap = _bdata + 1M;


	  /* The IBR is special and magical. It must be in a very
	     specific place, so placing it there is the job of the
	     linker, that's me. It is loaded into the end of flash
	     memory. */

	ibr : AT (ADDR(ibr) - ADDR(.text)) {
		*(ibr)
	} > IBR


}
ibr_checksum = -(start + prcb);

-- 
Steve Williams
steve@icarus.com
steve@picturel.com

"The woods are lovely, dark and deep.  But I have promises to keep,
And lines to code before I sleep, And lines to code before I sleep."



References:

Home | Subject Index | Thread Index