Skip to content

Commit 54ff1d6

Browse files
Add new power-of-two masking logic for >64KB apps
Takes advantage of subregions to lower the wasted space.
1 parent 06b05fd commit 54ff1d6

1 file changed

Lines changed: 37 additions & 14 deletions

File tree

src/convert.rs

Lines changed: 37 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)