Changes

Jump to navigation Jump to search
Update FCRAM memory management from latest TuxSH kernel idb
Line 178: Line 178:  
= How The Kernel Allocates And Tracks Memory =
 
= How The Kernel Allocates And Tracks Memory =
   −
== MemoryBlockHeader ==
+
FCRAM (128MiB for O3DS, or 256MiB for N3DS) is divided into three regions: APPLICATION, SYSTEM and BASE. A program is allowed to allocate memory in one of the three region. (For example games are always in the APPLICATION region). Inside one region, there are two kinds of memory that can be allocated: (regular) heap and linear heap.
 +
 
 +
(Regular) heap is allocated starting from the end of the memory region, and growing down. They are mostly for application private use, and sometimes for software-based memory sharing (with other process using KSharedMemory, for example). They can be mapped to anywhere inside 0x08000000~0x10000000 virtual memory range upon application request. When the application requests for a block of heap, the block is not guaranteed continuous in FCRAM and the location is not specified either.
 +
 
 +
Linear heap is allocated starting from the beginning of the memory region, and growing up. They are mostly for hardware-based memory sharing (with GPU, DMA etc.), but can also be used privately as well. They can be mapped to the linear heap virtual memory region (0x14000000+ or 0x30000000+, depending on game's kernel version). When the application requests for a linear heap block, the block is always continuous in FCRAM, and the difference between physical address and virtual address is always a constant. Therefore it gives virtual to physical address convertibility, which enables communication with other hardware.
 +
 
 +
Each region in the kernel is managed by a dedicated KPageHeap object, which tracks free memory blocks. Each free block is represented with a KPageHeapBlock structure stored in FCRAM that stores the size of the free region and links to adjacent blocks. When a chunk of memory is allocated from the heap, the block is removed from the linked list and the region is cleared, erasing the header. On initialization a free block is inserted that covers the entire region.
 +
 
 +
== KPageHeapBlock ==
    
Size: 0xC-bytes(?) pre-v11.0, 0x18-bytes starting with v11.0.
 
Size: 0xC-bytes(?) pre-v11.0, 0x18-bytes starting with v11.0.
Line 193: Line 201:  
|-
 
|-
 
| 0x4
 
| 0x4
| MemoryBlockHeader*
+
| KPageHeapBlock*
 
| Next
 
| Next
 
|-
 
|-
 
| 0x8
 
| 0x8
| MemoryBlockHeader*
+
| KPageHeapBlock*
 
| Prev
 
| Prev
 
|-
 
|-
 
| 0xC
 
| 0xC
| MemoryBlockHeader*
+
| KPageHeapBlock*
 
| Pointer to the current memchunk. Added with v11.0?
 
| Pointer to the current memchunk. Added with v11.0?
 
|-
 
|-
 
| 0x10
 
| 0x10
 
| u32
 
| u32
| Nonce, doesn't seem to be read at all except during MAC calculation. Added with v11.0. Used with the new heap [[11.0.0-33|security]] feature. A kernel state field is copied to this field before calculating the MAC. Once done, that kernel state field is subtracted by the value of the calculated MAC stored below. Since this kernel state field is initially 0x0, this field for the FCRAM APPLICATION+0 MemoryBlockHeader during kernel boot is set to 0x0.
+
| Nonce, doesn't seem to be read at all except during MAC calculation. Added with v11.0. Used with the new heap [[11.0.0-33|security]] feature. A kernel state field is copied to this field before calculating the MAC. Once done, that kernel state field is subtracted by the value of the calculated MAC stored below. Since this kernel state field is initially 0x0, this field for the FCRAM APPLICATION+0 KPageHeapBlock during kernel boot is set to 0x0.
 
|-
 
|-
 
| 0x14
 
| 0x14
Line 213: Line 221:  
|}
 
|}
   −
== RegionDescriptor ==
+
== KPageHeap ==
    
Size: 0x10-bytes pre-[[11.0.0-33|11.0.0-X]], 0x20-bytes starting with [[11.0.0-33|11.0.0-X]].
 
Size: 0x10-bytes pre-[[11.0.0-33|11.0.0-X]], 0x20-bytes starting with [[11.0.0-33|11.0.0-X]].
Line 224: Line 232:  
|-
 
|-
 
| 0x0
 
| 0x0
| MemoryBlockHeader*
+
| KPageHeapBlock*
 
| First
 
| First
 
|-
 
|-
 
| 0x4
 
| 0x4
| MemoryBlockHeader*
+
| KPageHeapBlock*
 
| Last
 
| Last
 
|-
 
|-
Line 244: Line 252:  
|}
 
|}
    +
The KPageHeap objects are owned by the KMemoryManager. This object acts as a light wrapper that abstracts allocations and freeing of memory from the heaps and handles page reference tracking.
   −
== FCRAM Region Descriptor ==
+
== KMemoryManager ==
    
Size: 0x50-bytes pre-[[11.0.0-33|11.0.0-X]], 0x80-bytes starting with [[11.0.0-33|11.0.0-X]].
 
Size: 0x50-bytes pre-[[11.0.0-33|11.0.0-X]], 0x80-bytes starting with [[11.0.0-33|11.0.0-X]].
   −
X = RegionDescriptor_size*3.
+
X = KPageHeap_size*3.
    
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
Line 258: Line 267:  
|-
 
|-
 
| 0x0
 
| 0x0
| RegionDescriptor
+
| KPageHeap
| RegionDescriptor for app memory
+
| KPageHeap for app memory
 
|-
 
|-
| RegionDescriptor_size*1
+
| KPageHeap_size*1
| RegionDescriptor
+
| KPageHeap
| RegionDescriptor for sys memory
+
| KPageHeap for sys memory
 
|-
 
|-
| RegionDescriptor_size*2
+
| KPageHeap_size*2
| RegionDescriptor
+
| KPageHeap
| RegionDescriptor for base memory
+
| KPageHeap for base memory
 
|-
 
|-
 
| X + 0x0
 
| X + 0x0
| u32
+
| KMemoryManager*
 
| Ptr to start of FCRAM region descriptor
 
| Ptr to start of FCRAM region descriptor
 
|-
 
|-
Line 282: Line 291:  
|-
 
|-
 
| X + 0xC
 
| X + 0xC
| u32
+
| u32*
| Base memory start in FCRAM
+
| Pointer to FCRAM memory used for page reference tracking. Each u32 represents a page.
 
|-
 
|-
 
| X + 0x10
 
| X + 0x10
Line 294: Line 303:  
|-
 
|-
 
| X + 0x18
 
| X + 0x18
| KThread*
+
| KLightMutex
| Thread operating on region data
+
| Mutex used for thread synchronization during memory (de)allocation from the heaps.
|-
  −
| X + 0x1C
  −
| s16
  −
| Error info for thread listed above
  −
|-
  −
| X + 0x1E
  −
| u16
  −
| Alignment
   
|}
 
|}
       
== Kernel Region Descriptor ==
 
== Kernel Region Descriptor ==
33

edits

Navigation menu