QUOTE(miker00lz @ Jan 24 2010, 06:48 PM)
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)
);
}