[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:
Gliniak
2026-06-22 21:32:42 +02:00
committed by Radosław Gliński
parent 0f281b6cb6
commit 9c8e34b29e
3 changed files with 45 additions and 45 deletions

View File

@@ -1276,8 +1276,7 @@ XE_COLD
uint32_t KernelState::CreateKeTimestampBundle() { uint32_t KernelState::CreateKeTimestampBundle() {
auto crit = global_critical_region::Acquire(); auto crit = global_critical_region::Acquire();
uint32_t pKeTimeStampBundle = const uint32_t pKeTimeStampBundle = 0x80240EE0;
memory_->SystemHeapAlloc(sizeof(X_TIME_STAMP_BUNDLE));
X_TIME_STAMP_BUNDLE* lpKeTimeStampBundle = X_TIME_STAMP_BUNDLE* lpKeTimeStampBundle =
memory_->TranslateVirtual<X_TIME_STAMP_BUNDLE*>(pKeTimeStampBundle); memory_->TranslateVirtual<X_TIME_STAMP_BUNDLE*>(pKeTimeStampBundle);

View File

@@ -69,6 +69,18 @@ bool XboxkrnlModule::SendPIXCommand(const char* cmd) {
XboxkrnlModule::XboxkrnlModule(Emulator* emulator, KernelState* kernel_state) XboxkrnlModule::XboxkrnlModule(Emulator* emulator, KernelState* kernel_state)
: KernelModule(kernel_state, "xe:\\xboxkrnl.exe") { : 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_); RegisterExportTable(export_resolver_);
// Register all exported functions. // 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. // 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 // 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. // 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) { if (!cvars::kernel_debug_monitor) {
pKeDebugMonitorData = memory_->SystemHeapAlloc(4); auto lpKeDebugMonitorData = memory_->TranslateVirtual(KeDebugMonitorData);
auto lpKeDebugMonitorData = memory_->TranslateVirtual(pKeDebugMonitorData);
xe::store_and_swap<uint32_t>(lpKeDebugMonitorData, 0); xe::store_and_swap<uint32_t>(lpKeDebugMonitorData, 0);
} else { } else {
pKeDebugMonitorData = uint32_t pKeDebugMonitorData =
memory_->SystemHeapAlloc(4 + sizeof(X_KEDEBUGMONITORDATA)); memory_->SystemHeapAlloc(sizeof(X_KEDEBUGMONITORDATA));
xe::store_and_swap<uint32_t>(memory_->TranslateVirtual(pKeDebugMonitorData), xe::store_and_swap<uint32_t>(memory_->TranslateVirtual(pKeDebugMonitorData),
pKeDebugMonitorData + 4); pKeDebugMonitorData);
auto lpKeDebugMonitorData = auto lpKeDebugMonitorData =
memory_->TranslateVirtual<X_KEDEBUGMONITORDATA*>(pKeDebugMonitorData + memory_->TranslateVirtual<X_KEDEBUGMONITORDATA*>(pKeDebugMonitorData);
4);
std::memset(lpKeDebugMonitorData, 0, sizeof(X_KEDEBUGMONITORDATA)); std::memset(lpKeDebugMonitorData, 0, sizeof(X_KEDEBUGMONITORDATA));
lpKeDebugMonitorData->callback_fn = lpKeDebugMonitorData->callback_fn =
GenerateTrampoline("KeDebugMonitorCallback", KeDebugMonitorCallback); GenerateTrampoline("KeDebugMonitorCallback", KeDebugMonitorCallback);
} }
export_resolver_->SetVariableMapping( export_resolver_->SetVariableMapping(
"xboxkrnl.exe", ordinals::KeDebugMonitorData, pKeDebugMonitorData); "xboxkrnl.exe", ordinals::KeDebugMonitorData, KeDebugMonitorData);
// KeCertMonitorData (?*) // KeCertMonitorData (?*)
// Always set to zero, ignored. // Always set to zero, ignored.
uint32_t pKeCertMonitorData; const uint32_t KeCertMonitorData = 0x80207A60;
if (!cvars::kernel_cert_monitor) { if (!cvars::kernel_cert_monitor) {
pKeCertMonitorData = memory_->SystemHeapAlloc(4); auto lpKeCertMonitorData = memory_->TranslateVirtual(KeCertMonitorData);
auto lpKeCertMonitorData = memory_->TranslateVirtual(pKeCertMonitorData);
xe::store_and_swap<uint32_t>(lpKeCertMonitorData, 0); xe::store_and_swap<uint32_t>(lpKeCertMonitorData, 0);
} else { } else {
pKeCertMonitorData = uint32_t pKeCertMonitorData =
memory_->SystemHeapAlloc(4 + sizeof(X_KECERTMONITORDATA)); memory_->SystemHeapAlloc(sizeof(X_KECERTMONITORDATA));
xe::store_and_swap<uint32_t>(memory_->TranslateVirtual(pKeCertMonitorData), xe::store_and_swap<uint32_t>(memory_->TranslateVirtual(pKeCertMonitorData),
pKeCertMonitorData + 4); pKeCertMonitorData);
auto lpKeCertMonitorData = auto lpKeCertMonitorData =
memory_->TranslateVirtual<X_KECERTMONITORDATA*>(pKeCertMonitorData + 4); memory_->TranslateVirtual<X_KECERTMONITORDATA*>(pKeCertMonitorData);
std::memset(lpKeCertMonitorData, 0, sizeof(X_KECERTMONITORDATA)); std::memset(lpKeCertMonitorData, 0, sizeof(X_KECERTMONITORDATA));
lpKeCertMonitorData->callback_fn = lpKeCertMonitorData->callback_fn =
GenerateTrampoline("KeCertMonitorCallback", KeCertMonitorCallback); GenerateTrampoline("KeCertMonitorCallback", KeCertMonitorCallback);
} }
export_resolver_->SetVariableMapping( export_resolver_->SetVariableMapping(
"xboxkrnl.exe", ordinals::KeCertMonitorData, pKeCertMonitorData); "xboxkrnl.exe", ordinals::KeCertMonitorData, KeCertMonitorData);
// XboxHardwareInfo (XboxHardwareInfo_t, 16b) // XboxHardwareInfo (XboxHardwareInfo_t, 16b)
// flags cpu# ? ? ? ? ? ? // flags cpu# ? ? ? ? ? ?
@@ -133,21 +142,21 @@ XboxkrnlModule::XboxkrnlModule(Emulator* emulator, KernelState* kernel_state)
// //
// From kernel dissasembly, after storage is initialized // From kernel dissasembly, after storage is initialized
// XboxHardwareInfo flags is set with flag 5 (0x20). // XboxHardwareInfo flags is set with flag 5 (0x20).
uint32_t pXboxHardwareInfo = memory_->SystemHeapAlloc(16); const uint32_t XboxHardwareInfo = 0x801D0030;
auto lpXboxHardwareInfo = memory_->TranslateVirtual(pXboxHardwareInfo); auto lpXboxHardwareInfo = memory_->TranslateVirtual(XboxHardwareInfo);
export_resolver_->SetVariableMapping( 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<uint32_t>(lpXboxHardwareInfo + 0, 0x20); // flags
xe::store_and_swap<uint8_t>(lpXboxHardwareInfo + 4, 0x06); // cpu count xe::store_and_swap<uint8_t>(lpXboxHardwareInfo + 4, 0x06); // cpu count
// Remaining 11b are zeroes? // Remaining 11b are zeroes?
// ExConsoleGameRegion, probably same values as keyvault region uses? // ExConsoleGameRegion, probably same values as keyvault region uses?
// Just return all 0xFF, should satisfy anything that checks it // Just return all 0xFF, should satisfy anything that checks it
uint32_t pExConsoleGameRegion = memory_->SystemHeapAlloc(4); const uint32_t ExConsoleGameRegion = 0x80205150;
auto lpExConsoleGameRegion = memory_->TranslateVirtual(pExConsoleGameRegion); auto lpExConsoleGameRegion = memory_->TranslateVirtual(ExConsoleGameRegion);
export_resolver_->SetVariableMapping( export_resolver_->SetVariableMapping(
"xboxkrnl.exe", ordinals::ExConsoleGameRegion, pExConsoleGameRegion); "xboxkrnl.exe", ordinals::ExConsoleGameRegion, ExConsoleGameRegion);
xe::store<uint32_t>(lpExConsoleGameRegion, 0xFFFFFFFF); xe::store<uint16_t>(lpExConsoleGameRegion, 0xFFFF);
// XexExecutableModuleHandle (?**) // XexExecutableModuleHandle (?**)
// Games try to dereference this to get a pointer to some module struct. // 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 // 0x80101000 <- our module structure
// 0x80101058 <- pointer to xex header // 0x80101058 <- pointer to xex header
// 0x80101100 <- xex header base // 0x80101100 <- xex header base
uint32_t ppXexExecutableModuleHandle = memory_->SystemHeapAlloc(4); const uint32_t XexExecutableModuleHandle = 0x802080D4;
export_resolver_->SetVariableMapping("xboxkrnl.exe", export_resolver_->SetVariableMapping("xboxkrnl.exe",
ordinals::XexExecutableModuleHandle, ordinals::XexExecutableModuleHandle,
ppXexExecutableModuleHandle); XexExecutableModuleHandle);
// ExLoadedImageName (char*) // ExLoadedImageName (char*)
// The full path to loaded image/xex including its name. // The full path to loaded image/xex including its name.
// Used usually in custom dashboards (Aurora) // Used usually in custom dashboards (Aurora)
// Todo(Gliniak): Confirm that official kernel always allocate space for this uint32_t ExLoadedImageName = 0x80207E60;
// variable.
uint32_t ppExLoadedImageName =
memory_->SystemHeapAlloc(kExLoadedImageNameSize);
export_resolver_->SetVariableMapping( export_resolver_->SetVariableMapping(
"xboxkrnl.exe", ordinals::ExLoadedImageName, ppExLoadedImageName); "xboxkrnl.exe", ordinals::ExLoadedImageName, ExLoadedImageName);
// ExLoadedCommandLine (char*) // ExLoadedCommandLine (char*)
// The name of the xex. Not sure this is ever really used on real devices. // 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()) { if (cvars::cl.length()) {
command_line += " " + cvars::cl; 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, xe::align(static_cast<uint32_t>(command_line.length()) + 1,
static_cast<uint32_t>(kExLoadedCommandLineSize)); static_cast<uint32_t>(kExLoadedCommandLineSize));
uint32_t pExLoadedCommandLine = memory_->SystemHeapAlloc(command_line_length); const uint32_t ExLoadedCommandLine = 0x80207C60;
auto lpExLoadedCommandLine = memory_->TranslateVirtual(pExLoadedCommandLine); auto lpExLoadedCommandLine = memory_->TranslateVirtual(ExLoadedCommandLine);
export_resolver_->SetVariableMapping( export_resolver_->SetVariableMapping(
"xboxkrnl.exe", ordinals::ExLoadedCommandLine, pExLoadedCommandLine); "xboxkrnl.exe", ordinals::ExLoadedCommandLine, ExLoadedCommandLine);
std::memset(lpExLoadedCommandLine, 0, command_line_length); std::memset(lpExLoadedCommandLine, 0, command_line_length);
std::memcpy(lpExLoadedCommandLine, command_line.c_str(), std::memcpy(lpExLoadedCommandLine, command_line.c_str(),
command_line.length()); command_line.length());
@@ -196,10 +202,10 @@ XboxkrnlModule::XboxkrnlModule(Emulator* emulator, KernelState* kernel_state)
// XboxKrnlVersion (8b) // XboxKrnlVersion (8b)
// Kernel version, looks like 2b.2b.2b.2b. // Kernel version, looks like 2b.2b.2b.2b.
// I've only seen games check >=, so we just fake something here. // I've only seen games check >=, so we just fake something here.
uint32_t pXboxKrnlVersion = memory_->SystemHeapAlloc(sizeof(KernelVersion)); const uint32_t XboxKrnlVersion = 0x8004045C;
auto lpXboxKrnlVersion = memory_->TranslateVirtual(pXboxKrnlVersion); auto lpXboxKrnlVersion = memory_->TranslateVirtual(XboxKrnlVersion);
export_resolver_->SetVariableMapping( export_resolver_->SetVariableMapping(
"xboxkrnl.exe", ordinals::XboxKrnlVersion, pXboxKrnlVersion); "xboxkrnl.exe", ordinals::XboxKrnlVersion, XboxKrnlVersion);
std::memcpy(lpXboxKrnlVersion, kernel_state_->GetKernelVersion(), std::memcpy(lpXboxKrnlVersion, kernel_state_->GetKernelVersion(),
sizeof(KernelVersion)); sizeof(KernelVersion));

View File

@@ -290,11 +290,6 @@ bool Memory::Initialize() {
kMemoryProtectRead | kMemoryProtectWrite, false, kMemoryProtectRead | kMemoryProtectWrite, false,
&hypervisor_range); &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 // Value taken from 544307D5. Title explicitly access this address and this is
// a value underneath it (It's constant between multiple runs) // a value underneath it (It's constant between multiple runs)
uint32_t value_to_write = xe::byte_swap(0x2a6e3f38); uint32_t value_to_write = xe::byte_swap(0x2a6e3f38);