diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index cfc36a82..96d9f616 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -45,8 +45,6 @@ jobs: xmake f --board=${{ matrix.board }} --sdk=/cheriot-tools/ ${{ matrix.build-flags }} xmake - name: Run tests - # Test suite needs HyperRAM support to be added to RTOS because SRAM is not big enough. - if: ${{ !matrix.sonata }} run: | cd tests xmake run diff --git a/scripts/model_output/sonata-simulator/examples/test-suite.txt b/scripts/model_output/sonata-simulator/examples/test-suite.txt new file mode 100644 index 00000000..1c88ab78 --- /dev/null +++ b/scripts/model_output/sonata-simulator/examples/test-suite.txt @@ -0,0 +1 @@ +All tests finished diff --git a/scripts/run-sonata-sim.sh b/scripts/run-sonata-sim.sh index 1b4c1a36..59a0535a 100755 --- a/scripts/run-sonata-sim.sh +++ b/scripts/run-sonata-sim.sh @@ -4,7 +4,7 @@ set -e # Specify the default environment variables if they haven't been already. : "${SONATA_SIMULATOR:=/cheriot-tools/bin/sonata_simulator}" -: "${SONATA_SIMULATOR_BOOT_STUB:=/cheriot-tools/elf/sonata_simulator_boot_stub}" +: "${SONATA_SIMULATOR_BOOT_STUB:=/cheriot-tools/elf/sonata_simulator_hyperram_boot_stub}" : "${SONATA_SIMULATOR_UART_LOG=uart0.log}" if [ -z "$1" ] ; then @@ -30,20 +30,26 @@ if [ -n "$2" ] ; then # Run the simulator in the background. ${SONATA_SIMULATOR} -E "${SONATA_SIMULATOR_BOOT_STUB}" -E "$1" & LOOP_TRACKER=0 - while (( LOOP_TRACKER <= 60 )) + while (( LOOP_TRACKER <= 1200 )) do sleep 1s # Returns 0 if found and 1 if not. MATCH_FOUND=$(grep -q -F -f "$2" "${SONATA_SIMULATOR_UART_LOG}"; echo $?) if (( MATCH_FOUND == 0 )) ; then - # Match was found so exit with success + # Match was found so kill the simulator pkill -P $$ + # Check to see if the output indicates failure + if grep -i failure "${SONATA_SIMULATOR_UART_LOG}"; then + exit 5 + fi exit 0 fi LOOP_TRACKER=$((LOOP_TRACKER+1)) done # Timeout was hit so no success. pkill -P $$ + echo "UART output:" + cat "${SONATA_SIMULATOR_UART_LOG}" exit 4 else # If there is no second argument, run simulator in foreground. diff --git a/sdk/boards/sonata-prerelease.json b/sdk/boards/sonata-prerelease.json index 83f22114..7f7b3273 100644 --- a/sdk/boards/sonata-prerelease.json +++ b/sdk/boards/sonata-prerelease.json @@ -77,9 +77,13 @@ "end" : 0x88400000 } }, + "data_memory": { + "start" : 0x00101000, + "end" : 0x00120000 + }, "instruction_memory": { - "start": 0x00101000, - "end": 0x00120000 + "start": 0x40000000, + "end": 0x40100000 }, "heap": { "end": 0x00120000 @@ -92,7 +96,8 @@ "SUNBURST_SHADOW_SIZE=0x800", "ipconfigDRIVER_INCLUDED_RX_IP_CHECKSUM=1", "ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM=1", - "CHERIOT_NO_SAIL_83" + "CHERIOT_NO_SAIL_83", + "STDERR_TO_STDOUT=1" ], "cxflags": "-mllvm -enable-machine-outliner=never", "driver_includes" : [ diff --git a/sdk/firmware.ldscript.in b/sdk/firmware.ldscript.in index 3ebe9aef..a591c3ad 100644 --- a/sdk/firmware.ldscript.in +++ b/sdk/firmware.ldscript.in @@ -5,302 +5,11 @@ SECTIONS { - . = @code_start@; - _start = .; - - .loader_start : - { - *(.loader_start); - } - - .compartment_export_tables : ALIGN(8) - { - # The scheduler and allocator's export tables are at the start. - .scheduler_export_table = .; - *.scheduler.compartment(.compartment_export_table); - .scheduler_export_table_end = .; - - .allocator_export_table = ALIGN(8); - */cheriot.allocator.compartment(.compartment_export_table); - .allocator_export_table_end = .; - - @compartment_exports@ - } - - - __compart_pccs = .; - - compartment_switcher_code : CAPALIGN - { - .compartment_switcher_start = .; - */switcher/entry.S.o(.text); - } - .compartment_switcher_end = .; - - scheduler_code : CAPALIGN - { - .scheduler_start = .; - *.scheduler.compartment(.compartment_sealing_keys); - .scheduler_import_start = .; - *.scheduler.compartment(.compartment_import_table); - .scheduler_import_end = .; - *.scheduler.compartment(.text .text.* .rodata .rodata.* .data.rel.ro); - } - .scheduler_end = .; - - allocator_code : CAPALIGN - { - .allocator_start = .; - */cheriot.allocator.compartment(.compartment_sealing_keys); - .allocator_import_start = .; - */cheriot.allocator.compartment(.compartment_import_table); - .allocator_import_end = .; - allocator.compartment(.text .text.* .rodata .rodata.* .data.rel.ro); - */cheriot.allocator.compartment(.text .text.* .rodata .rodata.* .data.rel.ro); - } - .allocator_end = .; - - - token_library_code : CAPALIGN - { - .token_library_start = .; - */cheriot.token_library.library(.compartment_sealing_keys); - .token_library_import_start = .; - */cheriot.token_library.library(.compartment_import_table); - .token_library_import_end = .; - token_library.library(.text .text.* .rodata .rodata.* .data.rel.ro); - */cheriot.token_library.library(.text .text.* .rodata .rodata.* .data.rel.ro); - } - .token_library_end = .; - - - @software_revoker_code@ - - @pcc_ld@ - __compart_pccs_end = .; - - # Revoker scan region must be cap aligned - . = ALIGN(8); - __revoker_scan_start = .; - __stack_space_start = .; - - @thread_trusted_stacks@ - - @thread_stacks@ - - __stack_space_end = .; - - __compart_cgps = ALIGN(64); - - .scheduler_globals : CAPALIGN - { - .scheduler_globals = .; - *.scheduler.compartment(.data .data.* .sdata .sdata.*); - .scheduler_bss_start = .; - *.scheduler.compartment(.sbss .sbss.* .bss .bss.*) - } - .scheduler_globals_end = .; - - .allocator_sealed_objects : CAPALIGN - { - .allocator_sealed_objects = .; - */cheriot.allocator.compartment(.sealed_objects) - } - .allocator_sealed_objects_end = .; - - .allocator_globals : CAPALIGN - { - .allocator_globals = .; - */cheriot.allocator.compartment(.data .data.* .sdata .sdata.*); - .allocator_bss_start = .; - */cheriot.allocator.compartment(.sbss .sbss.* .bss .bss.*); - } - .allocator_globals_end = .; - - - @software_revoker_globals@ - - @gdc_ld@ - - __compart_cgps_end = .; - - .sealed_objects : - { - @sealed_objects@ - } - - __shared_objects_start = .; - @shared_objects@ - __shared_objects_end = .; - - . = ALIGN(64); - - # Everything after this point can be discarded after the loader has - # finished. - __export_mem_heap = @heap_start@; - - __cap_relocs : - { - __cap_relocs = .; - # FIXME: This currently doesn't do anything. The linker creates this - # entire section. The linker script needs to be modified to create - # separate caprelocs sections for each section. - @cap_relocs@ - } - __cap_relocs_end = .; - - # Collect all compartment headers - .compartment_headers : ALIGN(4) - { - __compart_headers = .; - # Loader code start - LONG(.loader_code_start); - # Loader code length - SHORT(.loader_code_end - .loader_code_start); - # Loader data start - LONG(.loader_data_start); - # Loader data length - SHORT(.loader_data_end - .loader_data_start); - - # Compartment switcher start address - LONG(.compartment_switcher_start); - # Compartment switcher end - SHORT(.compartment_switcher_end - .compartment_switcher_start); - # Cross-compartment call return path - SHORT(switcher_after_compartment_call - .compartment_switcher_start); - # Compartment switcher sealing keys - SHORT(compartment_switcher_sealing_key - .compartment_switcher_start); - # Switcher's copy of the scheduler's PCC. - SHORT(switcher_scheduler_entry_pcc - .compartment_switcher_start); - # Switcher's copy of the scheduler's CGP - SHORT(switcher_scheduler_entry_cgp - .compartment_switcher_start); - # Switcher's copy of the scheduler's CSP - SHORT(switcher_scheduler_entry_csp - .compartment_switcher_start); - # Address of switcher export table - LONG(.switcher_export_table); - # Size of the switcher export table - SHORT(.switcher_export_table_end - .switcher_export_table); - - # sdk/core/loader/types.h:/PrivilegedCompartment - # Scheduler code start address - LONG(.scheduler_start); - # Scheduler code end - SHORT(.scheduler_end - .scheduler_start); - # Scheduler globals start address - LONG(.scheduler_globals); - # Scheduler globals end size - SHORT(SIZEOF(.scheduler_globals)); - # Start of the scheduler's import table - LONG(.scheduler_import_start); - # Size of the scheduler import table - SHORT(.scheduler_import_end - .scheduler_import_start); - # Address of scheduler export table - LONG(.scheduler_export_table); - # Size of the scheduler export table - SHORT(.scheduler_export_table_end - .scheduler_export_table); - # No sealed objects - LONG(0); - SHORT(0); - - # sdk/core/loader/types.h:/PrivilegedCompartment - # Allocator code start address - LONG(.allocator_start); - # Allocator code end - SHORT(.allocator_end - .allocator_start); - # Allocator globals start address - LONG(.allocator_globals); - # Allocator globals end - SHORT(SIZEOF(.allocator_globals)); - # Start of the allocator's import table - LONG(.allocator_import_start); - # Size of the allocator import table - SHORT(.allocator_import_end - .allocator_import_start); - # Address of allocator export table - LONG(.allocator_export_table); - # Size of the allocator export table - SHORT(.allocator_export_table_end - .allocator_export_table); - # The allocator may have sealed objects - LONG(.allocator_sealed_objects); - SHORT(SIZEOF(.allocator_sealed_objects)); - - # sdk/core/loader/types.h:/PrivilegedCompartment - # Token server compartment header - # Code - LONG(.token_library_start); - SHORT(.token_library_end - .token_library_start); - # No data segment - LONG(0); - SHORT(0); - # Start of the token_library's import table - LONG(.token_library_import_start); - # Size of the token server import table - SHORT(.token_library_import_end - .token_library_import_start); - # Address of the token server export table - LONG(.token_library_export_table); - # Size of the token server export table - SHORT(.token_library_export_table_end - .token_library_export_table); - # No sealed objects - LONG(0); - SHORT(0); - - @software_revoker_header@ - - # sdk/core/loader/types.h:/is_magic_valid - # Magic number, used to detect mismatches between linker script and - # loader versions. - # New versions of this can be generated with: - # head /dev/random | shasum | cut -c 0-8 - LONG(0xca2b63de); - # Number of library headers. - SHORT(@library_count@); - # Number of compartment headers. - SHORT(@compartment_count@); - @compartment_headers@ - } - - # Thread configuration. This follows the compartment headers but is in a - # separate section to make auditing easier. - # This section holds a `class ThreadInfo` (loader/types.h) - .thread_config : - { - .thread_config_start = .; - # Number of threads - __thread_count = .; - SHORT(@thread_count@); - # The thread structures - @thread_headers@ - __compart_headers_end = .; - } - - - .loader_code : CAPALIGN - { - .loader_code_start = .; - */loader/boot.cc.o(.text .text.* .rodata .rodata.* .data.rel.ro); - } - .loader_code_end = .; - - .loader_data : CAPALIGN - { - .loader_data_start = .; - */loader/boot.cc.o(.data .data.* .sdata .sdata.* .sbss .sbss.* .bss .bss.*); - } - .loader_data_end = .; - - .library_export_tables : ALIGN(8) - { - .token_library_export_table = ALIGN(8); - */cheriot.token_library.library(.compartment_export_table); - .token_library_export_table_end = .; - - .switcher_export_table = ALIGN(8); - */switcher/entry.S.o(.compartment_export_table); - .switcher_export_table_end = .; - - @library_exports@ - } - + # We link either rwdata or rocode first depending on board config + INCLUDE @firmware_low_ldscript@ + INCLUDE @firmware_high_ldscript@ } + # No symbols should be exported VERSION { VERSION_1 { diff --git a/sdk/firmware.rocode.ldscript.in b/sdk/firmware.rocode.ldscript.in new file mode 100644 index 00000000..6adecbaf --- /dev/null +++ b/sdk/firmware.rocode.ldscript.in @@ -0,0 +1,73 @@ +. = @code_start@; +_start = .; + +.loader_start : +{ + *(.loader_start); +} + +.compartment_export_tables : ALIGN(8) +{ + # The scheduler and allocator's export tables are at the start. + .scheduler_export_table = .; + *.scheduler.compartment(.compartment_export_table); + .scheduler_export_table_end = .; + + .allocator_export_table = ALIGN(8); + */cheriot.allocator.compartment(.compartment_export_table); + .allocator_export_table_end = .; + + @compartment_exports@ +} + + +__compart_pccs = .; + +compartment_switcher_code : CAPALIGN +{ + .compartment_switcher_start = .; + */switcher/entry.S.o(.text); +} +.compartment_switcher_end = .; + +scheduler_code : CAPALIGN +{ + .scheduler_start = .; + *.scheduler.compartment(.compartment_sealing_keys); + .scheduler_import_start = .; + *.scheduler.compartment(.compartment_import_table); + .scheduler_import_end = .; + *.scheduler.compartment(.text .text.* .rodata .rodata.* .data.rel.ro); +} +.scheduler_end = .; + +allocator_code : CAPALIGN +{ + .allocator_start = .; + */cheriot.allocator.compartment(.compartment_sealing_keys); + .allocator_import_start = .; + */cheriot.allocator.compartment(.compartment_import_table); + .allocator_import_end = .; + allocator.compartment(.text .text.* .rodata .rodata.* .data.rel.ro); + */cheriot.allocator.compartment(.text .text.* .rodata .rodata.* .data.rel.ro); +} +.allocator_end = .; + + +token_library_code : CAPALIGN +{ + .token_library_start = .; + */cheriot.token_library.library(.compartment_sealing_keys); + .token_library_import_start = .; + */cheriot.token_library.library(.compartment_import_table); + .token_library_import_end = .; + token_library.library(.text .text.* .rodata .rodata.* .data.rel.ro); + */cheriot.token_library.library(.text .text.* .rodata .rodata.* .data.rel.ro); +} +.token_library_end = .; + + +@software_revoker_code@ + +@pcc_ld@ +__compart_pccs_end = .; diff --git a/sdk/firmware.rwdata.ldscript.in b/sdk/firmware.rwdata.ldscript.in new file mode 100644 index 00000000..299921d2 --- /dev/null +++ b/sdk/firmware.rwdata.ldscript.in @@ -0,0 +1,222 @@ +#data_start will either be . or some address depending on board config +. = @data_start@; +# Revoker scan region must be cap aligned +. = ALIGN(8); +__revoker_scan_start = .; +__stack_space_start = .; + +@thread_trusted_stacks@ + +@thread_stacks@ + +__stack_space_end = .; + +__compart_cgps = ALIGN(64); + +.scheduler_globals : CAPALIGN +{ + .scheduler_globals = .; + *.scheduler.compartment(.data .data.* .sdata .sdata.*); + .scheduler_bss_start = .; + *.scheduler.compartment(.sbss .sbss.* .bss .bss.*) +} +.scheduler_globals_end = .; + +.allocator_sealed_objects : CAPALIGN +{ + .allocator_sealed_objects = .; + */cheriot.allocator.compartment(.sealed_objects) +} +.allocator_sealed_objects_end = .; + +.allocator_globals : CAPALIGN +{ + .allocator_globals = .; + */cheriot.allocator.compartment(.data .data.* .sdata .sdata.*); + .allocator_bss_start = .; + */cheriot.allocator.compartment(.sbss .sbss.* .bss .bss.*); +} +.allocator_globals_end = .; + + +@software_revoker_globals@ + +@gdc_ld@ + +__compart_cgps_end = .; + +.sealed_objects : +{ + @sealed_objects@ +} + +__shared_objects_start = .; +@shared_objects@ +__shared_objects_end = .; + +. = ALIGN(64); + +# Everything after this point can be discarded after the loader has +# finished. +__export_mem_heap = @heap_start@; + +__cap_relocs : +{ + __cap_relocs = .; + # FIXME: This currently doesn't do anything. The linker creates this + # entire section. The linker script needs to be modified to create + # separate caprelocs sections for each section. + @cap_relocs@ +} +__cap_relocs_end = .; + +# Collect all compartment headers +.compartment_headers : ALIGN(4) +{ + __compart_headers = .; + # Loader code start + LONG(.loader_code_start); + # Loader code length + SHORT(.loader_code_end - .loader_code_start); + # Loader data start + LONG(.loader_data_start); + # Loader data length + SHORT(.loader_data_end - .loader_data_start); + + # Compartment switcher start address + LONG(.compartment_switcher_start); + # Compartment switcher end + SHORT(.compartment_switcher_end - .compartment_switcher_start); + # Cross-compartment call return path + SHORT(switcher_after_compartment_call - .compartment_switcher_start); + # Compartment switcher sealing keys + SHORT(compartment_switcher_sealing_key - .compartment_switcher_start); + # Switcher's copy of the scheduler's PCC. + SHORT(switcher_scheduler_entry_pcc - .compartment_switcher_start); + # Switcher's copy of the scheduler's CGP + SHORT(switcher_scheduler_entry_cgp - .compartment_switcher_start); + # Switcher's copy of the scheduler's CSP + SHORT(switcher_scheduler_entry_csp - .compartment_switcher_start); + # Address of switcher export table + LONG(.switcher_export_table); + # Size of the switcher export table + SHORT(.switcher_export_table_end - .switcher_export_table); + + # sdk/core/loader/types.h:/PrivilegedCompartment + # Scheduler code start address + LONG(.scheduler_start); + # Scheduler code end + SHORT(.scheduler_end - .scheduler_start); + # Scheduler globals start address + LONG(.scheduler_globals); + # Scheduler globals end size + SHORT(SIZEOF(.scheduler_globals)); + # Start of the scheduler's import table + LONG(.scheduler_import_start); + # Size of the scheduler import table + SHORT(.scheduler_import_end - .scheduler_import_start); + # Address of scheduler export table + LONG(.scheduler_export_table); + # Size of the scheduler export table + SHORT(.scheduler_export_table_end - .scheduler_export_table); + # No sealed objects + LONG(0); + SHORT(0); + + # sdk/core/loader/types.h:/PrivilegedCompartment + # Allocator code start address + LONG(.allocator_start); + # Allocator code end + SHORT(.allocator_end - .allocator_start); + # Allocator globals start address + LONG(.allocator_globals); + # Allocator globals end + SHORT(SIZEOF(.allocator_globals)); + # Start of the allocator's import table + LONG(.allocator_import_start); + # Size of the allocator import table + SHORT(.allocator_import_end - .allocator_import_start); + # Address of allocator export table + LONG(.allocator_export_table); + # Size of the allocator export table + SHORT(.allocator_export_table_end - .allocator_export_table); + # The allocator may have sealed objects + LONG(.allocator_sealed_objects); + SHORT(SIZEOF(.allocator_sealed_objects)); + + # sdk/core/loader/types.h:/PrivilegedCompartment + # Token server compartment header + # Code + LONG(.token_library_start); + SHORT(.token_library_end - .token_library_start); + # No data segment + LONG(0); + SHORT(0); + # Start of the token_library's import table + LONG(.token_library_import_start); + # Size of the token server import table + SHORT(.token_library_import_end - .token_library_import_start); + # Address of the token server export table + LONG(.token_library_export_table); + # Size of the token server export table + SHORT(.token_library_export_table_end - .token_library_export_table); + # No sealed objects + LONG(0); + SHORT(0); + + @software_revoker_header@ + + # sdk/core/loader/types.h:/is_magic_valid + # Magic number, used to detect mismatches between linker script and + # loader versions. + # New versions of this can be generated with: + # head /dev/random | shasum | cut -c 0-8 + LONG(0xca2b63de); + # Number of library headers. + SHORT(@library_count@); + # Number of compartment headers. + SHORT(@compartment_count@); + @compartment_headers@ +} + +# Thread configuration. This follows the compartment headers but is in a +# separate section to make auditing easier. +# This section holds a `class ThreadInfo` (loader/types.h) +.thread_config : +{ + .thread_config_start = .; + # Number of threads + __thread_count = .; + SHORT(@thread_count@); + # The thread structures + @thread_headers@ + __compart_headers_end = .; +} + +# The loader code is placed in the data sections so that it can be used as heap after the loader runs +.loader_code : CAPALIGN +{ + .loader_code_start = .; + */loader/boot.cc.o(.text .text.* .rodata .rodata.* .data.rel.ro); +} +.loader_code_end = .; + +.loader_data : CAPALIGN +{ + .loader_data_start = .; + */loader/boot.cc.o(.data .data.* .sdata .sdata.* .sbss .sbss.* .bss .bss.*); +} +.loader_data_end = .; + +.library_export_tables : ALIGN(8) +{ + .token_library_export_table = ALIGN(8); + */cheriot.token_library.library(.compartment_export_table); + .token_library_export_table_end = .; + + .switcher_export_table = ALIGN(8); + */switcher/entry.S.o(.compartment_export_table); + .switcher_export_table_end = .; + + @library_exports@ +} diff --git a/sdk/include/stdio.h b/sdk/include/stdio.h index 9448b5c3..884924e9 100644 --- a/sdk/include/stdio.h +++ b/sdk/include/stdio.h @@ -28,12 +28,16 @@ typedef volatile void FILE; #elif DEVICE_EXISTS(uart) # define stdout MMIO_CAPABILITY(void, uart) # define stdin MMIO_CAPABILITY(void uart) +#else +#error No device found for stdout and stderr #endif -#if DEVICE_EXISTS(uart1) +#if DEVICE_EXISTS(uart1) && !STDERR_TO_STDOUT # define stderr MMIO_CAPABILITY(void, uart1) #elif defined(stdout) # define stderr stdout +#else +#error No device found for stderr #endif int __cheri_libcall vfprintf(FILE *stream, const char *fmt, va_list ap); diff --git a/sdk/xmake.lua b/sdk/xmake.lua index 9e8002b4..c0186403 100644 --- a/sdk/xmake.lua +++ b/sdk/xmake.lua @@ -455,6 +455,7 @@ rule("firmware") -- This must be after load so that dependencies are resolved. after_load(function (target) import("core.base.json") + import("core.project.config") local function visit_all_dependencies(callback) visit_all_dependencies_of(target, callback) @@ -568,7 +569,22 @@ rule("firmware") mmio = format("__mmio_region_start = 0x%x;\n%s__mmio_region_end = 0x%x;\n__export_mem_heap_end = 0x%x;\n", mmio_start, mmio, mmio_end, board.heap["end"]) - local code_start = format("0x%x", board.instruction_memory.start) + local code_start = format("0x%x", board.instruction_memory.start); + -- Put the data either at the specified address if given, or directly after code + local data_start = board.data_memory and format("0x%x", board.data_memory.start) or '.'; + local rwdata_ldscript = path.join(config.buildir(), target:name() .. "-firmware.rwdata.ldscript") + local rocode_ldscript = path.join(config.buildir(), target:name() .. "-firmware.rocode.ldscript") + if not board.data_memory or (board.instruction_memory.start < board.data_memory.start) then + -- If we're not explicilty given a data address or it's lower than the code address + -- then code needs to go first in the linker script. + firmware_low_ldscript = rocode_ldscript + firmware_high_ldscript = rwdata_ldscript + else + -- Otherwise the data is at a lower address than code (e.g. Sonata with SRAM and hyperram) + -- so it needs to go first. + firmware_low_ldscript = rwdata_ldscript; + firmware_high_ldscript = rocode_ldscript; + end -- Set the start of memory that can be revoked. -- By default, this is the start of code memory but it can be @@ -762,8 +778,11 @@ rule("firmware") software_revoker_header="", sealed_objects="", mmio=mmio, + data_start=data_start, code_start=code_start, heap_start=heap_start, + firmware_low_ldscript=firmware_low_ldscript, + firmware_high_ldscript=firmware_high_ldscript, thread_count=#(threads), thread_headers=thread_headers, thread_trusted_stacks=thread_trusted_stacks, @@ -894,7 +913,9 @@ rule("firmware") import("core.project.config") -- Get a specified linker script, or set the default to the compartment -- linker script. - local linkerscript = path.join(config.buildir(), target:name() .. "-firmware.ldscript") + local linkerscript1 = path.join(config.buildir(), target:name() .. "-firmware.ldscript") + local linkerscript2 = path.join(config.buildir(), target:name() .. "-firmware.rocode.ldscript") + local linkerscript3 = path.join(config.buildir(), target:name() .. "-firmware.rwdata.ldscript") -- Link using the firmware's linker script. batchcmds:show_progress(opt.progress, "linking firmware " .. target:targetfile()) batchcmds:mkdir(target:targetdir()) @@ -907,11 +928,11 @@ rule("firmware") table.insert(objects, dep:targetfile()) end end) - batchcmds:vrunv(target:tool("ld"), table.join({"-n", "--script=" .. linkerscript, "--relax", "-o", target:targetfile(), "--compartment-report=" .. target:targetfile() .. ".json" }, objects), opt) + batchcmds:vrunv(target:tool("ld"), table.join({"-n", "--script=" .. linkerscript1, "--relax", "-o", target:targetfile(), "--compartment-report=" .. target:targetfile() .. ".json" }, objects), opt) batchcmds:show_progress(opt.progress, "Creating firmware report " .. target:targetfile() .. ".json") batchcmds:show_progress(opt.progress, "Creating firmware dump " .. target:targetfile() .. ".dump") batchcmds:vexecv(target:tool("objdump"), {"-glxsdrS", "--demangle", target:targetfile()}, table.join(opt, {stdout = target:targetfile() .. ".dump"})) - batchcmds:add_depfiles(linkerscript) + batchcmds:add_depfiles(linkerscript1, linkerscript2, linkerscript3) batchcmds:add_depfiles(objects) end) @@ -980,6 +1001,8 @@ function firmware(name) -- The firmware linker script will be populated based on the set of -- compartments. add_configfiles(path.join(scriptdir, "firmware.ldscript.in"), {pattern = "@(.-)@", filename = name .. "-firmware.ldscript"}) + add_configfiles(path.join(scriptdir, "firmware.rocode.ldscript.in"), {pattern = "@(.-)@", filename = name .. "-firmware.rocode.ldscript"}) + add_configfiles(path.join(scriptdir, "firmware.rwdata.ldscript.in"), {pattern = "@(.-)@", filename = name .. "-firmware.rwdata.ldscript"}) end -- Helper to create a library.