[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() {
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);

View File

@@ -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));

View File

@@ -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);