[{"data":1,"prerenderedAt":1084},["ShallowReactive",2],{"developer-note-resizing-zephyr-devicetree-partitions":3},{"id":4,"title":5,"author":6,"body":7,"date":1076,"description":1077,"extension":1078,"meta":1079,"navigation":127,"path":1080,"seo":1081,"stem":1082,"__hash__":1083},"developerNotes\u002Fdevelopers\u002Fnotes\u002Fresizing-zephyr-devicetree-partitions.md","Zephyr: Resizing devicetree partitions","Jordan Yates",{"type":8,"value":9,"toc":1064},"minimark",[10,21,24,45,48,60,65,80,234,259,283,364,368,371,379,382,389,395,400,404,414,420,423,437,441,458,463,501,504,512,533,537,540,576,579,683,690,726,729,735,739,746,779,782,788,791,797,801,812,831,1001,1004,1044,1047,1053,1057,1060],[11,12,13],"p",{},[14,15],"img",{"alt":16,"src":17,"className":18,"width":20},"Embeint Blog Pictures","\u002Fimages\u002Fblog\u002F20251104.resizing-devicetree-partitions.png",[19],"rounded-lg",1200,[11,22,23],{},"One of Zephyr's nicer features is the ability to change the memory layout of your application without needing to dive into the murky world of linker scripts. This allows us to resize and shift bootloader, application, and configuration regions around as the application requirements dictate. There are three common reasons you might need to update the default layout provided by Zephyr.",[25,26,27,31,42],"ol",{},[28,29,30],"li",{},"Your application is too large to fit both application image slots in internal ROM, so you want to move the second image slot to an external flash chip.",[28,32,33,34,41],{},"You need to expand, shrink, or remove the ",[35,36,40],"a",{"href":37,"rel":38},"https:\u002F\u002Fdocs.zephyrproject.org\u002Flatest\u002Fservices\u002Fsettings\u002Findex.html",[39],"nofollow","settings partition",". In the later cases you can recover extra ROM for your application image slots, and in the first you need to shrink the application image slots to prevent overlaps.",[28,43,44],{},"You are defining your own board, so you are the one that needs to provide the defaults.",[11,46,47],{},"The purpose of this guide is to provide a summary of how Zephyr uses devicetree to define memory regions, and the process to follow when updating them.",[49,50,51],"blockquote",{},[11,52,53,54,59],{},"⚠️ Modifying bootloader and application ROM regions is only possible before a device has been deployed, since over-the-air upgrades only update the application image. The bootloader and application need to have a shared expectation of memory addresses, otherwise the bootloader will configure the wrong value into the ",[35,55,58],{"href":56,"rel":57},"https:\u002F\u002Fdeveloper.arm.com\u002Fdocumentation\u002F107706\u002F0100\u002FExceptions-and-interrupts-overview\u002FVector-table\u002FVTOR-register-and-initialization",[39],"VTOR register"," and jump to the wrong address when attempting to start the application.",[61,62,64],"h2",{"id":63},"devicetree-partitions","Devicetree Partitions",[11,66,67,68,73,74,79],{},"Before defining the steps to update the layouts, lets look at the default memory layout for a Nordic Semiconductor ",[35,69,72],{"href":70,"rel":71},"https:\u002F\u002Fwww.nordicsemi.com\u002FProducts\u002FDevelopment-hardware\u002FnRF52840-DK",[39],"nRF52840DK"," to familiarize ourselves with the format (",[35,75,78],{"href":76,"rel":77},"https:\u002F\u002Fgithub.com\u002Fzephyrproject-rtos\u002Fzephyr\u002Fblob\u002F8a72d776c5af6522478155adc91a5f4edb2794e3\u002Fdts\u002Fvendor\u002Fnordic\u002Fnrf52840_partition.dtsi#L15",[39],"source",").",[81,82,87],"pre",{"className":83,"code":84,"language":85,"meta":86,"style":86},"language-dts shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","&flash0 {\n    partitions {\n        compatible = \"fixed-partitions\";\n        #address-cells = \u003C1>;\n        #size-cells = \u003C1>;\n\n        boot_partition: partition@0 {\n            label = \"mcuboot\";\n            reg = \u003C0x00000000 0x0000C000>;\n        };\n        slot0_partition: partition@c000 {\n            label = \"image-0\";\n            reg = \u003C0x0000C000 0x00076000>;\n        };\n        slot1_partition: partition@82000 {\n            label = \"image-1\";\n            reg = \u003C0x00082000 0x00076000>;\n        };\n        storage_partition: partition@f8000 {\n            label = \"storage\";\n            reg = \u003C0x000f8000 0x00008000>;\n        };\n    };\n};\n","dts","",[88,89,90,98,104,110,116,122,129,135,141,147,153,159,165,171,176,182,188,194,199,205,211,217,222,228],"code",{"__ignoreMap":86},[91,92,95],"span",{"class":93,"line":94},"line",1,[91,96,97],{},"&flash0 {\n",[91,99,101],{"class":93,"line":100},2,[91,102,103],{},"    partitions {\n",[91,105,107],{"class":93,"line":106},3,[91,108,109],{},"        compatible = \"fixed-partitions\";\n",[91,111,113],{"class":93,"line":112},4,[91,114,115],{},"        #address-cells = \u003C1>;\n",[91,117,119],{"class":93,"line":118},5,[91,120,121],{},"        #size-cells = \u003C1>;\n",[91,123,125],{"class":93,"line":124},6,[91,126,128],{"emptyLinePlaceholder":127},true,"\n",[91,130,132],{"class":93,"line":131},7,[91,133,134],{},"        boot_partition: partition@0 {\n",[91,136,138],{"class":93,"line":137},8,[91,139,140],{},"            label = \"mcuboot\";\n",[91,142,144],{"class":93,"line":143},9,[91,145,146],{},"            reg = \u003C0x00000000 0x0000C000>;\n",[91,148,150],{"class":93,"line":149},10,[91,151,152],{},"        };\n",[91,154,156],{"class":93,"line":155},11,[91,157,158],{},"        slot0_partition: partition@c000 {\n",[91,160,162],{"class":93,"line":161},12,[91,163,164],{},"            label = \"image-0\";\n",[91,166,168],{"class":93,"line":167},13,[91,169,170],{},"            reg = \u003C0x0000C000 0x00076000>;\n",[91,172,174],{"class":93,"line":173},14,[91,175,152],{},[91,177,179],{"class":93,"line":178},15,[91,180,181],{},"        slot1_partition: partition@82000 {\n",[91,183,185],{"class":93,"line":184},16,[91,186,187],{},"            label = \"image-1\";\n",[91,189,191],{"class":93,"line":190},17,[91,192,193],{},"            reg = \u003C0x00082000 0x00076000>;\n",[91,195,197],{"class":93,"line":196},18,[91,198,152],{},[91,200,202],{"class":93,"line":201},19,[91,203,204],{},"        storage_partition: partition@f8000 {\n",[91,206,208],{"class":93,"line":207},20,[91,209,210],{},"            label = \"storage\";\n",[91,212,214],{"class":93,"line":213},21,[91,215,216],{},"            reg = \u003C0x000f8000 0x00008000>;\n",[91,218,220],{"class":93,"line":219},22,[91,221,152],{},[91,223,225],{"class":93,"line":224},23,[91,226,227],{},"    };\n",[91,229,231],{"class":93,"line":230},24,[91,232,233],{},"};\n",[11,235,236,237,240,241,246,247,250,251,254,255,258],{},"For this board, the onboard flash (the ",[88,238,239],{},"flash0"," node) is being split into 4 separate memory regions. This is done with a special devicetree node of compatible type ",[35,242,245],{"href":243,"rel":244},"https:\u002F\u002Fdocs.zephyrproject.org\u002Flatest\u002Fbuild\u002Fdts\u002Fapi\u002Fbindings\u002Fmtd\u002Ffixed-partitions.html",[39],"fixed-partitions",". The ",[88,248,249],{},"#address-cells"," and ",[88,252,253],{},"#size-cells"," properties can be ignored for our purposes, they are both always ",[88,256,257],{},"\u003C1>"," for memory partitions. Following the fixed-paritions boilerplate, we have our 4 memory regions; the bootloader, two equally sized application image slots, and the trailing storage partition. Each memory region follows the same structure:",[81,260,262],{"className":83,"code":261,"language":85,"meta":86,"style":86},"partition_nodelabel: partition@start_offset_1 {\n   label = \"partition-name\";\n   reg = \u003Cstart_offset_2 partition_size>;\n};\n",[88,263,264,269,274,279],{"__ignoreMap":86},[91,265,266],{"class":93,"line":94},[91,267,268],{},"partition_nodelabel: partition@start_offset_1 {\n",[91,270,271],{"class":93,"line":100},[91,272,273],{},"   label = \"partition-name\";\n",[91,275,276],{"class":93,"line":106},[91,277,278],{},"   reg = \u003Cstart_offset_2 partition_size>;\n",[91,280,281],{"class":93,"line":112},[91,282,233],{},[284,285,286,300],"table",{},[287,288,289],"thead",{},[290,291,292,297],"tr",{},[293,294,296],"th",{"align":295},"right","Device",[293,298,299],{},"Description",[301,302,303,314,324,334,344,354],"tbody",{},[290,304,305,311],{},[306,307,308],"td",{"align":295},[88,309,310],{},"partition_nodelabel",[306,312,313],{},"This field needs to be globally unique, and MCUBoot in particular has expectations for the names. Code can get a reference to the partition through DT_FIXED_PARTITION_ID(partition_nodelabel).",[290,315,316,321],{},[306,317,318],{"align":295},[88,319,320],{},"partition",[306,322,323],{},"By convention this field is named partition, but in practice it can be anything.",[290,325,326,331],{},[306,327,328],{"align":295},[88,329,330],{},"start_offset_1",[306,332,333],{},"The byte offset of the start of the memory region, in hexadecimal format. This value must not include a leading 0x or leading 0’s, and by convention uses lower case hex (e.g. @c000, not @C000).",[290,335,336,341],{},[306,337,338],{"align":295},[88,339,340],{},"\"partition-name\"",[306,342,343],{},"An optional string that identifies the partition. This can also be used to retrieve a reference to the partition with DT_NODE_BY_FIXED_PARTITION_LABEL(partition_name), but its usage is discouraged (use DT_FIXED_PARTITION_ID).",[290,345,346,351],{},[306,347,348],{"align":295},[88,349,350],{},"start_offset_2",[306,352,353],{},"This value must be the same numerical value as start_offset_1, but is formatted as an uint32_t hexadecimal number with leading 0x and 0’s. The convention is uppercase letters. (e.g. 0x0000C000).",[290,355,356,361],{},[306,357,358],{"align":295},[88,359,360],{},"partition_size",[306,362,363],{},"The size of the memory region in bytes, in the same numerical format as start_offset_2.",[61,365,367],{"id":366},"device-specific-knowledge","Device Specific Knowledge",[11,369,370],{},"Before proceeding to dividing up our memory space, there are two pieces of information that need to be known for each flash device we are using:",[25,372,373,376],{},[28,374,375],{},"Total flash size in bytes",[28,377,378],{},"Minimum partition unit",[11,380,381],{},"The first point is self-explanatory, we need to know how much space we have to allocate. The minimum partition unit is needed because flash memory typically can’t be erased on arbitrary byte boundaries, they have some minimum erase unit. Because we want memory partitions to appear independent, we don’t want an erase on a memory address in one memory partition to accidentally erase data on a second partition.",[11,383,384,385,79],{},"The total flash size is typically a headline item on a datasheet (1 MB for the nRF52840), while the minimum erase unit can usually be found in the FLASH peripheral sections (4 KB here) (",[35,386,78],{"href":387,"rel":388},"https:\u002F\u002Fdocs.nordicsemi.com\u002Fbundle\u002Fps_nrf52840\u002Fpage\u002Fmemory.html#ariaid-title3",[39],[11,390,391],{},[14,392],{"alt":393,"src":394},"nRF52840 Flash Layout","\u002Fimages\u002Fblog\u002F20251020_partitions\u002Fnrf52840_flash.png",[49,396,397],{},[11,398,399],{},"⚠️ For applications utilizing a Memory Protection Unit (MPU), the addressable resolution of the MPU must also be taken into account for the minimum partition unit.",[61,401,403],{"id":402},"partition-packing","Partition Packing",[11,405,406,407,250,410,413],{},"Generally speaking, we want to be efficient with our ROM. Leaving regions of memory unallocated, as shown in the center layout below, is generally undesirable. Additionally, most applications will want equally sized ",[88,408,409],{},"image-0",[88,411,412],{},"image-1"," partitions, since future images will be limited to the smaller of the two partitions.",[11,415,416],{},[14,417],{"alt":418,"src":419},"Parition Packing Example","\u002Fimages\u002Fblog\u002F20251020_partitions\u002Fpacking.png",[11,421,422],{},"This leads to a few simple rules that should be obeyed when dividing up your memory space.",[25,424,425,428,431,434],{},[28,426,427],{},"The offset of the first partition should be 0",[28,429,430],{},"The offset of a partition should equal the (offset + size) of the previous partition",[28,432,433],{},"The (offset + size) of the last partition should equal the total size of the memory space",[28,435,436],{},"The size of each partition MUST be a multiple of the minimum partition unit",[61,438,440],{"id":439},"examples","Examples",[11,442,443,444,449,450,453,454,457],{},"The following examples are all built and run on Zephyr ",[35,445,448],{"href":446,"rel":447},"https:\u002F\u002Fgithub.com\u002Fzephyrproject-rtos\u002Fzephyr\u002Ftree\u002Fv4.2.1",[39],"v4.2.1"," using the ",[88,451,452],{},"hello_world"," sample. We build the application using sysbuild with ",[88,455,456],{},"-DSB_CONFIG_BOOTLOADER_MCUBOOT=y"," so that MCUboot is automatically built at the same time.",[459,460,462],"h3",{"id":461},"default-build","Default build",[81,464,468],{"className":465,"code":466,"language":467,"meta":86,"style":86},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","west build -p -b nrf52840dk\u002Fnrf52840 zephyr\u002Fsamples\u002Fhello_world\u002F --sysbuild -- -DSB_CONFIG_BOOTLOADER_MCUBOOT=y\n","bash",[88,469,470],{"__ignoreMap":86},[91,471,472,476,480,483,486,489,492,495,498],{"class":93,"line":94},[91,473,475],{"class":474},"sBMFI","west",[91,477,479],{"class":478},"sfazB"," build",[91,481,482],{"class":478}," -p",[91,484,485],{"class":478}," -b",[91,487,488],{"class":478}," nrf52840dk\u002Fnrf52840",[91,490,491],{"class":478}," zephyr\u002Fsamples\u002Fhello_world\u002F",[91,493,494],{"class":478}," --sysbuild",[91,496,497],{"class":478}," --",[91,499,500],{"class":478}," -DSB_CONFIG_BOOTLOADER_MCUBOOT=y\n",[11,502,503],{},"Building the application with its default memory layout shows the (mostly) expected result. The 48 kB (0xc000) bootloader FLASH region matches our expectations, however the application image FLASH region of 474800 bytes (0x73eb0) is slightly smaller than the 472 kB (0x76000) size specified in devicetree.",[81,505,510],{"className":506,"code":508,"language":509},[507],"language-text","# MCUBoot\nMemory region         Used Size  Region Size  %age Used\n           FLASH:       32660 B        48 KB     66.45%\n             RAM:       22464 B       256 KB      8.57%\n        IDT_LIST:          0 GB        32 KB      0.00%\n# Application\nMemory region         Used Size  Region Size  %age Used\n           FLASH:       19228 B     474800 B      4.05%\n             RAM:        4480 B       256 KB      1.71%\n        IDT_LIST:          0 GB        32 KB      0.00%\n","text",[88,511,508],{"__ignoreMap":86},[11,513,514,515,520,521,524,525,528,529,532],{},"This is because the bootloader needs to store swap status and metadata at the end of an image. The amount of space needed is taken care of automatically by the build system with ",[35,516,519],{"href":517,"rel":518},"https:\u002F\u002Fdocs.zephyrproject.org\u002Flatest\u002Fkconfig.html#CONFIG_ROM_END_OFFSET",[39],"CONFIG_ROM_END_OFFSET",". If we examine the value of this kconfig in ",[88,522,523],{},"build\u002Fhello_world\u002Fzephyr\u002Finclude\u002Fgenerated\u002Fzephyr\u002Fautoconf.h",", we can see ",[88,526,527],{},"#define CONFIG_ROM_END_OFFSET 0x2150",", and ",[88,530,531],{},"0x76000 - 0x2150 == 474800",".",[459,534,536],{"id":535},"expanding-application-flash","Expanding application FLASH",[11,538,539],{},"The first example is expanding the FLASH space available to the application by removing the storage partition. Since this region is 32 kB, we should be able to expand the two application regions by 16 kB each. To calculate the new values for each of our regions:",[541,542,543,546,549,565],"ul",{},[28,544,545],{},"The bootloader partition is unchanged, 48 kB",[28,547,548],{},"The total remaining memory is 976 kB (1024 - 48)",[28,550,551,552],{},"An even split for application images would be 488 kB (976 \u002F 2)\n",[541,553,554,560],{},[28,555,556,559],{},[88,557,558],{},"slot0_partition"," is therefore 488 kB",[28,561,562,559],{},[88,563,564],{},"slot1_partition",[28,566,567,568],{},"To double check:\n",[541,569,570,573],{},[28,571,572],{},"Validate that 48 + 488 + 488 == 1024",[28,574,575],{},"Validate that each partition is a multiple of 4kB",[11,577,578],{},"Translating this into the devicetree format from above:",[81,580,582],{"className":83,"code":581,"language":85,"meta":86,"style":86},"\u002F* zephyr\u002Fsamples\u002Fhello_world\u002Fboards\u002Fnrf52840dk_nrf52840.overlay *\u002F\n\n\u002F* Delete the original partitions *\u002F\n\u002Fdelete-node\u002F &slot0_partition;\n\u002Fdelete-node\u002F &slot1_partition;\n\u002Fdelete-node\u002F &storage_partition;\n\n&flash0 {\n    partitions {\n        \u002F* The two application partitions, expanded *\u002F\n        slot0_partition: partition@c000 {\n            label = \"image-0\";\n            \u002F* reg = \u003C48kB 488kB> *\u002F\n            reg = \u003C0x0000C000 0x0007A000>;\n        };\n        slot1_partition: partition@86000{\n            label = \"image-1\";\n            \u002F* reg = \u003C540kB 488kB> *\u002F\n            reg = \u003C0x00086000 0x0007A000>;\n        };\n    };\n};\n",[88,583,584,589,593,598,603,608,613,617,621,625,630,634,638,643,648,652,657,661,666,671,675,679],{"__ignoreMap":86},[91,585,586],{"class":93,"line":94},[91,587,588],{},"\u002F* zephyr\u002Fsamples\u002Fhello_world\u002Fboards\u002Fnrf52840dk_nrf52840.overlay *\u002F\n",[91,590,591],{"class":93,"line":100},[91,592,128],{"emptyLinePlaceholder":127},[91,594,595],{"class":93,"line":106},[91,596,597],{},"\u002F* Delete the original partitions *\u002F\n",[91,599,600],{"class":93,"line":112},[91,601,602],{},"\u002Fdelete-node\u002F &slot0_partition;\n",[91,604,605],{"class":93,"line":118},[91,606,607],{},"\u002Fdelete-node\u002F &slot1_partition;\n",[91,609,610],{"class":93,"line":124},[91,611,612],{},"\u002Fdelete-node\u002F &storage_partition;\n",[91,614,615],{"class":93,"line":131},[91,616,128],{"emptyLinePlaceholder":127},[91,618,619],{"class":93,"line":137},[91,620,97],{},[91,622,623],{"class":93,"line":143},[91,624,103],{},[91,626,627],{"class":93,"line":149},[91,628,629],{},"        \u002F* The two application partitions, expanded *\u002F\n",[91,631,632],{"class":93,"line":155},[91,633,158],{},[91,635,636],{"class":93,"line":161},[91,637,164],{},[91,639,640],{"class":93,"line":167},[91,641,642],{},"            \u002F* reg = \u003C48kB 488kB> *\u002F\n",[91,644,645],{"class":93,"line":173},[91,646,647],{},"            reg = \u003C0x0000C000 0x0007A000>;\n",[91,649,650],{"class":93,"line":178},[91,651,152],{},[91,653,654],{"class":93,"line":184},[91,655,656],{},"        slot1_partition: partition@86000{\n",[91,658,659],{"class":93,"line":190},[91,660,187],{},[91,662,663],{"class":93,"line":196},[91,664,665],{},"            \u002F* reg = \u003C540kB 488kB> *\u002F\n",[91,667,668],{"class":93,"line":201},[91,669,670],{},"            reg = \u003C0x00086000 0x0007A000>;\n",[91,672,673],{"class":93,"line":207},[91,674,152],{},[91,676,677],{"class":93,"line":213},[91,678,227],{},[91,680,681],{"class":93,"line":219},[91,682,233],{},[11,684,685,686,689],{},"To provide the build system our new memory layouts, we need to create a new file in the application folder. In this case, ",[88,687,688],{},"zephyr\u002Fsamples\u002Fhello_world\u002Fboards\u002Fnrf52840dk_nrf52840.overlay",". The build system will automatically pick up the changes for the application image, but we need to manually specify it for the MCUboot image.",[81,691,693],{"className":465,"code":692,"language":467,"meta":86,"style":86},"west build -p -b nrf52840dk\u002Fnrf52840 zephyr\u002Fsamples\u002Fhello_world\u002F --sysbuild -- -DSB_CONFIG_BOOTLOADER_MCUBOOT=y -Dmcuboot_EXTRA_DTC_OVERLAY_FILE=$ZEPHYR_BASE\u002Fsamples\u002Fhello_world\u002Fboards\u002Fnrf52840dk_nrf52840.overlay\n",[88,694,695],{"__ignoreMap":86},[91,696,697,699,701,703,705,707,709,711,713,716,719,723],{"class":93,"line":94},[91,698,475],{"class":474},[91,700,479],{"class":478},[91,702,482],{"class":478},[91,704,485],{"class":478},[91,706,488],{"class":478},[91,708,491],{"class":478},[91,710,494],{"class":478},[91,712,497],{"class":478},[91,714,715],{"class":478}," -DSB_CONFIG_BOOTLOADER_MCUBOOT=y",[91,717,718],{"class":478}," -Dmcuboot_EXTRA_DTC_OVERLAY_FILE=",[91,720,722],{"class":721},"sTEyZ","$ZEPHYR_BASE",[91,724,725],{"class":478},"\u002Fsamples\u002Fhello_world\u002Fboards\u002Fnrf52840dk_nrf52840.overlay\n",[11,727,728],{},"Running the build shows us our updated FLASH regions, with the application FLASH region having increased by 16 kB compared to the baseline.",[81,730,733],{"className":731,"code":732,"language":509},[507],"# MCUBoot\nMemory region         Used Size  Region Size  %age Used\n           FLASH:       32660 B        48 KB     66.45%\n             RAM:       22464 B       256 KB      8.57%\n        IDT_LIST:          0 GB        32 KB      0.00%\n# Application\nMemory region         Used Size  Region Size  %age Used\n           FLASH:       19228 B     491184 B      3.91%\n             RAM:        4480 B       256 KB      1.71%\n        IDT_LIST:          0 GB        32 KB      0.00%\n",[88,734,732],{"__ignoreMap":86},[459,736,738],{"id":737},"shrinking-application-flash","Shrinking application FLASH",[11,740,741,742,745],{},"The next example moves in the other direction, shrinking application FLASH, to either add a new memory region or expand the settings partition. In this example we will add a new 64 kB partition (",[88,743,744],{},"file_partition",") after the second image partition.",[541,747,748,750,753,756,759,770],{},[28,749,545],{},[28,751,752],{},"The storage partition is unchanged, 32 kB",[28,754,755],{},"We are adding a new 64 kB partition",[28,757,758],{},"The total remaining memory is 880 kB (1024 - 48 - 32 - 64)",[28,760,761,762],{},"An even split for application images would be 440 kB (880 \u002F 2)\n",[541,763,764,767],{},[28,765,766],{},"slot0_partition is therefore 440 kB",[28,768,769],{},"slot1_partition is therefore 440 kB",[28,771,567,772],{},[541,773,774,777],{},[28,775,776],{},"Validate that 48 + 440 + 440 + 64 + 32 == 1024",[28,778,575],{},[11,780,781],{},"Again translating our new memory layout into devicetree:",[81,783,786],{"className":784,"code":785,"language":509},[507],"\u002F* zephyr\u002Fsamples\u002Fhello_world\u002Fboards\u002Fnrf52840dk_nrf52840.overlay *\u002F\n\n\u002F* Delete the original partitions *\u002F\n\u002Fdelete-node\u002F &slot0_partition;\n\u002Fdelete-node\u002F &slot1_partition;\n\n&flash0 {\n    partitions {\n        \u002F* The two application partitions, shrunk *\u002F\n        slot0_partition: partition@c000 {\n            label = \"image-0\";\n            \u002F* reg = \u003C48kB 440kB> *\u002F\n            reg = \u003C0x0000C000 0x0006E000>;\n        };\n        slot1_partition: partition@7a000 {\n            label = \"image-1\";\n            \u002F* reg = \u003C488kB 440kB> *\u002F\n            reg = \u003C0x0007A000 0x0006E000>;\n        };\n        \u002F* Our new partition *\u002F\n        file_partition: partition@e8000 {\n            label = \"files\";\n            \u002F* reg = \u003C928kB 64kB> *\u002F\n            reg = \u003C0x000E8000 0x00010000>;\n        };\n    };\n};\n",[88,787,785],{"__ignoreMap":86},[11,789,790],{},"After running the same build step from above, we can see our new smaller application FLASH region:",[81,792,795],{"className":793,"code":794,"language":509},[507],"# MCUBoot\nMemory region         Used Size  Region Size  %age Used\n           FLASH:       32660 B        48 KB     66.45%\n             RAM:       22464 B       256 KB      8.57%\n        IDT_LIST:          0 GB        32 KB      0.00%\n# Application\nMemory region         Used Size  Region Size  %age Used\n           FLASH:       19228 B     442032 B      4.35%\n             RAM:        4480 B       256 KB      1.71%\n        IDT_LIST:          0 GB        32 KB      0.00%\n",[88,796,794],{"__ignoreMap":86},[459,798,800],{"id":799},"moving-the-secondary-image-to-external-flash","Moving the secondary image to external flash",[11,802,803,804,806,807,809,810,532],{},"Moving the secondary image to external flash is simpler in terms of the calculations, but requires additional command line options since now MCUboot requires drivers to be enabled for the external flash memory. The ",[88,805,558],{}," is simply updated to be the combined size of the original partitions, while ",[88,808,564],{}," is re-added on the external flash chip node. The size of slot1_partition is the same size as ",[88,811,558],{},[541,813,814,816,818,821,826],{},[28,815,545],{},[28,817,752],{},[28,819,820],{},"The total remaining memory is 944 kB (1024 - 48 - 32)",[28,822,823,825],{},[88,824,558],{}," is allocated the entire 944 kB",[28,827,828,830],{},[88,829,564],{}," on the external flash, 944 kB",[81,832,834],{"className":83,"code":833,"language":85,"meta":86,"style":86},"\u002F* zephyr\u002Fsamples\u002Fhello_world\u002Fboards\u002Fnrf52840dk_nrf52840.overlay *\u002F\n\n\u002F* Delete the original partitions *\u002F\n\u002Fdelete-node\u002F &slot0_partition;\n\u002Fdelete-node\u002F &slot1_partition;\n\n&flash0 {\n    partitions {\n        \u002F* Our new, much larger, slot0_partition *\u002F\n        slot0_partition: partition@c000 {\n            label = \"image-0\";\n            \u002F* reg = \u003C48kB 944kB> *\u002F\n            reg = \u003C0x0000C000 0x000EC000>;\n        };\n    };\n};\n\n\u002F* External flash chip on the nRF52840DK QSPI bus *\u002F\n&mx25r64 {\n    partitions {\n        \u002F* The base board files do not define any partitions on this flash\n         * chip, so we need to add the boilerplate.\n         *\u002F\n        compatible = \"fixed-partitions\";\n        #address-cells = \u003C 0x1 >;\n        #size-cells = \u003C 0x1 >;\n\n        \u002F* slot1_partition moved to external flash *\u002F\n        slot1_partition: partition@0 {\n            label = \"image-1\";\n            \u002F* reg = \u003C0kB 936kB> *\u002F\n            reg = \u003C 0x00000000 0x000EA000 >;\n        };\n    };\n};\n",[88,835,836,840,844,848,852,856,860,864,868,873,877,881,886,891,895,899,903,907,912,917,921,926,931,936,940,946,952,957,963,969,974,980,986,991,996],{"__ignoreMap":86},[91,837,838],{"class":93,"line":94},[91,839,588],{},[91,841,842],{"class":93,"line":100},[91,843,128],{"emptyLinePlaceholder":127},[91,845,846],{"class":93,"line":106},[91,847,597],{},[91,849,850],{"class":93,"line":112},[91,851,602],{},[91,853,854],{"class":93,"line":118},[91,855,607],{},[91,857,858],{"class":93,"line":124},[91,859,128],{"emptyLinePlaceholder":127},[91,861,862],{"class":93,"line":131},[91,863,97],{},[91,865,866],{"class":93,"line":137},[91,867,103],{},[91,869,870],{"class":93,"line":143},[91,871,872],{},"        \u002F* Our new, much larger, slot0_partition *\u002F\n",[91,874,875],{"class":93,"line":149},[91,876,158],{},[91,878,879],{"class":93,"line":155},[91,880,164],{},[91,882,883],{"class":93,"line":161},[91,884,885],{},"            \u002F* reg = \u003C48kB 944kB> *\u002F\n",[91,887,888],{"class":93,"line":167},[91,889,890],{},"            reg = \u003C0x0000C000 0x000EC000>;\n",[91,892,893],{"class":93,"line":173},[91,894,152],{},[91,896,897],{"class":93,"line":178},[91,898,227],{},[91,900,901],{"class":93,"line":184},[91,902,233],{},[91,904,905],{"class":93,"line":190},[91,906,128],{"emptyLinePlaceholder":127},[91,908,909],{"class":93,"line":196},[91,910,911],{},"\u002F* External flash chip on the nRF52840DK QSPI bus *\u002F\n",[91,913,914],{"class":93,"line":201},[91,915,916],{},"&mx25r64 {\n",[91,918,919],{"class":93,"line":207},[91,920,103],{},[91,922,923],{"class":93,"line":213},[91,924,925],{},"        \u002F* The base board files do not define any partitions on this flash\n",[91,927,928],{"class":93,"line":219},[91,929,930],{},"         * chip, so we need to add the boilerplate.\n",[91,932,933],{"class":93,"line":224},[91,934,935],{},"         *\u002F\n",[91,937,938],{"class":93,"line":230},[91,939,109],{},[91,941,943],{"class":93,"line":942},25,[91,944,945],{},"        #address-cells = \u003C 0x1 >;\n",[91,947,949],{"class":93,"line":948},26,[91,950,951],{},"        #size-cells = \u003C 0x1 >;\n",[91,953,955],{"class":93,"line":954},27,[91,956,128],{"emptyLinePlaceholder":127},[91,958,960],{"class":93,"line":959},28,[91,961,962],{},"        \u002F* slot1_partition moved to external flash *\u002F\n",[91,964,966],{"class":93,"line":965},29,[91,967,968],{},"        slot1_partition: partition@0 {\n",[91,970,972],{"class":93,"line":971},30,[91,973,187],{},[91,975,977],{"class":93,"line":976},31,[91,978,979],{},"            \u002F* reg = \u003C0kB 936kB> *\u002F\n",[91,981,983],{"class":93,"line":982},32,[91,984,985],{},"            reg = \u003C 0x00000000 0x000EA000 >;\n",[91,987,989],{"class":93,"line":988},33,[91,990,152],{},[91,992,994],{"class":93,"line":993},34,[91,995,227],{},[91,997,999],{"class":93,"line":998},35,[91,1000,233],{},[11,1002,1003],{},"In order to build this updated configuration, we also need to enable the QSPI driver in MCUboot. MCUboot has an existing Kconfig file for this, which we can reuse.",[81,1005,1007],{"className":465,"code":1006,"language":467,"meta":86,"style":86},"west build -p -b nrf52840dk\u002Fnrf52840 zephyr\u002Fsamples\u002Fhello_world\u002F --sysbuild --  -DSB_CONFIG_BOOTLOADER_MCUBOOT=y -Dmcuboot_EXTRA_CONF_FILE=$ZEPHYR_BASE\u002F..\u002Fbootloader\u002Fmcuboot\u002Fboot\u002Fzephyr\u002Fboards\u002Fnrf52840dk_qspi_nor.conf -Dmcuboot_EXTRA_DTC_OVERLAY_FILE=$ZEPHYR_BASE\u002Fsamples\u002Fhello_world\u002Fboards\u002Fnrf52840dk_nrf52840.overlay\n",[88,1008,1009],{"__ignoreMap":86},[91,1010,1011,1013,1015,1017,1019,1021,1023,1025,1027,1030,1033,1035,1038,1040,1042],{"class":93,"line":94},[91,1012,475],{"class":474},[91,1014,479],{"class":478},[91,1016,482],{"class":478},[91,1018,485],{"class":478},[91,1020,488],{"class":478},[91,1022,491],{"class":478},[91,1024,494],{"class":478},[91,1026,497],{"class":478},[91,1028,1029],{"class":478},"  -DSB_CONFIG_BOOTLOADER_MCUBOOT=y",[91,1031,1032],{"class":478}," -Dmcuboot_EXTRA_CONF_FILE=",[91,1034,722],{"class":721},[91,1036,1037],{"class":478},"\u002F..\u002Fbootloader\u002Fmcuboot\u002Fboot\u002Fzephyr\u002Fboards\u002Fnrf52840dk_qspi_nor.conf",[91,1039,718],{"class":478},[91,1041,722],{"class":721},[91,1043,725],{"class":478},[11,1045,1046],{},"With this command, our primary application image has now significantly expanded, while still retaining the ability to upgrade after deployment. The MCUboot resource usage has also increased slightly due to the additional drivers.",[81,1048,1051],{"className":1049,"code":1050,"language":509},[507],"# MCUBoot\nMemory region         Used Size  Region Size  %age Used\n           FLASH:       36396 B        48 KB     74.05%\n             RAM:       24384 B       256 KB      9.30%\n        IDT_LIST:          0 GB        32 KB      0.00%\n# Application\nMemory region         Used Size  Region Size  %age Used\n           FLASH:       19180 B       936 KB      2.00%\n             RAM:        5696 B       256 KB      2.17%\n        IDT_LIST:          0 GB        32 KB      0.00%\n",[88,1052,1050],{"__ignoreMap":86},[61,1054,1056],{"id":1055},"summary","Summary",[11,1058,1059],{},"The provided examples give a foundation on the steps to take when resizing Zephyr devicetree partitions. The same process can be followed regardless of the microcontroller or board, as long as you can find the total flash memory size and the page erase size.",[1061,1062,1063],"style",{},"html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}",{"title":86,"searchDepth":100,"depth":100,"links":1065},[1066,1067,1068,1069,1075],{"id":63,"depth":100,"text":64},{"id":366,"depth":100,"text":367},{"id":402,"depth":100,"text":403},{"id":439,"depth":100,"text":440,"children":1070},[1071,1072,1073,1074],{"id":461,"depth":106,"text":462},{"id":535,"depth":106,"text":536},{"id":737,"depth":106,"text":738},{"id":799,"depth":106,"text":800},{"id":1055,"depth":100,"text":1056},"2025-11-08","Resize partitions from their default sizes to optimise flash usage.","md",{},"\u002Fdevelopers\u002Fnotes\u002Fresizing-zephyr-devicetree-partitions",{"title":5,"description":1077},"developers\u002Fnotes\u002Fresizing-zephyr-devicetree-partitions","W6N3O7WWynW3b5yIs79j0CUx0oFDt1kLidkeTpmwsTc",1790559262387]