Add proper user/kernel space linker scripts for knsh target

The old implementation used the default ld.script for the kernel side
which did not obey the memory.ld limits whatsoever.

Also, provide the user space addresses from the linker script to get rid
of the pre-processor macros that define (incorrect) default values for
the user space composition.
This commit is contained in:
Ville Juven 2022-01-24 10:00:48 +02:00 committed by Xiang Xiao
parent 356ae984ac
commit 7eb726d57f
7 changed files with 172 additions and 53 deletions

View File

@ -38,26 +38,19 @@
* Pre-processor Definitions
****************************************************************************/
/* Configuration ************************************************************/
/* TODO: get user space mem layout info from ld script or Configuration ? */
#ifndef CONFIG_NUTTX_USERSPACE_SIZE
# define CONFIG_NUTTX_USERSPACE_SIZE (0x00100000)
#endif
#ifndef CONFIG_NUTTX_USERSPACE_RAM_START
# define CONFIG_NUTTX_USERSPACE_RAM_START (0x00100000)
#endif
#ifndef CONFIG_NUTTX_USERSPACE_RAM_SIZE
# define CONFIG_NUTTX_USERSPACE_RAM_SIZE (0x00100000)
#endif
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Public Data
****************************************************************************/
extern uintptr_t __uflash_start;
extern uintptr_t __uflash_size;
extern uintptr_t __usram_start;
extern uintptr_t __usram_size;
/****************************************************************************
* Name: mpfs_userspace
*
@ -104,24 +97,35 @@ void mpfs_userspace(void)
}
/* Configure the PMP to permit user-space access to its ROM and RAM.
* Now this is done by simply adding the whole memory area to PMP.
* 1. no access for the 1st 4KB
* 2. "RX" for the left space until 1MB
* 3. "RW" for the user RAM area
* TODO: more accurate memory size control.
*
* Note: PMP by default revokes access, thus if different privilege modes
* are in use (mstatus.mprv is set), the the user space _must_ be granted
* access here, otherwise an exception will fire when the user space task
* is started.
*
* Note: according to the Polarfire reference manual, address bits [1:0]
* are not considered (due to 4 octet alignment), so strictly they don't
* have to be cleared here.
*
* Note: do not trust the stext / etc sections to be correctly aligned
* here, they should be but it is simpler and safer to handle the user
* region as a whole
*
* Access is currently granted by simply adding each userspace memory area
* to PMP, without further granularity.
*
* "RX" for the user progmem
* "RW" for the user RAM area
*
*/
riscv_config_pmp_region(0, PMPCFG_A_NAPOT,
0,
0x1000);
riscv_config_pmp_region(0, PMPCFG_A_NAPOT | PMPCFG_X | PMPCFG_R,
(uintptr_t)&__uflash_start,
(uintptr_t)&__uflash_size);
riscv_config_pmp_region(1, PMPCFG_A_TOR | PMPCFG_X | PMPCFG_R,
0 + CONFIG_NUTTX_USERSPACE_SIZE,
0);
riscv_config_pmp_region(2, PMPCFG_A_NAPOT | PMPCFG_W | PMPCFG_R,
CONFIG_NUTTX_USERSPACE_RAM_START,
CONFIG_NUTTX_USERSPACE_RAM_SIZE);
riscv_config_pmp_region(1, PMPCFG_A_NAPOT | PMPCFG_W | PMPCFG_R,
(uintptr_t)&__usram_start,
(uintptr_t)&__usram_size);
}
#endif /* CONFIG_BUILD_PROTECTED */

View File

@ -43,10 +43,6 @@
# error "CONFIG_NUTTX_USERSPACE not defined"
#endif
#if CONFIG_NUTTX_USERSPACE != 0x00001000
# error "CONFIG_NUTTX_USERSPACE must match the value in memory.ld"
#endif
/****************************************************************************
* Public Data
****************************************************************************/

View File

@ -11,16 +11,14 @@ CONFIG_ARCH="risc-v"
CONFIG_ARCH_BOARD="icicle"
CONFIG_ARCH_BOARD_ICICLE_MPFS=y
CONFIG_ARCH_CHIP="mpfs"
CONFIG_ARCH_CHIP_MPFS250T_FCVG484=y
CONFIG_ARCH_CHIP_MPFS=y
CONFIG_ARCH_INTERRUPTSTACK=2048
CONFIG_ARCH_RISCV=y
CONFIG_ARCH_STACKDUMP=y
CONFIG_ARCH_USE_MPU=y
CONFIG_BUILD_PROTECTED=y
CONFIG_SYS_RESERVED=9
CONFIG_PASS1_BUILDIR="boards/risc-v/mpfs/common/kernel"
CONFIG_NUTTX_USERSPACE=0x80040000
CONFIG_BOARD_LOOPSPERMSEC=54000
CONFIG_BUILD_PROTECTED=y
CONFIG_BUILTIN=y
CONFIG_DEBUG_ASSERTIONS=y
CONFIG_DEBUG_ERROR=y
@ -54,9 +52,11 @@ CONFIG_NSH_DISABLE_RMDIR=y
CONFIG_NSH_DISABLE_UMOUNT=y
CONFIG_NSH_LINELEN=160
CONFIG_NSH_STRERROR=y
CONFIG_NUTTX_USERSPACE=0x80040000
CONFIG_PASS1_BUILDIR="boards/risc-v/mpfs/common/kernel"
CONFIG_PREALLOC_TIMERS=4
CONFIG_RAM_SIZE=1048576
CONFIG_RAM_START=0x80200000
CONFIG_RAM_SIZE=262144
CONFIG_RAM_START=0x80080000
CONFIG_RAW_BINARY=y
CONFIG_READLINE_CMD_HISTORY=y
CONFIG_READLINE_TABCOMPLETION=y
@ -73,6 +73,7 @@ CONFIG_SYSTEM_CLE_CMD_HISTORY=y
CONFIG_SYSTEM_COLOR_CLE=y
CONFIG_SYSTEM_NSH=y
CONFIG_SYSTEM_TIME64=y
CONFIG_SYS_RESERVED=9
CONFIG_TASK_NAME_SIZE=20
CONFIG_TESTING_GETPRIME=y
CONFIG_TESTING_OSTEST=y

View File

@ -23,20 +23,32 @@ include $(TOPDIR)/tools/Config.mk
include $(TOPDIR)/tools/mpfs/Config.mk
include $(TOPDIR)/arch/risc-v/src/common/Toolchain.defs
LDMEMORY =
ARCHSCRIPT =
ifeq ($(CONFIG_MPFS_BOOTLOADER),y)
ifeq ($(CONFIG_MPFS_OPENSBI),y)
LDSCRIPT = ld-envm-opensbi.script
else
LDSCRIPT = ld-envm.script
endif
else ifeq ($(CONFIG_BUILD_PROTECTED),y)
LDMEMORY = memory.ld
LDSCRIPT = kernel-space.ld
else
LDSCRIPT = ld.script
endif
ifeq ($(CONFIG_CYGWIN_WINTOOL),y)
ARCHSCRIPT = -T "${shell cygpath -w $(BOARD_DIR)$(DELIM)scripts$(DELIM)$(LDSCRIPT)}"
ifneq ($(LDMEMORY),)
ARCHSCRIPT += -T "${shell cygpath -w $(BOARD_DIR)$(DELIM)scripts$(DELIM)$(LDMEMORY)}"
endif
ARCHSCRIPT += -T "${shell cygpath -w $(BOARD_DIR)$(DELIM)scripts$(DELIM)$(LDSCRIPT)}"
else
ARCHSCRIPT = -T$(BOARD_DIR)$(DELIM)scripts$(DELIM)$(LDSCRIPT)
ifneq ($(LDMEMORY),)
ARCHSCRIPT += -T$(BOARD_DIR)$(DELIM)scripts$(DELIM)$(LDMEMORY)
endif
ARCHSCRIPT += -T$(BOARD_DIR)$(DELIM)scripts$(DELIM)$(LDSCRIPT)
endif
ifeq ($(CONFIG_DEBUG_SYMBOLS),y)

View File

@ -0,0 +1,113 @@
/****************************************************************************
* boards/risc-v/mpfs/icicle/scripts/ld.script
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you 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.
*
****************************************************************************/
/* NOTE: This depends on the memory.ld script having been included prior to
* this script.
*/
OUTPUT_ARCH("riscv")
/* Provide these so there is no need for using config files for this */
__uflash_start = ORIGIN(uflash);
__uflash_size = LENGTH(uflash);
__usram_start = ORIGIN(usram);
__usram_size = LENGTH(usram);
/* Provide the kernel boundaries as well */
__kflash_start = ORIGIN(kflash);
__kflash_size = LENGTH(kflash);
__ksram_start = ORIGIN(ksram);
__ksram_size = LENGTH(ksram);
ENTRY(_stext)
EXTERN(_vectors)
SECTIONS
{
.text : {
_stext = ABSOLUTE(.);
*(.vectors)
*(.text .text.*)
*(.fixup)
*(.gnu.warning)
*(.rodata .rodata.* .srodata .srodata.*)
*(.gnu.linkonce.t.*)
*(.glue_7)
*(.glue_7t)
*(.got)
*(.gcc_except_table)
*(.gnu.linkonce.r.*)
_etext = ABSOLUTE(.);
} > kflash
.init_section : ALIGN(4) {
_sinit = ABSOLUTE(.);
KEEP(*(.init_array .init_array.*))
_einit = ABSOLUTE(.);
} > kflash
_eronly = ABSOLUTE(.);
.data : ALIGN(4) {
_sdata = ABSOLUTE(.);
*(.data .data.*)
*(.sdata .sdata.* .sdata2.*)
*(.gnu.linkonce.d.*)
*(.gnu.linkonce.s.*)
CONSTRUCTORS
. = ALIGN(4);
_edata = ABSOLUTE(.);
} > ksram AT > kflash
PROVIDE(__global_pointer$ = _sdata + ((_edata - _sdata) / 2));
.bss : ALIGN(4) {
_sbss = ABSOLUTE(.);
*(.bss .bss.*)
*(.sbss .sbss.*)
*(.gnu.linkonce.b.*)
*(.gnu.linkonce.sb.*)
*(COMMON)
. = ALIGN(4);
_ebss = ABSOLUTE(.);
} > ksram
/* Stack top */
.stack_top : {
. = ALIGN(32);
_default_stack_limit = ABSOLUTE(.);
} > ksram
/* Stabs debugging sections. */
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
.stab.excl 0 : { *(.stab.excl) }
.stab.exclstr 0 : { *(.stab.exclstr) }
.stab.index 0 : { *(.stab.index) }
.stab.indexstr 0 : { *(.stab.indexstr) }
.comment 0 : { *(.comment) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_info 0 : { *(.debug_info) }
.debug_line 0 : { *(.debug_line) }
.debug_pubnames 0 : { *(.debug_pubnames) }
.debug_aranges 0 : { *(.debug_aranges) }
}

View File

@ -18,18 +18,11 @@
*
****************************************************************************/
/* Reg Access Start addr End addr Size
* QEMU CPU w/ cache 0x00000000 - 0x003fffff : 4MB
* QEMU CPU w/o cache 0x1f000000 - 0x1f01ffff : 128KB
*/
MEMORY
{
kflash (rx) : ORIGIN = 0x80000000, LENGTH = 256K /* w/ cache */
uflash (rx) : ORIGIN = 0x80040000, LENGTH = 256K /* w/ cache */
xflash (rx) : ORIGIN = 0x80080000, LENGTH = 256K /* w/o cache */
ksram (rwx) : ORIGIN = 0x800C0000, LENGTH = 256K /* w/ cache */
usram (rwx) : ORIGIN = 0x80100000, LENGTH = 256K /* w/ cache */
xsram (rwx) : ORIGIN = 0x80140000, LENGTH = 256K /* w/o cache */
ksram (rwx) : ORIGIN = 0x80080000, LENGTH = 256K /* w/ cache */
usram (rwx) : ORIGIN = 0x800C0000, LENGTH = 256K /* w/ cache */
}

View File

@ -45,7 +45,7 @@ SECTIONS
*(.text .text.*)
*(.fixup)
*(.gnu.warning)
*(.rodata .rodata.*)
*(.rodata .rodata.* .srodata .srodata.*)
*(.gnu.linkonce.t.*)
*(.glue_7)
*(.glue_7t)