moonboot_codegen/
linker.rs

1use moonboot::{
2    hardware::{Config, LinkerConfig},
3    state::{StateCrcType, STATE_SERIALIZED_MAX_SIZE},
4    Address,
5};
6fn generate_linker_script(
7    flash_origin: Address,
8    flash_length: Address,
9    ram_origin: Address,
10    ram_length: Address,
11    with_ram_state: bool,
12) -> String {
13    let ram_length = ram_length as usize;
14    if with_ram_state {
15        let crc_length = core::mem::size_of::<StateCrcType>(); // 4 byte crc
16        let data_len_length = core::mem::size_of::<u32>();
17        let state_length = STATE_SERIALIZED_MAX_SIZE;
18        let ram_length = ram_length as usize - state_length - crc_length - data_len_length;
19        let state_origin = ram_origin as usize + ram_length;
20        format!(
21            "
22
23    MEMORY {{
24        FLASH : ORIGIN = 0x{flash_origin:08x}, LENGTH = {flash_length}
25        RAM : ORIGIN = 0x{ram_origin:08x}, LENGTH = {ram_length}
26        MOONBOOT_STATE: ORIGIN = 0x{state_origin:08x}, LENGTH = {state_section_length}
27    }}
28
29    _moonboot_state_crc_start = ORIGIN(MOONBOOT_STATE);
30    _moonboot_state_len_start = ORIGIN(MOONBOOT_STATE) + {crc_length};
31    _moonboot_state_data_start = ORIGIN(MOONBOOT_STATE) + {crc_length} + {data_len_length};
32    PROVIDE(_moonboots_pre_jump = __moonboots_default_pre_jump);
33",
34            flash_origin = flash_origin,
35            flash_length = flash_length,
36            ram_origin = ram_origin,
37            ram_length = ram_length,
38            state_origin = state_origin,
39            state_section_length = state_length + crc_length + data_len_length,
40            data_len_length = data_len_length,
41            crc_length = crc_length,
42        )
43    } else {
44        format!(
45            "
46    MEMORY {{
47        FLASH : ORIGIN = 0x{flash_origin:08x}, LENGTH = {flash_length}
48        RAM : ORIGIN = 0x{ram_origin:08x}, LENGTH = {ram_length}
49    }}
50    
51    PROVIDE(_moonboots_pre_jump = __moonboots_default_pre_jump);
52",
53            flash_origin = flash_origin,
54            flash_length = flash_length,
55            ram_origin = ram_origin,
56            ram_length = ram_length,
57        )
58    }
59}
60
61pub fn generate_bootloader_script(config: Config, linker_config: LinkerConfig) -> String {
62    generate_linker_script(
63        linker_config.flash_origin + config.bootloader_bank.location,
64        config.bootloader_bank.size,
65        linker_config.ram_origin + config.ram_bank.location,
66        config.ram_bank.size,
67        linker_config.has_ram_state,
68    )
69}
70
71pub fn generate_application_script(config: Config, linker_config: LinkerConfig) -> String {
72    // find the bootable image
73    let bootable_firmware = config.boot_bank;
74
75    generate_linker_script(
76        linker_config.flash_origin + bootable_firmware.location,
77        bootable_firmware.size,
78        linker_config.ram_origin + config.ram_bank.location,
79        config.ram_bank.size,
80        linker_config.has_ram_state,
81    )
82}