mirror of
https://github.com/apache/nuttx.git
synced 2026-08-09 14:35:08 +00:00
boards/esp32: load RAM sections in board_boot_image
board_boot_image chain-boots directly to the selected slot and does not go through ROM bootloader section loading. Load IRAM/DRAM/LP RTC sections from the image load header before jumping, and keep ROM remap in the IRAM stub for non-primary-slot boot. Also include the required loader/cache headers so BOARDCTL_BOOT_IMAGE builds cleanly when this file is enabled. Signed-off-by: aviralgarg05 <gargaviral99@gmail.com>
This commit is contained in:
parent
faa037fda6
commit
29a700f1f4
1 changed files with 120 additions and 3 deletions
|
|
@ -25,6 +25,7 @@
|
|||
#include <nuttx/config.h>
|
||||
|
||||
#include <debug.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <inttypes.h>
|
||||
#include <stdint.h>
|
||||
|
|
@ -36,7 +37,8 @@
|
|||
#include <nuttx/cache.h>
|
||||
#include <nuttx/irq.h>
|
||||
|
||||
#include "esp_loader.h"
|
||||
#include "espressif/esp_loader.h"
|
||||
#include "xtensa_attr.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
|
|
@ -88,12 +90,80 @@ struct esp32_boot_loader_args_s
|
|||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_ARCH_CHIP_ESP32
|
||||
extern void cache_read_disable(int cpu);
|
||||
extern void cache_flush(int cpu);
|
||||
#endif
|
||||
|
||||
static int esp32_load_ram_segment(int fd, uint32_t flash_offset,
|
||||
uint32_t dest_addr, uint32_t size,
|
||||
FAR const char *name);
|
||||
static void IRAM_ATTR esp32_boot_loader_stub(void *arg);
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: esp32_load_ram_segment
|
||||
*
|
||||
* Description:
|
||||
* Load a RAM-resident segment from the application image into its
|
||||
* destination address.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int esp32_load_ram_segment(int fd, uint32_t flash_offset,
|
||||
uint32_t dest_addr, uint32_t size,
|
||||
FAR const char *name)
|
||||
{
|
||||
uint8_t *dest;
|
||||
off_t read_offset;
|
||||
ssize_t nread;
|
||||
size_t remaining;
|
||||
|
||||
if (size == 0)
|
||||
{
|
||||
return OK;
|
||||
}
|
||||
|
||||
if (dest_addr == 0)
|
||||
{
|
||||
ferr("ERROR: Invalid %s destination address\n", name);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
finfo("Loading %-12s: dst=0x%08" PRIx32 " off=0x%08" PRIx32
|
||||
" size=0x%08" PRIx32 "\n",
|
||||
name, dest_addr, flash_offset, size);
|
||||
|
||||
dest = (uint8_t *)(uintptr_t)dest_addr;
|
||||
read_offset = (off_t)flash_offset;
|
||||
remaining = (size_t)size;
|
||||
|
||||
while (remaining > 0)
|
||||
{
|
||||
nread = pread(fd, dest, remaining, read_offset);
|
||||
if (nread < 0)
|
||||
{
|
||||
ferr("ERROR: Failed to read %s segment: %d\n", name, errno);
|
||||
return -errno;
|
||||
}
|
||||
|
||||
if (nread == 0)
|
||||
{
|
||||
ferr("ERROR: Unexpected EOF while reading %s segment\n", name);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
dest += nread;
|
||||
read_offset += nread;
|
||||
remaining -= nread;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: esp32_boot_loader_stub
|
||||
*
|
||||
|
|
@ -124,8 +194,15 @@ static void IRAM_ATTR esp32_boot_loader_stub(void *arg)
|
|||
|
||||
/* Map new segments */
|
||||
|
||||
map_rom_segments(args->drom_addr, args->drom_vaddr, args->drom_size,
|
||||
args->irom_addr, args->irom_vaddr, args->irom_size);
|
||||
/* board_boot_image() may boot from non-primary slots, so remap ROM
|
||||
* segments here before entering the new image.
|
||||
*/
|
||||
|
||||
if (map_rom_segments(args->drom_addr, args->drom_vaddr, args->drom_size,
|
||||
args->irom_addr, args->irom_vaddr, args->irom_size))
|
||||
{
|
||||
PANIC();
|
||||
}
|
||||
|
||||
/* Jump to entry point */
|
||||
|
||||
|
|
@ -223,6 +300,46 @@ int board_boot_image(FAR const char *path, uint32_t hdr_size)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* RAM sections are normally loaded by the ROM bootloader. Since
|
||||
* board_boot_image() chain-boots directly, load these sections here.
|
||||
*/
|
||||
|
||||
ret = esp32_load_ram_segment(fd, load_header.iram_flash_offset,
|
||||
load_header.iram_dest_addr,
|
||||
load_header.iram_size, "iram");
|
||||
if (ret < 0)
|
||||
{
|
||||
close(fd);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = esp32_load_ram_segment(fd, load_header.dram_flash_offset,
|
||||
load_header.dram_dest_addr,
|
||||
load_header.dram_size, "dram");
|
||||
if (ret < 0)
|
||||
{
|
||||
close(fd);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = esp32_load_ram_segment(fd, load_header.lp_rtc_iram_flash_offset,
|
||||
load_header.lp_rtc_iram_dest_addr,
|
||||
load_header.lp_rtc_iram_size, "lp_rtc_iram");
|
||||
if (ret < 0)
|
||||
{
|
||||
close(fd);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = esp32_load_ram_segment(fd, load_header.lp_rtc_dram_flash_offset,
|
||||
load_header.lp_rtc_dram_dest_addr,
|
||||
load_header.lp_rtc_dram_size, "lp_rtc_dram");
|
||||
if (ret < 0)
|
||||
{
|
||||
close(fd);
|
||||
return ret;
|
||||
}
|
||||
|
||||
args.entry_addr = load_header.entry_addr;
|
||||
args.drom_addr = offset + load_header.drom_flash_offset;
|
||||
args.drom_vaddr = load_header.drom_map_addr;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue