xboxscene.org forums

Author Topic: Creating A Xbe From Linux  (Read 361 times)

ldotsfan

  • Archived User
  • Hero Member
  • *
  • Posts: 2072
Creating A Xbe From Linux
« on: October 14, 2012, 06:53:00 AM »

There is one more method originated by rmenhal and used in driveimageutils and thanks to a post by dus, I managed to recreate and test this out with a recent version of gcc, ld and nasm.

It uses a ld script to create a valid XBE file, see this

CODE

/*
 * ldscript.ld
 * GNU LD script for XBE (Xbox executable) files.
 *
 * Copyright 2004 rmenhal
 *
 * Licensed under GNU General Public License version 2. See the file COPYING
 * for details.
 */

OUTPUT_FORMAT("binary");
OUTPUT_ARCH("i386");

BASE_ADDRESS = 0x10000;

SECTIONS {

    .headers ( BASE_ADDRESS ) : AT ( 0 ) {

        /* Image header */

        LONG( 0x48454258 );        /* XBE magic ("XBEH") */
        . = . + 0x100;            /* RSA signature */
        LONG( BASE_ADDRESS );        /* Base address */
        LONG( SIZEOF(.headers) );    /* Size reserved for headers */
        LONG( ADDR(.bss) + SIZEOF(.bss) ); /* Size of image */
        LONG( image_header_size );    /* Size for image header */
        LONG( 0x41b384e0 );        /* Time/date stamp */
        LONG( cert_header );        /* Certificate address */
        LONG( section_headers_size / 0x38 ); /* Number of sections */
        LONG( section_headers );        /* Section headers address */
        LONG( 0 );            /* Init flags */
        LONG( ( ( -1 - ABSOLUTE(boot) ) & 0xA8FC57AB ) + ( ABSOLUTE(boot) & ( -1 - 0xA8FC57AB ) ) ); /* Entry point address */
        LONG( 0 );            /* TLS address */
        LONG( 0 );            /* PE stack commit */
        LONG( 0 );            /* PE heap reserve */
        LONG( 0 );            /* PE heap commit */
        LONG( 0 );            /* PE base address */
        LONG( 0 );            /* PE size of image */
        LONG( 0 );            /* PE checksum */
        LONG( 0 );            /* PE time/date */
        LONG( debug_path );        /* Debug pathname address */
        LONG( debug_path );        /* Debug filename address */
        LONG( debug_unicode_path );    /* Debug unicode name address */
        LONG( ( ( -1 - kernel_thunk_table ) & 0x5B6D40B6 ) + ( kernel_thunk_table & ( -1 - 0x5B6D40B6 ) ) ); /* Kernel thunk table address */
        LONG( 0 );            /* Non-kernel import dir addx */
        LONG( 0 );            /* Number of library versions */
        LONG( 0 );            /* Library versions address */
        LONG( 0 );            /* Kernel library version addx */
        LONG( 0 );            /* XAPI library version addx */
        LONG( 0 );            /* Logo bitmap address */
        LONG( 0 );            /* Logo bitmap size */
        
        image_header_size = .;


        /* Certificate header */

        cert_header = ABSOLUTE(.);

        LONG( cert_header_size );    /* Certificate header size */
        LONG( 0x41b384e0 );        /* Time/date */
        LONG( 0 );            /* Title ID */
        SHORT( 0x49 ); SHORT( 0x53 ); SHORT( 0x4f ); SHORT( 0x20 );
        SHORT( 0x42 ); SHORT( 0x61 ); SHORT( 0x63 ); SHORT( 0x6b );
        SHORT( 0x75 ); SHORT( 0x70 ); SHORT( 0x20 ); SHORT( 0x55 );
        SHORT( 0x74 ); SHORT( 0x69 ); SHORT( 0x6c ); SHORT( 0x69 );
        SHORT( 0x74 ); SHORT( 0x79 ); SHORT( 0x00 ); SHORT( 0x00 );
        SHORT( 0x00 ); SHORT( 0x00 ); SHORT( 0x00 ); SHORT( 0x00 );
        SHORT( 0x00 ); SHORT( 0x00 ); SHORT( 0x00 ); SHORT( 0x00 );
        SHORT( 0x00 ); SHORT( 0x00 ); SHORT( 0x00 ); SHORT( 0x00 );
        SHORT( 0x00 ); SHORT( 0x00 ); SHORT( 0x00 ); SHORT( 0x00 );
        SHORT( 0x00 ); SHORT( 0x00 ); SHORT( 0x00 ); SHORT( 0x00 );
        /* . = . + 0x50; */            /* Title name */
        . = . + 0x40;            /* Alternative title IDs */
        LONG( 0xC0FFFFFF );        /* Allowed media */
        LONG( 0x80000007 );        /* Game regions */
        LONG( 0xFFFFFFFF );        /* Game ratings */
        LONG( 0 );            /* Disk number */
        LONG( 0 );            /* Version */
        . = . + 0x10;            /* LAN key */
        . = . + 0x10;            /* Signature key */
        . = . + 0x100;            /* Alternative signature keys */

        cert_header_size = ABSOLUTE(.) - cert_header;


        /* Section headers */

        section_headers = ABSOLUTE(.);

        /* .text section */

        LONG( 0x7 );            /* Section flags */
        LONG( BASE_ADDRESS + LOADADDR(.text) ); /* Section virtual address */
        LONG( SIZEOF(.text) + SIZEOF(.data) + SIZEOF(.bss) ); /* Section virtual size */
        LONG( LOADADDR(.text) );        /* Section raw/file address */
        LONG( SIZEOF(.text) + SIZEOF(.data) ); /* Section raw/file size */
        LONG( text_section_name );    /* Section name address */
        LONG( 0 );            /* Section reference count */
        LONG( text_head_count );        /* Head shared page ref addx */
        LONG( text_tail_count );        /* Tail shared page ref addx */
        . = . + 20;            /* Section SHA-1 hash */

        section_headers_size = ABSOLUTE(.) - section_headers;
        

        text_section_name = ABSOLUTE(.);
        BYTE( 0x2E ); BYTE( 0x74 ); BYTE( 0x65 ); BYTE( 0x78 );
        BYTE( 0x74 ); BYTE( 0x00 ); BYTE( 0x00 ); BYTE( 0x00 );
        text_head_count = ABSOLUTE(.);
        LONG( 0 );
        text_tail_count = ABSOLUTE(.);
        LONG( 0 );


        debug_path = ABSOLUTE(.);
        . = . + 40;

        debug_unicode_path = ABSOLUTE(.);
        . = . + 40;

        . = 0x1000;
    }

    .text ( BASE_ADDRESS + SIZEOF(.headers) ) : AT ( SIZEOF(.headers) ) {
        *(.text);
        *(.rodata);
                *(.rodata.*);
    }

    .data ( BASE_ADDRESS + LOADADDR(.text) + SIZEOF(.text) ) : AT ( LOADADDR(.text) + SIZEOF(.text) ) {
        *(.data);
    }

    .bss ( BASE_ADDRESS + LOADADDR(.data) + SIZEOF(.data) ) : AT ( LOADADDR(.data) + SIZEOF(.data) ) {
        *(COMMON)
    }
}


This has implications in a few of my projects:
1. Linux based dash
2. hdd partitioning in linux: xboxdumper, LUD, chimp2618.
3. Extending nkpatcher with C code components.

I intend to develop this further.
Logged

ldotsfan

  • Archived User
  • Hero Member
  • *
  • Posts: 2072
Creating A Xbe From Linux
« Reply #1 on: July 17, 2010, 09:15:00 AM »

I know of the following methods for compiling a XBE:

a. M$ XDK. DirectX API, MS XDK API and xbox kernel support. Executables are not freely distributable.
b. OpenXDK. Uses Cxbe to generate the XBE from PE executable and relies on Cygwin primarily - though it might work on MinGW and Linux (with the help of cross-compiler). I find it inconvenient that gcc is used to compile a PE and Cxbe is needed to generate the actual XBE. Library support: OpenXDK's , newLib, SDL,xbox kernel. Executables are freely distributable though.
c. NASM. rmenhal's nkpatcher uses this. Assembly language is used instead of C/C++. Can call xbox kernel. Freely distributable executables. A variant of this is hex editing of XBE directly.

There is actually another method that is lesser known. Team Xbox Linux came up with their own imagebld tool which converts a Linux ELF binary compiled by gcc into a XBE. This is employed in xbetool, Cromwell and their derivatives (Phoenix Bios Loader, Gentoox Loader). This method used the GNU toolchain (gcc, binutils) to generate ELF and allows xbox kernel calls via kernel thunks.

For Linux fans, this avoids use of Cygwin and cxbe and M$ Win OS completely in the generation of XBE. I intend to release a source code example of this method if I can integrate more of the OpenXDK APIs beyond just xbox kernel calls.

To be continued.
Logged

ldotsfan

  • Archived User
  • Hero Member
  • *
  • Posts: 2072
Creating A Xbe From Linux
« Reply #2 on: July 21, 2010, 04:05:00 AM »

Seems like Artifex (Team Xodus and creator of WinCe.net on Xbox) released similar code under Free-XDK in the past.

I'll look at his code instead of reinventing the wheel.
Logged

Hyper_Eye

  • Recovered User
  • Sr. Member
  • *
  • Posts: 366
Creating A Xbe From Linux
« Reply #3 on: July 21, 2010, 09:03:00 AM »

Right now I use M$ XDK in virtualbox on my Gentoo desktop (been a Gentoo junkie for about 7 years now and a Linux junkie for 10.) I am certain that I have built an xbe from openxdk in Linux before. It would have been quite some time ago so my memory is fuzzy but I don't remember having to do much to get it working. I will have to look through my stuff and see what I find. Also, I am pretty sure I have looked at Free-XDK in the past but I never did anything with it. Let us know where it leads you.
Logged

ldotsfan

  • Archived User
  • Hero Member
  • *
  • Posts: 2072
Creating A Xbe From Linux
« Reply #4 on: July 21, 2010, 09:01:00 PM »

QUOTE(Hyper_Eye @ Jul 21 2010, 11:03 PM) View Post

I am certain that I have built an xbe from openxdk in Linux before. It would have been quite some time ago so my memory is fuzzy but I don't remember having to do much to get it working. I will have to look through my stuff and see what I find. Also, I am pretty sure I have looked at Free-XDK in the past but I never did anything with it. Let us know where it leads you.

As I've explained in post #1, yes, you can build an xbe with openxdk in linux. But it uses a cross-compiler to generate PE and pretty much everything else in Linux is an ELF so you cannot link any external libraries unless you also have the sources to recompile. Personally I find the openxdk way - use gcc to cross compile and convert PE to XBE too convoluted. I prefer plain old gcc, make and the usual binutils stuff.

Free-XDK has zero documentation other than the source code - at least I couldn't find anything. But with the prior experience of hacking Cromwell/Gentoox Loader, at least I can make some sense of the code. More importantly because it uses the standard gnu compiler toolchain, I can link to external libraries. I think the lwip tcp/ip stack in Gentoox Loader (which in turn came from FlashBios) can be easily adapted and added to free-xdk. I intend to retrofit some of the openxdk stuff back to freexdk as well.

However I haven't done any low-level network programming before so I am going easy on this and taking my time. I don't expect any release any time soon - if there's ever any release.

By the way, what are the dependencies in your version of libSDLx? Is it heavily dependent on MS XDK APIs? I'm asking with the view of somehow merging that into freexdk.
Logged

Hyper_Eye

  • Recovered User
  • Sr. Member
  • *
  • Posts: 366
Creating A Xbe From Linux
« Reply #5 on: July 21, 2010, 11:02:00 PM »

As I stated in the Huntsvegas SVN thread I started with the 0.11_beta libSDLx code. It makes heavy use of DirectX and Xbox API for

Audio: http://svn.huntsvega...SDL_xboxaudio.c
Video: http://svn.huntsvega...SDL_xboxvideo.c
Joystick: http://svn.huntsvega...L_sysjoystick.c

The threads component uses CreateThread() API and the rest looks like it is probably portable as well. But, considering the fact that the 3 listed are the most important components, it is probably not worth starting there. It would probably be better to start with the openxdk port.
Logged