[Ovmsdev] Firmware size approaching 4 MB limit
Mark Webb-Johnson
mark at webb-johnson.net
Sun Feb 22 23:00:32 HKT 2026
I’ve made some progress with this:
OVMS# ota status nocheck
Hardware: OVMS WIFI BLE BT cores=2 rev=ESP32/1
Firmware: 3.3.005-704-g6a1fed98-dirty/factory/edge (build idf v3.3.4-854-g9063c8662-dirty Feb 22 2026 22:28:00)
Partition type: v3-f12 (factory, ota1, ota2)
Partition table: 0x8000
Running partition: factory
Boot partition: factory
Factory image: 3.3.005-704-g6a1fed98-dirty
OTA_O image: 3.3.005-662-g1f318f04
OTA_1 image: 3.3.005-643-gdbec4a13
OVMS# ota partitions list
Partition table:
Label Type Subtype Address Size
nvs data nvs 0x00009000 16 KB
otadata data ota 0x0000d000 8 KB
phy_init data phy 0x0000f000 4 KB
factory app factory 0x00010000 4 MB
ota_0 app ota_0 0x00410000 4 MB
ota_1 app ota_1 0x00810000 4 MB
store data fat 0x00c10000 1 MB
Digest: cfe36765a6bfe1b802a2abd4ec9f6851 pass
## Before upgrade, user needs to copy current OTA to FACTORY, set boot partition to FACTORY, then reboot
## The upgrade process checks this and will refuse to upgrade unless that is the case
OVMS# ota partitions upgrade
0x00009000 Skipping over data/nvs partition
0x0000d000 Skipping over data/ota partition
0x0000f000 Skipping over data/phy partition
0x00010000 Converted factory partition to 6MB OTA 0
0x00610000 Converted OTA 0 partition to 6MB OTA 1
0x00c10000 Moved data/fat partition up one position
Recalculated MD5 checksum
Clearing trailing old MD5 checksum record
Erasing old partition table (4096 bytes at 0x00008000)...
Writing new partition table (4096 bytes at 0x00008000)...
Partition table upgraded successfully - reboot required
OVMS# ota partitions list
Partition table:
Label Type Subtype Address Size
nvs data nvs 0x00009000 16 KB
otadata data ota 0x0000d000 8 KB
phy_init data phy 0x0000f000 4 KB
ota_0 app ota_0 0x00010000 6 MB
ota_1 app ota_1 0x00610000 6 MB
store data fat 0x00c10000 1 MB
Digest: a0d94b1efa7f6d8852b44150db218e8d pass
This is mostly implemented in a new ovms_partitions.{h,cpp} in ovms_ota component, with only minor extensions to ovms_ota itself. I have removed the ‘factory’ commands from ovms_ota if the new partition layout is detected at boot.
One big ‘gotcha’ I found was that we need to set CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ABORT= and CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ALLOWED=y in our sdkconfig - otherwise the partition table cannot be re-flashed.
The partition table must also be held in internal (not external SPI) RAM - which is about a 4KB overhead just for these checks.
The usual app-flash still works (and now targets the first OTA at 0x0010000, rather than factory), so this approach seems feasible and workable now. Once we are happy with this, and have a production firmware supporting this layout, I can also provide a new partitions.bin to the factory for new units to ship with.
I have a few minor enhancements to make: (a) add a ‘yes/no’ (like factory reset), (b) an option to load partition table in internal/external ram (internal only at the moment), and (c) some minor tidy-ups. I suggest then to just check it in with this basic manual functionality that can be experimented with. Absent any comments / suggestions, I should be able to commit this early in the coming week.
Regards, Mark.
P.S. OVMS v2 had to fit in 96KB of flash ;-)
> On Jan 21, 2026, at 11:12 AM, Mark Webb-Johnson <mark at webb-johnson.net> wrote:
>
> Michael,
>
> The links are very helpful.
>
> I have some time, and inclination to handle this (now that my new home build host is up and running and a make of OVMS from clean, with 32 cores and a fast SSD, is under 25 seconds).
>
> real 0m24.642s
> user 5m50.376s
> sys 0m38.276s
>
> We’ve already got the ‘ota copy’ command, so I will start with trying to work on manipulation of the partition table and improving the ‘ota status’ command to show partition table format and sizes.
>
> Regards, Mark.
>
>> On 11 Jan 2026, at 5:34 PM, Michael Balzer via OvmsDev <ovmsdev at lists.openvehicles.com> wrote:
>>
>> Signed PGP part
>> On the migration tool for changing the partition table from a running application, we're (of course) not the first having that issue.
>>
>> If we're about to go that way, here is an implementation of the process:
>> Explanation: https://johnmu.com/2024-esp32-partition-update/
>> Source: https://github.com/softplus/Esp32Repartition
>> It's written for the Arduino IDE with the PlatformIO lib to create a UI, but the core function is straight forward and should be adaptable for us.
>>
>> The implementation allows for direct manipulations of the partition table, i.e. doesn't need a prepared table blob to flash.
>>
>> Using a prepared blob should be even more simple, basically just a matter of `spi_flash_erase_range()` & `spi_flash_write()` (→https://github.com/softplus/Esp32Repartition/blob/main/src/part_mgr.cpp#L297). We probably don't even need `getPartitionTableAddr()`, as our table is fixed at 0x8000.
>>
>> The code needed is small. When using a blob, the table in theory uses a full flash sector of 4096 bytes, but probably doesn't fill the whole sector.
>>
>> Regards,
>> Michael
>>
>>
>> Am 08.12.25 um 07:01 schrieb Mark Webb-Johnson via OvmsDev:
>>> Michael, Carsten,
>>>
>>> I think that if targeting things to cull, we would need to be balance size vs importance. For example, the RE tools mentioned is just 10KB total size. By comparison TPMS is 9KB, and web server is 538KB.
>>>
>>> We learned with OVMS v2 that the biggest culprits in the long-run are always the vehicle modules. The core system stays pretty stable, but the space required for *all* vehicle modules grows with the number of vehicles supported.
>>>
>>> I don’t think we can simply switch to 32MB flash, as that would abandon the existing users. We would also need to source a standard certified 32MB module (which I don’t think Espressif offer themselves).
>>>
>>> Looking at the partition table:
>>>
>>> # OVMS 16MB flash ESP32 Partition Table
>>> # Name, Type, SubType, Offset, Size
>>> nvs, data, nvs, 0x9000, 0x4000
>>> otadata, data, ota, 0xd000, 0x2000
>>> phy_init, data, phy, 0xf000, 0x1000
>>> factory, app, factory, 0x10000, 4M
>>> ota_0, app, ota_0, , 4M
>>> ota_1, app, ota_1, , 4M
>>> store, data, fat, , 1M
>>>
>>> Assuming we could (and that is a big assumption given our older SDK) change that at runtime, then a possible migration path could be:
>>>
>>> Have our code support both old and new partition table formats, and refuse to update to old format if firmware > 4MB. Get that code out into the hands of users.
>>> Provide a migration tool for partition table:
>>> Copy running code to factory (from ota_0 or ota_1, whichever is current).
>>> Reboot
>>> Change partition table (most likely replacing the entire table with a binary blob of the new format)
>>> factory 4MB -> ota_0 same offset, 6MB size
>>> ota_0 -> ota_1 6MB offset, 6MB size
>>> Change boot to ota_0.
>>> Reboot
>>> Liase with factory so new modules use new partition format (and ship with firmware that supports it).
>>> Wait a reasonable time for users to update before releasing any firmware > 4MB.
>>>
>>> That would work more similarly to other more modern ESP frameworks which don’t bother with ‘factory’. It would allow us another 50% expansion. But it does run the risk of bricking (requiring espflash to recover) during the process.
>>>
>>> But longer-term, the solution to me seems to be to allow the vehicle module code to overlay - so only the single vehicle you choose is loaded. And (absent any dynamic linking of modular code in freertos), the only straightforward way of doing that I know of is migrating vehicle support to Javascript (which comes along with a host of other advantages - most notably not having to be a C++ embedded developer to add/refine vehicle support).
>>>
>>> Regards, Mark.
>>>
>>>> On 7 Dec 2025, at 4:39 PM, Carsten Schmiemann via OvmsDev <ovmsdev at lists.openvehicles.com> <mailto:ovmsdev at lists.openvehicles.com> wrote:
>>>>
>>>> Hi Michael,
>>>>
>>>> It was to be expected that we would eventually run out of flash storage. That’s why I would immediately question whether we should detach ourselves from components that aren’t really being used. We could even start a survey or something like that.
>>>>
>>>> For example, the RE tools — the idea behind them is great, but without documentation they’re not easy to use, and every time I tried to work with them, it just resulted in crashes.
>>>>
>>>> Then there’s the question of who actually uses Telnet, SSH, the Duktape framework, the DBC parser, OBD2ECU, or CANopen (yes, the Twizy integration is the only one that uses it).
>>>>
>>>> All great ideas, but in the end, how many users really make use of them?
>>>> The fewer active components we have to maintain, the ‘easier’ it would also be to port the code to a more current ESP-IDF version — and that would bring significant benefits such as improved networking features, including firewall capabilities and a much more stable switching between LTE and Wi-Fi. I’ve looked at llanges attempts and it’s extremely tough.
>>>>
>>>> As an example, in my own custom firmware builds, I don’t enable the components (and of course not all vehicles, so not 100 percent representative) mentioned above. This requires small modifications in the code because, for example, the ESP logger is missing but referenced in another file, etc. But my firmware file is only about 2.8 MB.
>>>>
>>>> Just my 2 cents
>>>> Carsten
>>>>
>>>>> Am 07.12.2025 um 08:57 schrieb Michael Balzer via OvmsDev <ovmsdev at lists.openvehicles.com> <mailto:ovmsdev at lists.openvehicles.com>:
>>>>>
>>>>> FYI: use `make size-components` to create a report on all component sizes (`make size-files` for source file level).
>>>>>
>>>>> Unsurprisingly the webserver is on top, even with all assets precompressed already.
>>>>>
>>>>>
>>>>> Top 10 components:
>>>>>
>>>>> Per-archive contributions to ELF file:
>>>>> Archive File DRAM .data & .bss IRAM Flash code & rodata Total
>>>>> libovms_webserver.a 0 255 0 134342 399846 534443
>>>>> libstdc++.a 149 5640 0 141045 72513 219347
>>>>> libmain.a 15 2104 0 139216 40086 181421
>>>>> libduktape.a 0 0 0 141641 20367 162008
>>>>> libvehicle_renaulttwizy. 0 29 0 86517 75357 161903
>>>>> libc-psram-workaround.a 1854 66 18391 118283 10943 149537
>>>>> liblwip.a 17 3873 0 118366 16722 138978
>>>>> libnet80211.a 938 9042 10475 92339 21900 134694
>>>>> libmbedtls.a 100 560 76 107079 26785 134600
>>>>> libvehicle_vweup.a 8 8 0 60846 43432 104294
>>>>>
>>>>>
>>>>> Vehicles:
>>>>>
>>>>> Per-archive contributions to ELF file:
>>>>> Archive File DRAM .data & .bss IRAM Flash code & rodata Total
>>>>> libvehicle_renaulttwizy. 0 29 0 86517 75357 161903
>>>>> libvehicle_vweup.a 8 8 0 60846 43432 104294
>>>>> libvehicle_mgev.a 156 26 0 47756 33998 81936
>>>>> libvehicle_smarteq.a 82 15 0 59267 19527 78891
>>>>> libvehicle_smarted.a 0 9 0 48481 28801 77291
>>>>> libvehicle_renaultzoe_ph 4 10 0 44622 29564 74200
>>>>> libvehicle.a 0 68 0 57735 12062 69865
>>>>> libvehicle_bmwi3.a 0 2 0 33370 14357 47729
>>>>> libvehicle_minise.a 9432 2 0 35360 2210 47004
>>>>> libvehicle_hyundai_ioniq 176 7 0 32921 13425 46529
>>>>> libvehicle_nissanleaf.a 0 3 0 35491 8941 44435
>>>>> libvehicle_kiasoulev.a 240 9 0 32508 5473 38230
>>>>> libvehicle_kianiroev.a 108 7 0 24070 4006 28191
>>>>> libvehicle_mitsubishi.a 0 5 0 21645 3893 25543
>>>>> libvehicle_boltev.a 0 5 0 15999 7864 23868
>>>>> libvehicle_niu_gtevo.a 4 12 0 18248 3733 21997
>>>>> libvehicle_maxus_edelive 156 3 0 10713 7477 18349
>>>>> libvehicle_renaultzoe.a 0 6 0 14828 2859 17693
>>>>> libvehicle_maxus_euniq56 156 3 0 8363 6840 15362
>>>>> libvehicle_voltampera.a 0 5 0 13221 1932 15158
>>>>> libvehicle_hyundai_ioniq 0 3 0 11081 3191 14275
>>>>> libvehicle_teslaroadster 0 6 0 10367 2238 12611
>>>>> libvehicle_thinkcity.a 0 3 0 6114 3449 9566
>>>>> libvehicle_jaguaripace.a 0 8 0 5445 3941 9394
>>>>> libvehicle_fiatedoblo.a 0 2 0 4262 2126 6390
>>>>> libvehicle_teslamodels.a 0 2 0 5361 948 6311
>>>>> libvehicle_toyotarav4ev. 0 2 0 5023 1255 6280
>>>>> libvehicle_maxus_t90.a 0 3 0 2567 2204 4774
>>>>> libvehicle_byd_atto3.a 0 2 0 3503 947 4452
>>>>> libvehicle_energica.a 0 1 0 3319 880 4200
>>>>> libvehicle_demo.a 0 2 0 3205 795 4002
>>>>> libvehicle_maxus_euniq6. 0 2 0 2470 1182 3654
>>>>> libvehicle_fiat500.a 0 2 0 2838 732 3572
>>>>> libvehicle_zombie_vcu.a 0 4 0 1882 1259 3145
>>>>> libvehicle_mercedesb250e 0 2 0 2113 955 3070
>>>>> libvehicle_zeva.a 0 2 0 2209 688 2899
>>>>> libvehicle_dbc.a 0 2 0 1278 1395 2675
>>>>> libvehicle_cadillac_c2_c 0 7 0 1293 1105 2405
>>>>> libvehicle_maple60s.a 0 2 0 1416 698 2116
>>>>> libvehicle_chevrolet_c6_ 0 2 0 1053 1049 2104
>>>>> libvehicle_obdii.a 0 2 0 957 1007 1966
>>>>> libvehicle_teslamodel3.a 0 2 0 458 713 1173
>>>>> libvehicle_none.a 0 2 0 418 684 1104
>>>>> libvehicle_track.a 0 2 0 416 680 1098
>>>>>
>>>>>
>>>>> Regards,
>>>>> Michael
>>>>>
>>>>>
>>>>> Am 06.12.25 um 10:33 schrieb Michael Balzer via OvmsDev:
>>>>>> Everyone,
>>>>>>
>>>>>> with the latest vehicle additions, the firmware size has now grown to 4,015,328 bytes in build 3.3.005-485-gc4664881.
>>>>>>
>>>>>> Our flash partitioning scheme is currently designed to provide three firmware partitions (factory, ota_0 & ota_1) of 4MB = 4,194,304 bytes each.
>>>>>>
>>>>>> So we've now got 178,976 bytes = ~4% left.
>>>>>>
>>>>>> Options beyond the 4 MB limit:
>>>>>>
>>>>>> a) split features, e.g. vehicle support, into two or more builds
>>>>>>
>>>>>> b) repartition into two firmware partitions of 6 MB each, reusing the factory partition for OTA
>>>>>>
>>>>>> c) switch to an ESP32 WROOM module with 32 MB flash (possible?)
>>>>>>
>>>>>> We've got some time left, new vehicles normally don't need that much space, I just wanted to raise awareness.
>>>>>>
>>>>>> Regards,
>>>>>> Michael
>>>>>>
>>>>>>
>>>>>>
>>>>>> _______________________________________________
>>>>>> OvmsDev mailing list
>>>>>> OvmsDev at lists.openvehicles.com <mailto:OvmsDev at lists.openvehicles.com>
>>>>>> http://lists.openvehicles.com/mailman/listinfo/ovmsdev
>>>>>
>>>>> --
>>>>> Michael Balzer * Am Rahmen 5 * D-58313 Herdecke
>>>>> Fon 02330 9104094 * Handy 0176 20698926
>>>>>
>>>>> _______________________________________________
>>>>> OvmsDev mailing list
>>>>> OvmsDev at lists.openvehicles.com <mailto:OvmsDev at lists.openvehicles.com>
>>>>> http://lists.openvehicles.com/mailman/listinfo/ovmsdev
>>>>
>>>> _______________________________________________
>>>> OvmsDev mailing list
>>>> OvmsDev at lists.openvehicles.com <mailto:OvmsDev at lists.openvehicles.com>
>>>> http://lists.openvehicles.com/mailman/listinfo/ovmsdev
>>>
>>>
>>>
>>> _______________________________________________
>>> OvmsDev mailing list
>>> OvmsDev at lists.openvehicles.com <mailto:OvmsDev at lists.openvehicles.com>
>>> http://lists.openvehicles.com/mailman/listinfo/ovmsdev
>>
>> --
>> Michael Balzer * Am Rahmen 5 * D-58313 Herdecke
>> Fon 02330 9104094 * Handy 0176 20698926
>>
>> _______________________________________________
>> OvmsDev mailing list
>> OvmsDev at lists.openvehicles.com <mailto:OvmsDev at lists.openvehicles.com>
>> http://lists.openvehicles.com/mailman/listinfo/ovmsdev
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.openvehicles.com/pipermail/ovmsdev/attachments/20260222/3484754e/attachment-0001.htm>
More information about the OvmsDev
mailing list