[Ovmsdev] Firmware size approaching 4 MB limit

Michael Balzer dexter at expeedo.de
Mon Feb 23 00:27:30 HKT 2026


Awesome :-)

We need to update the user manual's firmware rescue guide 
(https://docs.openvehicles.com/en/latest/userguide/factory.html#flash-factory-firmware-via-usb) 
accordingly, so in case anything goes wrong, users can help themselves 
or get local help.

The 4KB RAM overhead shouldn't be an issue I think, but we could add a 
free memory check and recommend switching to the "NONE" vehicle while 
performing the operation, if memory is too tight.

> P.S. OVMS v2 had to fit in 96KB of flash ;-)

…and 3328 bytes of RAM in total… so much for the "overhead" ;-)

Regards,
Michael


Am 22.02.26 um 16:00 schrieb Mark Webb-Johnson:
> 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).
>>
>>     real0m24.642s
>>     user5m50.376s
>>     sys0m38.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:
>>>>
>>>>  1. 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.
>>>>  2. Provide a migration tool for partition table:
>>>>      1. Copy running code to factory (from ota_0 or ota_1,
>>>>         whichever is current).
>>>>      2. Reboot
>>>>      3. Change partition table (most likely replacing the entire
>>>>         table with a binary blob of the new format)
>>>>          1. factory 4MB -> ota_0 same offset, 6MB size
>>>>          2. ota_0 -> ota_1 6MB offset, 6MB size
>>>>      4. Change boot to ota_0.
>>>>      5. Reboot
>>>>  3. Liase with factory so new modules use new partition format (and
>>>>     ship with firmware that supports it).
>>>>  4. 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>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>:
>>>>>>
>>>>>> 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
>>>>>>> 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
>>>>>> http://lists.openvehicles.com/mailman/listinfo/ovmsdev
>>>>>
>>>>> _______________________________________________
>>>>> OvmsDev mailing list
>>>>> OvmsDev at lists.openvehicles.com
>>>>> http://lists.openvehicles.com/mailman/listinfo/ovmsdev
>>>>
>>>>
>>>> _______________________________________________
>>>> OvmsDev mailing list
>>>> 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
>>> http://lists.openvehicles.com/mailman/listinfo/ovmsdev
>>
>

-- 
Michael Balzer * Am Rahmen 5 * D-58313 Herdecke
Fon 02330 9104094 * Handy 0176 20698926


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.openvehicles.com/pipermail/ovmsdev/attachments/20260222/cf06ec49/attachment-0001.htm>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: OpenPGP_signature.asc
Type: application/pgp-signature
Size: 203 bytes
Desc: OpenPGP digital signature
URL: <http://lists.openvehicles.com/pipermail/ovmsdev/attachments/20260222/cf06ec49/attachment-0001.sig>


More information about the OvmsDev mailing list