Skip to content

Commit

Permalink
mps3-an547:let ap build with pic,and use bootloader boot it
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
anjiahao1 committed Oct 16, 2024
1 parent 06ce35e commit 1effe24
Show file tree
Hide file tree
Showing 7 changed files with 260 additions and 15 deletions.
18 changes: 18 additions & 0 deletions Documentation/platforms/arm/mps/boards/mps3-an547/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
===================

Expand Down
2 changes: 2 additions & 0 deletions arch/arm/src/mps/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
134 changes: 120 additions & 14 deletions arch/arm/src/mps/mps_allocateheap.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@
* Pre-processor Definitions
****************************************************************************/

#define ALIGN_UP(x, a) (((x) + (a) - 1) & ~((a) - 1))

/* Configuration ************************************************************/

/* Terminology.
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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
29 changes: 29 additions & 0 deletions arch/arm/src/mps/mps_start.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
****************************************************************************/
Expand Down Expand Up @@ -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 */

Expand All @@ -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; )
Expand All @@ -120,6 +148,7 @@ void __start(void)
{
*dest++ = *src++;
}
#endif

/* Perform early serial initialization */

Expand Down
2 changes: 2 additions & 0 deletions boards/arm/mps/mps3-an547/configs/bl/defconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
10 changes: 9 additions & 1 deletion boards/arm/mps/mps3-an547/scripts/flash.ld
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
*
****************************************************************************/

#include "nuttx/config.h"

MEMORY
{
flash (rx) : ORIGIN = 0x00000000, LENGTH = 512K
Expand All @@ -33,15 +35,16 @@ SECTIONS
{
.text : {
_stext = ABSOLUTE(.);
#ifndef CONFIG_BUILD_PIC /* We need change vectors use pic */
*(.vectors)
#endif
*(.text .text.*)
*(.fixup)
*(.gnu.warning)
*(.rodata .rodata.*)
*(.gnu.linkonce.t.*)
*(.glue_7)
*(.glue_7t)
*(.got)
*(.gcc_except_table)
*(.gnu.linkonce.r.*)
_etext = ABSOLUTE(.);
Expand Down Expand Up @@ -93,6 +96,11 @@ SECTIONS
_edata = ABSOLUTE(.);
} > sram1 AT > flash

.got :
{
*(.got*)
} > sram1

.bss : ALIGN(4) {
_sbss = ABSOLUTE(.);
*(.bss .bss.*)
Expand Down
80 changes: 80 additions & 0 deletions boards/arm/mps/mps3-an547/src/mps3_bringup.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,13 @@
#include <sys/mount.h>
#include <syslog.h>

#include <nuttx/lib/modlib.h>
#include <nuttx/fs/fs.h>
#include <nuttx/drivers/ramdisk.h>

#include "nvic.h"
#include "arm_internal.h"

/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
Expand Down Expand Up @@ -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
*
Expand Down

0 comments on commit 1effe24

Please sign in to comment.