From ba611101e53e977a6854ef03b11c2269bc430774 Mon Sep 17 00:00:00 2001 From: Philip Gladstone Date: Tue, 1 Sep 2020 17:40:57 -0400 Subject: [PATCH] Don't allocate flash to SPIFFS that is reserved by the system. (#3260) --- app/modules/node.c | 58 +++++++++++++++++------------------- app/user/user_main.c | 60 +++++++++++++++++++++++++------------- tools/nodemcu-partition.py | 20 ++++++++----- 3 files changed, 78 insertions(+), 60 deletions(-) diff --git a/app/modules/node.c b/app/modules/node.c index 4d361ba6..c3ba7f29 100644 --- a/app/modules/node.c +++ b/app/modules/node.c @@ -750,8 +750,9 @@ static void delete_partition(partition_item_t *p, int n) { #define IROM0_PARTITION (SYSTEM_PARTITION_CUSTOMER_BEGIN + NODEMCU_IROM0TEXT_PARTITION) #define LFS_PARTITION (SYSTEM_PARTITION_CUSTOMER_BEGIN + NODEMCU_LFS0_PARTITION) #define SPIFFS_PARTITION (SYSTEM_PARTITION_CUSTOMER_BEGIN + NODEMCU_SPIFFS0_PARTITION) +#define SYSTEM_PARAMETER_SIZE 0x3000 -// Lua: node.setpartitiontable(pt_settings) +// Lua: node.setpartitiontable(ptvals) static int node_setpartitiontable (lua_State *L) { partition_item_t *rcr_pt = NULL, *pt; uint32_t flash_size = flash_rom_get_size_byte(); @@ -760,6 +761,7 @@ static int node_setpartitiontable (lua_State *L) { uint32_t n = i / sizeof(partition_item_t); uint32_t param[max_pt] = {SKIP, SKIP, SKIP, SKIP}; +/* stack 1=ptvals, 2=pt_map, 3=key, 4=ptval[key], 5=pt_map[key] */ luaL_argcheck(L, lua_istable(L, 1), 1, "must be table"); lua_settop(L, 1); /* convert input table into 4 option array */ @@ -771,9 +773,8 @@ static int node_setpartitiontable (lua_State *L) { lua_pushvalue(L, 3); /* dup key to index 5 */ lua_rawget(L, 2); /* lookup in pt_map */ luaL_argcheck(L, !lua_isnil(L, -1), 1, "invalid partition setting"); - param[lua_tointeger(L, 5)] = lua_tointeger(L, 4); - /* removes 'value'; keeps 'key' for next iteration */ - lua_pop(L, 2); /* discard value and lookup */ + param[lua_tointeger(L, 5)] = lua_tounsigned(L, 4); + lua_pop(L, 2); /* discard value and lookup; keeps 'key' for next iteration */ } /* * Allocate a scratch Partition Table as userdata on the Lua stack, and copy the @@ -793,43 +794,34 @@ static int node_setpartitiontable (lua_State *L) { n++; } else if (p->type == LFS_PARTITION) { + // update the LFS options if set + if (param[lfs_addr] != SKIP) + p->addr = param[lfs_addr]; + if (param[lfs_size] != SKIP) + p->size = param[lfs_size]; if (p[1].type != SPIFFS_PARTITION) { // if the SPIFFS partition is not following LFS then slot a blank one in insert_partition(p + 1, n-i-1, SPIFFS_PARTITION, 0); n++; } - // update the LFS options if set - if (param[lfs_addr] != SKIP) { - p->addr = param[lfs_addr]; - } - if (param[lfs_size] != SKIP) { - p->size = param[lfs_size]; - } + } else if (p->type == SPIFFS_PARTITION) { // update the SPIFFS options if set - if (param[spiffs_addr] != SKIP) { + if (param[spiffs_size] != SKIP) { + p->size = param[spiffs_size]; + p->addr = (param[spiffs_addr] != SKIP) ? param[spiffs_addr] : + ((p->size <= flash_size - SYSTEM_PARAMETER_SIZE - 0x100000) + ? 0x100000 : last); + } else if (param[spiffs_addr] != SKIP) { p->addr = param[spiffs_addr]; - p->size = SKIP; } +#if 0 if (param[spiffs_size] != SKIP) { // BOTCH: - at the moment the firmware doesn't boot if the SPIFFS partition // is deleted so the minimum SPIFFS size is 64Kb p->size = param[spiffs_size] > 0x10000 ? param[spiffs_size] : 0x10000; } - if (p->size == SKIP) { - if (p->addr < 0) { - // This allocate all the remaining flash to SPIFFS - p->addr = last; - p->size = flash_size - last; - } else { - p->size = flash_size - p->addr; - } - } else if (/* size is specified && */ p->addr == 0) { - // if the is addr not specified then start SPIFFS at 1Mb - // boundary if the size will fit otherwise make it consecutive - // to the previous partition. - p->addr = (p->size <= flash_size - 0x100000) ? 0x100000 : last; - } +#endif } if (p->size == 0) { @@ -842,14 +834,16 @@ static int node_setpartitiontable (lua_State *L) { p->size & (INTERNAL_FLASH_SECTOR_SIZE - 1) || p->addr < last || p->addr + p->size > flash_size) { - luaL_error(L, "value out of range"); + luaL_error(L, "Partition value out of range"); } + last = p->addr + p->size; } } -// for (i = 0; i < n; i ++) -// dbg_printf("Partition %d: %04x %06x %06x\n", i, pt[i].type, pt[i].addr, pt[i].size); - platform_rcr_write(PLATFORM_RCR_PT, pt, n*sizeof(partition_item_t)); - while(1); // Trigger WDT; the new PT will be loaded on reboot + for (i = 0; i < n; i ++) + dbg_printf("Partition %d: %04x %06x %06x\n", i, pt[i].type, pt[i].addr, pt[i].size); + + platform_rcr_write(PLATFORM_RCR_PT, pt, n*sizeof(partition_item_t)); + while(1); // Trigger WDT; the new PT will be loaded on reboot return 0; } diff --git a/app/user/user_main.c b/app/user/user_main.c index c5639b9c..fc319386 100644 --- a/app/user/user_main.c +++ b/app/user/user_main.c @@ -40,8 +40,8 @@ __asm__( "init_data_end:\n" ); extern const char _irom0_text_start[], _irom0_text_end[], _flash_used_end[]; -#define IROM0_SIZE (_irom0_text_end - _irom0_text_start) +#define IROM0_SIZE (_irom0_text_end - _irom0_text_start) #define PRE_INIT_TEXT_ATTR __attribute__((section(".p3.pre_init"))) #define IROM_PTABLE_ATTR __attribute__((section(".irom0.ptable"))) @@ -60,9 +60,14 @@ extern const char _irom0_text_start[], _irom0_text_end[], _flash_used_end[]; #define NODEMCU_PARTITION_LFS PLATFORM_PARTITION(NODEMCU_LFS0_PARTITION) #define NODEMCU_PARTITION_SPIFFS PLATFORM_PARTITION(NODEMCU_SPIFFS0_PARTITION) +#define RF_CAL_SIZE 0x1000 +#define PHY_DATA_SIZE 0x1000 +#define SYSTEM_PARAMETER_SIZE 0x3000 + #define MAX_PARTITIONS 20 #define WORDSIZE sizeof(uint32_t) #define PTABLE_SIZE 7 /** THIS MUST BE MATCHED TO NO OF PT ENTRIES BELOW **/ + struct defaultpt { platform_rcr_t hdr; partition_item_t pt[PTABLE_SIZE+1]; // the +! is for the endmarker @@ -78,12 +83,12 @@ static const struct defaultpt rompt IROM_PTABLE_ATTR USED_ATTR = { .id = PLATFORM_RCR_PT}, .pt = { { NODEMCU_PARTITION_EAGLEROM, 0x00000, 0x0B000}, - { SYSTEM_PARTITION_RF_CAL, 0x0B000, 0x1000}, - { SYSTEM_PARTITION_PHY_DATA, 0x0C000, 0x1000}, - { SYSTEM_PARTITION_SYSTEM_PARAMETER, 0x0D000, 0x3000}, - { NODEMCU_PARTITION_IROM0TEXT, 0x10000, 0x0000}, - { NODEMCU_PARTITION_LFS, 0x0, LUA_FLASH_STORE}, - { NODEMCU_PARTITION_SPIFFS, 0x0, SPIFFS_MAX_FILESYSTEM_SIZE}, + { SYSTEM_PARTITION_RF_CAL, 0x0D000, RF_CAL_SIZE}, + { SYSTEM_PARTITION_PHY_DATA, 0x0F000, PHY_DATA_SIZE}, + { NODEMCU_PARTITION_IROM0TEXT, 0x10000, 0x0000}, + { NODEMCU_PARTITION_LFS, 0x0, LUA_FLASH_STORE}, + { NODEMCU_PARTITION_SPIFFS, 0x0, SPIFFS_MAX_FILESYSTEM_SIZE}, + { SYSTEM_PARTITION_SYSTEM_PARAMETER, 0x0, SYSTEM_PARAMETER_SIZE}, {0,(uint32_t) &_irom0_text_end,0} } }; @@ -161,7 +166,6 @@ void user_pre_init(void) { } // Now register the partition and return -// for (i=0;i 1 && system_partition_table_regist(pt, n, fs_size_code)) { return; } @@ -230,26 +234,41 @@ static uint32_t first_time_setup(partition_item_t *pt, uint32_t n, uint32_t flas p->addr = last; break; + /* + * Set up the SPIFFS partition based on some sensible defaults: + * size == 0 mean no SPIFFS partition. + * size == ~0 means use all of the available flash for SPIFFS (resp the addr if set). + * if size > 0 then float the default boundary to 1M if the SPIFFS will fit. + */ case NODEMCU_PARTITION_SPIFFS: - if (p->size == ~0x0 && p->addr == 0) { - // This allocate all the remaining flash to SPIFFS - p->addr = last; - p->size = flash_size - last; - } else if (p->size == ~0x0) { - p->size = flash_size - p->addr; - } else if (p->addr == 0) { - // if the is addr not specified then start SPIFFS at 1Mb - // boundary if the size will fit otherwise make it consecutive - // to the previous partition. - p->addr = (p->size <= flash_size - 0x100000) ? 0x100000 : last; + if (p->size == ~0x0) { /* Maximum SPIFFS partition */ + if (p->addr == 0) + p->addr = last; + p->size = flash_size - SYSTEM_PARAMETER_SIZE - last; + } else if (p->size > 0x0) { /* Explicit SPIFFS size */ + if (p->addr < last) // SPIFFS can't overlap the previous region; + p->addr = 0; + if (p->addr == 0) + p->addr = (p->size <= flash_size - SYSTEM_PARAMETER_SIZE - 0x100000) ? + 0x100000 : last; } + /* else p->size == 0 No SPIFFS partition */ + break; + + case SYSTEM_PARTITION_SYSTEM_PARAMETER: + p->addr = flash_size - SYSTEM_PARAMETER_SIZE; + p->size = SYSTEM_PARAMETER_SIZE; } if (p->size == 0) { // Delete 0-sized partitions as the SDK barfs on these newn--; } else { - // Do consistency tests on the partition + /* + * Do consistency tests on the partition. The address and size must + * be flash sector aligned. Partitions can't overlap, and the last + * patition must fit within the flash size. + */ if (p->addr & (INTERNAL_FLASH_SECTOR_SIZE - 1) || p->size & (INTERNAL_FLASH_SECTOR_SIZE - 1) || p->addr < last || @@ -259,7 +278,6 @@ static uint32_t first_time_setup(partition_item_t *pt, uint32_t n, uint32_t flas } if (j < i) // shift the partition down if we have any deleted slots pt[j] = *p; -//os_printf("Partition %d: %04x %06x %06x\n", j, p->type, p->addr, p->size); j++; last = p->addr + p->size; } diff --git a/tools/nodemcu-partition.py b/tools/nodemcu-partition.py index 49c512be..b28550c7 100755 --- a/tools/nodemcu-partition.py +++ b/tools/nodemcu-partition.py @@ -57,9 +57,10 @@ PARTITION_TYPE = { 106: 'SPIFFS0', 107: 'SPIFFS1'} -IROM0TEXT = 102 -LFS = 103 -SPIFFS = 106 +SYSTEM_PARAMETER = 6 +IROM0TEXT = 102 +LFS = 103 +SPIFFS = 106 MAX_PT_SIZE = 20*3 FLASH_SIG = 0xfafaa150 @@ -145,13 +146,15 @@ def load_PT(data, args): # and SPIFFS is the last partition. We will need to revisit these algos if # we adopt a more flexible partiton allocation policy. *** BOTCH WARNING *** - for i in range (0, len(PTrec), 3): + i = 0 + while i < len(PTrec): if PTrec[i] == IROM0TEXT and args.ls is not None and \ (len(PTrec) == i+3 or PTrec[i+3] != LFS): PTrec[i+3:i+3] = [LFS, 0, 0] - break - if PTrec[-3] != SPIFFS: - PTrec.extend([SPIFFS, 0, 0]) + i += 3 + + if PTrec[-6] != SPIFFS: + PTrec[-6:-6] = [SPIFFS, PTrec[-5] + PTrec[-4], 0x1000] lastEnd, newPT, map = 0,[], dict() print " Partition Start Size \n ------------------ ------ ------" @@ -208,6 +211,9 @@ def load_PT(data, args): if Psize > 0: map['SPIFFS'] = {"addr" : Paddr, "size" : Psize} + elif Ptype == SYSTEM_PARAMETER and Paddr == 0: + Paddr = flash_size - Psize + if Psize > 0: Pname = PARTITION_TYPE[Ptype] if Ptype in PARTITION_TYPE \ else ("Type %d" % Ptype)