[Kernel] Moved kernel memory allocation to proper location.
- Moved few globals to kernel memory range to prevent overuse of SystemHeapAlloc
This commit is contained in:
committed by
Radosław Gliński
parent
0f281b6cb6
commit
9c8e34b29e
@@ -1276,8 +1276,7 @@ XE_COLD
|
||||
uint32_t KernelState::CreateKeTimestampBundle() {
|
||||
auto crit = global_critical_region::Acquire();
|
||||
|
||||
uint32_t pKeTimeStampBundle =
|
||||
memory_->SystemHeapAlloc(sizeof(X_TIME_STAMP_BUNDLE));
|
||||
const uint32_t pKeTimeStampBundle = 0x80240EE0;
|
||||
X_TIME_STAMP_BUNDLE* lpKeTimeStampBundle =
|
||||
memory_->TranslateVirtual<X_TIME_STAMP_BUNDLE*>(pKeTimeStampBundle);
|
||||
|
||||
|
||||
@@ -69,6 +69,18 @@ bool XboxkrnlModule::SendPIXCommand(const char* cmd) {
|
||||
|
||||
XboxkrnlModule::XboxkrnlModule(Emulator* emulator, KernelState* kernel_state)
|
||||
: KernelModule(kernel_state, "xe:\\xboxkrnl.exe") {
|
||||
// Allocate kernel memory for export global variables. Allocate memory from
|
||||
// 0x80070000 because guest trampoline for kernel, xam and xbdm are allocated
|
||||
// from 0x80040000.
|
||||
auto heap = memory()->LookupHeap(0x80070000);
|
||||
// Allocate remaining memory for kernel
|
||||
uint32_t kernel_range;
|
||||
if (!heap->AllocRange(
|
||||
0x80070000, 0x80280000, 0x200000, 0x1000, kMemoryAllocationCommit,
|
||||
kMemoryProtectRead | kMemoryProtectWrite, false, &kernel_range)) {
|
||||
XELOGW("XboxkrnlModule could not allocate kernel memory!");
|
||||
}
|
||||
|
||||
RegisterExportTable(export_resolver_);
|
||||
|
||||
// Register all exported functions.
|
||||
@@ -81,46 +93,43 @@ XboxkrnlModule::XboxkrnlModule(Emulator* emulator, KernelState* kernel_state)
|
||||
// Set to a valid value when a remote debugger is attached.
|
||||
// Offset 0x18 is a 4b pointer to a handler function that seems to take two
|
||||
// arguments. If we wanted to see what would happen we could fake that.
|
||||
uint32_t pKeDebugMonitorData;
|
||||
const uint32_t KeDebugMonitorData = 0x80207A64;
|
||||
if (!cvars::kernel_debug_monitor) {
|
||||
pKeDebugMonitorData = memory_->SystemHeapAlloc(4);
|
||||
auto lpKeDebugMonitorData = memory_->TranslateVirtual(pKeDebugMonitorData);
|
||||
auto lpKeDebugMonitorData = memory_->TranslateVirtual(KeDebugMonitorData);
|
||||
xe::store_and_swap<uint32_t>(lpKeDebugMonitorData, 0);
|
||||
} else {
|
||||
pKeDebugMonitorData =
|
||||
memory_->SystemHeapAlloc(4 + sizeof(X_KEDEBUGMONITORDATA));
|
||||
uint32_t pKeDebugMonitorData =
|
||||
memory_->SystemHeapAlloc(sizeof(X_KEDEBUGMONITORDATA));
|
||||
xe::store_and_swap<uint32_t>(memory_->TranslateVirtual(pKeDebugMonitorData),
|
||||
pKeDebugMonitorData + 4);
|
||||
pKeDebugMonitorData);
|
||||
auto lpKeDebugMonitorData =
|
||||
memory_->TranslateVirtual<X_KEDEBUGMONITORDATA*>(pKeDebugMonitorData +
|
||||
4);
|
||||
memory_->TranslateVirtual<X_KEDEBUGMONITORDATA*>(pKeDebugMonitorData);
|
||||
std::memset(lpKeDebugMonitorData, 0, sizeof(X_KEDEBUGMONITORDATA));
|
||||
lpKeDebugMonitorData->callback_fn =
|
||||
GenerateTrampoline("KeDebugMonitorCallback", KeDebugMonitorCallback);
|
||||
}
|
||||
export_resolver_->SetVariableMapping(
|
||||
"xboxkrnl.exe", ordinals::KeDebugMonitorData, pKeDebugMonitorData);
|
||||
"xboxkrnl.exe", ordinals::KeDebugMonitorData, KeDebugMonitorData);
|
||||
|
||||
// KeCertMonitorData (?*)
|
||||
// Always set to zero, ignored.
|
||||
uint32_t pKeCertMonitorData;
|
||||
const uint32_t KeCertMonitorData = 0x80207A60;
|
||||
if (!cvars::kernel_cert_monitor) {
|
||||
pKeCertMonitorData = memory_->SystemHeapAlloc(4);
|
||||
auto lpKeCertMonitorData = memory_->TranslateVirtual(pKeCertMonitorData);
|
||||
auto lpKeCertMonitorData = memory_->TranslateVirtual(KeCertMonitorData);
|
||||
xe::store_and_swap<uint32_t>(lpKeCertMonitorData, 0);
|
||||
} else {
|
||||
pKeCertMonitorData =
|
||||
memory_->SystemHeapAlloc(4 + sizeof(X_KECERTMONITORDATA));
|
||||
uint32_t pKeCertMonitorData =
|
||||
memory_->SystemHeapAlloc(sizeof(X_KECERTMONITORDATA));
|
||||
xe::store_and_swap<uint32_t>(memory_->TranslateVirtual(pKeCertMonitorData),
|
||||
pKeCertMonitorData + 4);
|
||||
pKeCertMonitorData);
|
||||
auto lpKeCertMonitorData =
|
||||
memory_->TranslateVirtual<X_KECERTMONITORDATA*>(pKeCertMonitorData + 4);
|
||||
memory_->TranslateVirtual<X_KECERTMONITORDATA*>(pKeCertMonitorData);
|
||||
std::memset(lpKeCertMonitorData, 0, sizeof(X_KECERTMONITORDATA));
|
||||
lpKeCertMonitorData->callback_fn =
|
||||
GenerateTrampoline("KeCertMonitorCallback", KeCertMonitorCallback);
|
||||
}
|
||||
export_resolver_->SetVariableMapping(
|
||||
"xboxkrnl.exe", ordinals::KeCertMonitorData, pKeCertMonitorData);
|
||||
"xboxkrnl.exe", ordinals::KeCertMonitorData, KeCertMonitorData);
|
||||
|
||||
// XboxHardwareInfo (XboxHardwareInfo_t, 16b)
|
||||
// flags cpu# ? ? ? ? ? ?
|
||||
@@ -133,21 +142,21 @@ XboxkrnlModule::XboxkrnlModule(Emulator* emulator, KernelState* kernel_state)
|
||||
//
|
||||
// From kernel dissasembly, after storage is initialized
|
||||
// XboxHardwareInfo flags is set with flag 5 (0x20).
|
||||
uint32_t pXboxHardwareInfo = memory_->SystemHeapAlloc(16);
|
||||
auto lpXboxHardwareInfo = memory_->TranslateVirtual(pXboxHardwareInfo);
|
||||
const uint32_t XboxHardwareInfo = 0x801D0030;
|
||||
auto lpXboxHardwareInfo = memory_->TranslateVirtual(XboxHardwareInfo);
|
||||
export_resolver_->SetVariableMapping(
|
||||
"xboxkrnl.exe", ordinals::XboxHardwareInfo, pXboxHardwareInfo);
|
||||
"xboxkrnl.exe", ordinals::XboxHardwareInfo, XboxHardwareInfo);
|
||||
xe::store_and_swap<uint32_t>(lpXboxHardwareInfo + 0, 0x20); // flags
|
||||
xe::store_and_swap<uint8_t>(lpXboxHardwareInfo + 4, 0x06); // cpu count
|
||||
// Remaining 11b are zeroes?
|
||||
|
||||
// ExConsoleGameRegion, probably same values as keyvault region uses?
|
||||
// Just return all 0xFF, should satisfy anything that checks it
|
||||
uint32_t pExConsoleGameRegion = memory_->SystemHeapAlloc(4);
|
||||
auto lpExConsoleGameRegion = memory_->TranslateVirtual(pExConsoleGameRegion);
|
||||
const uint32_t ExConsoleGameRegion = 0x80205150;
|
||||
auto lpExConsoleGameRegion = memory_->TranslateVirtual(ExConsoleGameRegion);
|
||||
export_resolver_->SetVariableMapping(
|
||||
"xboxkrnl.exe", ordinals::ExConsoleGameRegion, pExConsoleGameRegion);
|
||||
xe::store<uint32_t>(lpExConsoleGameRegion, 0xFFFFFFFF);
|
||||
"xboxkrnl.exe", ordinals::ExConsoleGameRegion, ExConsoleGameRegion);
|
||||
xe::store<uint16_t>(lpExConsoleGameRegion, 0xFFFF);
|
||||
|
||||
// XexExecutableModuleHandle (?**)
|
||||
// Games try to dereference this to get a pointer to some module struct.
|
||||
@@ -158,20 +167,17 @@ XboxkrnlModule::XboxkrnlModule(Emulator* emulator, KernelState* kernel_state)
|
||||
// 0x80101000 <- our module structure
|
||||
// 0x80101058 <- pointer to xex header
|
||||
// 0x80101100 <- xex header base
|
||||
uint32_t ppXexExecutableModuleHandle = memory_->SystemHeapAlloc(4);
|
||||
const uint32_t XexExecutableModuleHandle = 0x802080D4;
|
||||
export_resolver_->SetVariableMapping("xboxkrnl.exe",
|
||||
ordinals::XexExecutableModuleHandle,
|
||||
ppXexExecutableModuleHandle);
|
||||
XexExecutableModuleHandle);
|
||||
|
||||
// ExLoadedImageName (char*)
|
||||
// The full path to loaded image/xex including its name.
|
||||
// Used usually in custom dashboards (Aurora)
|
||||
// Todo(Gliniak): Confirm that official kernel always allocate space for this
|
||||
// variable.
|
||||
uint32_t ppExLoadedImageName =
|
||||
memory_->SystemHeapAlloc(kExLoadedImageNameSize);
|
||||
uint32_t ExLoadedImageName = 0x80207E60;
|
||||
export_resolver_->SetVariableMapping(
|
||||
"xboxkrnl.exe", ordinals::ExLoadedImageName, ppExLoadedImageName);
|
||||
"xboxkrnl.exe", ordinals::ExLoadedImageName, ExLoadedImageName);
|
||||
|
||||
// ExLoadedCommandLine (char*)
|
||||
// The name of the xex. Not sure this is ever really used on real devices.
|
||||
@@ -182,13 +188,13 @@ XboxkrnlModule::XboxkrnlModule(Emulator* emulator, KernelState* kernel_state)
|
||||
if (cvars::cl.length()) {
|
||||
command_line += " " + cvars::cl;
|
||||
}
|
||||
uint32_t command_line_length =
|
||||
const uint32_t command_line_length =
|
||||
xe::align(static_cast<uint32_t>(command_line.length()) + 1,
|
||||
static_cast<uint32_t>(kExLoadedCommandLineSize));
|
||||
uint32_t pExLoadedCommandLine = memory_->SystemHeapAlloc(command_line_length);
|
||||
auto lpExLoadedCommandLine = memory_->TranslateVirtual(pExLoadedCommandLine);
|
||||
const uint32_t ExLoadedCommandLine = 0x80207C60;
|
||||
auto lpExLoadedCommandLine = memory_->TranslateVirtual(ExLoadedCommandLine);
|
||||
export_resolver_->SetVariableMapping(
|
||||
"xboxkrnl.exe", ordinals::ExLoadedCommandLine, pExLoadedCommandLine);
|
||||
"xboxkrnl.exe", ordinals::ExLoadedCommandLine, ExLoadedCommandLine);
|
||||
std::memset(lpExLoadedCommandLine, 0, command_line_length);
|
||||
std::memcpy(lpExLoadedCommandLine, command_line.c_str(),
|
||||
command_line.length());
|
||||
@@ -196,10 +202,10 @@ XboxkrnlModule::XboxkrnlModule(Emulator* emulator, KernelState* kernel_state)
|
||||
// XboxKrnlVersion (8b)
|
||||
// Kernel version, looks like 2b.2b.2b.2b.
|
||||
// I've only seen games check >=, so we just fake something here.
|
||||
uint32_t pXboxKrnlVersion = memory_->SystemHeapAlloc(sizeof(KernelVersion));
|
||||
auto lpXboxKrnlVersion = memory_->TranslateVirtual(pXboxKrnlVersion);
|
||||
const uint32_t XboxKrnlVersion = 0x8004045C;
|
||||
auto lpXboxKrnlVersion = memory_->TranslateVirtual(XboxKrnlVersion);
|
||||
export_resolver_->SetVariableMapping(
|
||||
"xboxkrnl.exe", ordinals::XboxKrnlVersion, pXboxKrnlVersion);
|
||||
"xboxkrnl.exe", ordinals::XboxKrnlVersion, XboxKrnlVersion);
|
||||
std::memcpy(lpXboxKrnlVersion, kernel_state_->GetKernelVersion(),
|
||||
sizeof(KernelVersion));
|
||||
|
||||
|
||||
@@ -290,11 +290,6 @@ bool Memory::Initialize() {
|
||||
kMemoryProtectRead | kMemoryProtectWrite, false,
|
||||
&hypervisor_range);
|
||||
|
||||
uint32_t kernel_range;
|
||||
heaps_.v80000000.Alloc(0x1C0000, 4 * 1024, kMemoryAllocationCommit,
|
||||
kMemoryProtectRead | kMemoryProtectWrite, false,
|
||||
&kernel_range);
|
||||
|
||||
// Value taken from 544307D5. Title explicitly access this address and this is
|
||||
// a value underneath it (It's constant between multiple runs)
|
||||
uint32_t value_to_write = xe::byte_swap(0x2a6e3f38);
|
||||
|
||||
Reference in New Issue
Block a user