mirror of
https://github.com/Atmosphere-NX/Atmosphere.git
synced 2024-11-18 01:46:47 +00:00
kern: begin 1.0.0 backwards compat changes (kips run, full boot fails)
This commit is contained in:
parent
e8ffbe630f
commit
49af4fae32
6 changed files with 40 additions and 19 deletions
|
@ -39,7 +39,7 @@ namespace ams::kern::board::nintendo::nx {
|
||||||
/* Initialization. */
|
/* Initialization. */
|
||||||
static NOINLINE void InitializePhase1();
|
static NOINLINE void InitializePhase1();
|
||||||
static NOINLINE void InitializePhase2();
|
static NOINLINE void InitializePhase2();
|
||||||
static NOINLINE u32 GetInitialProcessBinaryPool();
|
static NOINLINE u32 GetCreateProcessMemoryPool();
|
||||||
|
|
||||||
/* Randomness. */
|
/* Randomness. */
|
||||||
static void GenerateRandomBytes(void *dst, size_t size);
|
static void GenerateRandomBytes(void *dst, size_t size);
|
||||||
|
|
|
@ -485,7 +485,7 @@ namespace ams::kern::board::nintendo::nx {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 KSystemControl::GetInitialProcessBinaryPool() {
|
u32 KSystemControl::GetCreateProcessMemoryPool() {
|
||||||
return KMemoryManager::Pool_Unsafe;
|
return KMemoryManager::Pool_Unsafe;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -66,6 +66,10 @@ namespace ams::kern {
|
||||||
u8 *current = GetPointer<u8>(binary_address + sizeof(InitialProcessBinaryHeader));
|
u8 *current = GetPointer<u8>(binary_address + sizeof(InitialProcessBinaryHeader));
|
||||||
const u8 * const end = GetPointer<u8>(binary_address + header.size - sizeof(KInitialProcessHeader));
|
const u8 * const end = GetPointer<u8>(binary_address + header.size - sizeof(KInitialProcessHeader));
|
||||||
|
|
||||||
|
/* Decide on pools to use. */
|
||||||
|
const auto unsafe_pool = static_cast<KMemoryManager::Pool>(KSystemControl::GetCreateProcessMemoryPool());
|
||||||
|
const auto secure_pool = (GetTargetFirmware() >= TargetFirmware_2_0_0) ? KMemoryManager::Pool_Secure : unsafe_pool;
|
||||||
|
|
||||||
const size_t num_processes = header.num_processes;
|
const size_t num_processes = header.num_processes;
|
||||||
for (size_t i = 0; i < num_processes; i++) {
|
for (size_t i = 0; i < num_processes; i++) {
|
||||||
/* Validate that we can read the current KIP. */
|
/* Validate that we can read the current KIP. */
|
||||||
|
@ -86,7 +90,7 @@ namespace ams::kern {
|
||||||
|
|
||||||
/* Allocate memory for the process. */
|
/* Allocate memory for the process. */
|
||||||
auto &mm = Kernel::GetMemoryManager();
|
auto &mm = Kernel::GetMemoryManager();
|
||||||
const auto pool = reader.UsesSecureMemory() ? KMemoryManager::Pool_System : static_cast<KMemoryManager::Pool>(KSystemControl::GetInitialProcessBinaryPool());
|
const auto pool = reader.UsesSecureMemory() ? secure_pool : unsafe_pool;
|
||||||
MESOSPHERE_R_ABORT_UNLESS(mm.Allocate(std::addressof(pg), params.code_num_pages, KMemoryManager::EncodeOption(pool, KMemoryManager::Direction_FromFront)));
|
MESOSPHERE_R_ABORT_UNLESS(mm.Allocate(std::addressof(pg), params.code_num_pages, KMemoryManager::EncodeOption(pool, KMemoryManager::Direction_FromFront)));
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -164,7 +168,7 @@ namespace ams::kern {
|
||||||
MESOSPHERE_ABORT_UNLESS(Kernel::GetSystemResourceLimit().Reserve(ams::svc::LimitableResource_PhysicalMemoryMax, total_size));
|
MESOSPHERE_ABORT_UNLESS(Kernel::GetSystemResourceLimit().Reserve(ams::svc::LimitableResource_PhysicalMemoryMax, total_size));
|
||||||
|
|
||||||
/* Allocate memory for the image. */
|
/* Allocate memory for the image. */
|
||||||
const KMemoryManager::Pool pool = static_cast<KMemoryManager::Pool>(KSystemControl::GetInitialProcessBinaryPool());
|
const KMemoryManager::Pool pool = static_cast<KMemoryManager::Pool>(KSystemControl::GetCreateProcessMemoryPool());
|
||||||
const auto allocate_option = KMemoryManager::EncodeOption(pool, KMemoryManager::Direction_FromFront);
|
const auto allocate_option = KMemoryManager::EncodeOption(pool, KMemoryManager::Direction_FromFront);
|
||||||
KVirtualAddress allocated_memory = mm.AllocateContinuous(num_pages, 1, allocate_option);
|
KVirtualAddress allocated_memory = mm.AllocateContinuous(num_pages, 1, allocate_option);
|
||||||
MESOSPHERE_ABORT_UNLESS(allocated_memory != Null<KVirtualAddress>);
|
MESOSPHERE_ABORT_UNLESS(allocated_memory != Null<KVirtualAddress>);
|
||||||
|
|
|
@ -105,8 +105,8 @@ namespace ams::kern {
|
||||||
|
|
||||||
const uintptr_t start_address = rx_address;
|
const uintptr_t start_address = rx_address;
|
||||||
const uintptr_t end_address = bss_size > 0 ? bss_address + bss_size : rw_address + rw_size;
|
const uintptr_t end_address = bss_size > 0 ? bss_address + bss_size : rw_address + rw_size;
|
||||||
const size_t as_width = this->Is64BitAddressSpace() ? 39 : 32;
|
const size_t as_width = this->Is64BitAddressSpace() ? ((GetTargetFirmware() >= TargetFirmware_2_0_0) ? 39 : 36) : 32;
|
||||||
const ASType as_type = this->Is64BitAddressSpace() ? KAddressSpaceInfo::Type_Map39Bit : KAddressSpaceInfo::Type_MapSmall;
|
const ASType as_type = this->Is64BitAddressSpace() ? ((GetTargetFirmware() >= TargetFirmware_2_0_0) ? KAddressSpaceInfo::Type_Map39Bit : KAddressSpaceInfo::Type_MapSmall) : KAddressSpaceInfo::Type_MapSmall;
|
||||||
const uintptr_t map_start = KAddressSpaceInfo::GetAddressSpaceStart(as_width, as_type);
|
const uintptr_t map_start = KAddressSpaceInfo::GetAddressSpaceStart(as_width, as_type);
|
||||||
const size_t map_size = KAddressSpaceInfo::GetAddressSpaceSize(as_width, as_type);
|
const size_t map_size = KAddressSpaceInfo::GetAddressSpaceSize(as_width, as_type);
|
||||||
const uintptr_t map_end = map_start + map_size;
|
const uintptr_t map_end = map_start + map_size;
|
||||||
|
@ -135,7 +135,7 @@ namespace ams::kern {
|
||||||
out->flags |= ams::svc::CreateProcessFlag_Is64Bit;
|
out->flags |= ams::svc::CreateProcessFlag_Is64Bit;
|
||||||
}
|
}
|
||||||
if (this->Is64BitAddressSpace()) {
|
if (this->Is64BitAddressSpace()) {
|
||||||
out->flags |= ams::svc::CreateProcessFlag_AddressSpace64Bit;
|
out->flags |= (GetTargetFirmware() >= TargetFirmware_2_0_0) ? ams::svc::CreateProcessFlag_AddressSpace64Bit : ams::svc::CreateProcessFlag_AddressSpace64BitDeprecated;
|
||||||
} else {
|
} else {
|
||||||
out->flags |= ams::svc::CreateProcessFlag_AddressSpace32Bit;
|
out->flags |= ams::svc::CreateProcessFlag_AddressSpace32Bit;
|
||||||
}
|
}
|
||||||
|
|
|
@ -151,7 +151,7 @@ namespace ams::kern {
|
||||||
/* Insert the system pool. */
|
/* Insert the system pool. */
|
||||||
const uintptr_t system_pool_size = pool_management_start - pool_partitions_start;
|
const uintptr_t system_pool_size = pool_management_start - pool_partitions_start;
|
||||||
InsertPoolPartitionRegionIntoBothTrees(pool_partitions_start, system_pool_size, KMemoryRegionType_DramSystemPool, KMemoryRegionType_VirtualDramSystemPool, cur_pool_attr);
|
InsertPoolPartitionRegionIntoBothTrees(pool_partitions_start, system_pool_size, KMemoryRegionType_DramSystemPool, KMemoryRegionType_VirtualDramSystemPool, cur_pool_attr);
|
||||||
} else if (GetTargetFirmware() >= TargetFirmware_2_0_0) {
|
} else {
|
||||||
/* On < 5.0.0, setup a legacy 2-pool layout for backwards compatibility. */
|
/* On < 5.0.0, setup a legacy 2-pool layout for backwards compatibility. */
|
||||||
|
|
||||||
static_assert(KMemoryManager::Pool_Count == 4);
|
static_assert(KMemoryManager::Pool_Count == 4);
|
||||||
|
@ -159,12 +159,33 @@ namespace ams::kern {
|
||||||
static_assert(KMemoryManager::Pool_Secure == KMemoryManager::Pool_System);
|
static_assert(KMemoryManager::Pool_Secure == KMemoryManager::Pool_System);
|
||||||
|
|
||||||
/* Get Secure pool size. */
|
/* Get Secure pool size. */
|
||||||
constexpr size_t LegacySecureKernelSize = 6_MB; /* KPageBuffer pages, other small kernel allocations. */
|
const size_t secure_pool_size = [] ALWAYS_INLINE_LAMBDA (auto target_firmware) -> size_t {
|
||||||
constexpr size_t LegacySecureMiscSize = 1_MB; /* Miscellaneous pages for secure process mapping. */
|
constexpr size_t LegacySecureKernelSize = 8_MB; /* KPageBuffer pages, other small kernel allocations. */
|
||||||
constexpr size_t LegacySecureHeapSize = 24_MB; /* Heap pages for secure process mapping (fs). */
|
constexpr size_t LegacySecureMiscSize = 1_MB; /* Miscellaneous pages for secure process mapping. */
|
||||||
constexpr size_t LegacySecureEsSize = 1_MB + 232_KB; /* Size for additional secure process (es, 4.0.0+). */
|
constexpr size_t LegacySecureHeapSize = 24_MB; /* Heap pages for secure process mapping (fs). */
|
||||||
|
constexpr size_t LegacySecureEsSize = 1_MB + 232_KB; /* Size for additional secure process (es, 4.0.0+). */
|
||||||
|
|
||||||
const size_t secure_pool_size = GetInitialProcessesSecureMemorySize() + LegacySecureKernelSize + LegacySecureHeapSize + LegacySecureMiscSize + (GetTargetFirmware() >= TargetFirmware_4_0_0 ? LegacySecureEsSize : 0);
|
/* The baseline size for the secure region is enough to cover any allocations the kernel might make. */
|
||||||
|
size_t size = LegacySecureKernelSize;
|
||||||
|
|
||||||
|
/* If on 2.0.0+, initial processes will fall within the secure region. */
|
||||||
|
if (target_firmware >= TargetFirmware_2_0_0) {
|
||||||
|
/* Account for memory used directly for the processes. */
|
||||||
|
size += GetInitialProcessesSecureMemorySize();
|
||||||
|
|
||||||
|
/* Account for heap and transient memory used by the processes. */
|
||||||
|
size += LegacySecureHeapSize + LegacySecureMiscSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If on 4.0.0+, any process may use secure memory via a create process flag. */
|
||||||
|
/* In process this is used for es alone, and the secure pool's size should be */
|
||||||
|
/* increased to accommodate es's binary. */
|
||||||
|
if (target_firmware >= TargetFirmware_4_0_0) {
|
||||||
|
size += LegacySecureEsSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
return size;
|
||||||
|
}(GetTargetFirmware());
|
||||||
|
|
||||||
/* Calculate the overhead for the secure and (defunct) applet/non-secure-system pools. */
|
/* Calculate the overhead for the secure and (defunct) applet/non-secure-system pools. */
|
||||||
size_t total_overhead_size = KMemoryManager::CalculateManagementOverheadSize(secure_pool_size);
|
size_t total_overhead_size = KMemoryManager::CalculateManagementOverheadSize(secure_pool_size);
|
||||||
|
@ -208,9 +229,6 @@ namespace ams::kern {
|
||||||
|
|
||||||
u32 pool_management_attr = 0;
|
u32 pool_management_attr = 0;
|
||||||
InsertPoolPartitionRegionIntoBothTrees(pool_management_start, pool_management_size, KMemoryRegionType_DramPoolManagement, KMemoryRegionType_VirtualDramPoolManagement, pool_management_attr);
|
InsertPoolPartitionRegionIntoBothTrees(pool_management_start, pool_management_size, KMemoryRegionType_DramPoolManagement, KMemoryRegionType_VirtualDramPoolManagement, pool_management_attr);
|
||||||
} else {
|
|
||||||
/* TODO: 1.0.0 single-pool layout. */
|
|
||||||
MESOSPHERE_UNIMPLEMENTED();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -219,14 +219,13 @@ namespace ams::kern::svc {
|
||||||
if ((flags & ams::svc::CreateProcessFlag_DeprecatedUseSecureMemory) != 0) {
|
if ((flags & ams::svc::CreateProcessFlag_DeprecatedUseSecureMemory) != 0) {
|
||||||
return KMemoryManager::Pool_Secure;
|
return KMemoryManager::Pool_Secure;
|
||||||
} else {
|
} else {
|
||||||
return KMemoryManager::Pool_Unsafe;
|
return static_cast<KMemoryManager::Pool>(KSystemControl::GetCreateProcessMemoryPool());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return KMemoryManager::Pool_Unsafe;
|
return static_cast<KMemoryManager::Pool>(KSystemControl::GetCreateProcessMemoryPool());
|
||||||
}
|
}
|
||||||
}(params.flags);
|
}(params.flags);
|
||||||
|
|
||||||
|
|
||||||
/* Initialize the process. */
|
/* Initialize the process. */
|
||||||
R_TRY(process->Initialize(params, user_caps, num_caps, process_resource_limit, pool));
|
R_TRY(process->Initialize(params, user_caps, num_caps, process_resource_limit, pool));
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue