Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
ae6f1b1
fix(sync): reuse semaphore and mutex storage only through destroy
teo1747 Oct 27, 2026
240fbda
docs(obj): record ADR-045 and the object lifecycle review
teo1747 Oct 27, 2026
f6e3bfb
Merge branch 'chore/clangd-clean' into fix/sync-storage-reuse
teo1747 Oct 27, 2026
299204d
docs(obj): add the local RV32, AVR and EmbSIM runs to the lifecycle r…
teo1747 Oct 27, 2026
c61339d
docs(m2-01): close the seed-5 report as not reproducible
teo1747 Oct 27, 2026
fb95367
tools(footprint): take the TCB size from the layout probe
teo1747 Oct 27, 2026
db96a6b
perf(tiny): allocate only the prefix of the idle control block
teo1747 Oct 27, 2026
f9a864f
style(list): format the static initializer as clang-format 18.1.3 does
teo1747 Oct 27, 2026
e91be91
Merge branch 'fix/sync-storage-reuse' into docs/m2-01-seed5-disposition
teo1747 Oct 27, 2026
19aedbd
Merge branch 'docs/m2-01-seed5-disposition' into tools/footprint-tcb-…
teo1747 Oct 27, 2026
1ce4546
Merge branch 'tools/footprint-tcb-metric' into perf/tiny-slim-idle
teo1747 Oct 27, 2026
7abc439
perf(tiny): drop the idle table slot, bind the fault hook at link time
teo1747 Oct 27, 2026
5925c17
docs(specs): correct five contradictions in existing contracts
teo1747 Oct 27, 2026
47227e6
feat(notify): unbind, and a bound thread outlives its bindings (M2-03)
teo1747 Oct 27, 2026
b823fbb
feat(evidence): report and collect individual conformance cases (M2-04)
teo1747 Oct 27, 2026
0810d64
docs(bounds): inventory every non-constant API cost (M2-04)
teo1747 Oct 27, 2026
a78f8f7
feat(sync): event flags (M2-05)
teo1747 Oct 27, 2026
6264cda
feat(sync): condition variables (M2-06)
teo1747 Oct 27, 2026
db76296
model(msgq): message queues ahead of the implementation (M2-07)
teo1747 Oct 27, 2026
0e8d6ff
feat(ipc): copy-by-value message queues (M2-07)
teo1747 Oct 27, 2026
7f6b3aa
fix(toolchain): include the IPC objects in the native ABI probe (M2-07)
teo1747 Oct 27, 2026
11ff856
feat(work): work queues on kernel threads (M2-08)
teo1747 Oct 27, 2026
31ef680
fix(riscv): keep the reset code out of the -ffunction-sections namespace
teo1747 Oct 27, 2026
922f6c7
feat(timer): software timers in their own deadline list (M2-09)
teo1747 Oct 27, 2026
34a7c7c
feat(work): delayed work over internal timers (M2-09)
teo1747 Oct 30, 2026
bb60e2f
test(m2-10): combined scenarios, a coverage preset and the campaign r…
teo1747 Oct 30, 2026
77768fb
fix(sched): raising a ready thread above the running one preempts at …
teo1747 Oct 30, 2026
617e1db
fix(native): keep registration tables dense under Mach-O AddressSanit…
teo1747 Oct 30, 2026
b04cf96
fix(model): resolve campaign runner paths before naming them
teo1747 Oct 30, 2026
f563ef5
fix(thread): preempt after a priority raise without mutexes too
teo1747 Oct 30, 2026
2a29b1b
docs(m2-10): integrated campaign evidence and report
teo1747 Oct 30, 2026
2bb7f90
docs(m2-11): M2 exit review
teo1747 Oct 30, 2026
db6d36f
docs(m2-11): record the final CI state
teo1747 Oct 30, 2026
8d2cb2a
docs(m2): record the accepted M2 contract decisions
teo1747 Oct 30, 2026
d84b56e
docs(requirements): migrate the scheduler and memory groups (M2 lefto…
teo1747 Oct 30, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
92 changes: 91 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ jobs:
strategy:
fail-fast: false
matrix:
preset: [native-gcc, native-clang, native-release, native-tiny, native-periodic, native-asan, native-tsan]
preset: [native-gcc, native-clang, native-release, native-tiny, native-periodic, native-asan, native-tsan, native-coverage]
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Install tools
Expand All @@ -39,6 +39,25 @@ jobs:
run: cmake --build --preset ${{ matrix.preset }}
- name: Test
run: ctest --preset ${{ matrix.preset }} --output-on-failure --no-tests=error
- name: Coverage report
if: matrix.preset == 'native-coverage'
run: python3 -I tools/coverage/report.py --json coverage.json --markdown coverage.md && cat coverage.md >> "$GITHUB_STEP_SUMMARY"
- name: Upload coverage
if: matrix.preset == 'native-coverage'
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
with:
name: coverage
path: coverage.*
- name: Collect case evidence
if: always()
run: python3 -I tools/evidence/collect.py --build build/${{ matrix.preset }} --preset ${{ matrix.preset }} --out case-evidence-${{ matrix.preset }}.json
- name: Upload case evidence
if: always()
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
with:
name: case-evidence-${{ matrix.preset }}
path: case-evidence-${{ matrix.preset }}.json
if-no-files-found: warn
- name: Numeric fault IDs without location strings
if: matrix.preset == 'native-gcc'
run: |
Expand Down Expand Up @@ -73,6 +92,16 @@ jobs:
run: cmake --build --preset ${{ matrix.preset }}
- name: Test under QEMU
run: ctest --preset ${{ matrix.preset }} --output-on-failure --no-tests=error --verbose
- name: Collect case evidence
if: always()
run: python3 -I tools/evidence/collect.py --build build/${{ matrix.preset }} --preset ${{ matrix.preset }} --out case-evidence-${{ matrix.preset }}.json
- name: Upload case evidence
if: always()
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
with:
name: case-evidence-${{ matrix.preset }}
path: case-evidence-${{ matrix.preset }}.json
if-no-files-found: warn
- name: Single-level non-nesting IRQ conformance
if: matrix.preset == 'cm3-an385'
run: |
Expand All @@ -86,6 +115,7 @@ jobs:
python3 -I tools/footprint/footprint.py \
build/${{ matrix.preset }}/samples/first_execution/first_execution.elf.map \
--elf build/${{ matrix.preset }}/samples/first_execution/first_execution.elf --nm arm-none-eabi-nm \
--storage-h build/${{ matrix.preset }}/generated/include/emb/storage.h \
--title "${{ matrix.preset }}" --json footprint-${{ matrix.preset }}.json | tee footprint-${{ matrix.preset }}.md
- uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
with:
Expand All @@ -110,11 +140,22 @@ jobs:
run: cmake --build --preset ${{ matrix.preset }}
- name: Test under QEMU
run: ctest --preset ${{ matrix.preset }} --output-on-failure --no-tests=error
- name: Collect case evidence
if: always()
run: python3 -I tools/evidence/collect.py --build build/${{ matrix.preset }} --preset ${{ matrix.preset }} --out case-evidence-${{ matrix.preset }}.json
- name: Upload case evidence
if: always()
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
with:
name: case-evidence-${{ matrix.preset }}
path: case-evidence-${{ matrix.preset }}.json
if-no-files-found: warn
- name: Footprint report
run: |
python3 -I tools/footprint/footprint.py \
build/${{ matrix.preset }}/samples/first_execution/first_execution.elf.map \
--elf build/${{ matrix.preset }}/samples/first_execution/first_execution.elf --nm riscv64-unknown-elf-nm \
--storage-h build/${{ matrix.preset }}/generated/include/emb/storage.h \
--title "${{ matrix.preset }}" --json footprint-${{ matrix.preset }}.json | tee footprint-${{ matrix.preset }}.md
- uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
with:
Expand Down Expand Up @@ -145,11 +186,22 @@ jobs:
run: cmake --build --preset ${{ matrix.preset }}
- name: Test under QEMU
run: ctest --preset ${{ matrix.preset }} --output-on-failure --no-tests=error
- name: Collect case evidence
if: always()
run: python3 -I tools/evidence/collect.py --build build/${{ matrix.preset }} --preset ${{ matrix.preset }} --out case-evidence-${{ matrix.preset }}.json
- name: Upload case evidence
if: always()
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
with:
name: case-evidence-${{ matrix.preset }}
path: case-evidence-${{ matrix.preset }}.json
if-no-files-found: warn
- name: Footprint
run: |
python3 -I tools/footprint/footprint.py \
build/${{ matrix.preset }}/samples/${{ matrix.sample }}/${{ matrix.sample }}.elf.map \
--elf build/${{ matrix.preset }}/samples/${{ matrix.sample }}/${{ matrix.sample }}.elf --nm avr-nm \
--storage-h build/${{ matrix.preset }}/generated/include/emb/storage.h \
--title "${{ matrix.preset }}" --json footprint-${{ matrix.preset }}.json \
--thresholds tools/footprint/thresholds-${{ matrix.preset }}.json | tee footprint-${{ matrix.preset }}.md
- uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
Expand Down Expand Up @@ -181,6 +233,14 @@ jobs:
run: python3 -I -m unittest discover -s tools/toolchain -p 'test_*.py' -v
- name: ESP32-C3 image format
run: python3 -I -m unittest discover -s tools/esp -p 'test_*.py' -v
- name: Footprint report tool
run: python3 -I -m unittest discover -s tools/footprint -p 'test_*.py' -v
- name: Case evidence tools
run: python3 -I -m unittest discover -s tools/evidence -p 'test_*.py' -v
- name: Coverage report tool tests
run: python3 -I -m unittest discover -s tools/coverage -p 'test_*.py' -v
- name: Resource-bound inventory covers every non-constant cost
run: python3 -I tools/evidence/check_bounds.py
- name: Configuration tool self-check
run: |
python3 -I tools/kconfig/embconfig.py --kconfig Kconfig --manifest arch/native/arch.yaml \
Expand Down Expand Up @@ -221,6 +281,16 @@ jobs:
run: cmake --build --preset avr-uno-embsim
- name: Test on EmbSIM
run: ctest --preset avr-uno-embsim --output-on-failure --no-tests=error
- name: Collect case evidence
if: always()
run: python3 -I tools/evidence/collect.py --build build/avr-uno-embsim --preset avr-uno-embsim --out case-evidence-avr-uno-embsim.json
- name: Upload case evidence
if: always()
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
with:
name: case-evidence-avr-uno-embsim
path: case-evidence-avr-uno-embsim.json
if-no-files-found: warn

cm4-embsim:
# the conformance suite on EmbSIM's NUCLEO-F446RE (SIM-002), built as for the board
Expand Down Expand Up @@ -250,6 +320,16 @@ jobs:
run: cmake --build --preset cm4-nucleo-embsim
- name: Test on EmbSIM
run: ctest --preset cm4-nucleo-embsim --output-on-failure --no-tests=error --verbose
- name: Collect case evidence
if: always()
run: python3 -I tools/evidence/collect.py --build build/cm4-nucleo-embsim --preset cm4-nucleo-embsim --out case-evidence-cm4-nucleo-embsim.json
- name: Upload case evidence
if: always()
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
with:
name: case-evidence-cm4-nucleo-embsim
path: case-evidence-cm4-nucleo-embsim.json
if-no-files-found: warn

rv32-embsim:
# the conformance suite on EmbSIM's ESP32-C3-DevKitM-1 (SIM-002): each image turned into the
Expand Down Expand Up @@ -280,6 +360,16 @@ jobs:
run: cmake --build --preset rv32-c3-embsim
- name: Test on EmbSIM
run: ctest --preset rv32-c3-embsim --output-on-failure --no-tests=error
- name: Collect case evidence
if: always()
run: python3 -I tools/evidence/collect.py --build build/rv32-c3-embsim --preset rv32-c3-embsim --out case-evidence-rv32-c3-embsim.json
- name: Upload case evidence
if: always()
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
with:
name: case-evidence-rv32-c3-embsim
path: case-evidence-rv32-c3-embsim.json
if-no-files-found: warn

merge_gate:
name: CI merge gate
Expand Down
45 changes: 45 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,49 @@ User-visible changes are recorded here. There are no released versions or releas

## Unreleased

### Changed

- The tiny thread table has no slot for idle, and `CONFIG_EMB_FAULT_HOOK_RUNTIME=n` binds the fault hook at link time through an application-defined `emb_fault_hook()` (weak empty default), keeping no hook pointer in RAM. The `footprint_t1` reference configuration uses it; AVR `footprint_t1` kernel static RAM is 39 bytes and its gate is lowered from 64 to that value.

- The idle context is no longer reachable through a thread handle, and `emb_thread_self()` returns `EMB_HANDLE_NULL` in it (KRN-THR-026, ADR-050). On the tiny profile without an idle thread only the prefix of its control block is allocated: AVR `footprint_t1` kernel static RAM drops from 64 to 43 bytes.

- The historical M2-01 `cancel_waiter_disinherits` seed-5 report is closed as not reproducible (input unavailable, cause unknown) after bounded triage: not fixed, not classified, still listed among the known limits, with named reopen triggers. `timing-and-evidence.md` defines that disposition.

- `emb_sem_init()` and `emb_mutex_init()` refuse storage that still holds an active object of their type (fault in checked builds, `EMB_EBUSY` in release) instead of overwriting it, when `CONFIG_EMB_OBJ_LIST` is on (default except on the tiny profile). Storage is reused only through destroy. Semaphore and mutex storage grows by one list node where the option is on. KRN-OBJ-007 now specifies `EMB_EBUSY` instead of `EMB_EEXIST` (ADR-045).

### Added

- The M2 contract decisions are accepted: amendments A29 to A61 and ADR-045 to ADR-048 and ADR-050 (project-owner review, 2026-10-31).

- The M2 exit review (`docs/engineering/m2-exit-review.md`): every checklist item with its pull requests and evidence, the reconciliation of APIs, configuration, model and requirements, the defects found, and the remaining M3a hardware work.

- The M2-10 integrated campaign: combined model scenarios across primitives, a `native-coverage` preset with `tools/coverage/report.py` (statement and branch coverage, run in CI), and `tools/model/campaign.py`, whose 158,800-run summaries are archived under `tools/model/evidence/m2-10/` (see `docs/engineering/m2-10-campaign.md`).

- Delayed work (`emb_dwork_t`, M2-09, KRN-WQ-003/007): an item that an internal interrupt-context timer submits to a work queue after a delay or at an instant, with idempotent schedule, reschedule, cancel reporting a stopped delay or removed item as pending, and `cancel_sync`. The queue cannot be destroyed while a delay names it. The reference model, the differential bridge and the work queue conformance suite cover it.

- Software timers (`CONFIG_EMB_TIMER`, `include/emb/timer.h`, M2-09): one-shot and periodic timers whose callbacks run on a named work queue or, with `EMB_TIMER_ISR_CONTEXT`, in the expiry interrupt. Periodic timers re-arm from the previous deadline, skip missed periods in closed form and count them with coalesced callbacks as overruns; `stop` reports the callback's state and `stop_sync` waits for it. Timers have their own deadline list, merged with thread timeouts at expiry (ADR-047). The reference model, the differential bridge and a conformance suite cover them; they require the list scheduler, so the tiny profile has none in this milestone.

- The RISC-V reset code is in its own `.text.embn_rv_reset` section, so an application function named `reset` built with `-ffunction-sections` can no longer take the reset vector's place.

- Work queues (`CONFIG_EMB_WORKQ`, `include/emb/work.h`, M2-08): a kernel thread per queue runs submitted items one at a time in FIFO order. Submit is O(1) and ISR-safe, idempotent while queued and kept while running; cancel reports the state, `cancel_sync` and `flush` wait for completion, and destroy joins the queue's thread. The system work queue (`CONFIG_EMB_SYSTEM_WORKQ`) is linked only into images that reference `emb_workq_system()`. The reference model, the differential bridge and a conformance suite cover them; they require the list scheduler, so the tiny profile has none in this milestone.

- Message queues (`CONFIG_EMB_MSGQ`, `include/emb/msgq.h`, M2-07): fixed-size items copied by value through a caller-provided ring declared with `EMB_MSGQ_RING()`, with direct hand-off to a waiting receiver, slot hand-off from a waiting sender, `send_front`, `peek`, `count` and `free`, `EMB_NO_WAIT` calls from interrupts, timeouts and absolute deadlines, cancellation, destroy with ABORT_WAITERS, and a receive-side notification binding. Items are bounded by `CONFIG_EMB_MSGQ_MAX_ITEM` (64 bytes, 16 on tiny, where `CONFIG_EMB_IPC_SMALL` keeps 8-bit counts). The reference model, the differential bridge and a conformance suite cover them; they are off in the tiny `footprint_t1` reference configuration.

- The reference model covers copy-by-value message queues ahead of their implementation (KRN-IPC-022, M2-07): send, send_front, receive and peek, ISR calls with `EMB_NO_WAIT`, hand-off to a waiting receiver, refill from a waiting sender, destroy, and the empty-to-nonempty binding, checking in every explored state that each accepted item is received once, still stored or dropped by destroy, and that no side waits while the other could proceed.

- Condition variables (`CONFIG_EMB_COND`, `include/emb/cond.h`, M2-06): an atomic enqueue-and-release wait, signal and broadcast, and a mandatory, non-cancelable relock on every result, with `EMB_EOWNERDEAD` and relock failures taking precedence. The reference model, the differential bridge and a conformance suite cover them; they are off on the tiny profile.

- Event flags (`CONFIG_EMB_EVENT`, `include/emb/event.h`, M2-05): ANY/ALL waits with optional CLEAR, deterministic consumption in queue order, ISR-safe set and clear, timeouts, cancellation, destroy with ABORT_WAITERS, and notification binding with unbind. The reference model, the differential bridge and a conformance suite cover them; they are off in the tiny `footprint_t1` reference configuration.

- A reviewed resource-bound inventory (`docs/engineering/resource-bounds.json` and its page) for every cost input in the public `@time` annotations, with `tools/evidence/check_bounds.py` failing CI when a non-constant cost has no entry (M2-04).

- Executed case evidence (M2-04): conformance runs print each case's requirement citations and outcome with assertion and skip counts; `tools/evidence/collect.py` gathers them from the CTest log of any port, CI uploads them per configuration, and `tools/evidence/matrix.py` derives the requirement-by-configuration matrix from executed, asserting cases only.

- `emb_sem_unbind_notify()` (KRN-NOTIF-013). A thread counts the bindings that name it, and `emb_thread_destroy()` refuses it while any does; `emb_sem_bind_notify()` refuses terminated (`EMB_ESTATE`) and kernel (`EMB_EPERM`) targets (KRN-NOTIF-014, ADR-046). The reference model and the differential bridge cover bind, unbind and thread destroy.

- `CONFIG_EMB_OBJ_LIST`: per-type lists of active semaphores and mutexes (KRN-OBJ-011).
- A `.clangd` and exported `compile_commands.json` for editor support; `.clang-tidy` disables, with reasons, the checks that contradict the coding standard.

- Stable numeric IDs in public API misuse fault records, a generated header and downloadable decoder map, with checked-in assignments and compatibility checks. Shared helpers retain the public caller ID and location strings remain optional.

- The Arduino Uno conformance suite on EmbSIM's simulated Uno (`avr-uno-embsim` preset,
Expand Down Expand Up @@ -38,6 +79,10 @@ User-visible changes are recorded here. There are no released versions or releas

### Fixed

- Raising a ready thread's priority above the running thread with `emb_thread_set_priority()` now preempts at once; before, the caller ran on until its next block or yield (found by the M2-10 campaign).

- The conformance suites run under AddressSanitizer on macOS: registration-table entries no longer get Mach-O redzones that the table walk read as entries.

- Thread diagnostic IDs remain stable across priority changes on tiny and unique among live objects on every profile. IDs are released only by successful destroy; exhaustion returns `EMB_ENOMEM` without partial construction.

- Generic IRQ priorities now increase with urgency on Cortex-M, with board-derived bounds and validation before register writes; fixed-level native/AVR/RV32 reject nonzero levels. SysTick defaults to highest kernel-aware urgency. Raw kernel-independent vectors remain unsupported.
Expand Down
22 changes: 22 additions & 0 deletions CMakePresets.json
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,17 @@
"EMB_PROFILE": "base"
}
},
{
"name": "native-coverage",
"displayName": "native, GCC, gcov coverage, checked",
"generator": "Ninja",
"binaryDir": "${sourceDir}/build/native-coverage",
"toolchainFile": "${sourceDir}/cmake/toolchains/native-coverage.cmake",
"cacheVariables": {
"EMB_BOARD": "native",
"EMB_PROFILE": "base"
}
},
{
"name": "avr-uno",
"displayName": "Arduino Uno, avr-gcc, tiny profile, checked",
Expand Down Expand Up @@ -283,6 +294,10 @@
"name": "native-tsan",
"configurePreset": "native-tsan"
},
{
"name": "native-coverage",
"configurePreset": "native-coverage"
},
{
"name": "avr-uno",
"configurePreset": "avr-uno"
Expand Down Expand Up @@ -402,6 +417,13 @@
"outputOnFailure": true
}
},
{
"name": "native-coverage",
"configurePreset": "native-coverage",
"output": {
"outputOnFailure": true
}
},
{
"name": "avr-uno",
"configurePreset": "avr-uno",
Expand Down
7 changes: 7 additions & 0 deletions arch/native/native_port.c
Original file line number Diff line number Diff line change
Expand Up @@ -565,8 +565,15 @@ void emb_arch_breakpoint(void)
{
}

#ifdef EMB_NATIVE_COVERAGE
void __gcov_dump(void); /* the gcov runtime: _exit() skips its exit-time flush */
#endif

void emb_native_exit(int code)
{
(void)fflush(NULL);
#ifdef EMB_NATIVE_COVERAGE
__gcov_dump();
#endif
_exit(code);
}
2 changes: 1 addition & 1 deletion arch/riscv/rv_switch.S
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ embn_rv_vectors:
/* Reset (QEMU virt with -bios none starts here in machine mode; the ESP32-C3's boot ROM
* jumps here once it has loaded the image): interrupts off, the
* stack, .bss cleared, then C. Everything is loaded in RAM, so .data needs no copy. */
.section .text.reset, "ax"
.section .text.embn_rv_reset, "ax" /* the one function this name can belong to */
.globl embn_rv_reset
.align 2
embn_rv_reset:
Expand Down
2 changes: 1 addition & 1 deletion boards/espressif/esp32c3_devkitm1/esp32c3.ld
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ SECTIONS
{
.text : {
KEEP(*(.text.embn_rv_vectors))
KEEP(*(.text.reset))
KEEP(*(.text.embn_rv_reset))
*(.text .text.*)
} > IRAM

Expand Down
2 changes: 1 addition & 1 deletion boards/qemu/riscv32_virt/riscv32_virt.ld
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ MEMORY
SECTIONS
{
.text : {
KEEP(*(.text.reset))
KEEP(*(.text.embn_rv_reset))
*(.text .text.*)
} > RAM

Expand Down
Loading