Line 59: |
Line 59: |
| ===BootImagePackages=== | | ===BootImagePackages=== |
| All files in RomFs were updated. | | All files in RomFs were updated. |
| + | |
| + | ====Kernel==== |
| + | * Compiler changes: |
| + | ** Compiler upgrade |
| + | *** [What version of clang?] |
| + | *** Clang is optimizing much more aggressively in some places. |
| + | *** Notably, there are many code locations now where clang doesn't actually increment the KSchedulerLock's count field, presumably because it sees it will be decremented at end of scope... |
| + | **** This isn't exploitable, and it is """correct""", but it is worth noting to other reverse engineers because it is very confusing to see the count field unchanged or reloaded after function calls. |
| + | ** Code is now compiled with -fomit-frame-pointer. |
| + | * Initialization changes: |
| + | ** When the thread resource limit is increased, 24 MB of virtual space is now reserved for the Kernel stack region instead of 14 MB. |
| + | * In HorizonKernelMain: |
| + | ** DoOnEachCoreInOrder is no longer inlined, when setting up the main/interrupt threads. It is still inlined in all other places. |
| + | * Multiple fixed-allocations from the system pool/resource limit were removed/revised, presumably to prevent them from unnecessarily fragmenting the pool forever. |
| + | ** AppletSecureMemory is now allocated statically, instead of dynamically. |
| + | *** Previously, 4 MB was allocated from the system pool/resource limit during main. |
| + | *** Initialize0 now reserves the 4 MB immediately after the slab heaps for this. |
| + | **** DRAM layout is now like [tz reserved] [kernel] [slab heaps] [applet secure memory] [pt heap] [init pt] [memory pool partitions]. |
| + | **** The virtual memory region type is 0x62; the physical memory region type is 0xC200018E. |
| + | ** The KPageBuffer slab heap is no longer dynamically allocated from KMemoryManager. |
| + | *** Previously, the required number of pages were allocated from the system pool/resource limit to setup the heap *immediately* after KMemoryManager was initialized. |
| + | *** Now, it is set up during Kernel::InitializeResourceManagers, after setting up the page manager. |
| + | **** InitializeKPageBufferSlabHeap now takes heap and page manager as arguments; the slab heap's members are randomly allocated pages from the page manager. |
| + | ***** This effectively randomizes the page buffer slabheap's page locations, where previously they were a contiguous range somewhere in the system pool. |
| + | ***** To facilitate this, the page manager now has an Allocate(count) member function in addition to the previous single-page Allocate(). |
| + | ****** To facilitate this, the page manager now tracks the bitmap ends in addition to the bitmap starts, to enable a linear walk of the lowest bitmap layer. |
| + | *** This has an important knock-on effect: TLS pages are allocated from the page buffer slab, and correspondingly are no longer heap pages. |
| + | **** Correspondingly, KMemoryState_ThreadLocal no longer has the FlagReferenceCounted (0x400000) bit set. |
| + | **** However, removing this bit naively breaks IPC, which previously checked FlagReferenceCounted before copying to/from the message buffer. |
| + | **** Now, FlagReferenceCounted is checked if and only if the message buffer is a UserBuffer. If it is not, a new flag "FlagLinearMapped" (0x4000000) is checked. |
| + | ***** This bit is set only on memory types guaranteed to be accessible via the kernel's linear mapping of non-kernel dram (physical ranges with memory region flag 0x80000000). |
| + | ***** This new flag is set on all memory states other than Free, Io, Static, Inaccessible, Kernel, Coverage. |
| + | * Two new SVCs were added for a new "InsecureMemory" concept. |
| + | ** Svc 0x90 is Result MapInsecureMemory(uintptr_t address, size_t size); |
| + | *** This allocates the requested size memory from a pool partition/resource limit, and map it with a new memory state ("KMemoryState_Insecure") at the user-specified address. |
| + | **** The resource limit/pool partition are gotten via new KSystemControl functions ("KSystemControl::GetInsecureMemoryResourceLimit", "KSystemControl::GetInsecureMemoryPool"). |
| + | ***** On NX board, these are the system resource limit, and Pool_SystemNonSecure respectively. |
| + | **** The specified address/size must be within the alias code region. |
| + | **** KMemoryState_Insecure has value 0x5583817. |
| + | ***** This is type 0x17 with flags CanUseNonDeviceIpc, CanUseNonSecureIpc, Mapped, CanDeviceMap, CanAlignedDeviceMap, ReferenceCounted, CanChangeAttribute, LinearMapped. |
| + | ** Svc 0x91 is Result UnmapInsecureMemory(uintptr_t address, size_t size); |
| + | *** This unmaps/deallocates/releases memory previously mapped with MapInsecureMemory. |
| + | * More changes to SvcMapDeviceAddressSpace(ByForce/Aligned). |
| + | ** The argument which was previously a memory permission ("device_perm") is now an encoded u32 ("option"). |
| + | *** The low 16 bits of this are the device permission. |
| + | *** The upper 16 bits of this are an enum (only defined values are 0 and 1). |
| + | ** If the enum-arg is not 0 or 1, svc::ResultInvalidEnumValue() is now returned. |
| + | ** If the enum-arg is 1 and the specified memory is IO, svc::ResultInvalidCombination is returned. |
| + | * Partial support was added for the KPageBuffer size being different from the hardware page size. |
| + | ** There are now two globals, g_PageBufferSize = 0x1000, g_PageBufferCount = 0. |
| + | ** The KPageBuffer slab heap is initialized with g_PageBufferCount blocks of g_PageBufferSize. |
| + | *** if g_PageBufferSize is 0x1000, g_PageBufferCount has the number of required TLS pages added to it (# processes + # threads + (# processes + #threads) / 8). |
| + | ** KDynamicPageManager::Initialize now takes in an alignment argument for the page buffer size. |
| + | *** KSecureSystemResource always passes 0x1000. |
| + | ** It is possible this is full support but ifdef'd, but on NX board at least all places which allocate/free to the heap panic if g_PageBufferSize != 0x1000... |
| + | * The page table heap now receives all but 64 of the available pages; prior to this, it was all but 70. |
| + | * KSessionRequest's additional mappings (when sending an IPC request with more than 8 buffers) are now slab-allocated, rather than using KPageBuffers. |
| + | ** This slab has a count of 40; object size is 0x4A0 (exactly the maximum required size). |
| + | ** 13.0.0+ Dynamic expansion is supported. |
| + | * Scoped setting/clearing of the 14.0.0 exception flag for cache operations has changed. |
| + | ** Previously, |= on set, &= ~ on clear. Now, the flag is orr'd in only if it is not already set, and cleared only if it was newly set. |
| + | ** This adds support for recursively setting these flags via a scoped setter, although there are no places in kernel where it is possible for this to occur. |
| + | ** This applies to cpu::InvalidateDataCache, cpu::StoreDataCache, cpu::FlushDataCache |
| + | * The IsInUsermodeExceptionHandler exception flag management was changed: |
| + | ** This is now cleared by RestoreContext (same place it clears other flags) rather than ClearExceptionSvcPermissions. It is still set by SetExceptionSvcPermissions. |
| + | * Changes in and surrounding page table logic: |
| + | ** Devices can now theoretically (but not on the NX board) be given access to memory mapped as Io. |
| + | *** Why one would want to do this is unclear. |
| + | *** KMemoryState_Io now supports the CanAlignedDeviceMap and CanDeviceMap flags. |
| + | *** KPageTableBase::GetContiguousMemoryRangeWithState no longer checks that the passed memory address is heap. |
| + | *** KPageTableBase::OpenMemoryRangeForMapDeviceAddressSpace no longer checks passes KMemoryState_FlagReferenceCounted. |
| + | *** KPageTableBase::LockForMapDeviceAddressSpace takes two new arguments, an output bool * to write whether the state was io, and a bool for whether to check KMemoryState_FlagReferenceCounted. |
| + | **** The bool is always passed on true on NX board, preventing this feature from being actually used. |
| + | *** KPageTableBase::LockForUnmapDeviceAddressSpace now takes a bool argument for whether to check KMemoryState_FlagReferenceCounted |
| + | **** The bool is always passed on true on NX board, preventing this feature from being actually used. |
| + | ** Pages mapped via MapIoRegion now have KMemoryAttribute_Locked instead of KMemoryAttribute_None. |
| + | ** Changes were made with respect to the way MapPhysicalMemory/UnmapPhysicalMemory are implemented: |
| + | *** KMemoryManager::AllocatePageGroupForProcess no longer calls KPageGroup::Open on the returned page group (essentially reverting the change in 11.0.0). |
| + | **** Other KMemoryManager::Allocate* functions still call KPageGroup::Open. |
| + | *** KPageTableBase::MapPhysicalMemory now calls a new KPageTable::Operate operation ("MapFirst"), which behaves the same as Map but calls KernelPanic() if the mapped pages have a non-zero reference count. |
| + | **** This enforces that MapPhysicalMemory is the first place the pages being mapped have been allocated/opened. |
| + | *** KPageTableBase::UnmapPhysicalMemory now calls a new KPageTable::Operate operation ("SeparatePages"), which performs page separation on the requested range. |
| + | **** SeparatePages is identical to the separation done at the prologue of ChangePermissions; practically, this just enforces that the pages exist. |
| + | *** KPageTableBase::UnmapPhysicalMemory now calls KernelPanic if the unmapping operation fails (since it is guaranteed to succeed by the success of SeparatePages). |
| + | **** Logic which previously existed for re-mapping on failure has been removed. |
| + | ** New Kernel Objects ("KSystemResource", "KSecureSystemResource"). |
| + | *** Type ID = 0x4600, KSystemResource : public KAutoObject, KSecureSystemResource : public KSystemResource |
| + | *** KSystemResource just stores pointers to the three kinds of dynamic resource managers required by processes/page tables. |
| + | *** KSecureSystemResource stores the pointed-to objects for these as members. |
| + | **** Previously, these were just KProcess members; they are no longer KProcess members and instead live in the KSecureSystemResource object. |
| + | *** The slab heap for KSecureSystemResource has capacity = KProcess slab heap. |
| + | *** When a process is created with system resource size > 0, it now creates a KSecureSystemResource (which manages allocation with KSystemControl). |
| + | **** All actual underlying logic is the same, this just abstracts the KSystemControl/secure memory interaction out of KProcess. |
| + | * KInterruptEventTask was removed and no longer exists. |
| + | ** KInterruptEvent now inherits from KInterruptTask directly. |
| + | ** There is no longer a global task table; KInterruptManager is expected to return ResultBusy if an interrupt is already bound (it already did this). |
| + | ** KInterruptEvent::Finalize now unbinds the interrupt directly, and then calls KDpcManager::Request() with a no-op KDpcTask. |
| + | *** In practice, this unbinds the interrupt, and then creates an ordering to guarantee all cores will see the interrupt as unbound before continuing. |
| + | *** Trivia: this is the first use of KDpcManager::Request on non-debug kernels. |
| + | * Minor changes to KHandleTable: |
| + | ** KHandleTable::KHandleTable now initializes the table_size, max_count, and next_id fields to zero, previously they were uninitialized until Initialize was called. |
| + | ** KHandleTable::Initialize now instantiates a KScopedDisableDispatch while setting up the table. |
| + | |
| | | |
| ===[[HID_services|hid]]=== | | ===[[HID_services|hid]]=== |