Runtime Lifecycle¶
rex::kernel::TitleRuntime, declared in rex/kernel/title_runtime.h, is the object that runs a title. It maps guest memory, creates the kernel services, loads the XEX, connects the title to the systems of the app and starts its main thread. It has three calls: Load, Launch and Unload.
A TitleRuntime is constructed from the PPCImage that codegen writes for the project, the description of the recompiled code. Only one TitleRuntime can be loaded at a time. TitleApp::LaunchTitle calls Load and Launch, and TitleApp::UnloadTitle calls Unload. A tool that only inspects a title calls Load and never Launch.
rex::Result<void> RunTitle(const rex::ppc::PPCImage& image) {
rex::kernel::TitleRuntime title(image);
REX_TRY_VOID(title.Load());
REX_TRY_VOID(title.Launch());
title.Unload();
return rex::Ok();
}
A failed Load leaves the runtime empty. After Unload, the same object can load again:
stateDiagram-v2
direction LR
[*] --> Empty
Empty --> Loaded : Load
Loaded --> Running : Launch
Loaded --> Empty : Unload
Loaded --> Empty : Launch fails
Running --> Empty : Unload
Load¶
Load prepares the title without running any of its code. An image with no recompiled code runs in tool mode, which tools such as rexglue use to read a XEX. Tool mode skips step 2.
Loadmaps guest memory within theruntime.title_memory_mbbudget and creates the kernel services. It creates the kernel modulesxboxkrnl.exe,xam.xexandxbdm.xex, the host objects that stand for the system libraries a XEX imports from. It then mountstitle.game_rootasgame:. Iftitle.game_rootis empty,Loadlogs a warning and skips the mounts.Loadfills the function table, which maps each guest function address to its recompiled function.Loadregisters the DLL modules of the image. For each DLL module of the project, the generatedregister_modulesfunction passes its PE name, its guest path and its host library toIModuleRegistry::RegisterRecompiledModule. An empty host library name means that the code is linked into the executable.Loadadds each file intitle.importsas an import candidate, a file that the module registry tries when the XEX imports a library that it finds nowhere else. It then loads the executable attitle.entry,game:\default.xexby default.- If the image uses the shim heap,
Loadcreates it with the size fromruntime.heap_size_mb. See Shims.
Loading the executable in step 4 maps its data sections and resolves its imports. Code and read only data sections stay read only unless runtime.writable_code_segments is set. The step reads the stack size, the TLS layout and the title workspace size from the executable headers, writes the kernel variables ExLoadedImageName and ExLoadedCommandLine, starts the Kernel Dispatch thread and loads the achievements of the title.
title.imports separates its entries with |. An empty title.entry loads no executable.
A failed Load unmaps everything. Load fails in these cases:
- Another runtime is loaded, the
rexkernelmodule is not running or therexxammodule is not loaded. - Guest memory cannot be mapped, or the function table cannot be filled.
- The executable is missing, with the message "Entrypoint XEX game:\default.xex was not found".
- The executable fails to load, or the shim heap cannot be created.
Module Loading¶
Loading an image binds its imports from xboxkrnl, xam and xbdm to the kernel exports. An import from another library is bound at its first call, to the export of the loaded module with that name.
- A variable import with no export behind it gets a marker value, and the load logs a warning.
- A call through an import that no export table and no registered library implements stops the process with "Unresolved import of ordinal" and the library name.
At runtime, the title loads more modules with XexLoadImage. The export calls IModuleRegistry::LoadUserModule, which loads a XEX or ELF image and binds the recompiled library that register_modules registered for it.
Launch¶
Launch connects the loaded title to the systems of the app and starts it. It takes no arguments, because App::Init handed the system interfaces to the kernel module at startup. Launch needs the UI system and the settings of the app. Graphics, input and audio are optional, and the title runs without the ones that are missing.
sequenceDiagram
participant R as TitleRuntime
participant A as Guest audio
participant G as IGraphicsSystem
participant U as IUISystem
participant T as Main thread
R->>R: Give XAM UI and input
R->>A: Start
R->>G: AttachTitle
R->>G: Route GPU block
R->>U: AttachTitle
R->>T: Create suspended
R->>R: Freeze kUntilLaunch
R->>T: Resume
R->>R: Start Title Monitor
Launchgives XAM the UI and input systems and the language of the title.- It starts guest audio: the render client slots that the XAudio exports use, the
Audio Workerthread that calls the audio callbacks of the title, and the XMA decoder. A failure here logs a warning and the title runs without audio. - It attaches the title to the graphics system with the driver context and routes the GPU register block to it.
- It attaches the title to the UI system with the title information.
- It creates
Main XThreadat the entry point of the executable, suspended. - It freezes the
kUntilLaunchsettings, then resumes the thread. - It starts
Title Monitor, which reports a normal exit when the main thread returns.
If an attach or the thread creation fails, Launch unloads the title and returns the error.
Unload¶
Unload reverses Launch, then frees guest memory:
sequenceDiagram
participant R as TitleRuntime
participant U as IUISystem
participant T as Guest threads
participant G as IGraphicsSystem
participant A as Guest audio
R->>U: DetachTitle
R->>T: Terminate
R->>R: Join Title Monitor
R->>R: Thaw kUntilLaunch
R->>R: Stop threads
R->>G: Detach GPU block
R->>G: DetachTitle
R->>A: Shut down
R->>R: Detach XAM
R->>R: Destroy services
R->>R: Free guest memory
Unloadwaits for every guest thread to stop. See Stopping a Thread.- After a launch,
Unloadmust run on the UI thread. Unloaddoes nothing when no title is loaded, and the destructor ofTitleRuntimecalls it.
Settings and Services¶
See TitleRuntime in the API reference for every call.
- The service calls such as
GetObjectTableandGetFileSystem, andFindFunction, work fromLoadon, without a launch, and stay valid untilUnload. REX_RUNTIME()returns the loaded runtime from any thread. It returns the runtime once the first step ofLoadhas created the kernel services, and null again onceUnloadhas stopped the guest threads.GetTitlePaths,GetRuntimeSettingsandGetKernelSettingsreturn the settings classes of thetitle,runtimeandkernelscopes.