Changes

1,206 bytes added ,  04:48, 31 August 2019
KernelLdr_GetAdjustedKernelPhysicalBase
Line 64: Line 64:  
== KernelLdr_LoadKernel ==
 
== KernelLdr_LoadKernel ==
   −
First, it backs up the original kernel base, and then relocates the kernel for
+
First, it backs up the original kernel base, and then relocates the kernel physically to the upper half of DRAM if enough memory is available.
    
<pre>
 
<pre>
Line 98: Line 98:  
== KernelLdr_GetAdjustedKernelPhysicalBase ==
 
== KernelLdr_GetAdjustedKernelPhysicalBase ==
   −
TODO: secmon calls here
+
This sees how much more memory is available than expected, and relocates the kernel accordingly.
 +
 
 +
Note: Panic (infloop) happens on any smc call error, this isn't depicted in pseudocode for brevity reasons.
 +
 
 +
<pre>
 +
    // Gets DRAM size information from Memory Controller
 +
    dram_size_from_mc = (smc_read_write_register(MC_EMEM_CFG, 0, 0) & 0x3FFF) << 20;
 +
   
 +
    // Gets DRAM size information from Secure Monitor KernelConfiguration
 +
    memory_type = (smc_get_config(ConfigItem_KernelConfiguration) >> 16) & 3;
 +
    switch (memory_type) {
 +
        case MemoryType_4GB: // 0
 +
            dram_size_from_kernel_cfg = 0x100000000;
 +
            break;
 +
        case MemoryType_6GB: // 1
 +
            dram_size_from_kernel_cfg = 0x180000000;
 +
            break;
 +
        case MemoryType_8GB: // 2
 +
        default:
 +
            dram_size_from_kernel_cfg = 0x200000000;
 +
            break;
 +
    }
 +
   
 +
    // On normal systems, these should be equal (and kernel will not be relocated).
 +
    if (dram_size_from_mc < 2 * dram_size_from_kernel_cfg) {
 +
        return kernel_base + (dram_size_from_mc - dram_size_from_kernel_cfg) / 2;
 +
    } else {
 +
        return kernel_base;
 +
    }
 +
</pre>
    
== KInitialPageAllocator::KInitialPageAllocator ==
 
== KInitialPageAllocator::KInitialPageAllocator ==