/* * Copyright (c) 2013-2014 Wind River Systems, Inc. * Copyright (c) 2016-2017 Jean-Paul Etienne * Copyright (c) 2018 Foundries.io Ltd * * This file is based on: * * - include/arch/arm/cortex_m/scripts/linker.ld * - include/arch/riscv/common/linker.ld * - include/arch/riscv/pulpino/linker.ld * * SPDX-License-Identifier: Apache-2.0 */ #include #include #include #include /* * Extra efforts would need to be taken to ensure the IRQ handlers are within * jumping distance of the vector table in non-XIP builds, so avoid them. */ #define ROMABLE_REGION ROM #define RAMABLE_REGION RAM #define VECTOR_SIZE 0x100 #ifdef CONFIG_USE_DT_CODE_PARTITION #ifdef CONFIG_BOOTLOADER_MCUBOOT #define ROM_BASE (DT_REG_ADDR(DT_CHOSEN(zephyr_code_partition))) #define ROM_SIZE (DT_REG_SIZE(DT_CHOSEN(zephyr_code_partition))) #define VECTOR_BASE (ROM_BASE + CONFIG_ROM_START_OFFSET) #else #define ROM_BASE (DT_REG_ADDR(DT_CHOSEN(zephyr_code_partition))) #define ROM_SIZE (DT_REG_SIZE(DT_CHOSEN(zephyr_code_partition)) - VECTOR_BASE) #define VECTOR_BASE (ROM_BASE + ROM_SIZE) #endif #else #define ROM_BASE DT_REG_ADDR(DT_CHOSEN(zephyr_flash)) #define ROM_SIZE (DT_REG_SIZE(DT_CHOSEN(zephyr_flash)) - VECTOR_SIZE) #define VECTOR_BASE (ROM_BASE + ROM_SIZE) #endif #define RAM_BASE CONFIG_SRAM_BASE_ADDRESS #define RAM_SIZE KB(CONFIG_SRAM_SIZE) MEMORY { ROM (rx) : ORIGIN = ROM_BASE, LENGTH = ROM_SIZE /* * Each RISC-V core on this chip (RI5CY and ZERO-RISCY) has * a vector table at the end of its flash bank. They are relocatable * at runtime, but we need to put the reset vectors in hardcoded places. * * (The Arm core vector tables are at the beginning of each * flash bank.) */ #ifndef CONFIG_BOOTLOADER_MCUBOOT VECTORS (rx) : ORIGIN = VECTOR_BASE, LENGTH = VECTOR_SIZE #endif RAM (rwx) : ORIGIN = RAM_BASE, LENGTH = RAM_SIZE /* * Special section, not included in the final binary, used * to generate interrupt tables. See include/linker/intlist.ld. */ IDT_LIST (wx) : ORIGIN = 0xFFFFF7FF, LENGTH = 2K } ENTRY(CONFIG_KERNEL_ENTRY) SECTIONS { #include #ifdef CONFIG_LLEXT #include #endif SECTION_PROLOGUE(.plt,,) { *(.plt) } SECTION_PROLOGUE(.iplt,,) { *(.iplt) } GROUP_START(ROM) __rom_region_start = ROM_BASE; SECTION_PROLOGUE(_TEXT_SECTION_NAME,,) { /* Located in generated directory. This file is populated by calling * zephyr_linker_sources(ROM_START ...). This typically contains the vector * table and debug information. */ #include __text_region_start = .; *(.text .text.*) *(.gnu.linkonce.t.*) *(.eh_frame) } GROUP_LINK_IN(ROM) __text_region_end = .; __rodata_region_start = .; #include /* Located in generated directory. This file is populated by calling * zephyr_linker_sources(ROM_SECTIONS ...). Useful for grouping iterable RO structs. */ #include #include SECTION_PROLOGUE(_RODATA_SECTION_NAME,,) { . = ALIGN(4); *(.srodata) *(".srodata.*") *(.rodata) *(.rodata.*) *(.gnu.linkonce.r.*) /* Located in generated directory. This file is populated by the * zephyr_linker_sources() Cmake function. */ #include } GROUP_LINK_IN(ROMABLE_REGION) #include __rodata_region_end = .; __rom_region_end = .; #ifndef CONFIG_BOOTLOADER_MCUBOOT /* The vector table goes into core-dependent flash locations. */ SECTION_PROLOGUE(vectors,,) { _vector_start = .; KEEP(*(.vectors.*)) } GROUP_LINK_IN(VECTORS) _vector_end = .; #endif GROUP_END(ROM) GROUP_START(RAM) SECTION_DATA_PROLOGUE(_DATA_SECTION_NAME,,) { . = ALIGN(4); _image_ram_start = .; __data_region_start = .; __data_start = .; *(.data) *(.data.*) *(.gnu.linkonce.s.*) /* https://groups.google.com/a/groups.riscv.org/d/msg/sw-dev/60IdaZj27dY/TKT3hbNlAgAJ */ *(.sdata .sdata.* .gnu.linkonce.s.*) *(.sdata2 .sdata2.* .gnu.linkonce.s2.*) /* Located in generated directory. This file is populated by the * zephyr_linker_sources() Cmake function. */ #include __data_end = .; } GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION) __data_size = __data_end - __data_start; __data_load_start = LOADADDR(_DATA_SECTION_NAME); #include #include /* Located in generated directory. This file is populated by the * zephyr_linker_sources() Cmake function. */ #include __data_region_end = .; __data_region_load_start = LOADADDR(_DATA_SECTION_NAME); SECTION_DATA_PROLOGUE(_BSS_SECTION_NAME,(NOLOAD),) { /* * For performance, BSS section is assumed to be 4 byte aligned and * a multiple of 4 bytes, so it can be cleared in words. */ . = ALIGN(4); __bss_start = .; *(.bss .bss.*) *(.sbss .sbss.*) COMMON_SYMBOLS /* Ensure 4 byte alignment for the entire section. */ . = ALIGN(4); __bss_end = .; } GROUP_DATA_LINK_IN(RAMABLE_REGION, RAMABLE_REGION) SECTION_PROLOGUE(_NOINIT_SECTION_NAME,(NOLOAD),) { /* * This section is used for non-initialized objects that * will not be cleared during the boot process. */ *(.noinit .noinit.*) /* Located in generated directory. This file is populated by the * zephyr_linker_sources() Cmake function. */ #include } GROUP_LINK_IN(RAMABLE_REGION) /* Located in generated directory. This file is populated by the * zephyr_linker_sources() Cmake function. */ #include /* Located in generated directory. This file is populated by the * zephyr_linker_sources() Cmake function. */ #include #include GROUP_END(RAMABLE_REGION) #ifdef CONFIG_GEN_ISR_TABLES /* Bogus section, post-processed during the build to initialize interrupts. */ #include #endif #include SECTION_PROLOGUE(.riscv.attributes, 0,) { KEEP(*(.riscv.attributes)) KEEP(*(.gnu.attributes)) } /* * Pulpino toolchains emit these sections; we don't care about them, * but need to avoid build system warnings about orphaned sections. */ SECTION_PROLOGUE(.Pulp_Chip.Info,,) { *(.Pulp_Chip.*) } }