xenia-project / xenia

Xbox 360 Emulator Research Project
https://xenia.jp
Other
8.26k stars 1.14k forks source link

KeCreateUserMode / KeEnterUserMode for Xbox1 XEFU emulator #1352

Open emoose opened 5 years ago

emoose commented 5 years ago

(I know supporting the Xbox OG emu etc is pretty much lowest priority, but figure I'd post my findings here in case anyone else wants to look into it.)

These get used by the Xbox OG emulator when the correct launch data is set & imports are fixed (afaik the XNA loader also uses these along with some other sandbox/emulator type apps), looks like supporting these is required for these kind of things to work.

On 360 these pretty much just get passed directly to the hypervisors HvCreateUserMode / HvEnterUserMode funcs, I guess it's used to create some sort of seperate partition to the main kernel & userland?

KeEnterUserMode seems to take a UserMode context (from KeCreateUserMode), a function ptr + two parameters as arguments, the code for it in the kernel does some stuff involving a CONTEXT struct being passed to HV (a field for each register, with the two parameters being used to set r3/r4), maybe other registers get setup there too.

Not sure what kind of differences/restrictions this "UserMode" code might be ran with on 360, maybe we can get away with just running it as normal code (just copy the context args over our current state + and save the actual LR somewhere so we can return to it after the UserMode code has finished executing?) Or maybe start a new thread for it? Tried some things like this but haven't had much luck though, maybe something else gets done by HV before it runs the funcptr...

For anyone interested, the launch data needed for XEFU is as follows:

typedef struct {
  xe::be<uint32_t> Source;
  xe::be<uint32_t> Reason;
  xe::be<uint32_t> LiveEnabled;
  char Padding[0x1F0];
  char XBE[0x200];
} X_FU_LAUNCH_DATA;
static_assert_size(X_FU_LAUNCH_DATA, 0x3FC);

Set Source to 2 (SOURCE_XBOX), Reason to 0, LiveEnabled to 0 and XBE to the full path to the XBE (\Device\Harddisk0\Partition...), then run xefu7b.xex (note that it requires imports fix so that it can import from xefutitle7b.xex properly...) You probably need to setup mount points in emulator.cc too (\Device\Harddisk0\SystemPartition, X: & Y: ...). Also, recommend using the modded Compatibility files so that it doesn't try checking XBE signatures etc.

DrChat commented 5 years ago

.NET games wrapped in a .xex container will also attempt to do this. See Terraria for an example.