mirror of
https://github.com/Atmosphere-NX/Atmosphere-libs.git
synced 2025-09-18 17:53:19 +02:00
kern: update Initialize0 for new arguments/randomization semantics
This commit is contained in:
parent
f103b6876b
commit
3e328eae72
@ -293,7 +293,7 @@ namespace ams::kern::arch::arm64::init {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Swap the mappings. */
|
/* Swap the mappings. */
|
||||||
const u64 attr_preserve_mask = (negative_block_size_for_mask | 0xFFFF000000000000ul) ^ ((1ul << 48) - 1);
|
const u64 attr_preserve_mask = (block_size - 1) | 0xFFFF000000000000ul;
|
||||||
const size_t shift_for_contig = contig ? 4 : 0;
|
const size_t shift_for_contig = contig ? 4 : 0;
|
||||||
size_t advanced_size = 0;
|
size_t advanced_size = 0;
|
||||||
const u64 src_attr_val = src_saved.GetRawAttributesUnsafeForSwap() & attr_preserve_mask;
|
const u64 src_attr_val = src_saved.GetRawAttributesUnsafeForSwap() & attr_preserve_mask;
|
||||||
@ -726,8 +726,8 @@ namespace ams::kern::arch::arm64::init {
|
|||||||
m_state.end_address = address;
|
m_state.end_address = address;
|
||||||
}
|
}
|
||||||
|
|
||||||
ALWAYS_INLINE void InitializeFromState(uintptr_t state_val) {
|
ALWAYS_INLINE void InitializeFromState(const State *state) {
|
||||||
m_state = *reinterpret_cast<State *>(state_val);
|
m_state = *state;
|
||||||
}
|
}
|
||||||
|
|
||||||
ALWAYS_INLINE void GetFinalState(State *out) {
|
ALWAYS_INLINE void GetFinalState(State *out) {
|
||||||
|
@ -16,6 +16,12 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <mesosphere/kern_common.hpp>
|
#include <mesosphere/kern_common.hpp>
|
||||||
|
|
||||||
|
namespace ams::kern {
|
||||||
|
|
||||||
|
struct InitialProcessBinaryLayout;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
namespace ams::kern::board::nintendo::nx {
|
namespace ams::kern::board::nintendo::nx {
|
||||||
|
|
||||||
class KSystemControl {
|
class KSystemControl {
|
||||||
@ -25,7 +31,7 @@ namespace ams::kern::board::nintendo::nx {
|
|||||||
/* Initialization. */
|
/* Initialization. */
|
||||||
static size_t GetIntendedMemorySize();
|
static size_t GetIntendedMemorySize();
|
||||||
static KPhysicalAddress GetKernelPhysicalBaseAddress(uintptr_t base_address);
|
static KPhysicalAddress GetKernelPhysicalBaseAddress(uintptr_t base_address);
|
||||||
static KPhysicalAddress GetInitialProcessBinaryPhysicalAddress();
|
static void GetInitialProcessBinaryLayout(InitialProcessBinaryLayout *out);
|
||||||
static bool ShouldIncreaseThreadResourceLimit();
|
static bool ShouldIncreaseThreadResourceLimit();
|
||||||
static void CpuOn(u64 core_id, uintptr_t entrypoint, uintptr_t arg);
|
static void CpuOn(u64 core_id, uintptr_t entrypoint, uintptr_t arg);
|
||||||
static size_t GetApplicationPoolSize();
|
static size_t GetApplicationPoolSize();
|
||||||
|
@ -29,14 +29,19 @@ namespace ams::kern {
|
|||||||
u32 reserved;
|
u32 reserved;
|
||||||
};
|
};
|
||||||
|
|
||||||
NOINLINE size_t CopyInitialProcessBinaryToKernelMemory();
|
struct InitialProcessBinaryLayout {
|
||||||
NOINLINE void CreateAndRunInitialProcesses();
|
uintptr_t address;
|
||||||
|
uintptr_t _08;
|
||||||
|
};
|
||||||
|
|
||||||
|
KPhysicalAddress GetInitialProcessBinaryPhysicalAddress();
|
||||||
|
void SetInitialProcessBinaryPhysicalAddress(KPhysicalAddress phys_addr);
|
||||||
|
|
||||||
u64 GetInitialProcessIdMin();
|
u64 GetInitialProcessIdMin();
|
||||||
u64 GetInitialProcessIdMax();
|
u64 GetInitialProcessIdMax();
|
||||||
KVirtualAddress GetInitialProcessBinaryAddress();
|
|
||||||
size_t GetInitialProcessesSecureMemorySize();
|
size_t GetInitialProcessesSecureMemorySize();
|
||||||
|
|
||||||
void LoadInitialProcessBinaryHeaderDeprecated(KPhysicalAddress pool_end);
|
NOINLINE size_t CopyInitialProcessBinaryToKernelMemory();
|
||||||
|
NOINLINE void CreateAndRunInitialProcesses();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -237,12 +237,6 @@ namespace ams::kern {
|
|||||||
public:
|
public:
|
||||||
NOINLINE void InsertDirectly(uintptr_t address, uintptr_t last_address, u32 attr = 0, u32 type_id = 0);
|
NOINLINE void InsertDirectly(uintptr_t address, uintptr_t last_address, u32 attr = 0, u32 type_id = 0);
|
||||||
NOINLINE bool Insert(uintptr_t address, size_t size, u32 type_id, u32 new_attr = 0, u32 old_attr = 0);
|
NOINLINE bool Insert(uintptr_t address, size_t size, u32 type_id, u32 new_attr = 0, u32 old_attr = 0);
|
||||||
|
|
||||||
NOINLINE KVirtualAddress GetRandomAlignedRegion(size_t size, size_t alignment, u32 type_id);
|
|
||||||
|
|
||||||
ALWAYS_INLINE KVirtualAddress GetRandomAlignedRegionWithGuard(size_t size, size_t alignment, u32 type_id, size_t guard_size) {
|
|
||||||
return this->GetRandomAlignedRegion(size + 2 * guard_size, alignment, type_id) + guard_size;
|
|
||||||
}
|
|
||||||
public:
|
public:
|
||||||
/* Iterator accessors. */
|
/* Iterator accessors. */
|
||||||
iterator begin() {
|
iterator begin() {
|
||||||
|
@ -346,8 +346,11 @@ namespace ams::kern::board::nintendo::nx {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
KPhysicalAddress KSystemControl::Init::GetInitialProcessBinaryPhysicalAddress() {
|
void KSystemControl::Init::GetInitialProcessBinaryLayout(InitialProcessBinaryLayout *out) {
|
||||||
return GetKernelPhysicalBaseAddress(DramPhysicalAddress) + GetIntendedMemorySize() - KTraceBufferSize - InitialProcessBinarySizeMax;
|
*out = {
|
||||||
|
.address = GetInteger(GetKernelPhysicalBaseAddress(DramPhysicalAddress)) + GetIntendedMemorySize() - KTraceBufferSize - InitialProcessBinarySizeMax,
|
||||||
|
._08 = 0,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
bool KSystemControl::Init::ShouldIncreaseThreadResourceLimit() {
|
bool KSystemControl::Init::ShouldIncreaseThreadResourceLimit() {
|
||||||
|
@ -25,18 +25,18 @@ namespace ams::kern {
|
|||||||
s32 priority;
|
s32 priority;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
constinit KPhysicalAddress g_initial_process_binary_phys_addr = Null<KPhysicalAddress>;
|
||||||
constinit KVirtualAddress g_initial_process_binary_address = Null<KVirtualAddress>;
|
constinit KVirtualAddress g_initial_process_binary_address = Null<KVirtualAddress>;
|
||||||
constinit InitialProcessBinaryHeader g_initial_process_binary_header = {};
|
constinit InitialProcessBinaryHeader g_initial_process_binary_header = {};
|
||||||
constinit size_t g_initial_process_secure_memory_size = 0;
|
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_min = std::numeric_limits<u64>::max();
|
||||||
constinit u64 g_initial_process_id_max = std::numeric_limits<u64>::min();
|
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) {
|
if (g_initial_process_binary_header.magic != InitialProcessBinaryMagic) {
|
||||||
/* Get the virtual address, if it's not overridden. */
|
/* Get the virtual address. */
|
||||||
if (virt_addr == Null<KVirtualAddress>) {
|
MESOSPHERE_INIT_ABORT_UNLESS(g_initial_process_binary_phys_addr != Null<KPhysicalAddress>);
|
||||||
virt_addr = GetInitialProcessBinaryAddress();
|
const KVirtualAddress virt_addr = KMemoryLayout::GetLinearVirtualAddress(g_initial_process_binary_phys_addr);
|
||||||
}
|
|
||||||
|
|
||||||
/* Copy and validate the header. */
|
/* Copy and validate the header. */
|
||||||
g_initial_process_binary_header = *GetPointer<InitialProcessBinaryHeader>(virt_addr);
|
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() {
|
u64 GetInitialProcessIdMin() {
|
||||||
@ -287,15 +295,6 @@ namespace ams::kern {
|
|||||||
return g_initial_process_id_max;
|
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() {
|
size_t GetInitialProcessesSecureMemorySize() {
|
||||||
LoadInitialProcessBinaryHeader();
|
LoadInitialProcessBinaryHeader();
|
||||||
|
|
||||||
@ -321,10 +320,6 @@ namespace ams::kern {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void LoadInitialProcessBinaryHeaderDeprecated(KPhysicalAddress pool_end) {
|
|
||||||
LoadInitialProcessBinaryHeader(GetInitialProcessBinaryAddress(KMemoryLayout::GetLinearVirtualAddress(pool_end)));
|
|
||||||
}
|
|
||||||
|
|
||||||
void CreateAndRunInitialProcesses() {
|
void CreateAndRunInitialProcesses() {
|
||||||
/* Allocate space for the processes. */
|
/* Allocate space for the processes. */
|
||||||
InitialProcessInfo *infos = static_cast<InitialProcessInfo *>(__builtin_alloca(sizeof(InitialProcessInfo) * g_initial_process_binary_header.num_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_Unsafe == KMemoryManager::Pool_Application);
|
||||||
static_assert(KMemoryManager::Pool_Secure == KMemoryManager::Pool_System);
|
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. */
|
/* Get Secure pool size. */
|
||||||
const size_t secure_pool_size = [] ALWAYS_INLINE_LAMBDA (auto target_firmware) -> size_t {
|
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. */
|
constexpr size_t LegacySecureKernelSize = 8_MB; /* KPageBuffer pages, other small kernel allocations. */
|
||||||
|
@ -111,43 +111,6 @@ namespace ams::kern {
|
|||||||
return true;
|
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() {
|
void KMemoryLayout::InitializeLinearMemoryRegionTrees() {
|
||||||
/* Initialize linear trees. */
|
/* Initialize linear trees. */
|
||||||
for (auto ®ion : GetPhysicalMemoryRegionTree()) {
|
for (auto ®ion : GetPhysicalMemoryRegionTree()) {
|
||||||
|
@ -107,7 +107,7 @@ namespace ams::kern {
|
|||||||
|
|
||||||
/* Free each region to its corresponding heap. */
|
/* Free each region to its corresponding heap. */
|
||||||
size_t reserved_sizes[MaxManagerCount] = {};
|
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_end = ini_start + InitialProcessBinarySizeMax;
|
||||||
const KPhysicalAddress ini_last = ini_end - 1;
|
const KPhysicalAddress ini_last = ini_end - 1;
|
||||||
for (const auto &it : KMemoryLayout::GetPhysicalMemoryRegionTree()) {
|
for (const auto &it : KMemoryLayout::GetPhysicalMemoryRegionTree()) {
|
||||||
|
Loading…
Reference in New Issue
Block a user