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