Skip to content

Commit ba61110

Browse files
authored
Don't allocate flash to SPIFFS that is reserved by the system. (#3260)
1 parent b4c148e commit ba61110

File tree

3 files changed

+78
-60
lines changed

3 files changed

+78
-60
lines changed

app/modules/node.c

Lines changed: 26 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -750,8 +750,9 @@ static void delete_partition(partition_item_t *p, int n) {
750750
#define IROM0_PARTITION (SYSTEM_PARTITION_CUSTOMER_BEGIN + NODEMCU_IROM0TEXT_PARTITION)
751751
#define LFS_PARTITION (SYSTEM_PARTITION_CUSTOMER_BEGIN + NODEMCU_LFS0_PARTITION)
752752
#define SPIFFS_PARTITION (SYSTEM_PARTITION_CUSTOMER_BEGIN + NODEMCU_SPIFFS0_PARTITION)
753+
#define SYSTEM_PARAMETER_SIZE 0x3000
753754

754-
// Lua: node.setpartitiontable(pt_settings)
755+
// Lua: node.setpartitiontable(ptvals)
755756
static int node_setpartitiontable (lua_State *L) {
756757
partition_item_t *rcr_pt = NULL, *pt;
757758
uint32_t flash_size = flash_rom_get_size_byte();
@@ -760,6 +761,7 @@ static int node_setpartitiontable (lua_State *L) {
760761
uint32_t n = i / sizeof(partition_item_t);
761762
uint32_t param[max_pt] = {SKIP, SKIP, SKIP, SKIP};
762763

764+
/* stack 1=ptvals, 2=pt_map, 3=key, 4=ptval[key], 5=pt_map[key] */
763765
luaL_argcheck(L, lua_istable(L, 1), 1, "must be table");
764766
lua_settop(L, 1);
765767
/* convert input table into 4 option array */
@@ -771,9 +773,8 @@ static int node_setpartitiontable (lua_State *L) {
771773
lua_pushvalue(L, 3); /* dup key to index 5 */
772774
lua_rawget(L, 2); /* lookup in pt_map */
773775
luaL_argcheck(L, !lua_isnil(L, -1), 1, "invalid partition setting");
774-
param[lua_tointeger(L, 5)] = lua_tointeger(L, 4);
775-
/* removes 'value'; keeps 'key' for next iteration */
776-
lua_pop(L, 2); /* discard value and lookup */
776+
param[lua_tointeger(L, 5)] = lua_tounsigned(L, 4);
777+
lua_pop(L, 2); /* discard value and lookup; keeps 'key' for next iteration */
777778
}
778779
/*
779780
* 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) {
793794
n++;
794795

795796
} else if (p->type == LFS_PARTITION) {
797+
// update the LFS options if set
798+
if (param[lfs_addr] != SKIP)
799+
p->addr = param[lfs_addr];
800+
if (param[lfs_size] != SKIP)
801+
p->size = param[lfs_size];
796802
if (p[1].type != SPIFFS_PARTITION) {
797803
// if the SPIFFS partition is not following LFS then slot a blank one in
798804
insert_partition(p + 1, n-i-1, SPIFFS_PARTITION, 0);
799805
n++;
800806
}
801-
// update the LFS options if set
802-
if (param[lfs_addr] != SKIP) {
803-
p->addr = param[lfs_addr];
804-
}
805-
if (param[lfs_size] != SKIP) {
806-
p->size = param[lfs_size];
807-
}
807+
808808
} else if (p->type == SPIFFS_PARTITION) {
809809
// update the SPIFFS options if set
810-
if (param[spiffs_addr] != SKIP) {
810+
if (param[spiffs_size] != SKIP) {
811+
p->size = param[spiffs_size];
812+
p->addr = (param[spiffs_addr] != SKIP) ? param[spiffs_addr] :
813+
((p->size <= flash_size - SYSTEM_PARAMETER_SIZE - 0x100000)
814+
? 0x100000 : last);
815+
} else if (param[spiffs_addr] != SKIP) {
811816
p->addr = param[spiffs_addr];
812-
p->size = SKIP;
813817
}
818+
#if 0
814819
if (param[spiffs_size] != SKIP) {
815820
// BOTCH: - at the moment the firmware doesn't boot if the SPIFFS partition
816821
// is deleted so the minimum SPIFFS size is 64Kb
817822
p->size = param[spiffs_size] > 0x10000 ? param[spiffs_size] : 0x10000;
818823
}
819-
if (p->size == SKIP) {
820-
if (p->addr < 0) {
821-
// This allocate all the remaining flash to SPIFFS
822-
p->addr = last;
823-
p->size = flash_size - last;
824-
} else {
825-
p->size = flash_size - p->addr;
826-
}
827-
} else if (/* size is specified && */ p->addr == 0) {
828-
// if the is addr not specified then start SPIFFS at 1Mb
829-
// boundary if the size will fit otherwise make it consecutive
830-
// to the previous partition.
831-
p->addr = (p->size <= flash_size - 0x100000) ? 0x100000 : last;
832-
}
824+
#endif
833825
}
834826

835827
if (p->size == 0) {
@@ -842,14 +834,16 @@ static int node_setpartitiontable (lua_State *L) {
842834
p->size & (INTERNAL_FLASH_SECTOR_SIZE - 1) ||
843835
p->addr < last ||
844836
p->addr + p->size > flash_size) {
845-
luaL_error(L, "value out of range");
837+
luaL_error(L, "Partition value out of range");
846838
}
839+
last = p->addr + p->size;
847840
}
848841
}
849-
// for (i = 0; i < n; i ++)
850-
// dbg_printf("Partition %d: %04x %06x %06x\n", i, pt[i].type, pt[i].addr, pt[i].size);
851-
platform_rcr_write(PLATFORM_RCR_PT, pt, n*sizeof(partition_item_t));
852-
while(1); // Trigger WDT; the new PT will be loaded on reboot
842+
for (i = 0; i < n; i ++)
843+
dbg_printf("Partition %d: %04x %06x %06x\n", i, pt[i].type, pt[i].addr, pt[i].size);
844+
845+
platform_rcr_write(PLATFORM_RCR_PT, pt, n*sizeof(partition_item_t));
846+
while(1); // Trigger WDT; the new PT will be loaded on reboot
853847

854848
return 0;
855849
}

app/user/user_main.c

Lines changed: 39 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,8 @@ __asm__(
4040
"init_data_end:\n"
4141
);
4242
extern const char _irom0_text_start[], _irom0_text_end[], _flash_used_end[];
43-
#define IROM0_SIZE (_irom0_text_end - _irom0_text_start)
4443

44+
#define IROM0_SIZE (_irom0_text_end - _irom0_text_start)
4545

4646
#define PRE_INIT_TEXT_ATTR __attribute__((section(".p3.pre_init")))
4747
#define IROM_PTABLE_ATTR __attribute__((section(".irom0.ptable")))
@@ -60,9 +60,14 @@ extern const char _irom0_text_start[], _irom0_text_end[], _flash_used_end[];
6060
#define NODEMCU_PARTITION_LFS PLATFORM_PARTITION(NODEMCU_LFS0_PARTITION)
6161
#define NODEMCU_PARTITION_SPIFFS PLATFORM_PARTITION(NODEMCU_SPIFFS0_PARTITION)
6262

63+
#define RF_CAL_SIZE 0x1000
64+
#define PHY_DATA_SIZE 0x1000
65+
#define SYSTEM_PARAMETER_SIZE 0x3000
66+
6367
#define MAX_PARTITIONS 20
6468
#define WORDSIZE sizeof(uint32_t)
6569
#define PTABLE_SIZE 7 /** THIS MUST BE MATCHED TO NO OF PT ENTRIES BELOW **/
70+
6671
struct defaultpt {
6772
platform_rcr_t hdr;
6873
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 = {
7883
.id = PLATFORM_RCR_PT},
7984
.pt = {
8085
{ NODEMCU_PARTITION_EAGLEROM, 0x00000, 0x0B000},
81-
{ SYSTEM_PARTITION_RF_CAL, 0x0B000, 0x1000},
82-
{ SYSTEM_PARTITION_PHY_DATA, 0x0C000, 0x1000},
83-
{ SYSTEM_PARTITION_SYSTEM_PARAMETER, 0x0D000, 0x3000},
84-
{ NODEMCU_PARTITION_IROM0TEXT, 0x10000, 0x0000},
85-
{ NODEMCU_PARTITION_LFS, 0x0, LUA_FLASH_STORE},
86-
{ NODEMCU_PARTITION_SPIFFS, 0x0, SPIFFS_MAX_FILESYSTEM_SIZE},
86+
{ SYSTEM_PARTITION_RF_CAL, 0x0D000, RF_CAL_SIZE},
87+
{ SYSTEM_PARTITION_PHY_DATA, 0x0F000, PHY_DATA_SIZE},
88+
{ NODEMCU_PARTITION_IROM0TEXT, 0x10000, 0x0000},
89+
{ NODEMCU_PARTITION_LFS, 0x0, LUA_FLASH_STORE},
90+
{ NODEMCU_PARTITION_SPIFFS, 0x0, SPIFFS_MAX_FILESYSTEM_SIZE},
91+
{ SYSTEM_PARTITION_SYSTEM_PARAMETER, 0x0, SYSTEM_PARAMETER_SIZE},
8792
{0,(uint32_t) &_irom0_text_end,0}
8893
}
8994
};
@@ -161,7 +166,6 @@ void user_pre_init(void) {
161166
}
162167

163168
// Now register the partition and return
164-
// for (i=0;i<n;i++) os_printf("P%d: %3d %06x %06x\n", i, pt[i].type, pt[i].addr, pt[i].size);
165169
if( fs_size_code > 1 && system_partition_table_regist(pt, n, fs_size_code)) {
166170
return;
167171
}
@@ -230,26 +234,41 @@ static uint32_t first_time_setup(partition_item_t *pt, uint32_t n, uint32_t flas
230234
p->addr = last;
231235
break;
232236

237+
/*
238+
* Set up the SPIFFS partition based on some sensible defaults:
239+
* size == 0 mean no SPIFFS partition.
240+
* size == ~0 means use all of the available flash for SPIFFS (resp the addr if set).
241+
* if size > 0 then float the default boundary to 1M if the SPIFFS will fit.
242+
*/
233243
case NODEMCU_PARTITION_SPIFFS:
234-
if (p->size == ~0x0 && p->addr == 0) {
235-
// This allocate all the remaining flash to SPIFFS
236-
p->addr = last;
237-
p->size = flash_size - last;
238-
} else if (p->size == ~0x0) {
239-
p->size = flash_size - p->addr;
240-
} else if (p->addr == 0) {
241-
// if the is addr not specified then start SPIFFS at 1Mb
242-
// boundary if the size will fit otherwise make it consecutive
243-
// to the previous partition.
244-
p->addr = (p->size <= flash_size - 0x100000) ? 0x100000 : last;
244+
if (p->size == ~0x0) { /* Maximum SPIFFS partition */
245+
if (p->addr == 0)
246+
p->addr = last;
247+
p->size = flash_size - SYSTEM_PARAMETER_SIZE - last;
248+
} else if (p->size > 0x0) { /* Explicit SPIFFS size */
249+
if (p->addr < last) // SPIFFS can't overlap the previous region;
250+
p->addr = 0;
251+
if (p->addr == 0)
252+
p->addr = (p->size <= flash_size - SYSTEM_PARAMETER_SIZE - 0x100000) ?
253+
0x100000 : last;
245254
}
255+
/* else p->size == 0 No SPIFFS partition */
256+
break;
257+
258+
case SYSTEM_PARTITION_SYSTEM_PARAMETER:
259+
p->addr = flash_size - SYSTEM_PARAMETER_SIZE;
260+
p->size = SYSTEM_PARAMETER_SIZE;
246261
}
247262

248263
if (p->size == 0) {
249264
// Delete 0-sized partitions as the SDK barfs on these
250265
newn--;
251266
} else {
252-
// Do consistency tests on the partition
267+
/*
268+
* Do consistency tests on the partition. The address and size must
269+
* be flash sector aligned. Partitions can't overlap, and the last
270+
* patition must fit within the flash size.
271+
*/
253272
if (p->addr & (INTERNAL_FLASH_SECTOR_SIZE - 1) ||
254273
p->size & (INTERNAL_FLASH_SECTOR_SIZE - 1) ||
255274
p->addr < last ||
@@ -259,7 +278,6 @@ static uint32_t first_time_setup(partition_item_t *pt, uint32_t n, uint32_t flas
259278
}
260279
if (j < i) // shift the partition down if we have any deleted slots
261280
pt[j] = *p;
262-
//os_printf("Partition %d: %04x %06x %06x\n", j, p->type, p->addr, p->size);
263281
j++;
264282
last = p->addr + p->size;
265283
}

tools/nodemcu-partition.py

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,10 @@
5757
106: 'SPIFFS0',
5858
107: 'SPIFFS1'}
5959

60-
IROM0TEXT = 102
61-
LFS = 103
62-
SPIFFS = 106
60+
SYSTEM_PARAMETER = 6
61+
IROM0TEXT = 102
62+
LFS = 103
63+
SPIFFS = 106
6364

6465
MAX_PT_SIZE = 20*3
6566
FLASH_SIG = 0xfafaa150
@@ -145,13 +146,15 @@ def load_PT(data, args):
145146
# and SPIFFS is the last partition. We will need to revisit these algos if
146147
# we adopt a more flexible partiton allocation policy. *** BOTCH WARNING ***
147148

148-
for i in range (0, len(PTrec), 3):
149+
i = 0
150+
while i < len(PTrec):
149151
if PTrec[i] == IROM0TEXT and args.ls is not None and \
150152
(len(PTrec) == i+3 or PTrec[i+3] != LFS):
151153
PTrec[i+3:i+3] = [LFS, 0, 0]
152-
break
153-
if PTrec[-3] != SPIFFS:
154-
PTrec.extend([SPIFFS, 0, 0])
154+
i += 3
155+
156+
if PTrec[-6] != SPIFFS:
157+
PTrec[-6:-6] = [SPIFFS, PTrec[-5] + PTrec[-4], 0x1000]
155158

156159
lastEnd, newPT, map = 0,[], dict()
157160
print " Partition Start Size \n ------------------ ------ ------"
@@ -208,6 +211,9 @@ def load_PT(data, args):
208211
if Psize > 0:
209212
map['SPIFFS'] = {"addr" : Paddr, "size" : Psize}
210213

214+
elif Ptype == SYSTEM_PARAMETER and Paddr == 0:
215+
Paddr = flash_size - Psize
216+
211217
if Psize > 0:
212218
Pname = PARTITION_TYPE[Ptype] if Ptype in PARTITION_TYPE \
213219
else ("Type %d" % Ptype)

0 commit comments

Comments
 (0)