kern: begin 1.0.0 backwards compat changes (kips run, full boot fails)

This commit is contained in:
Michael Scire 2020-08-25 23:28:39 -07:00 committed by SciresM
parent e8ffbe630f
commit 49af4fae32
6 changed files with 40 additions and 19 deletions

View File

@ -39,7 +39,7 @@ namespace ams::kern::board::nintendo::nx {
/* Initialization. */
static NOINLINE void InitializePhase1();
static NOINLINE void InitializePhase2();
static NOINLINE u32 GetInitialProcessBinaryPool();
static NOINLINE u32 GetCreateProcessMemoryPool();
/* Randomness. */
static void GenerateRandomBytes(void *dst, size_t size);

View File

@ -485,7 +485,7 @@ namespace ams::kern::board::nintendo::nx {
}
}
u32 KSystemControl::GetInitialProcessBinaryPool() {
u32 KSystemControl::GetCreateProcessMemoryPool() {
return KMemoryManager::Pool_Unsafe;
}

View File

@ -66,6 +66,10 @@ namespace ams::kern {
u8 *current = GetPointer<u8>(binary_address + sizeof(InitialProcessBinaryHeader));
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;
for (size_t i = 0; i < num_processes; i++) {
/* Validate that we can read the current KIP. */
@ -86,7 +90,7 @@ namespace ams::kern {
/* Allocate memory for the process. */
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)));
{
@ -164,7 +168,7 @@ namespace ams::kern {
MESOSPHERE_ABORT_UNLESS(Kernel::GetSystemResourceLimit().Reserve(ams::svc::LimitableResource_PhysicalMemoryMax, total_size));
/* 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);
KVirtualAddress allocated_memory = mm.AllocateContinuous(num_pages, 1, allocate_option);
MESOSPHERE_ABORT_UNLESS(allocated_memory != Null<KVirtualAddress>);

View File

@ -105,8 +105,8 @@ namespace ams::kern {
const uintptr_t start_address = rx_address;
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 ASType as_type = this->Is64BitAddressSpace() ? KAddressSpaceInfo::Type_Map39Bit : KAddressSpaceInfo::Type_MapSmall;
const size_t as_width = this->Is64BitAddressSpace() ? ((GetTargetFirmware() >= TargetFirmware_2_0_0) ? 39 : 36) : 32;
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 size_t map_size = KAddressSpaceInfo::GetAddressSpaceSize(as_width, as_type);
const uintptr_t map_end = map_start + map_size;
@ -135,7 +135,7 @@ namespace ams::kern {
out->flags |= ams::svc::CreateProcessFlag_Is64Bit;
}
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 {
out->flags |= ams::svc::CreateProcessFlag_AddressSpace32Bit;
}

View File

@ -151,7 +151,7 @@ namespace ams::kern {
/* Insert the system pool. */
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);
} else if (GetTargetFirmware() >= TargetFirmware_2_0_0) {
} else {
/* On < 5.0.0, setup a legacy 2-pool layout for backwards compatibility. */
static_assert(KMemoryManager::Pool_Count == 4);
@ -159,12 +159,33 @@ namespace ams::kern {
static_assert(KMemoryManager::Pool_Secure == KMemoryManager::Pool_System);
/* 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 LegacySecureKernelSize = 8_MB; /* KPageBuffer pages, other small kernel allocations. */
constexpr size_t LegacySecureMiscSize = 1_MB; /* Miscellaneous pages for secure process mapping. */
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. */
size_t total_overhead_size = KMemoryManager::CalculateManagementOverheadSize(secure_pool_size);
@ -208,9 +229,6 @@ namespace ams::kern {
u32 pool_management_attr = 0;
InsertPoolPartitionRegionIntoBothTrees(pool_management_start, pool_management_size, KMemoryRegionType_DramPoolManagement, KMemoryRegionType_VirtualDramPoolManagement, pool_management_attr);
} else {
/* TODO: 1.0.0 single-pool layout. */
MESOSPHERE_UNIMPLEMENTED();
}
}

View File

@ -219,14 +219,13 @@ namespace ams::kern::svc {
if ((flags & ams::svc::CreateProcessFlag_DeprecatedUseSecureMemory) != 0) {
return KMemoryManager::Pool_Secure;
} else {
return KMemoryManager::Pool_Unsafe;
return static_cast<KMemoryManager::Pool>(KSystemControl::GetCreateProcessMemoryPool());
}
} else {
return KMemoryManager::Pool_Unsafe;
return static_cast<KMemoryManager::Pool>(KSystemControl::GetCreateProcessMemoryPool());
}
}(params.flags);
/* Initialize the process. */
R_TRY(process->Initialize(params, user_caps, num_caps, process_resource_limit, pool));