nios2: set up common linker script for XIP and non-XIP

We will require 6 variables to be defined by SOC-specific
linker script; these values in turn can be pulled from
defines in layout.h.

To help position code correctly we define two new ELF sections
for this arch, 'reset' and 'exceptions'.

Change-Id: Idffbd53895945b7d0ec0aac281e5bf7c85b4b2c2
Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
This commit is contained in:
Andrew Boie 2016-06-07 13:11:45 -07:00 committed by Anas Nashif
parent dca76617f0
commit 3b9302158c
4 changed files with 113 additions and 18 deletions

View file

@ -0,0 +1,26 @@
/*
* Copyright (c) 2016 Intel Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <system.h>
#define _RESET_VECTOR ALT_CPU_RESET_ADDR
#define _EXC_VECTOR ALT_CPU_EXCEPTION_ADDR
#define _ROM_ADDR ONCHIP_FLASH_0_DATA_BASE
#define _ROM_SIZE ONCHIP_FLASH_0_DATA_SPAN
#define _RAM_ADDR ONCHIP_MEMORY2_0_BASE
#define _RAM_SIZE ONCHIP_MEMORY2_0_SPAN

View file

@ -18,4 +18,6 @@
* @brief Linker script for the Nios II/e CPU with timer and 16550 UART
*/
#include <layout.h>
#include <arch/nios2/linker.ld>

View file

@ -30,30 +30,76 @@
#include <linker-defs.h>
#include <linker-tool.h>
#define ROMABLE_REGION FLASH
#define RAMABLE_REGION SRAM
/* These sections are specific to this CPU */
#define _EXCEPTION_SECTION_NAME exceptions
#define _RESET_SECTION_NAME reset
#define ROM_ADDR CONFIG_FLASH_BASE_ADDRESS
#define ROM_SIZE CONFIG_FLASH_SIZE * 1K
/* This linker script requires the following macros to be defined in the
* SOC-specfic linker script. All of these values can be found defined
* in system.h for CPU configurations that can generate a HAL.
*
* _RESET_VECTOR CPU entry point at boot
* _EXC_VECTOR General exception vector
* _ROM_ADDR Beginning of flash memory
* _ROM_SIZE Size in bytes of flash memory
* _RAM_ADDR Beginning of RAM
* _RAM_SIZE Size of RAM in bytes
*
* For now we support two scenarios:
*
* 1. Non-XIP systems where the reset vector is at the beginning of RAM
* with the exception vector 0x20 bytes after it.
* 2. XIP systems where the reset vector is at the beginning of ROM and
* the exception vector is in RAM
*/
#define RAM_ADDR CONFIG_SRAM_BASE_ADDRESS
#define RAM_SIZE CONFIG_SRAM_SIZE * 1K
#define _DATA_IN_ROM __data_rom_start
#ifdef CONFIG_XIP
#define ROMABLE_REGION FLASH
#define RAMABLE_REGION SRAM
#else
#define ROMABLE_REGION SRAM
#define RAMABLE_REGION SRAM
#endif
#ifdef CONFIG_XIP
ASSERT(_RESET_VECTOR == _ROM_ADDR, "Reset vector not at beginning of ROM!")
MEMORY
{
FLASH (rx) : ORIGIN = ROM_ADDR, LENGTH = ROM_SIZE
SRAM (wx) : ORIGIN = RAM_ADDR, LENGTH = RAM_SIZE
RESET (rx) : ORIGIN = _RESET_VECTOR, LENGTH = 0x20
FLASH (rx) : ORIGIN = _RESET_VECTOR + 0x20 , LENGTH = (_ROM_SIZE - 0x20)
SRAM (wx) : ORIGIN = _EXC_VECTOR, LENGTH = _RAM_SIZE - (_EXC_VECTOR - _RAM_ADDR)
}
#else
ASSERT(_RESET_VECTOR == _RAM_ADDR, "Reset vector not at beginning of RAM!")
ASSERT(_EXC_VECTOR - _RESET_VECTOR == 0x20, "Exception vector in wrong place?")
MEMORY
{
RESET (wx) : ORIGIN = _RESET_VECTOR, LENGTH = 0x20
SRAM (wx) : ORIGIN = _EXC_VECTOR, LENGTH = _RAM_SIZE - (_EXC_VECTOR - _RAM_ADDR)
}
#endif
SECTIONS
{
GROUP_START(ROMABLE_REGION)
_image_rom_start = CONFIG_FLASH_BASE_ADDRESS;
_image_rom_start = _ROM_ADDR;
SECTION_PROLOGUE(_RESET_SECTION_NAME,,)
{
*(.reset.*)
} GROUP_LINK_IN(RESET)
SECTION_PROLOGUE(_TEXT_SECTION_NAME,,)
{
/* XXX If ALT_CPU_RESET_ADDR is not the same as _ROM_ADDR
* we are going to waste flash space? */
. = ALT_CPU_RESET_ADDR;
_image_text_start = .;
*(.text)
@ -108,18 +154,37 @@ SECTIONS
_image_rom_end = .;
__data_rom_start = ALIGN(4); /* XIP imaged DATA ROM start addr */
GROUP_END(ROMABLE_REGION)
GROUP_START(RAMABLE_REGION)
_gp = ALIGN(16) + 0x7ff0;
PROVIDE(gp = _gp);
#ifdef CONFIG_XIP
/* Altera strongly recommends keeping exception entry code in RAM
* even on XIP systems
*
* XXX any space between _RAM_ADDR and ALT_CPU_EXCEPTION_ADDR is lost,
* currently 0x20 bytes
*
* This is code not data, but we need this copied just like XIP data
*/
SECTION_AT_PROLOGUE(_DATA_SECTION_NAME,,,_DATA_IN_ROM)
SECTION_AT_PROLOGUE(_EXCEPTION_SECTION_NAME,,, __data_rom_start)
{
_image_ram_start = .;
__data_ram_start = .;
/* FIXME these KEEP()s shouldn't be necessary */
KEEP(*(".exception.entry.*"))
KEEP(*(".exception.other.*"))
} GROUP_LINK_IN(RAMABLE_REGION)
#endif
SECTION_PROLOGUE(_DATA_SECTION_NAME,,)
{
#ifndef CONFIG_XIP
_image_ram_start = .;
__data_ram_start = .;
#endif
*(.data)
*(".data.*")
} GROUP_LINK_IN(RAMABLE_REGION)
@ -207,7 +272,6 @@ SECTIONS
} GROUP_LINK_IN(RAMABLE_REGION)
/* Define linker symbols */
_image_ram_end = .;
_end = .; /* end of image */
__bss_num_words = (__bss_end - __bss_start) >> 2;
@ -216,6 +280,7 @@ SECTIONS
}
#if CONFIG_XIP
/*
* Round up number of words for DATA section to ensure that XIP copies the
* entire data section. XIP copy is done in words only, so there may be up
@ -224,4 +289,5 @@ SECTIONS
*/
__data_size = (__data_ram_end - __data_ram_start);
__data_num_words = (__data_size + 3) >> 2;
#endif

View file

@ -385,9 +385,10 @@ class SizeCalculator:
alloc_sections = ["bss", "noinit"]
rw_sections = ["datas", "initlevel", "_k_mem_map_ptr", "_k_pipe_ptr",
"_k_task_ptr", "_k_task_list", "_k_event_list"]
"_k_task_ptr", "_k_task_list", "_k_event_list",
"exceptions"]
# These get copied into RAM only on non-XIP
ro_sections = ["text", "ctors", "init_array",
ro_sections = ["text", "ctors", "init_array", "reset",
"rodata", "devconfig", "gpio_compat"]
def __init__(self, filename):