mirror of
https://github.com/Atmosphere-NX/Atmosphere.git
synced 2025-05-23 03:06:52 -04:00
kern: update Initialize0 for new arguments/randomization semantics
This commit is contained in:
parent
2f2c36b22b
commit
481ce12b7b
13 changed files with 160 additions and 115 deletions
|
@ -346,8 +346,11 @@ namespace ams::kern::board::nintendo::nx {
|
|||
}
|
||||
}
|
||||
|
||||
KPhysicalAddress KSystemControl::Init::GetInitialProcessBinaryPhysicalAddress() {
|
||||
return GetKernelPhysicalBaseAddress(DramPhysicalAddress) + GetIntendedMemorySize() - KTraceBufferSize - InitialProcessBinarySizeMax;
|
||||
void KSystemControl::Init::GetInitialProcessBinaryLayout(InitialProcessBinaryLayout *out) {
|
||||
*out = {
|
||||
.address = GetInteger(GetKernelPhysicalBaseAddress(DramPhysicalAddress)) + GetIntendedMemorySize() - KTraceBufferSize - InitialProcessBinarySizeMax,
|
||||
._08 = 0,
|
||||
};
|
||||
}
|
||||
|
||||
bool KSystemControl::Init::ShouldIncreaseThreadResourceLimit() {
|
||||
|
|
|
@ -25,18 +25,18 @@ namespace ams::kern {
|
|||
s32 priority;
|
||||
};
|
||||
|
||||
constinit KPhysicalAddress g_initial_process_binary_phys_addr = Null<KPhysicalAddress>;
|
||||
constinit KVirtualAddress g_initial_process_binary_address = Null<KVirtualAddress>;
|
||||
constinit InitialProcessBinaryHeader g_initial_process_binary_header = {};
|
||||
constinit size_t g_initial_process_secure_memory_size = 0;
|
||||
constinit u64 g_initial_process_id_min = std::numeric_limits<u64>::max();
|
||||
constinit u64 g_initial_process_id_max = std::numeric_limits<u64>::min();
|
||||
|
||||
void LoadInitialProcessBinaryHeader(KVirtualAddress virt_addr = Null<KVirtualAddress>) {
|
||||
void LoadInitialProcessBinaryHeader() {
|
||||
if (g_initial_process_binary_header.magic != InitialProcessBinaryMagic) {
|
||||
/* Get the virtual address, if it's not overridden. */
|
||||
if (virt_addr == Null<KVirtualAddress>) {
|
||||
virt_addr = GetInitialProcessBinaryAddress();
|
||||
}
|
||||
/* Get the virtual address. */
|
||||
MESOSPHERE_INIT_ABORT_UNLESS(g_initial_process_binary_phys_addr != Null<KPhysicalAddress>);
|
||||
const KVirtualAddress virt_addr = KMemoryLayout::GetLinearVirtualAddress(g_initial_process_binary_phys_addr);
|
||||
|
||||
/* Copy and validate the header. */
|
||||
g_initial_process_binary_header = *GetPointer<InitialProcessBinaryHeader>(virt_addr);
|
||||
|
@ -273,10 +273,18 @@ namespace ams::kern {
|
|||
}
|
||||
}
|
||||
|
||||
ALWAYS_INLINE KVirtualAddress GetInitialProcessBinaryAddress(KVirtualAddress pool_end) {
|
||||
return pool_end - InitialProcessBinarySizeMax;
|
||||
}
|
||||
}
|
||||
|
||||
void SetInitialProcessBinaryPhysicalAddress(KPhysicalAddress phys_addr) {
|
||||
MESOSPHERE_INIT_ABORT_UNLESS(g_initial_process_binary_phys_addr == Null<KPhysicalAddress>);
|
||||
|
||||
g_initial_process_binary_phys_addr = phys_addr;
|
||||
}
|
||||
|
||||
KPhysicalAddress GetInitialProcessBinaryPhysicalAddress() {
|
||||
MESOSPHERE_INIT_ABORT_UNLESS(g_initial_process_binary_phys_addr != Null<KPhysicalAddress>);
|
||||
|
||||
return g_initial_process_binary_phys_addr;
|
||||
}
|
||||
|
||||
u64 GetInitialProcessIdMin() {
|
||||
|
@ -287,15 +295,6 @@ namespace ams::kern {
|
|||
return g_initial_process_id_max;
|
||||
}
|
||||
|
||||
KVirtualAddress GetInitialProcessBinaryAddress() {
|
||||
/* Get, validate the pool region. */
|
||||
const auto *pool_region = KMemoryLayout::GetVirtualMemoryRegionTree().FindLastDerived(KMemoryRegionType_VirtualDramUserPool);
|
||||
MESOSPHERE_INIT_ABORT_UNLESS(pool_region != nullptr);
|
||||
MESOSPHERE_INIT_ABORT_UNLESS(pool_region->GetEndAddress() != 0);
|
||||
MESOSPHERE_ABORT_UNLESS(pool_region->GetSize() >= InitialProcessBinarySizeMax);
|
||||
return GetInitialProcessBinaryAddress(pool_region->GetEndAddress());
|
||||
}
|
||||
|
||||
size_t GetInitialProcessesSecureMemorySize() {
|
||||
LoadInitialProcessBinaryHeader();
|
||||
|
||||
|
@ -321,10 +320,6 @@ namespace ams::kern {
|
|||
}
|
||||
}
|
||||
|
||||
void LoadInitialProcessBinaryHeaderDeprecated(KPhysicalAddress pool_end) {
|
||||
LoadInitialProcessBinaryHeader(GetInitialProcessBinaryAddress(KMemoryLayout::GetLinearVirtualAddress(pool_end)));
|
||||
}
|
||||
|
||||
void CreateAndRunInitialProcesses() {
|
||||
/* Allocate space for the processes. */
|
||||
InitialProcessInfo *infos = static_cast<InitialProcessInfo *>(__builtin_alloca(sizeof(InitialProcessInfo) * g_initial_process_binary_header.num_processes));
|
||||
|
|
|
@ -190,12 +190,6 @@ namespace ams::kern {
|
|||
static_assert(KMemoryManager::Pool_Unsafe == KMemoryManager::Pool_Application);
|
||||
static_assert(KMemoryManager::Pool_Secure == KMemoryManager::Pool_System);
|
||||
|
||||
/* NOTE: Beginning with 12.0.0 (and always, in mesosphere), the initial process binary is at the end of the pool region. */
|
||||
/* However, this is problematic for < 5.0.0, because we require the initial process binary to be parsed in order */
|
||||
/* to determine the pool sizes. Hence, we will force an initial binary load with the known pool end directly, so */
|
||||
/* that we retain compatibility with lower firmware versions. */
|
||||
LoadInitialProcessBinaryHeaderDeprecated(pool_end);
|
||||
|
||||
/* Get Secure pool size. */
|
||||
const size_t secure_pool_size = [] ALWAYS_INLINE_LAMBDA (auto target_firmware) -> size_t {
|
||||
constexpr size_t LegacySecureKernelSize = 8_MB; /* KPageBuffer pages, other small kernel allocations. */
|
||||
|
|
|
@ -111,43 +111,6 @@ namespace ams::kern {
|
|||
return true;
|
||||
}
|
||||
|
||||
KVirtualAddress KMemoryRegionTree::GetRandomAlignedRegion(size_t size, size_t alignment, u32 type_id) {
|
||||
/* We want to find the total extents of the type id. */
|
||||
const auto extents = this->GetDerivedRegionExtents(type_id);
|
||||
|
||||
/* Ensure that our alignment is correct. */
|
||||
MESOSPHERE_INIT_ABORT_UNLESS(util::IsAligned(extents.GetAddress(), alignment));
|
||||
|
||||
const uintptr_t first_address = extents.GetAddress();
|
||||
const uintptr_t last_address = extents.GetLastAddress();
|
||||
|
||||
const uintptr_t first_index = first_address / alignment;
|
||||
const uintptr_t last_index = last_address / alignment;
|
||||
|
||||
while (true) {
|
||||
const uintptr_t candidate = KSystemControl::Init::GenerateRandomRange(first_index, last_index) * alignment;
|
||||
|
||||
/* Ensure that the candidate doesn't overflow with the size. */
|
||||
if (!(candidate < candidate + size)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const uintptr_t candidate_last = candidate + size - 1;
|
||||
|
||||
/* Ensure that the candidate fits within the region. */
|
||||
if (candidate_last > last_address) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Locate the candidate region, and ensure it fits and has the correct type id. */
|
||||
if (const auto &candidate_region = *this->Find(candidate); !(candidate_last <= candidate_region.GetLastAddress() && candidate_region.GetType() == type_id)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
return candidate;
|
||||
}
|
||||
}
|
||||
|
||||
void KMemoryLayout::InitializeLinearMemoryRegionTrees() {
|
||||
/* Initialize linear trees. */
|
||||
for (auto ®ion : GetPhysicalMemoryRegionTree()) {
|
||||
|
|
|
@ -107,7 +107,7 @@ namespace ams::kern {
|
|||
|
||||
/* Free each region to its corresponding heap. */
|
||||
size_t reserved_sizes[MaxManagerCount] = {};
|
||||
const KPhysicalAddress ini_start = KMemoryLayout::GetLinearPhysicalAddress(GetInitialProcessBinaryAddress());
|
||||
const KPhysicalAddress ini_start = GetInitialProcessBinaryPhysicalAddress();
|
||||
const KPhysicalAddress ini_end = ini_start + InitialProcessBinarySizeMax;
|
||||
const KPhysicalAddress ini_last = ini_end - 1;
|
||||
for (const auto &it : KMemoryLayout::GetPhysicalMemoryRegionTree()) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue