diff --git a/.github/workflows/package_core.yml b/.github/workflows/package_core.yml index 2fbdbf6e..62be1487 100644 --- a/.github/workflows/package_core.yml +++ b/.github/workflows/package_core.yml @@ -29,7 +29,7 @@ jobs: - name: Initialize Zephyr environment run: | - ./extra/bootstrap.sh -o=--filter=tree:0 + yes | ./extra/bootstrap.sh -o=--filter=tree:0 echo "CORE_TAG=$(git describe --always)" >> "$GITHUB_ENV" echo "CORE_ARTIFACT=ArduinoCore-zephyr-$(git describe --always)" >> "$GITHUB_ENV" echo "BOARD_VARIANTS=$(extra/get_board_details.sh | jq -cr 'sort_by(.variant)')" >> "$GITHUB_ENV" diff --git a/.gitignore b/.gitignore index 09974049..5c3ff0e6 100644 --- a/.gitignore +++ b/.gitignore @@ -6,4 +6,5 @@ llext-edk/ cflags.txt cxxflags.txt includes.txt -provides.ld +syms-dynamic.ld +syms-static.ld diff --git a/boards.txt b/boards.txt index b36a45f8..ff52cb7e 100644 --- a/boards.txt +++ b/boards.txt @@ -1,5 +1,7 @@ menu.debug=Debug -menu.mode=Mode +menu.link_mode=Link mode + +########################################################################################## giga.name=Arduino Giga R1 giga.build.core=arduino @@ -19,14 +21,12 @@ giga.build.variant=arduino_giga_r1_stm32h747xx_m7 giga.build.mcu=cortex-m7 giga.build.fpu=-mfpu=fpv5-d16 giga.build.architecture=cortex-m7 -giga.compiler.zephyr.arch.define=-DCORE_CM7 giga.build.float-abi=-mfloat-abi=softfp giga.build.extra_flags= giga.build.postbuild.cmd="{tools.imgtool.path}/{tools.imgtool.cmd}" exit giga.build.architecture=cortex-m7 giga.build.board=ARDUINO_GIGA -giga.compiler.zephyr= giga.vid.0=0x2341 giga.pid.0=0x0066 giga.upload_port.0.vid=0x2341 @@ -85,14 +85,12 @@ nano33ble.build.variant=arduino_nano_33_ble_nrf52840_sense nano33ble.build.mcu=cortex-m4 nano33ble.build.fpu=-mfpu=fpv4-sp-d16 nano33ble.build.architecture=cortex-m4 -nano33ble.compiler.zephyr.arch.define= nano33ble.build.float-abi=-mfloat-abi=hard nano33ble.build.extra_flags= nano33ble.build.postbuild.cmd="{tools.imgtool.path}/{tools.imgtool.cmd}" exit nano33ble.build.architecture=cortex-m4 nano33ble.build.board=ARDUINO_NANO33BLE -nano33ble.compiler.zephyr= nano33ble.vid.0=0x2341 nano33ble.pid.0=0x035a nano33ble.upload_port.0.vid=0x2341 @@ -149,19 +147,16 @@ ek_ra8d1.build.variant=ek_ra8d1_r7fa8d1bhecbd ek_ra8d1.build.mcu=cortex-m85+nomve ek_ra8d1.build.fpu=-mfpu=fpv5-d16 ek_ra8d1.build.architecture=cortex-m85+nomve -ek_ra8d1.compiler.zephyr.arch.define= ek_ra8d1.build.float-abi=-mfloat-abi=hard ek_ra8d1.build.extra_flags= ek_ra8d1.build.postbuild.cmd="{tools.imgtool.path}/{tools.imgtool.cmd}" exit ek_ra8d1.build.architecture=cortex-m85+nomve ek_ra8d1.build.board=EK_RA8D1 -ek_ra8d1.compiler.zephyr.arch.define= #ek_ra8d1.recipe.hooks.objcopy.postobjcopy.4.pattern=cp {build.variant.path}/flasher.jlink "{build.path}/flasher.jlink" #ek_ra8d1.recipe.hooks.objcopy.postobjcopy.5.pattern=sed -i 's|SKETCH|"{build.path}/{build.project_name}.llext.dfu.bin"|g' "{build.path}/flasher.jlink" -ek_ra8d1.compiler.zephyr= ek_ra8d1.vid.0=0x2341 ek_ra8d1.pid.0=0x0077 ek_ra8d1.upload_port.0.vid=0x2341 @@ -208,14 +203,11 @@ frdm_mcxn947.build.variant=frdm_mcxn947_mcxn947_cpu0 frdm_mcxn947.build.mcu=cortex-m33 frdm_mcxn947.build.fpu=-mfpu=fpv5-sp-d16 frdm_mcxn947.build.architecture=cortex-m33 -frdm_mcxn947.compiler.zephyr.arch.define= frdm_mcxn947.build.float-abi=-mfloat-abi=hard frdm_mcxn947.build.extra_flags= frdm_mcxn947.build.postbuild.cmd="{tools.imgtool.path}/{tools.imgtool.cmd}" exit frdm_mcxn947.build.board=FRDM_MCXN947 -frdm_mcxn947.compiler.zephyr.arch.define= -frdm_mcxn947.compiler.zephyr= frdm_mcxn947.vid.0=0x1fc9 frdm_mcxn947.pid.0=0x0143 frdm_mcxn947.upload_port.0.vid=0x1fc9 @@ -262,14 +254,12 @@ portentah7.build.variant=arduino_portenta_h7_stm32h747xx_m7 portentah7.build.mcu=cortex-m7 portentah7.build.fpu=-mfpu=fpv5-d16 portentah7.build.architecture=cortex-m7 -portentah7.compiler.zephyr.arch.define=-DCORE_CM7 portentah7.build.float-abi=-mfloat-abi=softfp portentah7.build.extra_flags= portentah7.build.postbuild.cmd="{tools.imgtool.path}/{tools.imgtool.cmd}" exit portentah7.build.architecture=cortex-m7 portentah7.build.board=ARDUINO_PORTENTA_H7 -portentah7.compiler.zephyr= portentah7.vid.0=0x2341 portentah7.pid.0=0x005b portentah7.upload_port.0.vid=0x2341 @@ -328,14 +318,11 @@ frdm_rw612.build.variant=frdm_rw612_rw612 frdm_rw612.build.mcu=cortex-m33+nodsp frdm_rw612.build.fpu=-mfpu=fpv5-sp-d16 frdm_rw612.build.architecture=cortex-m33+nodsp -frdm_rw612.compiler.zephyr.arch.define= frdm_rw612.build.float-abi=-mfloat-abi=hard frdm_rw612.build.extra_flags= frdm_rw612.build.postbuild.cmd="{tools.imgtool.path}/{tools.imgtool.cmd}" exit frdm_rw612.build.board=FRDM_RW612 -frdm_rw612.compiler.zephyr.arch.define= -frdm_rw612.compiler.zephyr= frdm_rw612.vid.0=0x1fc9 frdm_rw612.pid.0=0x0143 frdm_rw612.upload_port.0.vid=0x1fc9 @@ -381,14 +368,12 @@ niclasense.build.variant=arduino_nicla_sense_me_nrf52832 niclasense.build.mcu=cortex-m4 niclasense.build.fpu=-mfpu=fpv4-sp-d16 niclasense.build.architecture=cortex-m4 -niclasense.compiler.zephyr.arch.define= niclasense.build.float-abi=-mfloat-abi=hard niclasense.build.extra_flags= niclasense.build.postbuild.cmd="{tools.imgtool.path}/{tools.imgtool.cmd}" exit niclasense.build.architecture=cortex-m4 niclasense.build.board=ARDUINO_NICLA_SENSE_ME -niclasense.compiler.zephyr= niclasense.vid.0=0x2341 niclasense.pid.0=0x0360 niclasense.upload_port.0.vid=0x2341 @@ -440,19 +425,12 @@ portentac33.build.compiler_path={runtime.tools.arm-zephyr-eabi-0.16.8.path}/bin/ portentac33.menu.debug.false=Standard portentac33.menu.debug.true=Debug +portentac33.menu.debug.true.build.zsk_args.debug=-debug -portentac33.menu.debug.false.postbuild_debug= -portentac33.menu.debug.true.postbuild_debug=-debug - -portentac33.menu.mode.llext=llext -portentac33.menu.mode.linked=linked - -portentac33.menu.mode.linked.build.extra_ldflags=-lc -lm -lgcc -L{build.variant.path} -Wl,--wrap=random -Wl,--wrap=calloc -Wl,--wrap=free -Wl,--wrap=malloc -Wl,--wrap=realloc -portentac33.menu.mode.linked.build.llext_link_flags= -portentac33.menu.mode.linked.build.suffix=_linked -portentac33.menu.mode.linked.build.ldscript={runtime.platform.path}/variants/_linked/linker_script.ld -portentac33.menu.mode.linked.upload.extension=bin-zsk.bin -portentac33.menu.mode.linked.postbuild_mode=-prelinked +portentac33.menu.link_mode.dynamic=Dynamic +portentac33.menu.link_mode.static=Static +portentac33.menu.link_mode.static.build.link_mode=static +portentac33.menu.link_mode.static.upload.extension=bin-zsk.bin portentac33.build.zephyr_target=arduino_portenta_c33 portentac33.build.zephyr_args= @@ -461,14 +439,11 @@ portentac33.build.variant=arduino_portenta_c33_r7fa6m5bh3cfc portentac33.build.mcu=cortex-m33 portentac33.build.fpu=-mfpu=fpv5-sp-d16 portentac33.build.architecture=cortex-m33 -portentac33.compiler.zephyr.arch.define= portentac33.build.float-abi=-mfloat-abi=hard portentac33.build.extra_flags= portentac33.build.postbuild.cmd="{tools.imgtool.path}/{tools.imgtool.cmd}" exit portentac33.build.board=ARDUINO_PORTENTA_C33 -portentac33.compiler.zephyr.arch.define= -portentac33.compiler.zephyr= portentac33.vid.0=0x2341 portentac33.pid.0=0x0068 portentac33.upload_port.0.vid=0x2341 @@ -517,14 +492,12 @@ opta.build.variant=arduino_opta_stm32h747xx_m7 opta.build.mcu=cortex-m7 opta.build.fpu=-mfpu=fpv5-d16 opta.build.architecture=cortex-m7 -opta.compiler.zephyr.arch.define=-DCORE_CM7 opta.build.float-abi=-mfloat-abi=softfp opta.build.extra_flags= opta.build.postbuild.cmd="{tools.imgtool.path}/{tools.imgtool.cmd}" exit opta.build.architecture=cortex-m7 opta.build.board=ARDUINO_OPTA -opta.compiler.zephyr= opta.vid.0=0x2341 opta.pid.0=0x0064 opta.upload_port.0.vid=0x2341 diff --git a/extra/build.sh b/extra/build.sh index 90321ee5..310a850d 100755 --- a/extra/build.sh +++ b/extra/build.sh @@ -90,23 +90,17 @@ for ext in elf bin hex; do done # Generate the provides.ld file for linked builds -echo "Exporting provides.ld" -READELF=${ZEPHYR_SDK_INSTALL_DIR}/arm-zephyr-eabi/bin/arm-zephyr-eabi-readelf -GDB=${ZEPHYR_SDK_INSTALL_DIR}/arm-zephyr-eabi/bin/arm-zephyr-eabi-gdb -$READELF --wide -s ${BUILD_DIR}/zephyr/zephyr.elf | grep FUNC | awk -F' ' '{print "PROVIDE("$8" = 0x"$2");"}' > ${VARIANT_DIR}/provides.ld -$READELF --wide -s ${BUILD_DIR}/zephyr/zephyr.elf | grep kheap_llext_heap | awk -F' ' '{print "PROVIDE("$8" = 0x"$2");"}' >> ${VARIANT_DIR}/provides.ld -$READELF --wide -s ${BUILD_DIR}/zephyr/zephyr.elf | grep kheap_llext_heap | awk -F' ' '{print "PROVIDE(kheap_llext_heap_size = "$3");"}' >> ${VARIANT_DIR}/provides.ld -$READELF --wide -s ${BUILD_DIR}/zephyr/zephyr.elf | grep kheap__system_heap | awk -F' ' '{print "PROVIDE("$8" = 0x"$2");"}' >> ${VARIANT_DIR}/provides.ld -$READELF --wide -s ${BUILD_DIR}/zephyr/zephyr.elf | grep kheap__system_heap | awk -F' ' '{print "PROVIDE(kheap__system_heap_size = "$3");"}' >> ${VARIANT_DIR}/provides.ld -cat ${BUILD_DIR}/zephyr/zephyr.map | grep __device_dts_ord | grep -v rodata | grep -v llext_const_symbol | awk -F' ' '{print "PROVIDE("$2" = "$1");"}' >> ${VARIANT_DIR}/provides.ld -#TEXT_START=`cat variants/$variant/$variant.overlay | grep user_sketch: | cut -f2 -d"@" | cut -f1 -d"{"` -TEXT_START=`$GDB --quiet -ex "p/x sketch_base_addr" ${BUILD_DIR}/zephyr/zephyr.elf -ex "exit" | grep "= 0x" | cut -f 2 -d"="` -echo "PROVIDE(_sketch_start = $TEXT_START);" >> ${VARIANT_DIR}/provides.ld - -sed -i 's/PROVIDE(malloc =/PROVIDE(__wrap_malloc =/g' ${VARIANT_DIR}/provides.ld -sed -i 's/PROVIDE(free =/PROVIDE(__wrap_free =/g' ${VARIANT_DIR}/provides.ld -sed -i 's/PROVIDE(realloc =/PROVIDE(__wrap_realloc =/g' ${VARIANT_DIR}/provides.ld -sed -i 's/PROVIDE(calloc =/PROVIDE(__wrap_calloc =/g' ${VARIANT_DIR}/provides.ld -sed -i 's/PROVIDE(random =/PROVIDE(__wrap_random =/g' ${VARIANT_DIR}/provides.ld +echo "Generating exported symbol scripts" +extra/gen_provides.py "${BUILD_DIR}/zephyr/zephyr.elf" -L > ${VARIANT_DIR}/syms-dynamic.ld +extra/gen_provides.py "${BUILD_DIR}/zephyr/zephyr.elf" -LF \ + "+kheap_llext_heap" \ + "+kheap__system_heap" \ + "*sketch_base_addr=_sketch_start" \ + "*sketch_max_size=_sketch_max_size" \ + "malloc=__wrap_malloc" \ + "free=__wrap_free" \ + "realloc=__wrap_realloc" \ + "calloc=__wrap_calloc" \ + "random=__wrap_random" > ${VARIANT_DIR}/syms-static.ld cmake -P extra/gen_arduino_files.cmake $variant diff --git a/extra/gen_provides.py b/extra/gen_provides.py new file mode 100755 index 00000000..09db69c7 --- /dev/null +++ b/extra/gen_provides.py @@ -0,0 +1,247 @@ +#!/usr/bin/env python +import argparse +import hashlib +import itertools +import os +import re +import struct +import sys +import textwrap +import traceback + +from elftools.construct.macros import UNInt32, UNInt64 +from elftools.common.exceptions import ELFError +from elftools.common.utils import parse_cstring_from_stream, struct_parse +from elftools.elf.elffile import ELFFile +from elftools.elf.sections import SymbolTableSection + + +NativePtr = None + +def get_str_at(elf, addr): + for section in elf.iter_sections(): + if section['sh_type'] == 'SHT_NOBITS' or addr < section['sh_addr'] or addr >= section['sh_addr'] + section['sh_size']: + continue + + file_offset = section['sh_offset'] + addr - section['sh_addr'] + return parse_cstring_from_stream(elf.stream, file_offset).decode('utf-8', errors='replace') + + return None + +def get_ptr_at(elf, addr): + for section in elf.iter_sections(): + if section['sh_type'] == 'SHT_NOBITS' or addr < section['sh_addr'] or addr >= section['sh_addr'] + section['sh_size']: + continue + + file_offset = section['sh_offset'] + addr - section['sh_addr'] + return struct_parse(NativePtr, elf.stream, file_offset) + + return None + +def get_all_syms(elf): + syms = {} + for section in elf.iter_sections(): + if not isinstance(section, SymbolTableSection): + continue + for symbol in section.iter_symbols(): + syms[symbol.name] = symbol + + return syms + +def get_llext_syms(elf): + syms = {} + for section in elf.iter_sections(): + if not isinstance(section, SymbolTableSection): + continue + for symbol in section.iter_symbols(): + if symbol.name.startswith("__llext_sym_"): + llext_sym_addr = symbol['st_value'] + sym_name = get_str_at(elf, get_ptr_at(elf, llext_sym_addr)) + sym_value = get_ptr_at(elf, llext_sym_addr + NativePtr.length) + if sym_value: + syms[sym_name] = sym_value + + return syms + +def main(): + global NativePtr + + # parse the command-line arguments and invoke ReadElf + argparser = argparse.ArgumentParser( + formatter_class=argparse.RawDescriptionHelpFormatter, + description="Extract symbols from ELF files", + epilog=textwrap.dedent(f'''\ + SYMBOL DEFINITION + ----------------- + Each describes symbol names to extract. This can be an exact symbol + name, a regular expression, or a rename expression. Also, the symbol can be + dereferenced, so that the pointer value stored at the symbol address is + exported, or the size of the symbol can be exported as well. + The exact rules are as follows: + + - if starts with a slash ('/'), the rest is treated as a regexp. All + symbols matching the regexp will be extracted. Can be combined with + dereferencing, but not renames. + - if does not start with a slash, but contains an equals sign ('='), + it is treated as a rename expression, where the part before the equals + is the symbol name to extract, and the part after the equals is + the new name to use in the output. + - if the first char of is an asterisk ('*'), the symbol is + dereferenced, i.e. the pointer value stored at the symbol address is + exported instead of the symbol address itself. + - if the first char of is a plus ('+'), in addition to itself, a + second symbol called '_size' is defined with the size of the + current symbol. + + For example, the symbol definition: + + *sketch_base_addr=__sketch_start + + will export the value stored at the address of the 'sketch_base_addr' symbol + as '__sketch_start', while + + /__device_dts_ord_.* + + will export all symbols starting with '__device_dts_ord_' as-is. Also, + + +kheap_llext_heap + + will export the value of the 'kheap_llext_heap' symbol and its size in a + separate 'kheap_llext_heap_size' symbol. + ''')) + argparser.add_argument('-v', '--verbose', + action='store_true', + help='Write the source of the symbol definition as a comment') + argparser.add_argument('-L', '--llext', + action='store_true', + help='Extract symbols from the __llext_sym_* symbols') + argparser.add_argument('-F', '--funcs', + action='store_true', + help='Extract all public functions') + argparser.add_argument('file', + help='ELF file to parse') + argparser.add_argument('syms', nargs='*', + help='Symbols to export') + + args = argparser.parse_intermixed_args() + + exact_syms = set() + regex_syms = set() + deref_syms = set() + sized_syms = set() + rename_map = {} + for sym in args.syms: + sym_class = None + if sym[0] == '/': + # Regexp + sym = f"^{sym[1:]}$" + sym_class = "regexp" + elif '=' in sym: + # Rename expression + sym, new_sym = sym.split('=') + sym_class = "rename" + else: + # Exact symbol + sym_class = "exact" + + if sym[0] == '*': + # Dereference symbol + sym = sym[1:] + deref_syms.add(sym) + elif sym[0] == '+': + # Store size as well + sym = sym[1:] + sized_syms.add(sym) + + if sym_class == "regexp": + regex_syms.add(sym) + else: + exact_syms.add(sym) + if sym_class == "rename": + rename_map[sym] = new_sym + + with open(args.file, 'rb') as file: + try: + elf_sha = hashlib.sha256(file.read()).hexdigest() + elf = ELFFile(file) + except ELFError as ex: + sys.stdout.flush() + sys.stderr.write('ELF error: %s\n' % ex) + traceback.print_exc() + sys.exit(1) + + if elf.elfclass == 32: + NativePtr = UNInt32("ptr") + elif elf.elfclass == 64: + NativePtr = UNInt64("ptr") + + all_syms = get_all_syms(elf) + out_syms = {} + fail = False + + for name, sym in all_syms.items(): + value = None + comment = [] + if name in exact_syms or any(re.match(r, name) for r in regex_syms): + comment = "cmd_line" + value = sym['st_value'] + elif args.funcs and (sym['st_info']['type'] == 'STT_FUNC' + and sym['st_info']['bind'] == 'STB_GLOBAL'): + comment = "public_fn" + value = sym['st_value'] + elif args.llext and name.startswith("__llext_sym_"): + comment = "llext_sym" + llext_sym_addr = sym['st_value'] + name = get_str_at(elf, get_ptr_at(elf, llext_sym_addr)) + value = get_ptr_at(elf, llext_sym_addr + NativePtr.length) + + if name in deref_syms: + value = get_ptr_at(elf, value) + if name in rename_map: + name = rename_map[name] + + if value is None: + continue + + if name in out_syms: + if out_syms[name][0] != value: + sys.stderr.write( + f"Warning: duplicate symbol {name} with different values: " + f"{out_syms[name][0]:#010x} vs {value:#010x}\n") + fail = True + out_syms[name][1].append(comment) + else: + out_syms[name] = (value, [comment]) + + if name in sized_syms: + out_syms[name + "_size"] = (sym['st_size'], [f"size of {name}"]) + + if not out_syms: + sys.stderr.write("No symbols found matching the criteria.\n") + fail = True + + if fail: + sys.exit(1) + + print(f""" +/* + * Automatically generated by {os.path.basename(sys.argv[0])}, do not edit! + * + * Source: {args.file} + * SHA256: {elf_sha} + */ +""") + sym_comment = nul_comment = "" + for name, (value, comments) in sorted(out_syms.items(), key=lambda x: x[0]): + if args.verbose: + comment = ', '.join(sorted(comments)) + sym_comment = f"/* {comment} */" + nul_comment = f" ({comment})" + if value: + print(f"PROVIDE({name} = {value:#010x});{sym_comment}") + else: + print(f"/* NULL {name}{nul_comment} */") + +#------------------------------------------------------------------------------- +if __name__ == '__main__': + main() diff --git a/extra/package_core.inc b/extra/package_core.inc index 61218d07..60a7d284 100644 --- a/extra/package_core.inc +++ b/extra/package_core.inc @@ -13,5 +13,4 @@ README.md doc/ cores/ libraries/ -variants/_llext/ -variants/_linked/ +variants/_ldscripts/ diff --git a/loader/main.c b/loader/main.c index f348f1da..643da9d7 100644 --- a/loader/main.c +++ b/loader/main.c @@ -66,6 +66,7 @@ void llext_entry(void *arg0, void *arg1, void *arg2) __attribute__((retain)) const uintptr_t sketch_base_addr = DT_REG_ADDR(DT_GPARENT(DT_NODELABEL(user_sketch))) + DT_REG_ADDR(DT_NODELABEL(user_sketch)); +__attribute__((retain)) const uintptr_t sketch_max_size = DT_REG_SIZE(DT_NODELABEL(user_sketch)); static int loader(const struct shell *sh) { diff --git a/platform.txt b/platform.txt index a85a76de..0e145686 100644 --- a/platform.txt +++ b/platform.txt @@ -3,7 +3,7 @@ # For more info: # https://github.com/arduino/Arduino/wiki/Arduino-IDE-1.5---3rd-party-Hardware-specification -name=Arduino Zephyr Boards (llext) +name=Arduino Zephyr Boards version=9.9.9 # Compile variables @@ -17,13 +17,13 @@ compiler.warning_flags.all=-Wall -Wextra compiler.path={build.compiler_path} compiler.c.cmd={build.crossprefix}gcc -compiler.c.flags=-g -c {compiler.warning_flags} {compiler.zephyr.macros} "@{compiler.zephyr.cflags_file}" {compiler.zephyr.arch.define} -MMD -mcpu={build.mcu} {build.float-abi} {build.fpu} +compiler.c.flags=-g -c {compiler.warning_flags} {compiler.zephyr.macros} "@{compiler.zephyr.cflags_file}" -MMD -mcpu={build.mcu} {build.float-abi} {build.fpu} compiler.c.elf.cmd={build.crossprefix}g++ -compiler.c.elf.flags={build.llext_link_flags} -Wl,--gc-sections -mcpu={build.mcu} {build.float-abi} {build.fpu} -std=gnu++17 +compiler.c.elf.flags=-Wl,--gc-sections -mcpu={build.mcu} {build.float-abi} {build.fpu} -std=gnu++17 compiler.S.cmd={build.crossprefix}g++ compiler.S.flags=-c -x assembler-with-cpp -mcpu={build.mcu} {build.fpu} compiler.cpp.cmd={build.crossprefix}g++ -compiler.cpp.flags=-g -Os -std=gnu++17 -c {compiler.warning_flags} {compiler.zephyr.macros} "@{compiler.zephyr.cxxflags_file}" {compiler.zephyr.common_ldflags} {compiler.zephyr.extra_ldflags} {compiler.zephyr.common_cxxflags} {compiler.zephyr.extra_cxxflags} {compiler.zephyr.arch.define} -MMD -mcpu={build.mcu} {build.float-abi} {build.fpu} +compiler.cpp.flags=-g -Os -std=gnu++17 -c {compiler.warning_flags} {compiler.zephyr.macros} "@{compiler.zephyr.cxxflags_file}" {compiler.zephyr.common_ldflags} {compiler.zephyr.extra_ldflags} {compiler.zephyr.common_cxxflags} {compiler.zephyr.extra_cxxflags} -MMD -mcpu={build.mcu} {build.float-abi} {build.fpu} compiler.ar.cmd={build.crossprefix}ar compiler.ar.flags=rcs compiler.objcopy.cmd= @@ -46,18 +46,36 @@ compiler.zephyr.common_ldflags=-fno-exceptions -fno-rtti -fno-threadsafe-statics compiler.zephyr.extra_cxxflags= compiler.zephyr.extra_ldflags=-lstdc++ -lsupc++ -# this can be overriden in boards.txt +# these can be overriden in boards.txt build.extra_flags= build.extra_ldflags= -compiler.zephyr= - -build.ldscript={runtime.platform.path}/variants/_llext/linker_script.ld -build.llext_link_flags=-r -e main -build.extra_extra_ldflags= -build.suffix= +build.link_mode=dynamic upload.extension=elf-zsk.bin -postbuild_debug= -postbuild_mode= + +build.ldscript.path={runtime.platform.path}/variants/_ldscripts +build.link_command="{compiler.path}{compiler.c.elf.cmd}" "-L{build.path}" "-L{build.variant.path}" {compiler.c.elf.flags} {compiler.c.elf.extra_flags} {build.extra_flags} {build.extra_ldflags} {compiler.zephyr.common_ldflags} --specs=picolibc.specs --specs=nosys.specs {compiler.ldflags} {object_files} -Wl,--start-group "{build.path}/{archive_file}" {compiler.zephyr.extra_ldflags} {compiler.libraries.ldflags} -Wl,--end-group {build.link_args.{build.link_mode}} + +build.check_command-dynamic={build.link_command} {build.link_args.check-dynamic} -o "{build.path}/{build.project_name}_check.tmp" +build.check_command-static=/bin/true +build.check_command-static.windows=cmd /C cd . +build.combine_command={build.link_command} {build.link_args.build-{build.link_mode}} {build.link_args.build-common} + +# link_args.* are included by any link_command depending on the link_mode +build.link_args.dynamic=-e main +build.link_args.static=-lc -lm -lgcc -Wl,--wrap=random -Wl,--wrap=calloc -Wl,--wrap=free -Wl,--wrap=malloc -Wl,--wrap=realloc + +# link_args.check-* are used to check the build. Only LLEXT needs these to emulate a static build (no -r!). +build.link_args.check-dynamic="-T{build.variant.path}/syms-dynamic.ld" "-T{build.ldscript.path}/memory-check.ld" "-T{build.ldscript.path}/build-static.ld" + +# link_args.build-* are used to create the final binary. -common are added to both static and dynamic. +build.link_args.build-dynamic="-T{build.ldscript.path}/build-dynamic.ld" -r +build.link_args.build-static="-T{build.variant.path}/syms-static.ld" "-T{build.ldscript.path}/memory-static.ld" "-T{build.ldscript.path}/build-static.ld" +build.link_args.build-common="-Wl,-Map,{build.path}/{build.project_name}.map" -o "{build.path}/{build.project_name}_debug.elf" + +# zsk_args are used to create the final binary with zephyr-sketch-tool +build.zsk_args.debug= +build.zsk_args.mode-dynamic= +build.zsk_args.mode-static=-prelinked # These can be overridden in platform.local.txt compiler.c.extra_flags= @@ -99,7 +117,9 @@ recipe.S.o.pattern="{compiler.path}{compiler.S.cmd}" {compiler.S.flags} -DARDUIN recipe.ar.pattern="{compiler.path}{compiler.ar.cmd}" {compiler.ar.flags} {compiler.ar.extra_flags} "{archive_file_path}" "{object_file}" ## Combine gc-sections, archives, and objects -recipe.c.combine.pattern="{compiler.path}{compiler.c.elf.cmd}" "-L{build.path}" {compiler.c.elf.flags} {compiler.c.elf.extra_flags} {build.extra_flags} {build.extra_ldflags} {compiler.zephyr.common_ldflags} "-T{build.ldscript}" "-Wl,-Map,{build.path}/{build.project_name}.map" --specs=picolibc.specs --specs=nosys.specs {compiler.ldflags} -o "{build.path}/{build.project_name}_debug.elf" {object_files} -Wl,--start-group "{build.path}/{archive_file}" {compiler.zephyr} {compiler.zephyr.extra_ldflags} {compiler.libraries.ldflags} -Wl,--end-group +recipe.c.combine.1.pattern={build.check_command-{build.link_mode}} +recipe.c.combine.2.pattern={build.combine_command} +recipe.c.combine.pattern={build.combine_command} recipe.hooks.linking.postlink.1.pattern="{compiler.path}{build.crossprefix}strip" --strip-debug "{build.path}/{build.project_name}_debug.elf" -o "{build.path}/{build.project_name}.elf" ## Create eeprom @@ -112,8 +132,8 @@ recipe.objcopy.bin.pattern="{compiler.path}{compiler.elf2hex.cmd}" {compiler.elf recipe.objcopy.hex.pattern="{compiler.path}{compiler.elf2hex.cmd}" {compiler.elf2hex.hex.flags} {compiler.elf2hex.extra_flags} "{build.path}/{build.project_name}.elf" "{build.path}/{build.project_name}.hex" ## Mangle the file -recipe.hooks.objcopy.postobjcopy.1.pattern="{runtime.tools.zephyr-sketch-tool.path}/zephyr-sketch-tool" {postbuild_debug} {postbuild_mode} "{build.path}/{build.project_name}.elf" -recipe.hooks.objcopy.postobjcopy.2.pattern="{runtime.tools.zephyr-sketch-tool.path}/zephyr-sketch-tool" {postbuild_debug} {postbuild_mode} "{build.path}/{build.project_name}.bin" +recipe.hooks.objcopy.postobjcopy.1.pattern="{runtime.tools.zephyr-sketch-tool.path}/zephyr-sketch-tool" {build.zsk_args.debug} {build.zsk_args.mode-{build.link_mode}} "{build.path}/{build.project_name}.elf" +recipe.hooks.objcopy.postobjcopy.2.pattern="{runtime.tools.zephyr-sketch-tool.path}/zephyr-sketch-tool" {build.zsk_args.debug} {build.zsk_args.mode-{build.link_mode}} "{build.path}/{build.project_name}.bin" ## Compute size recipe.size.pattern="{compiler.path}{compiler.size.cmd}" -A "{build.path}/{build.project_name}.elf" diff --git a/variants/_llext/linker_script.ld b/variants/_ldscripts/build-dynamic.ld similarity index 100% rename from variants/_llext/linker_script.ld rename to variants/_ldscripts/build-dynamic.ld diff --git a/variants/_linked/linker_script.ld b/variants/_ldscripts/build-static.ld similarity index 87% rename from variants/_linked/linker_script.ld rename to variants/_ldscripts/build-static.ld index 18a5ee6f..7154ee9a 100644 --- a/variants/_linked/linker_script.ld +++ b/variants/_ldscripts/build-static.ld @@ -1,19 +1,5 @@ -INCLUDE "provides.ld" - -PROVIDE(TEXT_LENGTH = 0x100000); - -MEMORY -{ - FLASH (rx) : ORIGIN = _sketch_start + 16, LENGTH = TEXT_LENGTH - RAM (rwx) : ORIGIN = kheap_llext_heap, LENGTH = kheap_llext_heap_size -} - -PROVIDE(__heap_start = kheap__system_heap); -PROVIDE(__heap_end = kheap__system_heap + kheap__system_heap_size); - ENTRY(entry_point) SECTIONS { - /DISCARD/ : { *(.ARM.attributes) *(.ARM.attributes.*) @@ -117,4 +103,4 @@ SECTIONS { .got : { KEEP(*(.got .got.* .got.plt .got.plt*)) } -} \ No newline at end of file +} diff --git a/variants/_ldscripts/memory-check.ld b/variants/_ldscripts/memory-check.ld new file mode 100644 index 00000000..fd09c59f --- /dev/null +++ b/variants/_ldscripts/memory-check.ld @@ -0,0 +1,13 @@ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x10000000 + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x10000000 +} + +PROVIDE(__heap_start = 0x40000000); +PROVIDE(__heap_end = 0x50000000); +PROVIDE(kheap__system_heap = 0x40000000); +PROVIDE(kheap__system_heap_size = 0x10000000); + +PROVIDE(kheap_llext_heap = 0x60000000); +PROVIDE(kheap_llext_heap_size = 0x10000000); diff --git a/variants/_ldscripts/memory-static.ld b/variants/_ldscripts/memory-static.ld new file mode 100644 index 00000000..fce3d398 --- /dev/null +++ b/variants/_ldscripts/memory-static.ld @@ -0,0 +1,9 @@ +MEMORY +{ + /* 16 below compensates for the zsk header that is added before the .bin */ + FLASH (rx) : ORIGIN = _sketch_start + 16, LENGTH = _sketch_max_size - 16 + RAM (rwx) : ORIGIN = kheap_llext_heap, LENGTH = kheap_llext_heap_size +} + +PROVIDE(__heap_start = kheap__system_heap); +PROVIDE(__heap_end = kheap__system_heap + kheap__system_heap_size); diff --git a/variants/arduino_giga_r1_stm32h747xx_m7/arduino_giga_r1_stm32h747xx_m7.overlay b/variants/arduino_giga_r1_stm32h747xx_m7/arduino_giga_r1_stm32h747xx_m7.overlay index f397b784..1bce0bdf 100644 --- a/variants/arduino_giga_r1_stm32h747xx_m7/arduino_giga_r1_stm32h747xx_m7.overlay +++ b/variants/arduino_giga_r1_stm32h747xx_m7/arduino_giga_r1_stm32h747xx_m7.overlay @@ -37,7 +37,7 @@ port { gc2145_ep_out: endpoint { - remote-endpoint = <&dcmi_ep_in>; + remote-endpoint-label = "dcmi_ep_in"; }; }; }; diff --git a/west.yml b/west.yml index 16a78b2f..8e94fe61 100644 --- a/west.yml +++ b/west.yml @@ -21,7 +21,7 @@ manifest: projects: - name: zephyr remote: arduino - revision: zephyr-arduino-20250529 + revision: zephyr-arduino-20250714 import: name-allowlist: - cmsis