GP32 Elf Files


loki666

rtems gp32 bsp maintainer
Joined
Dec 27, 2003
Messages
288
Age
44
Location
Belgium
Website
loki666-gp32.blogspot.com
i'm still (slowly) trying to port an embedded os(eCos) for the gp32
i think i've gathered all the pieces to make an simple test (but hadn't the time to put them together yet) but i have some question still remaining...
the building process use its own toolchain (an arm-elf-gcc+newlib+arm-elf-binutils with customs patch)
so I guess I could use the output(which is a .elf file) to create a .fxe file to be run by bios applauncher
but:
1) do the bios applauncher use some special tag to recognize a 'valid' gp32 exe? Is there some predifined value at predifined address? (like ro-base,ro-size,entry point,etc)...
2) in which cpu arm mode do the exec runs? (i think it's SVC)
3) can the exec redefines the stacks?
thank for your help
 
Hi,

1) Check the standard crt0.s that comes with the various toolchains for GP32, it contains the GXB header.

2) IIRC the GP32 runs SVC mode most of the time, except IRQ handlers ofcourse.

3) The stacks are setup to a defaul by the bootum sequence, but ofcourse you can move the stack if you want to, you can change to IRQ mode to change that stack aswell. But, to change the usermode stack you might want to use "LDMxx <base> {registers except PC}^" to load user mode registers, since you can't get back to Supervisor mode from User mode.
 
thanks
you mean this? this should only be at +0x04 (since first instruction is a branch)?
Code:
        .word   __text_start    @ Start of text (Read Only) section
_roe:   .word   __ro_end        @ End "
_rws:   .word   __data_start    @ Start of data (Read/Write) section
        .word   __bss_end       @ End of bss (this is the way sdt does it for some reason)
_zis:   .word   __bss_start     @ Start of bss (Zero Initialized) section
_zie:   .word   __bss_end       @ End "

        .word   0x44450011
        .word   0x44450011

        .word   0x01234567
        .word   0x12345678
        .word   0x23456789
        .word   0x34567890
        .word   0x45678901
        .word   0x56789012
        .word   0x23456789
        .word   0x34567890
        .word   0x45678901
        .word   0x56789012
        .word   0x23456789
        .word   0x34567890
        .word   0x45678901
        .word   0x56789012
 
Yep, thats the GXB header.
To get a GXB out of an ELF file you use the objcopy tool.
 
just one more thing.
how the applauncher loads gxb in memory? does it use the firsts pointers to copy section to their rights locations, or does it simply make a raw copy of the gxb at 0x0c000000?
how does the applauncher choose the address for entry point?
where in the gxb should the header located? (anywhere, only at 0x04)

thanks for your help mithris
 
Spiv knows more about this stuff, but afaik, the pointers in the header are used to copy the sections to the proper locations.
 
What is the current status of the porting?

If you write a routine to launch FXEs or GXBs, could you share the code to port it to gp32linux?

thanks
 
cyberic posted on Sep 13 2004 at 05:46 PM said:
What is the current status of the porting?

If you write a routine to launch FXEs or GXBs, could you share the code to port it to gp32linux?

thanks
well i need some more weekends to finish this (and i'll be on hollydays from tomorrow)
so dont except results soon... lot of things left to do/learn
btw:i'm not trying to write a gxb launcher, i'm trying to undestand how the bios applauncher works to build a valid gbx file.
 
Last edited by a moderator:
loki666 posted on Sep 13 2004 at 01:24 PM said:
just one more thing.
how the applauncher loads gxb in memory? does it use the firsts pointers to copy section to their rights locations, or does it simply make a raw copy of the gxb at 0x0c000000?
how does the applauncher choose the address for entry point?
where in the gxb should the header located? (anywhere, only at 0x04)

thanks for your help mithris

The Applauncher (e.g. infamous Gamepark Free Launcher) loads the FXE into a large enough
free RAM block, then decrypts FXE to GXB and calls GpAppExecute().
GpAppExecute() i.e. SWi #5 blindly believes the section start addresses you have in the
GXB header. This means a GXB may be located/run e.g. at 0x0c0acafe instead of 0x0c000000.
The BIOS code takes care that relocation of code/data succees. The GXB header _must_ start from
the offset 4 in the GXB file.

Just check what the SWI #5 does from the BIOS disassembly (from my site). The code is
pretty much commented well there.
 
Last edited by a moderator:
mr.spiv posted on Sep 16 2004 at 11:13 PM said:
loki666 posted on Sep 13 2004 at 01:24 PM said:
just one more thing.
how the applauncher loads gxb in memory? does it use the firsts pointers to copy section to their rights locations, or does it simply make a raw copy of the gxb at 0x0c000000?
how does the applauncher choose the address for entry point?
where in the gxb should the header located? (anywhere, only at 0x04)

thanks for your help mithris

The Applauncher (e.g. infamous Gamepark Free Launcher) loads the FXE into a large enough
free RAM block, then decrypts FXE to GXB and calls GpAppExecute().
GpAppExecute() i.e. SWi #5 blindly believes the section start addresses you have in the
GXB header. This means a GXB may be located/run e.g. at 0x0c0acafe instead of 0x0c000000.
The BIOS code takes care that relocation of code/data succees. The GXB header _must_ start from
the offset 4 in the GXB file.

Just check what the SWI #5 does from the BIOS disassembly (from my site). The code is
pretty much commented well there.
ok thank you
 
Last edited by a moderator:
Is a .gxb file a kind of linux binary?
Because it would be great to add .fxe launching ability to gp32linux.

I guess the apps would have to be launched in a kind of 'real mode' anyway, in order to provide direct access to the hardware...

Could anyone help us in this area?

Thanks
cyberic
 
cyberic posted on Sep 23 2004 at 11:56 AM said:
Is a .gxb file a kind of linux binary?
Because it would be great to add .fxe launching ability to gp32linux.

I guess the apps would have to be launched in a kind of 'real mode' anyway, in order to provide direct access to the hardware...

Could anyone help us in this area?

Thanks
cyberic
no this has nothing in common with linux library file.
the way eCos runs is different from linux, each apps is embeded with a litle OS, so all i need is a way to build some kind of gxb file to runs eCos.
that way each apps+eCos could be loaded with the Gamepark Free Launcher. (i dont need a bootloader since the BIOS has allready one)
 
Last edited by a moderator:
ok here is start.S and link script i'm using... do you think there is a chance it could workd?
Code:
/*
 * Cogent CSB336 startup code
 *
 * Copyright (c) 2004 by Jay Monkman <jtm@lopingdog.com>
 *      
 * The license and distribution terms for this file may be
 * found in the file LICENSE in this distribution or at
 *
 * http://www.OARcorp.com/rtems/license.html.
 *
 *
 * $Id$
 */

                
/* Some standard definitions...*/
.equ PSR_MODE_USR,       0x10
.equ PSR_MODE_FIQ,       0x11
.equ PSR_MODE_IRQ,       0x12
.equ PSR_MODE_SVC,       0x13
.equ PSR_MODE_ABT,       0x17
.equ PSR_MODE_UNDEF,     0x1B
.equ PSR_MODE_SYS,       0x1F

.equ PSR_I,              0x80
.equ PSR_F,              0x40
.equ PSR_T,              0x20

.text
.globl  _start
_start:
	b  _start2

@---------------------------------------------------------------------------------
@ AXF addresses
@---------------------------------------------------------------------------------
	.word   _text_start
	.word   _ro_end
	.word   _data_start
	.word   _bss_end
	.word   _bss_start
	.word   _bss_end

@---------------------------------------------------------------------------------
@ GamePark magic sequence
@---------------------------------------------------------------------------------
	.word   0x44450011
	.word   0x44450011
	.word   0x01234567
	.word   0x12345678
	.word   0x23456789
	.word   0x34567890
	.word   0x45678901
	.word   0x56789012
	.word   0x23456789
	.word   0x34567890
	.word   0x45678901
	.word   0x56789012
	.word   0x23456789
	.word   0x34567890
	.word   0x45678901
	.word   0x56789012

@---------------------------------------------------------------------------------
_start2:
@---------------------------------------------------------------------------------
        /* 
         * Since I don't plan to return to the bootloader,
         * I don't have to save the registers.
         *
         * I'll just set the CPSR for SVC mode, interrupts 
         * off, and ARM instructions.
         */
        mov     r0, #(PSR_MODE_SVC | PSR_I | PSR_F)
        msr     cpsr, r0
        
        /* zero the bss */
        ldr     r1, =_bss_end_
        ldr     r0, =_bss_start_

_bss_init:        
        mov     r2, #0
        cmp     r0, r1
        strlot  r2, [r0], #4
        blo     _bss_init        /* loop while r0 < r1 */ 


        /* --- Initialize stack pointer registers */
        /* Enter IRQ mode and set up the IRQ stack pointer */
        mov     r0, #(PSR_MODE_IRQ | PSR_I | PSR_F)     /* No interrupts */
        msr     cpsr, r0
        ldr     r1, =_irq_stack_size
        ldr     sp, =_irq_stack
        add     sp, sp, r1

        /* Enter FIQ mode and set up the FIQ stack pointer */
        mov     r0, #(PSR_MODE_FIQ | PSR_I | PSR_F)     /* No interrupts */
        msr     cpsr, r0
        ldr     r1, =_fiq_stack_size
        ldr     sp, =_fiq_stack
        add     sp, sp, r1

        /* Enter ABT mode and set up the ABT stack pointer */
        mov     r0, #(PSR_MODE_ABT | PSR_I | PSR_F)     /* No interrupts */
        msr     cpsr, r0
        ldr     r1, =_abt_stack_size
        ldr     sp, =_abt_stack
        add     sp, sp, r1
        
        /* Set up the SVC stack pointer last and stay in SVC mode */
        mov     r0, #(PSR_MODE_SVC | PSR_I | PSR_F)     /* No interrupts */
        msr     cpsr, r0
        ldr     r1, =_svc_stack_size
        ldr     sp, =_svc_stack
        add     sp, sp, r1
        sub     sp, sp, #0x64   

        /* 
         * Initialize the MMU. After we return, the MMU is enabled,
         * and memory may be remapped. I hope we don't remap this
         * memory away.
         */
        ldr     r0, =mem_map
        bl      mmu_init               

        /* 
         * Initialize the exception vectors. This includes the
         * exceptions vectors (0x00000000-0x0000001c), and the 
         * pointers to the exception handlers (0x00000020-0x0000003c).
         */
        mov     r0, #0
        adr     r1, vector_block
        ldmia   r1!, {r2-r9}
        stmia   r0!, {r2-r9}
        ldmia   r1!, {r2-r9}
        stmia   r0!, {r2-r9}

        /* Now we are prepared to start the BSP's C code */
        bl      boot_card

        /* 
         * Theoretically, we could return to what started us up,
         * but we'd have to have saved the registers and stacks.
         * Instead, we'll just reset.
         */
        bl      bsp_reset

        /* We shouldn't get here. If we do, hang */
_hang:  b       _hang

        
/* 
 * This is the exception vector table and the pointers to
 * the functions that handle the exceptions. It's a total
 * of 16 words (64 bytes)
 */
vector_block:   
        ldr     pc, Reset_Handler
        ldr     pc, Undefined_Handler
        ldr     pc, SWI_Handler
        ldr     pc, Prefetch_Handler
        ldr     pc, Abort_Handler
        nop
        ldr     pc, IRQ_Handler
        ldr     pc, FIQ_Handler

Reset_Handler:          b       bsp_reset
Undefined_Handler:      b       Undefined_Handler
SWI_Handler:            b       SWI_Handler 
Prefetch_Handler:       b       Prefetch_Handler
Abort_Handler:          b       Abort_Handler
                        nop
IRQ_Handler:            b       IRQ_Handler
FIQ_Handler:            b       FIQ_Handler

.globl Reset_Handler
.globl Undefined_Handler
.globl SWI_Handler
.globl Prefetch_Handler
.globl Abort_Handler
.globl IRQ_Handler
.globl FIQ_Handler
Code:
/*
 * Cogent CSB336 linker script
 *
 * Copyright (c) 2004 Cogent Computer Systems
 *      written by Jay Monkman <jtm@lopingdog.com>
 *	
 *  The license and distribution terms for this file may be
 *  found in the file LICENSE in this distribution or at
 *
 *  http://www.OARcorp.com/rtems/license.html.
 *
 *
 *  linkcmds,v 1.3 2003/01/20 19:51:11 joel Exp
*/

OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm",
       "elf32-littlearm")
OUTPUT_ARCH(arm)
ENTRY(_start)
/* SEARCH_DIR(/usr/local/rtems-arm-dev-tools/arm-rtems/lib); */


MEMORY {
	sdram : ORIGIN = 0x0c000000, LENGTH = 8M 
}

/*
 * Declare some sizes.
 */

/* The base for SDRAM is set to umon's APPRAMBASE */
_sdram_base = DEFINED(_sdram_base) ? _sdram_base : 0x0c000000; 
_sdram_size = DEFINED(_sdram_size) ? _sdram_size : 8M;


_irq_stack_size = DEFINED(_irq_stack_size) ? _irq_stack_size : 0x1000;
_fiq_stack_size = DEFINED(_fiq_stack_size) ? _fiq_stack_size : 0x400;
_abt_stack_size = DEFINED(_abt_stack_size) ? _abt_stack_size : 0x100;
_svc_stack_size = DEFINED(_svc_stack_size) ? _svc_stack_size : 0x1000;



/* Do we need any of these for elf?
   __DYNAMIC = 0;    */

SECTIONS
{
  .base :
  {
    arm_exception_table = .;    

    arm_reset_vect    = .;     /* 0x00 */
    . += 4;

    arm_undef_vect    = .;     /* 0x04 */
    . += 4;

    arm_swi_vect      = .;     /* 0x08 */
    . += 4;

    arm_iabrt_vect    = .;     /* 0x0c */
    . += 4;

    arm_dabrt_vect    = .;     /* 0x10 */
    . += 4;

    /* no vector here */
    . += 4;

    arm_irq_vect      = .;     /* 0x18 */
    . += 4;

    arm_fiq_vect      = .;     /* 0x1c */
    . += 4;
         /* FIXME: */

    rtems_vector_table = .;
    . += (8 * 4);                     /* 8 ARM interrupts */
	
    bsp_vector_table = .;
    . += (32 * 4);                    /* 32 S3C2400X interrupts */

    . = ALIGN (0x100);


  } > sdram

  .init          : 
  { 
    KEEP (*(.init))
  } > sdram   /*=0*/

  .text      :
  {
	_text_start = .; /*AXF address*/
  CREATE_OBJECT_SYMBOLS
	*(.text) 
	*(.text.*)

        /*
         * Special FreeBSD sysctl sections.
         */
        . = ALIGN (16);
        __start_set_sysctl_set = .;
        *(set_sysctl_*);
        __stop_set_sysctl_set = ABSOLUTE(.);
        *(set_domain_*);
        *(set_pseudo_*);

	/* .gnu.warning sections are handled specially by elf32.em.  */
	*(.gnu.warning)
	*(.gnu.linkonce.t*)
	*(.glue_7)
	*(.glue_7t)

	/* I think these come from the ld docs: */	
	___CTOR_LIST__ = .;
	LONG((___CTOR_END__ - ___CTOR_LIST__) / 4 - 2)
	*(.ctors)
	LONG(0)
	___CTOR_END__ = .;
	___DTOR_LIST__ = .;
	LONG((___DTOR_END__ - ___DTOR_LIST__) / 4 - 2)
	*(.dtors)
	LONG(0)
	___DTOR_END__ = .;

	_etext = .;
	PROVIDE (etext = .);
  } > sdram  

  .fini      :
  {
    KEEP (*(.fini))
  } > sdram  /*=0*/

  .eh_frame : { *(.eh_frame) } > RAM
  .data1   : { *(.data1) } > RAM
  .eh_frame : { *(.eh_frame) } > RAM
  .gcc_except_table : { *(.gcc_except_table) } > RAM

  .rodata :
  {
    *(.rodata)
    *(.rodata.*)
    *(.gnu.linkonce.r*)
  } > sdram
  _ro_end = .; /*AXF address*/

  .data :
  { 
    _data_start = ABSOLUTE(.); /*AXF address*/
    *(.data)
    *(.data.*)
    *(.gnu.linkonce.d*)
    *(.jcr)
    SORT(CONSTRUCTORS)
    _edata = .;
  } > sdram 

  .bss       :
  {
	_bss_start_ = .; /*AXF address*/
	_clear_start = .;
	*(.bss)
	*(.bss.*)
	*(COMMON)
	. = ALIGN(64);
	_clear_end = .;

	. = ALIGN (256);
	_abt_stack = .;
	. += _abt_stack_size;

	. = ALIGN (256);
	_irq_stack = .;
	. += _irq_stack_size;

	. = ALIGN (256);
	_fiq_stack = .;
	. += _fiq_stack_size;

	. = ALIGN (256);
	_svc_stack = .;
	. += _svc_stack_size;

	_bss_end_ = .; /*AXF address*/
	_end = .;
	__end = .;

/* 
 * Ideally, the MMU's translation table would be in SRAM. But we
 * don't have any. If we don't use more regions than TLB entries (64),
 * the lookup will only happen once for each region.
 */
	. = ALIGN (16 * 1024);
	_ttbl_base = .;
	. += (16 * 1024);

	. = ALIGN (1024);
	_bss_free_start = .;

  } > sdram


/* Debugging stuff follows? */

  /* Stabs debugging sections.  */
  .stab 0 : { *(.stab) } 
  .stabstr 0 : { *(.stabstr) } 
  .stab.excl 0 : { *(.stab.excl) } 
  .stab.exclstr 0 : { *(.stab.exclstr) }
  .stab.index 0 : { *(.stab.index) } 
  .stab.indexstr 0 : { *(.stab.indexstr) } 
  .comment 0 : { *(.comment) }
  /* 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) } 
  /*.stack 0x80000 : { _stack = .; *(.stack) }*/
  /* These must appear regardless of  .  */
}
 
Back
Top