This is the mail archive of the crossgcc@sources.redhat.com mailing list for the crossgcc project.
See the CrossGCC FAQ for lots more information.
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
Other format: | [Raw text] |
If I am understanding things correctly from your explanations and from code samples, your initial HW reset entry point is to a "boot code" reset vector located in your ROM space, which means that the vector table base address is also in ROM space. You then run some boot code that copies "application code" to SRAM (including an application vector table), after which you jump to the application reset in this vector table. Presumably the application software changes the vector table base address so that the application works. I have done a similar project with a PowerPC (MPC860). I created two images - a boot image and an application image. The boot image was linked to run out of ROM, while the application image was linked to run out of RAM. Both images were initially stored in ROM. The function of the boot image was to decompress and copy the application image from ROM to RAM (I had two compressed application images in ROM with a CRC tacked onto the end of each image, because this was useful for recovery when a remote network based application code update failed and corrupted one of the images). My vectorTable section and linker script for the boot code and application images are inserted below. Hope they help. I started with a linker script that used the MEMORY command, but I remember not being able to get my image to link due to some obscure error -something about not having enough space for section headers (if I remember correctly). When I changed to using PHDRS, this grief went away. Boot image vector table ----------------------- .file "vectorTable.S" .extern Entry .globl _vectorTable .section ".vectorTable","ax" #----------------------------------------------------------------------- ---- # Reset vector macro. .macro RESET_VECTOR name .p2align 8 .globl __vector_\name __vector_\name: lwi r3, Entry mtlr r3 blr .endm #----------------------------------------------------------------------- ---- # Exception vector table. _vectorTable: RESET_VECTOR dummy RESET_VECTOR reset RESET_VECTOR machine_check RESET_VECTOR data_storage RESET_VECTOR instruction_storage RESET_VECTOR external RESET_VECTOR alignment RESET_VECTOR program RESET_VECTOR floatingpoint_unavailable RESET_VECTOR decrementer RESET_VECTOR rsvd_00a00 RESET_VECTOR rsvd_00b00 RESET_VECTOR system_call RESET_VECTOR trace RESET_VECTOR floatingpoint_assist RESET_VECTOR rsvd_00f00 Boot image Linker script: ----------------------- OUTPUT_FORMAT("elf32-powerpc", "elf32-powerpc", "elf32-powerpc") OUTPUT_ARCH(powerpc) /* Specify the entry symbol. */ ENTRY(Entry) SEARCH_DIR(/tools/H-i686-pc-cygwin/powerpc-eabi/lib); __ram_size = 0x20000; __ram_start = 0x3e0000; __rom_start = 0xfff00000; __stack_size = DEFINED(__stack_size) ? __stack_size : __ram_size / 10; __stack = __ram_start + ((__ram_size - 4) & 0xfffffffc); __ram_align = DEFINED(__page_size) ? __page_size : 4; __text_start = __rom_start + 0x1000; PHDRS { text PT_LOAD; data PT_LOAD; dynamic PT_DYNAMIC AT (0x3e0000); } SECTIONS { . = __rom_start; .vectorTable : { *(.vectorTable) } /* Merge read-only sections into text segment. */ .interp : { *(.interp) } .hash : { *(.hash) } .dynsym : { *(.dynsym) } .dynstr : { *(.dynstr) } .gnu.version : { *(.gnu.version) } .gnu.version_d : { *(.gnu.version_d) } .gnu.version_r : { *(.gnu.version_r) } .rela.text : { *(.rela.text) *(.rela.gnu.linkonce.t*) } .rela.data : { *(.rela.data) *(.rela.gnu.linkonce.d*) } .rela.rodata : { *(.rela.rodata) *(.rela.gnu.linkonce.r*) } .rela.got : { *(.rela.got) } .rela.got1 : { *(.rela.got1) } .rela.got2 : { *(.rela.got2) } .rela.ctors : { *(.rela.ctors) } .rela.dtors : { *(.rela.dtors) } .rela.init : { *(.rela.init) } .rela.fini : { *(.rela.fini) } .rela.bss : { *(.rela.bss) } .rela.plt : { *(.rela.plt) } .rela.sdata : { *(.rela.sdata) } .rela.sbss : { *(.rela.sbss) } .rela.sdata2 : { *(.rela.sdata2) } .text __text_start : { __TEXT_START__ = .; *(.osinit) *(.text) /* .gnu.warning sections are handled specially by elf32.em. */ *(.gnu.warning) *(.gnu.linkonce.t*) /* Insert crt0 initialization records. */ . = ALIGN(4); crt0_initialization_list = ALIGN (4); *(.crt0ini) LONG (0); /* Insert user text. */ . = ALIGN(4); __usertext_start = ALIGN (4); *(.usertxt) __usertext_size = ABSOLUTE(.) - ABSOLUTE(__usertext_start); /* Terminate it with a null pointer. */ LONG (0); } = 0 .init : { *(.init) } =0 .fini : { *(.fini) } =0 .rodata : { *(.rodata) *(.gnu.linkonce.r*) } .rodata1 : { *(.rodata1) } _etext = .; PROVIDE (etext = .); .sdata2 : { *(.sdata2) } __TEXT_END__ = .; /* Now assign the read/write sections. */ .data BLOCK(__ram_align) : { __data_start = .; *(.data) *(.gnu.linkonce.d*) CONSTRUCTORS *(.data1) *(.got1) *(.dynamic) __data_end = ALIGN (4); } .got2 : { __GOT2_START__ = .; *(.got2) __GOT2_END__ = .; } .fixups : { __FIXUP_START__ = .; *(.fixup) __FIXUP_END__ = .; } .got : { __GOT_START__ = .; *(.got) *(.got.plt) __GOT_END__ = .; } /* Keep small data sections together, so that single-instruction offsets*/ /* can access them all. Also keep initialized data before uninitialized*/ /* to minimize the size of the data image. */ .sdata : { *(.sdata) /* Inser user data.*/ . = ALIGN(4); __userdata_start = ALIGN (4); *(.userdat) __userdata_size = ABSOLUTE(.) - ABSOLUTE(__userdata_start); LONG (0); } _edata = .; PROVIDE (edata = .); .sbss __ram_start : { PROVIDE (__sbss_start = .); *(.sbss) *(.scommon) *(.dynsbss) /* Insert user bss. */ . = ALIGN(4); __userbss_start = ALIGN (4); *(.userbss) __userbss_size = ABSOLUTE(.) - ABSOLUTE(__userbss_start); /* Terminate it with a null pointer. */ . = ALIGN (4) + 4; PROVIDE (__sbss_end = .); } .plt : { *(.plt) } .bss : { PROVIDE (__bss_start = .); *(.dynbss) *(.bss) *(COMMON) PROVIDE (__bss_end = .); } _end = . ; PROVIDE (end = .); /* These are needed for ELF backends which have not yet been*/ /* converted to the new style linker. */ .stab 0 : { *(.stab) } .stabstr 0 : { *(.stabstr) } /* DWARF debug sections.*/ /* Symbols in the DWARF debugging sections are relative to the beginning*/ /* of the section so we begin them at 0. */ /* DWARF 1.*/ .debug 0 : { *(.debug) } .line 0 : { *(.line) } /* GNU DWARF 1 extensions.*/ .debug_srcinfo 0 : { *(.debug_srcinfo) } .debug_sfnames 0 : { *(.debug_sfnames) } /* DWARF 1.1 and DWARF 2.*/ .debug_aranges 0 : { *(.debug_aranges) } .debug_pubnames 0 : { *(.debug_pubnames) } /* DWARF 2.*/ .debug_info 0 : { *(.debug_info) } .debug_abbrev 0 : { *(.debug_abbrev) } .debug_line 0 : { *(.debug_line) } .debug_frame 0 : { *(.debug_frame) } .debug_str 0 : { *(.debug_str) } .debug_loc 0 : { *(.debug_loc) } .debug_macinfo 0 : { *(.debug_macinfo) } /* SGI/MIPS DWARF 2 extensions.*/ .debug_weaknames 0 : { *(.debug_weaknames) } .debug_funcnames 0 : { *(.debug_funcnames) } .debug_typenames 0 : { *(.debug_typenames) } .debug_varnames 0 : { *(.debug_varnames) } /* These must appear regardless of . */ } /* The following optional symbols are accessed by startup code in crt0.o.*/ /* If they are not defined in user code, then zero them out.*/ PROVIDE (crt0_flags = 0); PROVIDE (_environ = 0); PROVIDE (hardware_init_hook = 0); PROVIDE (software_init_hook = 0); /* Default settings for heap start and end - referenced by sbrk. */ PROVIDE (__heap_start = _end); PROVIDE (__heap_end = __ram_start + (ABSOLUTE(__ram_size) - ABSOLUTE(__stack_size))); /* This script is for RAM-based systems, so __data_start_rom should be zero*/ /* so crt0 does not copy the data image.*/ PROVIDE (__data_start_rom = 0); Application image vector table: ------------------------------- #include <paragon/hw/ic/cpu/powerPC/powerPc.h> #include <paragon/device/cpu/powerPC/stackframe.h> .file "vectorTable.S" .extern Entry .extern TrapHandler .extern ExceptionHandler__11Decrementer .extern ExternalIrqHandler .extern Switch__7Context .globl _vectorTable .section ".vectorTable","ax" #----------------------------------------------------------------------- ---- # Reset vector macro. .macro RESET_VECTOR name .p2align 8 .globl __vector_\name __vector_\name: lwi r3, Entry mtlr r3 blr .endm #----------------------------------------------------------------------- ---- # Interrupt or trap vector macro. .macro EXCEPTION_VECTOR name handler .p2align 8 .globl __vector_\name __vector_\name: STACK_FRAME_SAVE li r3,__vector_\name@L # Vector number. bla \handler b _restoreStackFrame .endm #----------------------------------------------------------------------- ---- # Exception vector table. _vectorTable: # These are the architecture defined vectors that are always present. EXCEPTION_VECTOR rsvd_00000 TrapHandler RESET_VECTOR reset EXCEPTION_VECTOR machineCheck TrapHandler EXCEPTION_VECTOR dataStorage TrapHandler EXCEPTION_VECTOR instructionStorage TrapHandler EXCEPTION_VECTOR external ExternalIrqHandler EXCEPTION_VECTOR alignment TrapHandler EXCEPTION_VECTOR program TrapHandler EXCEPTION_VECTOR floatingpointUnavailable TrapHandler EXCEPTION_VECTOR decrementer ExceptionHandler__11Decrementer EXCEPTION_VECTOR rsvd_00a00 TrapHandler EXCEPTION_VECTOR rsvd_00b00 TrapHandler EXCEPTION_VECTOR systemCall Switch__7Context EXCEPTION_VECTOR trace TrapHandler EXCEPTION_VECTOR floatingpointAssist TrapHandler EXCEPTION_VECTOR rsvd_00f00 TrapHandler EXCEPTION_VECTOR softwareEmulation TrapHandler EXCEPTION_VECTOR instructionTlbMiss TrapHandler EXCEPTION_VECTOR dataTlbMiss TrapHandler EXCEPTION_VECTOR instructionTlbError TrapHandler EXCEPTION_VECTOR dataTlbError TrapHandler EXCEPTION_VECTOR rsvd_01500 TrapHandler EXCEPTION_VECTOR rsvd_01600 TrapHandler EXCEPTION_VECTOR rsvd_01700 TrapHandler EXCEPTION_VECTOR rsvd_01800 TrapHandler EXCEPTION_VECTOR rsvd_01900 TrapHandler EXCEPTION_VECTOR rsvd_01a00 TrapHandler EXCEPTION_VECTOR rsvd_01b00 TrapHandler .section ".text" _restoreStackFrame: STACK_FRAME_RESTORE Application image linker script: ------------------------------- OUTPUT_FORMAT("elf32-powerpc", "elf32-powerpc", "elf32-powerpc") OUTPUT_ARCH(powerpc) /* Specify the entry symbol. */ ENTRY(Entry) SEARCH_DIR(/tools/H-i686-pc-cygwin/powerpc-eabi/lib); __ram_size = 0x3d0000; __ram_start = 0x0; __stack_size = DEFINED(__stack_size) ? __stack_size : __ram_size / 10; __stack = ((__ram_size - 4) & 0xfffffffc); __ram_align = DEFINED(__page_size) ? __page_size : 4; __text_start = 0x3000; SECTIONS { . = 0x00000000; .vectorTable : { *(.vectorTable) } . = __text_start; /* Merge read-only sections into text segment. */ .interp : { *(.interp) } .hash : { *(.hash) } .dynsym : { *(.dynsym) } .dynstr : { *(.dynstr) } .gnu.version : { *(.gnu.version) } .gnu.version_d : { *(.gnu.version_d) } .gnu.version_r : { *(.gnu.version_r) } .rela.text : { *(.rela.text) *(.rela.gnu.linkonce.t*) } .rela.data : { *(.rela.data) *(.rela.gnu.linkonce.d*) } .rela.rodata : { *(.rela.rodata) *(.rela.gnu.linkonce.r*) } .rela.got : { *(.rela.got) } .rela.got1 : { *(.rela.got1) } .rela.got2 : { *(.rela.got2) } .rela.ctors : { *(.rela.ctors) } .rela.dtors : { *(.rela.dtors) } .rela.init : { *(.rela.init) } .rela.fini : { *(.rela.fini) } .rela.bss : { *(.rela.bss) } .rela.plt : { *(.rela.plt) } .rela.sdata : { *(.rela.sdata) } .rela.sbss : { *(.rela.sbss) } .rela.sdata2 : { *(.rela.sdata2) } .rela.sbss2 : { *(.rela.sbss2) } .text __text_start : { __TEXT_START__ = .; *(.osinit) *(.text) /* .gnu.warning sections are handled specially by elf32.em. */ *(.gnu.warning) *(.gnu.linkonce.t*) /* Insert crt0 initialization records. */ . = ALIGN(4); crt0_initialization_list = ALIGN (4); *(.crt0ini) LONG (0); /* Insert user text. */ . = ALIGN(4); __usertext_start = ALIGN (4); *(.usertxt) __usertext_size = ABSOLUTE(.) - ABSOLUTE(__usertext_start); /* Terminate it with a null pointer. */ LONG (0); } = 0 .init : { *(.init) } =0 .fini : { *(.fini) } =0 .rodata : { *(.rodata) *(.gnu.linkonce.r*) } .rodata1 : { *(.rodata1) } _etext = .; PROVIDE (etext = .); .sdata2 : { *(.sdata2) } .sbss2 : { *(.sbss2) } __TEXT_END__ = .; /* Now assign the read/write sections. */ .data BLOCK(__ram_align) : { __data_start = .; *(.data) *(.gnu.linkonce.d*) CONSTRUCTORS *(.data1) *(.got1) *(.dynamic) __data_end = ALIGN (4); } .got2 : { __GOT2_START__ = .; *(.got2) __GOT2_END__ = .; } .fixups : { __FIXUP_START__ = .; *(.fixup) __FIXUP_END__ = .; } .got : { __GOT_START__ = .; *(.got) *(.got.plt) __GOT_END__ = .; } /* Keep small data sections together, so that single-instruction offsets*/ /* can access them all. Also keep initialized data before uninitialized*/ /* to minimize the size of the data image. */ .sdata : { *(.sdata) /* Inser user data.*/ . = ALIGN(4); __userdata_start = ALIGN (4); *(.userdat) __userdata_size = ABSOLUTE(.) - ABSOLUTE(__userdata_start); LONG (0); } _edata = .; PROVIDE (edata = .); .sbss : { __bss_clear_start = .; PROVIDE (__sbss_start = .); *(.sbss) *(.scommon) *(.dynsbss) /* Insert user bss. */ . = ALIGN(4); __userbss_start = ALIGN (4); *(.userbss) __userbss_size = ABSOLUTE(.) - ABSOLUTE(__userbss_start); /* Terminate it with a null pointer. */ . = ALIGN (4) + 4; PROVIDE (__sbss_end = .); } .plt : { *(.plt) } .bss : { PROVIDE (__bss_start = .); *(.dynbss) *(.bss) *(COMMON) PROVIDE (__bss_end = .); } _end = . ; PROVIDE (end = .); /* These are needed for ELF backends which have not yet been*/ /* converted to the new style linker. */ .stab 0 : { *(.stab) } .stabstr 0 : { *(.stabstr) } /* DWARF debug sections.*/ /* Symbols in the DWARF debugging sections are relative to the beginning*/ /* of the section so we begin them at 0. */ /* DWARF 1.*/ .debug 0 : { *(.debug) } .line 0 : { *(.line) } /* GNU DWARF 1 extensions.*/ .debug_srcinfo 0 : { *(.debug_srcinfo) } .debug_sfnames 0 : { *(.debug_sfnames) } /* DWARF 1.1 and DWARF 2.*/ .debug_aranges 0 : { *(.debug_aranges) } .debug_pubnames 0 : { *(.debug_pubnames) } /* DWARF 2.*/ .debug_info 0 : { *(.debug_info) } .debug_abbrev 0 : { *(.debug_abbrev) } .debug_line 0 : { *(.debug_line) } .debug_frame 0 : { *(.debug_frame) } .debug_str 0 : { *(.debug_str) } .debug_loc 0 : { *(.debug_loc) } .debug_macinfo 0 : { *(.debug_macinfo) } /* SGI/MIPS DWARF 2 extensions.*/ .debug_weaknames 0 : { *(.debug_weaknames) } .debug_funcnames 0 : { *(.debug_funcnames) } .debug_typenames 0 : { *(.debug_typenames) } .debug_varnames 0 : { *(.debug_varnames) } /* These must appear regardless of . */ } /* The following optional symbols are accessed by startup code in crt0.o.*/ /* If they are not defined in user code, then zero them out.*/ PROVIDE (crt0_flags = 0); PROVIDE (_environ = 0); PROVIDE (hardware_init_hook = 0); PROVIDE (software_init_hook = 0); /* Default settings for heap start and end - referenced by sbrk. */ PROVIDE (__heap_end = __ram_start + (ABSOLUTE(__ram_size) - ABSOLUTE(__stack_size))); PROVIDE (__heap_start = __ram_start + (ABSOLUTE(__ram_size) - ABSOLUTE(__stack_size))- 0x60000); /* This script is for RAM-based systems, so __data_start_rom should be zero*/ /* so crt0 does not copy the data image.*/ PROVIDE (__data_start_rom = 0); -----Original Message----- From: crossgcc-owner@sources.redhat.com [mailto:crossgcc-owner@sources.redhat.com] On Behalf Of Davide Viti Sent: Wednesday, February 20, 2002 2:21 AM To: crossgcc@sourceware.cygnus.com Subject: RE: Custom section attributes (and more...) Ciao David, thanx for your help... I'd probably better to expalin why and what I'm tryin' to do: my target is a PowerPc based board and the cross environment is running on Cygwin. My software HAS to start from 0x10000 but the vector table on a PPC has to reside at lower addresses (starting from 0x0); in particular at 0x100 resides the system reset ISR and at 0x500 the external interrupt handler so... when I run at 0x10000 I want to buid the exception table. I created a custom section .vtable and I want to copy its contents; the assembler instructions are handled correctly, my problems arises when calliing c routines. here's part of my linker script: ----------- MEMORY { sram (rw) : org = 0x0, len = 16M flash (rx) : org = 0x4000000, len = 8M } SECTIONS { .... .vtable : AT(ADDR(.text)+SIZEOF(.text)) { _vtstart = .; *(.vtable) _vtend = .; } > sram ... } _VT_SIZE = SIZEOF(.vtable); ------------- this is how I copy the vector table and jump to 0x100: .globl _makevt .ORG 0x0 _makevt: addis r3, 0, _vtstart@h ori r3, r3, _vtstart@l /* Destination */ li r4,0x0 addis r5, 0, _VT_SIZE@h ori r5, r5, _VT_SIZE@l add r7, r3, r5 cont: lwzx r5, 0, r3 stwx r5, 0, r4 lwzx r8, 0, r4 cmp 0, 0, r8, r5 addi r4, r4, 4 addi r3, r3, 4 cmp 0, 0, r3, r7 ble cont /* Set PC */ lis r4, 0x0 ori r4, r4, 0x100 mtlr r4 blr ---------------------------------- and here's the custom section: .section .vtable, "ax" .org 0x100 /* System Reset - 1st instruction after hw power-on reset. */ addis 11, 0 , __SP_INIT@h # Initialize stack pointer r1 to addi 1, 11, __SP_INIT@l # value in linker command file. addis 13, 0, _SDA_BASE_@h # Initialize r13 to sdata base addi 13, 13, _SDA_BASE_@l # (provided by linker). addis 2, 0, _SDA2_BASE_@h # Initialize r2 to sdata2 base addi 2, 2, _SDA2_BASE_@l # (provided by linker). addi 0, 0, 0 # Clear r0. bl __init_main .org 0x200 bl isr_dummy200 .org 0x300 bl isr_dummy300 .org 0x400 bl isr_dummy400 ..... Thanx for your time, Davide Regards Davide --------------. ,-. SS Padana Sup. km 158 Davide Viti \ ,---------------' \ I-20060 Cassina de' Pecchi MI Siemens ICM/N `--' `-------------------------------- --------------. ,-. SS Padana Sup. km 158 Davide Viti \ ,---------------' \ I-20060 Cassina de' Pecchi MI Siemens ICM/N `--' `-------------------------------- ------ Want more information? See the CrossGCC FAQ, http://www.objsw.com/CrossGCC/ Want to unsubscribe? Send a note to crossgcc-unsubscribe@sources.redhat.com _________________________________________________________ Do You Yahoo!? Get your free @yahoo.com address at http://mail.yahoo.com ------ Want more information? See the CrossGCC FAQ, http://www.objsw.com/CrossGCC/ Want to unsubscribe? Send a note to crossgcc-unsubscribe@sources.redhat.com
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |