mirror of
https://github.com/apache/nuttx.git
synced 2025-01-13 08:38:38 +08:00
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 <anjiahao@xiaomi.com>
This commit is contained in:
parent
3e9c2e00ea
commit
15fa55f234
7 changed files with 260 additions and 15 deletions
|
@ -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
|
||||
===================
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.*)
|
||||
|
|
|
@ -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
|
||||
****************************************************************************/
|
||||
|
@ -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
|
||||
*
|
||||
|
|
Loading…
Reference in a new issue