@@ -187,22 +187,11 @@ pub fn elf_to_tbf(
187187 TotalSizePowerOfTwo ,
188188 /// Make sure the entire TBF is a multiple of a specific value.
189189 TotalSizeMultiple ( usize ) ,
190+ /// To prevent wasted space, only pad to:
191+ /// (X - 1) * (TotalSizePowerOfTwo / 8) < size < X * (TotalSizePowerOfTwo / 8)
192+ MaskedPowerOfTwo ,
190193 }
191194
192- // Add trailing padding for certain architectures.
193- //
194- // - ARM: make sure the entire TBF is a power of 2 to make configuring the
195- // MPU easy.
196- // - RISC_V: make sure the entire TBF is a multiple of 4 to meet TBF
197- // alignment requirements.
198- // - x86: use 4k padding to match page size.
199- let trailing_padding = match elf_file. ehdr . e_machine {
200- elf:: abi:: EM_ARM => Some ( TrailingPadding :: TotalSizePowerOfTwo ) ,
201- elf:: abi:: EM_RISCV => Some ( TrailingPadding :: TotalSizeMultiple ( 4 ) ) ,
202- elf:: abi:: EM_386 => Some ( TrailingPadding :: TotalSizeMultiple ( 4096 ) ) ,
203- _ => None ,
204- } ;
205-
206195 ////////////////////////////////////////////////////////////////////////////
207196 // Determine the amount of RAM this app needs.
208197 ////////////////////////////////////////////////////////////////////////////
@@ -897,6 +886,30 @@ pub fn elf_to_tbf(
897886 ensured_footer_reserved_space = true ;
898887 }
899888
889+ // Add trailing padding for certain architectures.
890+ // - ARM: make sure the entire TBF is a power of 2 to make configuring the
891+ // MPU easy and to make using the generated TBFs directly easy (for apps <64kB).
892+ // However, for larger apps (i.e., apps >64kB) round up to the
893+ // nearest power of 2 and then use subregions to limit wasted flash.
894+ // This is still compatible with the MPU but may make using multiple TBFs
895+ // more difficult due to alignment restrictions.
896+ // - RISC_V: make sure the entire TBF is a multiple of 4 to meet TBF
897+ // alignment requirements.
898+ // - x86: use 4k padding to match page size.
899+ let trailing_padding = match elf_file. ehdr . e_machine {
900+ elf:: abi:: EM_ARM => {
901+ // Do power of two padding if less than 64KB, otherwise do masked.
902+ if binary_index < 65536 {
903+ Some ( TrailingPadding :: TotalSizePowerOfTwo )
904+ } else {
905+ Some ( TrailingPadding :: MaskedPowerOfTwo )
906+ }
907+ }
908+ elf:: abi:: EM_RISCV => Some ( TrailingPadding :: TotalSizeMultiple ( 4 ) ) ,
909+ elf:: abi:: EM_386 => Some ( TrailingPadding :: TotalSizeMultiple ( 4096 ) ) ,
910+ _ => None ,
911+ } ;
912+
900913 // Optionally calculate the additional padding needed to ensure the app size
901914 // meets the padding requirements.
902915 //
@@ -921,6 +934,16 @@ pub fn elf_to_tbf(
921934 TrailingPadding :: TotalSizeMultiple ( multiple) => {
922935 ( multiple - ( binary_index % multiple) ) % multiple
923936 }
937+ TrailingPadding :: MaskedPowerOfTwo => {
938+ // Find the next power of two.
939+ let next_power2 = 1 << ( 32 - ( binary_index as u32 ) . leading_zeros ( ) ) ;
940+ let multiple = next_power2 / 8 ;
941+ let number_of_unmasked_subregions = binary_index. div_ceil ( multiple) ;
942+ let target_size = number_of_unmasked_subregions * multiple;
943+
944+ // Pad to the nearest multiple of (power of two / 8).
945+ target_size - binary_index
946+ }
924947 } ;
925948
926949 // Increment to include the padding.
0 commit comments