|  | /* | 
|  | * Copyright (c) 2011-2014, Wind River Systems, Inc. | 
|  | * Copyright (c) 2019-2020 Intel Corp. | 
|  | * | 
|  | * SPDX-License-Identifier: Apache-2.0 | 
|  | */ | 
|  |  | 
|  | /** | 
|  | * @file Directives for linker MEMORY regions for all x86 | 
|  | * | 
|  | * By default, the kernel is linked at its physical address and all addresses | 
|  | * are in RAM. | 
|  | * | 
|  | * If CONFIG_XIP is enabled, then another MEMORY region is declared for ROM, | 
|  | * and this is where the Zephyr image is booted from. The linker LMAs and VMAs | 
|  | * are set up, such that read/write data/bss have their VMA addresses | 
|  | * in RAM and are copied from flash at boot. Text/rodata linked in-place in | 
|  | * flash. | 
|  | * | 
|  | * If CONFIG_MMU is enabled, then the ROM region in MEMORY is used to set the | 
|  | * LMA for all sections relative to physical address. The virtual address VMAs | 
|  | * for all sections are relative to the base virtual address for the kernel. | 
|  | * Setting LMAs here helps let QEMU or any other ELF-aware loader know where to | 
|  | * physically load the image. | 
|  | */ | 
|  |  | 
|  | #ifndef ARCH_X86_MEMORY_LD | 
|  | #define ARCH_X86_MEMORY_LD | 
|  |  | 
|  | #include <autoconf.h> | 
|  | #include <devicetree.h> | 
|  | #include <sys/mem_manage.h> | 
|  |  | 
|  | /* Bounds of physical RAM from DTS */ | 
|  | #define PHYS_RAM_ADDR		DT_REG_ADDR(DT_CHOSEN(zephyr_sram)) | 
|  | #define PHYS_RAM_SIZE		DT_REG_SIZE(DT_CHOSEN(zephyr_sram)) | 
|  |  | 
|  | /* Virtual base address for the kernel; with CONFIG_MMU this is not necessarily | 
|  | * the same as its physical location, although an identity mapping for RAM | 
|  | * is still supported by setting CONFIG_KERNEL_VM_BASE=CONFIG_SRAM_BASE_ADDRESS. | 
|  | */ | 
|  | #ifdef Z_VM_KERNEL | 
|  | #define KERNEL_BASE_ADDR  (CONFIG_KERNEL_VM_BASE + CONFIG_KERNEL_VM_OFFSET) | 
|  | #define KERNEL_RAM_SIZE   (CONFIG_KERNEL_VM_SIZE - CONFIG_KERNEL_VM_OFFSET) | 
|  | #define PHYS_RAM_AVAIL    (PHYS_RAM_SIZE - CONFIG_SRAM_OFFSET) | 
|  | #else | 
|  | #define KERNEL_BASE_ADDR  (PHYS_RAM_ADDR + CONFIG_SRAM_OFFSET) | 
|  | #define KERNEL_RAM_SIZE   (PHYS_RAM_SIZE - CONFIG_SRAM_OFFSET) | 
|  | #endif | 
|  |  | 
|  | /* "kernel RAM" for linker VMA allocations starts at the offset */ | 
|  |  | 
|  | #ifdef CONFIG_XIP | 
|  | /* "ROM" is flash, we leave rodata and text there and just copy in data. | 
|  | * Board-level DTS must specify a flash region that doesn't overlap with | 
|  | * sram0, so that DT_PHYS_LOAD_ADDR is set. | 
|  | */ | 
|  | #define FLASH_ROM_SIZE      DT_REG_SIZE(DT_CHOSEN(zephyr_flash)) | 
|  | #define PHYS_LOAD_ADDR      DT_REG_ADDR(DT_CHOSEN(zephyr_flash)) | 
|  | #else | 
|  | /* Physical RAM location where the kernel image is loaded */ | 
|  | #define PHYS_LOAD_ADDR      (PHYS_RAM_ADDR + CONFIG_SRAM_OFFSET) | 
|  | #endif /* CONFIG_XIP */ | 
|  |  | 
|  | #ifdef CONFIG_X86_64 | 
|  | /* Locore must be addressable by real mode and so cannot extend past 64K. | 
|  | * Skip reserved stuff in the first page | 
|  | */ | 
|  | #define LOCORE_BASE         0x1000 | 
|  | #define LOCORE_SIZE         (0x10000 - LOCORE_BASE) | 
|  |  | 
|  | #if PHYS_RAM_ADDR != CONFIG_KERNEL_VM_BASE | 
|  | #error Virtual kernel linking is not yet implemented for 64-bit | 
|  | #endif | 
|  | #endif /* CONFIG_X86_64 */ | 
|  |  | 
|  | MEMORY | 
|  | { | 
|  | #if defined(CONFIG_XIP) | 
|  | /* Address range where the kernel will be installed on a flash part (XIP), | 
|  | * or copied into physical RAM by a loader (MMU) | 
|  | */ | 
|  | ROM (rx)        : ORIGIN = PHYS_LOAD_ADDR, LENGTH = FLASH_ROM_SIZE | 
|  | #elif defined(Z_VM_KERNEL) | 
|  | ROM (rx)        : ORIGIN = PHYS_LOAD_ADDR, LENGTH = PHYS_RAM_AVAIL | 
|  | #endif | 
|  | /* Linear address range to link the kernel. If non-XIP, everything is | 
|  | * linked in this space. Otherwise, rodata and text are linked at their | 
|  | * physical ROM locations | 
|  | */ | 
|  | RAM (wx)        : ORIGIN = KERNEL_BASE_ADDR, LENGTH = KERNEL_RAM_SIZE | 
|  |  | 
|  | #ifdef CONFIG_X86_64 | 
|  | /* Special low-memory area for bootstrapping other CPUs from real mode */ | 
|  | LOCORE (wx)     : ORIGIN = LOCORE_BASE, LENGTH = LOCORE_SIZE | 
|  | #else | 
|  | /* | 
|  | * On 32-bit x86, fake memory area for build-time IDT generation data. | 
|  | * 64-bit doesn't use this, interrupts are all manaaged at runtime. | 
|  | * | 
|  | * It doesn't matter where this region goes as it is stripped from the | 
|  | * final ELF image. The address doesn't even have to be valid on the | 
|  | * target. However, it shouldn't overlap any other regions. | 
|  | */ | 
|  |  | 
|  | IDT_LIST        : ORIGIN = 0xFFFF1000, LENGTH = 2K | 
|  | #endif /* !CONFIG_X86_64 */ | 
|  | } | 
|  | #endif /* ARCH_X86_MEMORY_LD */ |