xboxscene.org forums

Author Topic: Developing Bochs Bios Loader For Xbox.. A Problem  (Read 328 times)

obcd

  • Archived User
  • Hero Member
  • *
  • Posts: 881
Developing Bochs Bios Loader For Xbox.. A Problem
« on: January 23, 2010, 02:35:00 AM »

Pointers should be 32 bit values, so I don't expect an overflow in them.

You could study the xbeboot linux bootloader code. I have done it once to use it as the windows ce bootloader. There are a few very naughty tricks in it which take a while before you understand them.

Problem is that it was designed under linux. I never managed to compile it with the openxdk tools.
A virtual linux pc environment solved this issue.

I think it's the closest thing you will find that does pretty much what you are looking for.

regards.
Logged

miker00lz

  • Archived User
  • Newbie
  • *
  • Posts: 4
Developing Bochs Bios Loader For Xbox.. A Problem
« Reply #1 on: January 23, 2010, 04:57:00 PM »

QUOTE(obcd @ Jan 23 2010, 03:35 AM) View Post

Pointers should be 32 bit values, so I don't expect an overflow in them.

You could study the xbeboot linux bootloader code. I have done it once to use it as the windows ce bootloader. There are a few very naughty tricks in it which take a while before you understand them.

Problem is that it was designed under linux. I never managed to compile it with the openxdk tools.
A virtual linux pc environment solved this issue.

I think it's the closest thing you will find that does pretty much what you are looking for.

regards.


well, as it turns out it had nothing to do with accessing the file. (but i still changed fopen, etc to use XCreateFile/XReadFile from openxdk instead)  but rather it seems the problem is that the xbox just doesn't like me writing arbitrary data to F000 where every PC's BIOS code resides.

if i just have the code malloc some RAM for the whole read buffer i can load it to there just fine. i wonder if there's any way around this. i even tried a memcpy to f000:0000 from where the buffer was allocated, and it still locks.

i also tried adding asm("cli") to the beginning of the program to disable interrupts, i figured they might have been trying to run some code in that area of RAM but screwed up when the data was modified by me. of course, that didn't work either.

i know it's possible to do this somehow. i read a few days ago an old newsgroup post from 2002 where i guy said he did do this, and the BIOS ran. it panicked when it couldn't find a PS/2 keyboard so he deleted that part of the bochs BIOS source. after that he said the xbox went past there okay, but still locked just before trying to boot something.

i was hoping i'd be able to take it further and figure out why it does that. my thought is that it may be a simple case of the PC BIOS not understanding the xbox hard drive's MBR code, so it locks the system up.
Logged

ldotsfan

  • Archived User
  • Hero Member
  • *
  • Posts: 2072
Developing Bochs Bios Loader For Xbox.. A Problem
« Reply #2 on: January 23, 2010, 07:26:00 PM »

Interesting.

Hope this helps. You might also want to look at the rest of the cromwell source at xbox linux cvs.

Here's a description of the xbox linux boot process. And a more detailed writeup at this location
Logged

xboxmods2977

  • Recovered User
  • Hero Member
  • *
  • Posts: 733
Developing Bochs Bios Loader For Xbox.. A Problem
« Reply #3 on: January 23, 2010, 09:30:00 PM »

Read the "description" in the post above mine and then check this out copied from wikipedia.org.

"The Xbox runs a custom operating system which was once believed to be a modified version of the Windows 2000 kernel.[20] It exposes APIs similar to APIs found in Microsoft Windows, such as DirectX 8.1.

Sandy Duncan, former VP of Xbox in Europe, however states that "the [Xbox] Kernel was based on Windows NT...but that was about 150K of code....". [21] The system software may have been based on the Windows NT architecture that powered Windows 2000; it is not a modified version of either."


I thought that was pretty interesting. So is it or isn't it?? biggrin.gif

Logged

ldotsfan

  • Archived User
  • Hero Member
  • *
  • Posts: 2072
Developing Bochs Bios Loader For Xbox.. A Problem
« Reply #4 on: May 05, 2010, 07:21:00 AM »

QUOTE(miker00lz @ Jan 24 2010, 06:48 PM) View Post

regarding my bochs BIOS boot idea, from what i understand i am going to have to switch the CPU back to 16-bit real mode to even think about running it. this is getting more complicated than i expected so i'm going to put it on hold until i can do some more research.

You can look at PBL 1.4 source which is based on xbox linux's xbe loader. Extracted a portion of the code

CODE

void loadbios(unsigned char *rom, CONFIGENTRY *entry) {
    long ShadowRomPos;
    long RomSize;
    int i;
    int sum = 0;

    PHYSICAL_ADDRESS PhysicalRomPos;
    PVOID EntryPoint2BL;
    ULONG Version = 0;

    ULONG val;
    PUCHAR KernelParamPtr = 0;
    PVOID CopyPtr = 0;
    PVOID RC4State = 0;
    PVOID TempPtr = 0;
    PVOID Virt2BL = 0;
    PCHAR ParsePtr = 0;

    UCHAR RC4Key[16];
    UCHAR EEPROMKey[16];

    // Load the kernel image into RAM
    RomSize = MAX_KERNEL_SIZE;

    ShadowRomPos = LoadShadowROM(rom, &RomSize);

    // Get physical address of rom
    PhysicalRomPos = MmGetPhysicalAddress((PVOID)ShadowRomPos);

    // Allocate memory for the 2bl.  Has to be at 0x00400000
    printk("Allocate 2bl mem\n");
    Virt2BL = MmAllocateContiguousMemoryEx((ULONG) THE_2BL_SIZE,MIN_2BL, MAX_2BL, 0, PAGE_READWRITE);
    if (!Virt2BL) {
        Die("\nNo memory for 2BL!");
    }

    // Parse the RC4Key from the config file
    printk("Parsing RC4 key: %s\n",entry->szRC4Key);
    memset(RC4Key,0,16);
    ParsePtr = (PCHAR)(entry->szRC4Key);
     for (i = 0; *ParsePtr && i < 16; i++)
    {
        while(isspace(*ParsePtr))
        {
            ++ParsePtr;
        }
        val = strtoul(ParsePtr, &ParsePtr, 0);
        sum += val;
        RC4Key = (UCHAR)val;
    }

    CopyPtr = (PVOID)(ShadowRomPos + (SHADOW_ROM_SIZE - 0x6200));

    // If the RC4 key wasn't blank
    if (sum > 0)
    {
        printk("Decrypting 2bl\n");
        // Allocate memory for the RC4 state array
        RC4State = MmAllocateContiguousMemoryEx(0x100,MIN_KERNEL, MAX_KERNEL, 0, PAGE_READWRITE);
        if (!RC4State) {
            Die("\nNo memory for RC4 state!");
        }

        // Decrypt the 2bl
        XcRC4Key(RC4State, 0x10, RC4Key);
        XcRC4Crypt(RC4State, 0x6000, CopyPtr);

        MmFreeContiguousMemory(RC4State);    
    }

    // Copy the 2bl to the appropriate location
    printk("Copying 2bl\n");
    memcpy(Virt2BL, CopyPtr, THE_2BL_SIZE);


        // Detect xbox version
    asm(
        "movw    $0xCF8, %%dx\n"
        "movl    $0x80000810, %%eax\n"
        "outl    %%eax, %%dx\n"
        "addb    $4, %%dl\n"
        "inl     %%dx, %%eax\n"
        "mov     %%eax, %0\n"
        : "=m" (Version)
        : /* no input registers */
        : "%dx", "%eax", "%dl"
    );

    printk("Detecting xbox version: %08x\n", Version);

    // Pick appropriate EEprom key from config if specified
    memset(EEPROMKey,0,16);
    sum = 0;
    if (Version == 0x8001)
    {
        printk("Xbox is version 1.0\n");
        // 1.0
        if (strlen(entry->szEEPROMKey1_0) > 0)
        {
            printk("Parsing EEPROM 1.0 key: %s\n",entry->szEEPROMKey1_0);
            ParsePtr = (PCHAR)(entry->szEEPROMKey1_0);
             for (i = 0; *ParsePtr && i < 16; i++)
            {
                while(isspace(*ParsePtr))
                {
                    ++ParsePtr;
                }
                val = strtoul(ParsePtr, &ParsePtr, 0);
                sum += val;
                EEPROMKey = (UCHAR)val;
            }
        }
    }
    else
    {
        printk("Xbox is version 1.1+\n");
        // 1.1+
        if (strlen(entry->szEEPROMKey1_1) > 0)
        {
            printk("Parsing EEPROM 1.1 key: %s\n",entry->szEEPROMKey1_1);
            ParsePtr = (PCHAR)(entry->szEEPROMKey1_1);
             for (i = 0; *ParsePtr && i < 16; i++)
            {
                while(isspace(*ParsePtr))
                {
                    ++ParsePtr;
                }
                val = strtoul(ParsePtr, &ParsePtr, 0);
                sum += val;
                EEPROMKey = (UCHAR)val;
            }
        }
    }

    
    // Patch in the EEprom key if it was specified
    if (sum > 0)
    {
        printk("Patching EEPROM key\n");
        memcpy((PVOID)((ShadowRomPos + (SHADOW_ROM_SIZE - 0x6200)) + 0x64),EEPROMKey, 16);
        memcpy((PVOID)(Virt2BL+0x64),EEPROMKey, 16);

        for(i=0;i<16;i++)
        {
            printk("0x%02x ",EEPROMKey);
        }
        printk("\n");
    }



    
    // set the kernel param string
    printk("Patching param string\n");
    KernelParamPtr = (PUCHAR)0x80400004;
    memcpy(KernelParamPtr, (PUCHAR)" /SHADOW /HDBOOT", 16);

    // Calculate the 2bl entry point
    printk("Calculating 2bl entry point\n");
    TempPtr = (PVOID)(*(PULONG)Virt2BL + 0x8036FFFC);
    EntryPoint2BL = (PVOID)(*(PULONG)TempPtr) + 0x80000000;

    printk("Calling 2bl\n");

    if (!entry->DebugFlag)
    {
        // Clear the framebuffer
        fb_clear();
    }

    // Call the 2bl
    asm(
        "call   %%eax\n"
        : /* no output */
        : "a" (EntryPoint2BL), "c" (PhysicalRomPos)
    );

}
Logged

halofreak1990

  • Archived User
  • Newbie
  • *
  • Posts: 46
Developing Bochs Bios Loader For Xbox.. A Problem
« Reply #5 on: May 07, 2010, 04:58:00 PM »

This may be a stupid question, but are you sure you are writing to a physical memory address?
It could very well be you are writing to a virtual memory address, which might explain the hanging.

I would suggest using MmGetPhysicalAddress() to get the proper physical memory address you're looking for, and then try to write to it to see if it works. You might also be required to use MmLockUnlockBufferPages() but I'm not sure. I've based this suggestion on the usb code found at xbdev.net
Where the same problem (hanging) was encountered due to writing to wrong memory addresses and locked/unlocked pages.
Logged

ldotsfan

  • Archived User
  • Hero Member
  • *
  • Posts: 2072
Developing Bochs Bios Loader For Xbox.. A Problem
« Reply #6 on: July 21, 2010, 04:17:00 AM »

QUOTE(obcd @ Jan 23 2010, 05:35 PM) View Post

You could study the xbeboot linux bootloader code. I have done it once to use it as the windows ce bootloader. There are a few very naughty tricks in it which take a while before you understand them.

Problem is that it was designed under linux. I never managed to compile it with the openxdk tools.
A virtual linux pc environment solved this issue.

I'm not sure if you are still interested but I think this is also related to Windows CE Loader. I found this:
http://xbox-bsd.cvs......pe=text/plain.

It is linked against Free-xdk and not OpenXdk. The code base uses Free-xdk's libraries.
Logged