GP2X Gp2x Executable Format


Robster

Dodgy hardware mod maker
Joined
Jul 8, 2003
Messages
439
Location
New Zealand
Website
www.cobbleware.com
This is just a suggestion! I think it's a good idea to have a fixed format so that (for example) app launchers or file managers can display metadata about the files on SD. Inside Linux things are already defined, this is for apps that run outside of Linux.

Code:
GP2X "Open Executable" format (name thanks to DJWillis)
 
- filename extension is ".g2x"
- executable files go in "/GP2XBIN"
- game data files go in "/GP2XGAME/<gamename>"
- all data is little-endian
 
Base is 0x00008000
 
Contents of executable file:
 
Address
0x00008000     4 bytes   Jump to start code
0x00008004     4 bytes   Header version. Will start at zero and increase willy-nilly :)
0x00008008     4 bytes   Address of start of bss section
0x0000800C     4 bytes   Address of end of bss section
                         (if start and end of bss are the same, then don't clear anything)
0x00008010     4 bytes   Address of start of data section
0x00008014     4 bytes   Address of end of data section
                         (if start and end of data are the same, then there is no data section)
0x00008018    32 bytes   Application name
0x00008038    32 bytes   Application author
0x00008058    32 bytes   Application description
0x00008078     4 bytes   Application version
                         bits 31-24 are major version
                         bits 23-16 are minor version
                         bits 15-0 are build number
                         So version is "1.2.3456" sort of thing
0x0000807C     4 bytes   bits 31-16 are number of frames in application icon animation
                         (1 for a still image)
                         (if this number is zero, then there is no application icon and the loader should display a default)
                         bits 15-0 are animation speed, milliseconds per frame (a value of zero means 65536 ms/frame)
0x00008080  2048 bytes   32x32, 16-bit hicolour application icon
                         As many icons are included as there are frames in the animation
0x??????80  xxxx bytes   application code
 
stack can go at the top of RAM, perhaps backed off a bit so that a stack underflow won't immediately cause a crash... say, 0x03FF F000 (4k down from the top of RAM).

Comments welcome!
 
The first output of #gp2xdev committee work! :p

Some clarifications.. as there are separate start & end addresses for both data and bss areas that means they can appear in any order in memory as long as they don't overlap. So following are possible (M = mem, C = code, D = data, B = bss):

1) CCCCDDDDBBBBBBMMMMMMM
2) CCCCMMMMMMMMMDDDDBBBB
3) CCCCDDDMMMMMMMBBBBMMM
4) CCCCBBBBBDDDDDMMMMMMM
5) CCCCMMMMMDDDBBBMMMMMM

etc..

However.. who ever publishes the first linkerscript & the first 'b2x' program is strongly engouraged to produce ONLY case 1) like binaries.
 
Quite likely this will all go down the drain once the 'official' SDK comes out, by the way :)

Also might be good to avoid putting anything important in the first 4k of memory, as this is where the NAND bootloader's bootstrap code goes.
 
Nah, the official sdk will probably be crap, so we'll still be using this and running our own stuff ;)
 
OK, a couple of little issues:

1) I'd forgotten about icon transparency, which we should support. We could just define a transparent colour (maybe max red, min green, max blue -> 0xF81F) or include a transparency map, which will be extra space (128 bytes for a 32x32 bitmap).

How do people feel about using 8-bit colour with palette? It would be 1536 bytes for 32x32 + 256x2, so not a huge space saving.

Or we could make a pre-defined palette so that applications would not need to include it, but it's only saving 512 bytes per application and it will constrain people's creativity.

In fact, the more I think about it, the more I think we should allow as much freedom as possible. That means 16-bit colour data plus a separate transparency map. No-one in their right mind is going to make a file manager that uses 8-bit colour, or if they do, they deserve all the trouble they'll find.

2) Should we put in a "file type" value? The only two types I can think of are uncompressed and compressed. Would anyone be interested in that information? Apart from allowing spiv to make his compressor choke gracefully on files that have already been compressed :)
 
OK, hit a little snag: remember that the icons aren't there until the app is post-processed by a elf2g2x sort of program, so they aren't there when the app is linked. Putting in a variable number of icons will cause a problem because it will move the .text section and the addresses won't work any more.

I'm not really interested in writing a linker, so I think the icon graphics should be taken out and put at the end. I've thought of all sorts of options for putting them at the start, and I can't see it working.

Having the icon graphics at the end has a little advantage in that a launcher doesn't need to load the icon graphics to launch the app. It will make a file browser a little bit slower because it will have to seek to the end of the app to get the graphics.

Now, we need to put a pointer to the icon graphics in the header. Because the graphics will follow immediately after the .data section, the existing pointer to .bss in the header would probably be OK to point to the graphics, but another pointer just for that purpose would probably be safer.

Spiv, would that muck up your compressor?
 
For transparency, why not just have a short in the header which tells the color of the transparency? Would be easy to implement, and would make drawing the icon easy too.

As for the variable number of icon graphics, we could reserve an amount of memory, but this may constrain people again, so probably best to put at the end of the file, like you suggest.
 
Actually.. to make the file format a bit more generic.. how about the formal below?

Code:
index:
0x00000000      4 bytes  Magic -- 0x4F584531 i.e. "OXE1"
0x00000004      4 bytes  Address of start of code section (normally 0x00008000)
0x00000008      4 bytes  Size of code section (must be > 0)
0x0000000C      4 bytes  Address of start of data section
0x00000010      4 bytes  Size of data section
                                    If size == 0 then there is no data
0x00000014      4 bytes  Address of start of bss section
0x00000018      4 bytes  Size of bss section
                                    If size == 0 then there is no bss
0x0000001C      32 bytes   Application name
0x0000003C      32 bytes   Application author
0x0000005C      32 bytes   Application description
0x0000007C      4 bytes   Application version
                          bits 31-24 are major version
                          bits 23-16 are minor version
                          bits 15-0 are build number
                          So version is "1.2.3456" sort of thing
0x00000080      1 byte  number of frames in application icon animation
                          - 1 for a still image
                          - 0 for no image (loader should display a default)
0x00000081      1 byte  animation speed in 1/10th sec units (0 meas 256)
0x00000082      2 bytes  icon transparent color
0x00000084      n*2048 bytes   32x32, 16-bit hicolour application icon
                        As many icons are included as there are frames in the animation
0x??????84        xxxx bytes of application code and data

Data and bss areas are not allowed to overlap but may be consecutive.
This format is IMHO easy to parse and allows flexible use of the file.
But now I also assume that the loader actually needs to do some relocation
but is kinda inevitable... or will people start coughing blood if the file is not
a truly flat raw binary?
 
How would you suggest doing the relocation?

Actually, wouldn't it be easier for the loader to just load the header, stuff it somewhere, and then load the code at the address specified in the header and just execute it from there?
 
Squidge posted on Oct 7 2005 at 05:54 PM said:
How would you suggest doing the relocation?

Actually, wouldn't it be easier for the loader to just load the header, stuff it somewhere, and then load the code at the address specified in the header and just execute it from there?

Relocation as moving the code & data where header points it to. Nothing more fancier. The code has been compiled to a fixed position already. I think I didn't say anything about code itself be relocatable.

A loader pseudocode:

Code:
    fh = open("exe");
    hdr = parseHeader(fh);
    read(hdr->codeAddress,hdr->codeSize,fh);
    if (hdr->dataSize) read(hdr->dataAddress,hdr->dataSize);
    if (hdr->bssSize) bzero(hdr->bssAddress,hdr->bssSize);
    jmp(hdr->codeAddress);
 
Last edited by a moderator:
Yep, that's all good. The app can be linked to start executing at the specified start address, the loader can stuff the header somewhere (maybe just ignore the icon data) and load the code etc sections at the specified start address and start executing it.

In the original idea, I was quite keen on having the jump at the start of the file so it could be loaded through UBoot and executed very simply - but that's not necessary. UBoot will only be used for debugging, and for that there won't be any need for a header at all.

I don't think any relocation will be necessary. The code which will end up at the start address in RAM won't be at any fixed location in the .gx2 file, but the loader will sort it out.

Job done?
 
one trivial thing, this is little-endian so the magic should be 0x3145584F or else someone looking at a dump of the file will see "1EXO"... or is that what you wanted?
 
Robster posted on Oct 7 2005 at 08:32 PM said:
one trivial thing, this is little-endian so the magic should be 0x3145584F or else someone looking at a dump of the file will see "1EXO"... or is that what you wanted?
Oh.. right.. Magic would be like:

0x000000: 'O'
0x000001: 'X'
0x000002: 'E'
0x000003: '1' ; this also being the format version..
 
Last edited by a moderator:
ah right, I thought your were going to relocate the actual executable. Was getting a flap on there for a moment :)

Just loading the code/data/bss at different addresses in memory is no problem. Most of the time the sections will be sequential anyway, unless they are compressed?
 
Squidge posted on Oct 7 2005 at 11:21 PM said:
ah right, I thought your were going to relocate the actual executable. Was getting a flap on there for a moment :)

Just loading the code/data/bss at different addresses in memory is no problem. Most of the time the sections will be sequential anyway, unless they are compressed?

Having separate places for sections does allow some magic -- when really required. That's why I wanted that option there. But in majority of cases doing good old sequential way is the right way to go.
 
Last edited by a moderator:
i'd suggest a 48x48 or 64x64 sized icons too, although 32x32 is ok too i find it too small for doing pretty pictures sometimes...

what about animated icons like merging all them at the end of the file and specifing the delay between frames, something like the transparency word?


My proposal for the icon/animation specs:

Code:
[GP2x binary...]
<-> the icon/animation section starts here <->
[info]
[transparency value] [delay] [icon data]              (frame1)
[transparency value] [delay] [icon data]              (frame2)
[transparency value] [delay] [icon data]              (frame3)
[...]
[transparency value] [delay] [icon data]              (frameX)
[EOF]



[info] byte
7  6  |  5  | 4  3  2  1  0
 dim   |  C  |   reserved

dim = pixel dimensions for *all* folllowing frames
       00 32x32, 01 48x48, 10 64x64, 11 80x80 pixels

C = compression method for *all* folllowing frames
     1 compressed icons. I suggest raw LZ compression with zlib (easy as hell).
     0 uncompressed icons


[transparency] word
this word  sets the transparent color, in RGB:565 format


[delay] byte
this byte sets the delay in miliseconds to wait *after* showing the current frame


[icon data] variable size
- if icons are uncompressed, the data you find is 32x32, 48x48, 64x64 or 80x80 words containing the current frame in RGB565, being the first pixel the top-left one, classic orientation. 
- if icons are compressed, first you find a word containing the total amount of bytes for the current compressed stream, then you find the whole raw LZ compressed data. the uncompressed data size is obviously 32x32, 48x48, 64x64 or 80x80 words containing the current frame in RGB565, being the first pixel the top-left one, classic orientation. 


final note: animations are looped
 
Hey there Rlyeh :)

If I understand you correctly, you're asking for a few extra features:

1) Extra icon sizes: 48x48, 64x64, 80x80.
I don't know about having varying sizes. In my (non-artist's) imagination, a file launcher where the icons had varying sizes would look a bit messy, and I'd prefer one size. If we actually standardised on a single size that was bigger than 32x32, would that be OK?

If a launcher is to display a list of files that may be launched in a vertical list on the screen, then it could show 7.5 icons at 32x32, or 5 at 48x48, or 3.75 at 64x64, or 3 at 80x80. I do think that less than 5 icons would be too few, but maybe 48x48 would be a good size?

2) Per-icon delay time and transparency colour
Again, I don't know why these would be useful, but they wouldn't be hard to do, so I don't have anything against doing them.

3) Some (optional) compression for the icon data (ZLib by default)
Sounds fine to me. Will zlib get good compression with such a small file?

4) Putting the icon data at the end of the file
No need for this, as we've discovered during this discussion. I'll make a program that will take a .ELF from gcc + some icon files and construct the final file. Putting the icon data at the start will probably make the launcher a bit easier + faster, so we should probably just leave it there.

Anyone else have an opinion?
 
Robster posted on Oct 9 2005 at 07:05 AM said:
Hey there Rlyeh :)

If I understand you correctly, you're asking for a few extra features:

1) Extra icon sizes: 48x48, 64x64, 80x80.
I don't know about having varying sizes. In my (non-artist's) imagination, a file launcher where the icons had varying sizes would look a bit messy, and I'd prefer one size. If we actually standardised on a single size that was bigger than 32x32, would that be OK?

If a launcher is to display a list of files that may be launched in a vertical list on the screen, then it could show 7.5 icons at 32x32, or 5 at 48x48, or 3.75 at 64x64, or 3 at 80x80. I do think that less than 5 icons would be too few, but maybe 48x48 would be a good size?
Everything that is something power of 2 is fine.
2) Per-icon delay time and transparency colour
Again, I don't know why these would be useful, but they wouldn't be hard to do, so I don't have anything against doing them.
I don't see this as an essential feature and would complicate things some what..
3) Some (optional) compression for the icon data (ZLib by default)
Sounds fine to me. Will zlib get good compression with such a small file?
Assuming a small animation where icons are close to each other zlib could do ok.. even with such small amount of data. However, I would go for this as an optional feature.
4) Putting the icon data at the end of the file
No need for this, as we've discovered during this discussion. I'll make a program that will take a .ELF from gcc + some icon files and construct the final file. Putting the icon data at the start will probably make the launcher a bit easier + faster, so we should probably just leave it there.
I prefer having all header stuff at the beginning of the file. Makes it simpler to parse file and scan files when there is no need to load the whole file.
Anyone else have an opinion?
 
Last edited by a moderator:
Hey guys, I already wrote an extensible menu system, so writing a graphic shell for the launcher would be a piece of cake for me. About the icons, let's just scrap animation. When's the last time any of you guys used animated icons on, well, anywhere?

The metadata I suggest would be the following:
- small icon (32x32 for instance) that can go in the file list
- larger icon (64x64, maybe even larger) to show in a more detailed file description. We could for instance split the screen with a list of available programs on the right, and a detailed description of the file under cursor on the left. This then could show the larger, more detailed picture.
- a program description in ascii to go with the beforementioned detailed description (fixed size as not to fuxxor up the exe)

As for transparency, I say if you have 5:6:5 color format, use (31,0,31) as transparent (purple). It's quite standard to use that, and if you really need purple, (31,0,30) is close enough :)
 
Must admit, most of the windows icons I've 'borrowed' have a purple background, so that does backup your transparent color suggestion.
 
Back
Top