Kernel Loader: Difference between revisions

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 ==