From 1effe24b5fb946a5acfd149cd85094b8b7235985 Mon Sep 17 00:00:00 2001 From: anjiahao Date: Mon, 1 Jul 2024 17:33:23 +0800 Subject: [PATCH] mps3-an547:let ap build with pic,and use bootloader boot it Implement PIC loading in armv8-m qemu, for example: load address-independent AP ELF in the bootloader, and the text segment in AP ELF is XIP, no need to apply for memory and modify it. Two config: bootloader abbreviation bl: use romfs to load ap elf, use the boot command to parse and jump to ap application abbreviation ap: run os test We need to compile ap first, then compile bl. compile step: ./tools/configure.sh mps3-an547:ap make -j20 mkdir -p pic cp boot pic/. genromfs -a 128 -f ../romfs.img -d pic make distclean -j20 ./tools/configure.sh mps3-an547:bl make -j20 run qemu: qemu-system-arm -M mps3-an547 -m 2G -nographic -kernel nuttx.bin \ -gdb tcp::1127 -device loader,file=../romfs.img,addr=0x60000000 nsh> boot /etc/boot ap> ostest Signed-off-by: anjiahao --- .../arm/mps/boards/mps3-an547/index.rst | 18 +++ arch/arm/src/mps/Kconfig | 2 + arch/arm/src/mps/mps_allocateheap.c | 134 ++++++++++++++++-- arch/arm/src/mps/mps_start.c | 29 ++++ .../arm/mps/mps3-an547/configs/bl/defconfig | 2 + boards/arm/mps/mps3-an547/scripts/flash.ld | 10 +- boards/arm/mps/mps3-an547/src/mps3_bringup.c | 80 +++++++++++ 7 files changed, 260 insertions(+), 15 deletions(-) diff --git a/Documentation/platforms/arm/mps/boards/mps3-an547/index.rst b/Documentation/platforms/arm/mps/boards/mps3-an547/index.rst index 4489980147fd1..147355527a620 100644 --- a/Documentation/platforms/arm/mps/boards/mps3-an547/index.rst +++ b/Documentation/platforms/arm/mps/boards/mps3-an547/index.rst @@ -41,6 +41,24 @@ Configuring and Running $ nsh> /pic/ostest ``` +4. **Pic bootloader boot to ap, and run ostest:** + + ```bash + $ ./tools/configure.sh mps3-an547:ap + $ make -j20 + $ mkdir -p pic + $ arm-none-eabi-strip --remove-section=.rel.text --remove-section=.comment --strip-unneeded nuttx -o pic/boot + $ genromfs -a -f 128 ../romfs.img -d pic + $ make distclean -j20 + $ ./tools/configure.sh mps3-an547:bl + $ make -j20 + $ qemu-system-arm -M mps3-an547 -m 2G -nographic \ + -kernel nuttx.bin -gdb tcp::1127 \ + -device loader,file=../romfs.img,addr=0x60000000 + $ bl> boot /pic/boot + $ ap> ostest + ``` + Debugging with QEMU =================== diff --git a/arch/arm/src/mps/Kconfig b/arch/arm/src/mps/Kconfig index 5a60ac3ce8e25..8a89ae6da9d91 100644 --- a/arch/arm/src/mps/Kconfig +++ b/arch/arm/src/mps/Kconfig @@ -42,6 +42,8 @@ config ARCH_CHIP_MPS3_AN547 select ARCH_CORTEXM55 select ARCH_HAVE_FPU select ARM_HAVE_MVE + select ARCH_HAVE_TEXT_HEAP + select ARCH_HAVE_DATA_HEAP endchoice diff --git a/arch/arm/src/mps/mps_allocateheap.c b/arch/arm/src/mps/mps_allocateheap.c index ab838df831d14..a576c54c264b9 100644 --- a/arch/arm/src/mps/mps_allocateheap.c +++ b/arch/arm/src/mps/mps_allocateheap.c @@ -43,6 +43,8 @@ * Pre-processor Definitions ****************************************************************************/ +#define ALIGN_UP(x, a) (((x) + (a) - 1) & ~((a) - 1)) + /* Configuration ************************************************************/ /* Terminology. @@ -76,21 +78,12 @@ */ /**************************************************************************** - * Public Data + * Private Data ****************************************************************************/ -/* _sbss is the start of the BSS region (see the linker script) _ebss is the - * end of the BSS regions (see the linker script). The idle task stack starts - * at the end of BSS and is of size CONFIG_IDLETHREAD_STACKSIZE. The IDLE - * thread is the thread that the system boots on and, eventually, becomes the - * idle, do nothing task that runs only when there is nothing else to run. - * The heap continues from there until the configured end of memory. - * g_idle_topstack is the beginning of this heap region (not necessarily - * aligned). - */ - -const uintptr_t g_idle_topstack = (uintptr_t)_ebss + - CONFIG_IDLETHREAD_STACKSIZE; +#if defined(CONFIG_ARCH_USE_TEXT_HEAP) || defined(CONFIG_ARCH_USE_DATA_HEAP) +static uintptr_t g_alloc_count; +#endif /**************************************************************************** * Public Functions @@ -169,8 +162,13 @@ void up_allocate_heap(void **heap_start, size_t *heap_size) /* Allow user-mode access to the user heap memory */ mpu_user_intsram(ubase, usize); -#else +#elif defined(CONFIG_BUILD_PIC) + /* Use different heap useful to debug */ + + *heap_start = (void *)MPS_SRAM1_START; + *heap_size = MPS_SRAM1_SIZE; +#else /* Return the heap settings */ *heap_start = (void *)g_idle_topstack; @@ -271,3 +269,111 @@ void arm_addregion(void) #endif /* CONFIG_MM_REGIONS > 2 */ } #endif /* CONFIG_MM_REGIONS > 1 */ + +/**************************************************************************** + * Name: up_textheap_memalign + * + * Description: + * Allocate memory for text with the specified alignment and sectname. + * + ****************************************************************************/ + +#if defined(CONFIG_ARCH_USE_TEXT_HEAP) +# if defined(CONFIG_ARCH_USE_SEPARATED_SECTION) +void *up_textheap_memalign(const char *sectname, + size_t align, size_t size) +# else +void *up_textheap_memalign(size_t align, size_t size) +# endif +{ + uintptr_t base = (uintptr_t)MPS_SRAM2_START + g_alloc_count; + uintptr_t ret = ALIGN_UP(base, align); + + g_alloc_count += ret - base + size; + return (void *)ret; +} +#endif + +/**************************************************************************** + * Name: up_textheap_free + * + * Description: + * Free memory allocated for text sections. + * + ****************************************************************************/ + +#if defined(CONFIG_ARCH_USE_TEXT_HEAP) +void up_textheap_free(void *p) +{ +} +#endif + +/**************************************************************************** + * Name: up_textheap_heapmember + * + * Description: + * Test if memory is from text heap. + * + ****************************************************************************/ + +#if defined(CONFIG_ARCH_USE_TEXT_HEAP) +bool up_textheap_heapmember(void *p) +{ + return (uintptr_t)p >= MPS_SRAM2_START && + (uintptr_t)p < MPS_SRAM2_START + MPS_SRAM2_SIZE; +} +#endif + +/**************************************************************************** + * Name: up_dataheap_memalign + * + * Description: + * Allocate memory for data with the specified alignment and sectname. + * + ****************************************************************************/ + +#if defined(CONFIG_ARCH_USE_DATA_HEAP) +# if defined(CONFIG_ARCH_USE_SEPARATED_SECTION) +void *up_dataheap_memalign(const char *sectname, + size_t align, size_t size) +# else +void *up_dataheap_memalign(size_t align, size_t size) +# endif +{ + uintptr_t base = (uintptr_t)MPS_SRAM2_START + g_alloc_count; + uintptr_t ret = ALIGN_UP(base, align); + + g_alloc_count += ret - base + size; + return (void *)ret; +} +#endif + +/**************************************************************************** + * Name: up_dataheap_free + * + * Description: + * Free memory allocated for data sections. + * + ****************************************************************************/ + +#if defined(CONFIG_ARCH_USE_DATA_HEAP) +void up_dataheap_free(void *p) +{ +} +#endif + +/**************************************************************************** + * Name: up_dataheap_heapmember + * + * Description: + * Test if memory is from data heap. + * + ****************************************************************************/ + +#if defined(CONFIG_ARCH_USE_DATA_HEAP) +bool up_dataheap_heapmember(void *p) +{ + return (uintptr_t)p >= MPS_SRAM2_START && + (uintptr_t)p < MPS_SRAM2_START + MPS_SRAM2_SIZE; +} +#endif diff --git a/arch/arm/src/mps/mps_start.c b/arch/arm/src/mps/mps_start.c index 9336f1ab4f4f0..46b08f0c5b56b 100644 --- a/arch/arm/src/mps/mps_start.c +++ b/arch/arm/src/mps/mps_start.c @@ -36,6 +36,28 @@ #include "mps_userspace.h" #include "mpu.h" +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +#define HEAP_BASE ((uintptr_t)_ebss + CONFIG_IDLETHREAD_STACKSIZE) + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/* g_idle_topstack: _sbss is the start of the BSS region as defined by the + * linker script. _ebss lies at the end of the BSS region. The idle task + * stack starts at the end of BSS and is of size CONFIG_IDLETHREAD_STACKSIZE. + * The IDLE thread is the thread that the system boots on and, eventually, + * becomes the IDLE, do nothing task that runs only when there is nothing + * else to run. The heap continues from there until the end of memory. + * g_idle_topstack is a read-only variable the provides this computed + * address. + */ + +const uintptr_t g_idle_topstack = HEAP_BASE; + /**************************************************************************** * Private Functions ****************************************************************************/ @@ -94,8 +116,10 @@ static inline void mps_tcmenable(void) void __start(void) { +#ifndef CONFIG_BUILD_PIC const uint32_t *src; uint32_t *dest; +#endif /* If enabled reset the MPU */ @@ -105,6 +129,10 @@ void __start(void) #endif arm_fpuconfig(); + /* If used the PIC, then the PIC will have already been configured */ + +#ifndef CONFIG_BUILD_PIC + /* Set bss to zero */ for (dest = (uint32_t *)_sbss; dest < (uint32_t *)_ebss; ) @@ -120,6 +148,7 @@ void __start(void) { *dest++ = *src++; } +#endif /* Perform early serial initialization */ diff --git a/boards/arm/mps/mps3-an547/configs/bl/defconfig b/boards/arm/mps/mps3-an547/configs/bl/defconfig index fe20e876cc99e..023a5c4b2d64e 100644 --- a/boards/arm/mps/mps3-an547/configs/bl/defconfig +++ b/boards/arm/mps/mps3-an547/configs/bl/defconfig @@ -91,6 +91,8 @@ CONFIG_ARCH_CHIP_MPS3_AN547=y CONFIG_ARCH_CHIP_MPS=y CONFIG_ARCH_INTERRUPTSTACK=2048 CONFIG_ARCH_STACKDUMP=y +CONFIG_ARCH_USE_DATA_HEAP=y +CONFIG_ARCH_USE_SEPARATED_SECTION=y CONFIG_ARMV8M_SYSTICK=y CONFIG_BOARDCTL_APP_SYMTAB=y CONFIG_BOARDCTL_BOOT_IMAGE=y diff --git a/boards/arm/mps/mps3-an547/scripts/flash.ld b/boards/arm/mps/mps3-an547/scripts/flash.ld index e746a08677c3f..cd7a38c56637b 100644 --- a/boards/arm/mps/mps3-an547/scripts/flash.ld +++ b/boards/arm/mps/mps3-an547/scripts/flash.ld @@ -18,6 +18,8 @@ * ****************************************************************************/ +#include "nuttx/config.h" + MEMORY { flash (rx) : ORIGIN = 0x00000000, LENGTH = 512K @@ -33,7 +35,9 @@ SECTIONS { .text : { _stext = ABSOLUTE(.); +#ifndef CONFIG_BUILD_PIC /* We need change vectors use pic */ *(.vectors) +#endif *(.text .text.*) *(.fixup) *(.gnu.warning) @@ -41,7 +45,6 @@ SECTIONS *(.gnu.linkonce.t.*) *(.glue_7) *(.glue_7t) - *(.got) *(.gcc_except_table) *(.gnu.linkonce.r.*) _etext = ABSOLUTE(.); @@ -93,6 +96,11 @@ SECTIONS _edata = ABSOLUTE(.); } > sram1 AT > flash + .got : + { + *(.got*) + } > sram1 + .bss : ALIGN(4) { _sbss = ABSOLUTE(.); *(.bss .bss.*) diff --git a/boards/arm/mps/mps3-an547/src/mps3_bringup.c b/boards/arm/mps/mps3-an547/src/mps3_bringup.c index 1255a55f7c7cc..7ee00aa84841e 100644 --- a/boards/arm/mps/mps3-an547/src/mps3_bringup.c +++ b/boards/arm/mps/mps3-an547/src/mps3_bringup.c @@ -28,9 +28,13 @@ #include #include +#include #include #include +#include "nvic.h" +#include "arm_internal.h" + /**************************************************************************** * Pre-processor Definitions ****************************************************************************/ @@ -97,6 +101,82 @@ static int mps3_bringup(void) * Public Functions ****************************************************************************/ +#ifdef CONFIG_BOARDCTL_BOOT_IMAGE + +int board_boot_image(FAR const char *path, uint32_t hdr_size) +{ + struct mod_loadinfo_s loadinfo; + struct module_s mod; + uintptr_t bss; + uintptr_t got; + uintptr_t msp; + int ret; + + /* Initialize the ELF library to load the program binary. */ + + syslog(LOG_INFO, "modlib_init...\n"); + + ret = modlib_initialize(path, &loadinfo); + if (ret < 0) + { + syslog(LOG_ERR, "Failed to modlib_init: %d\n", ret); + return ret; + } + + /* Load the program binary */ + + syslog(LOG_INFO, "modlib_load...\n"); + + ret = modlib_load(&loadinfo); + if (ret < 0) + { + syslog(LOG_ERR, "Failed to modlib_load: %d\n", ret); + goto errout_with_init; + } + + syslog(LOG_INFO, "modlib_bind...\n"); + + memset(&mod, 0, sizeof(struct module_s)); + ret = modlib_bind(&mod, &loadinfo, NULL, 0); + if (ret < 0) + { + syslog(LOG_ERR, "Failed to modlib_bind: %d\n", ret); + goto errout_with_load; + } + + bss = modlib_findsection(&loadinfo, ".bss"); + got = loadinfo.shdr[loadinfo.gotindex].sh_addr; + msp = loadinfo.shdr[bss].sh_addr + loadinfo.shdr[bss].sh_size + + CONFIG_IDLETHREAD_STACKSIZE; + + syslog(LOG_INFO, "add-symbol-file ap.elf -s .text 0x%x -s .data" + " 0x%x\n", loadinfo.textalloc, loadinfo.datastart); + up_irq_disable(); + + /* Disable systick */ + + putreg32(0, NVIC_SYSTICK_CTRL); + putreg32(NVIC_SYSTICK_RELOAD_MASK, NVIC_SYSTICK_RELOAD); + putreg32(0, NVIC_SYSTICK_CURRENT); + + /* Set got address to r9 */ + + __asm__ __volatile__("mov r9, %0"::"r"(got)); + + /* set msp to the top of idle stack */ + + __asm__ __volatile__("msr msp, %0" : : "r" (msp)); + + ((void (*)(void))loadinfo.ehdr.e_entry + loadinfo.textalloc)(); + +errout_with_load: + modlib_unload(&loadinfo); +errout_with_init: + modlib_uninitialize(&loadinfo); + return ret; +} +#endif + /**************************************************************************** * Name: board_late_initialize *