# # SPDX-License-Identifier: BlueOak-1.0.0 # # Copyright (c) Berkus Decker # [config] min_version = "0.32.0" default_to_workspace = true [env] DEFAULT_TARGET = "aarch64-vesper-metta" # # === User-configurable === # # Pass TARGET env var if it does not match the default target above. TARGET = { value = "${DEFAULT_TARGET}", condition = { env_not_set = ["TARGET"] } } # Name of the target board "rpi3" or "rpi4" TARGET_BOARD = { value = "rpi4", condition = { env_not_set = ["TARGET_BOARD"] } } # Name of the DTB file for target board configuration, use bcm2710-rpi-3-b-plus.dtb for RasPi3B+ TARGET_DTB = { value = "${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/targets/bcm2711-rpi-4-b.dtb", condition = { env_not_set = ["TARGET_DTB"] } } # AArch64 QEMU binary QEMU = { value = "qemu-system-aarch64", condition = { env_not_set = ["QEMU"] } } # QEMU machine type, defaults to raspi3b but CI runners override it due to ancient QEMU versions they use. QEMU_MACHINE = { value = "raspi3b", condition = { env_not_set = ["QEMU_MACHINE"] } } # An aarch64-enabled GDB GDB = { value = "/usr/local/opt/gdb/HEAD-a2c58332-aarch64/bin/aarch64-unknown-elf-gdb", condition = { env_not_set = ["GDB"] } } # OpenOCD with JLink support # (RTT patch from http://openocd.zylin.com/#/c/4055/11 has already been merged into main line) OPENOCD = { value = "/usr/local/opt/openocd/4d6519593-rtt/bin/openocd", condition = { env_not_set = ["OPENOCD"] } } # Mounted sdcard partition path VOLUME = { value = "/Volumes/BOOT", condition = { env_not_set = ["VOLUME"] } } # # === Automatic === # CARGO_MAKE_EXTEND_WORKSPACE_MAKEFILE = true RUST_LIBS = "-Z build-std=compiler_builtins,core,alloc -Z build-std-features=compiler-builtins-mem" TARGET_JSON = "${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/targets/${TARGET}.json" PLATFORM_TARGET="--target=${TARGET_JSON} --features=${TARGET_FEATURES} ${RUST_LIBS}" DEVICE_FEATURES = "noserial" QEMU_FEATURES = "qemu,rpi3" OBJCOPY = "rust-objcopy" # Part of `cargo objcopy` in cargo-binutils OBJCOPY_PARAMS = "--strip-all -O binary" NM = "rust-nm" # Part of `cargo nm` in cargo-binutils UTILS_CONTAINER = "andrerichter/raspi3-utils" DOCKER_CMD = "docker run -it --rm -v ${PWD}:/work -w /work -p 5900:5900" QEMU_CONTAINER_CMD = "qemu-system-aarch64" # # Could additionally use -nographic to disable GUI -- this shall be useful for automated tests. # # QEMU has renamed the RasPi machines since version 6.2.0, use just `raspi3` for previous versions. QEMU_OPTS = "-M ${QEMU_MACHINE} -d int -semihosting" QEMU_DISASM_OPTS = "-d in_asm,unimp,int" QEMU_SERIAL_OPTS = "-serial pty -serial stdio" QEMU_TESTS_OPTS = "-nographic" # For gdb connection: # - if this is set, MUST have gdb attached for SYS_WRITE0 to work, otherwise QEMU will crash. # - port 5555 used to match JLink configuration, so we can reuse the same GDB command for both QEMU and JTAG. QEMU_GDB_OPTS = "-gdb tcp::5555 -S" GDB_CONNECT_FILE = "${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/target/${TARGET}/gdb-connect" KERNEL_ELF = "${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/target/${TARGET}/release/nucleus" KERNEL_BIN = "${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/target/nucleus.bin" CHAINBOOT_SERIAL = "/dev/tty.SLAB_USBtoUART" CHAINBOOT_BAUD = 115200 [tasks.default] alias = "all" [tasks.all] dependencies = ["kernel-binary"] [tasks.modules] command = "cargo" args = ["modules", "tree"] [tasks.build] env = { "TARGET_FEATURES" = "${TARGET_BOARD}" } command = "cargo" args = ["build", "@@split(PLATFORM_TARGET, )", "--release"] [tasks.build-qemu] env = { "TARGET_FEATURES" = "${QEMU_FEATURES}" } command = "cargo" args = ["build", "@@split(PLATFORM_TARGET, )", "--release"] [tasks.qemu-runner] dependencies = ["build-qemu", "kernel-binary"] env = { "TARGET_FEATURES" = "${QEMU_FEATURES}" } script = [ "echo Run QEMU ${QEMU_OPTS} ${QEMU_RUNNER_OPTS} with ${KERNEL_BIN}", "${QEMU} ${QEMU_OPTS} ${QEMU_RUNNER_OPTS} -dtb ${TARGET_DTB} -kernel ${KERNEL_BIN}" ] [tasks.expand] env = { "TARGET_FEATURES" = "" } command = "cargo" args = ["expand", "@@split(PLATFORM_TARGET, )", "--release"] [tasks.test] env = { "TARGET_FEATURES" = "${QEMU_FEATURES}" } command = "cargo" args = ["test", "@@split(PLATFORM_TARGET, )"] [tasks.docs] env = { "TARGET_FEATURES" = "" } command = "cargo" args = ["doc", "--open", "--no-deps", "@@split(PLATFORM_TARGET, )"] [tasks.clippy] env = { "TARGET_FEATURES" = "rpi3", "CLIPPY_FEATURES" = { value = "--features=${CLIPPY_FEATURES}", condition = { env_set = ["CLIPPY_FEATURES"] } } } command = "cargo" args = ["clippy", "@@split(PLATFORM_TARGET, )", "@@remove-empty(CLIPPY_FEATURES)", "--", "-D", "warnings"] # These tasks are written in cargo-make's own script to make it portable across platforms (no `basename` on Windows) [tasks.custom-binary] env = { "BINARY_FILE" = "${BINARY_FILE}" } script_runner = "@duckscript" script = [ ''' binaryFile = basename ${BINARY_FILE} outElf = set ${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/target/${binaryFile}.elf outBin = set ${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/target/${binaryFile}.bin cp ${BINARY_FILE} ${outElf} exec --fail-on-error ${OBJCOPY} %{OBJCOPY_PARAMS} ${BINARY_FILE} ${outBin} echo Copied ${binaryFile} to ${outElf} echo Converted ${binaryFile} to ${outBin} ''' ] install_crate = { crate_name = "cargo-binutils", binary = "rust-objcopy", test_arg = ["--help"] } [tasks.test-binary] env = { "BINARY_FILE" = "${CARGO_MAKE_TASK_ARGS}" } run_task = "custom-binary" [tasks.test-runner] dependencies = ["test-binary"] script_runner = "@duckscript" script = [ ''' binaryFile = basename ${CARGO_MAKE_TASK_ARGS} exec --fail-on-error ${QEMU} %{QEMU_OPTS} %{QEMU_TESTS_OPTS} -dtb ${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/targets/bcm2710-rpi-3-b-plus.dtb -kernel ${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/target/${binaryFile}.bin ''' ] [tasks.gdb-config] script_runner = "@duckscript" script = [ ''' writefile ${GDB_CONNECT_FILE} "target extended-remote :5555\n" appendfile ${GDB_CONNECT_FILE} "break 0x80000\n" ''' ] [tasks.zellij-config] dependencies = ["build-qemu", "kernel-binary"] script_runner = "@duckscript" env = { "ZELLIJ_CONFIG_FILE" = "${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/emulation/zellij-config.sh" } script = [ ''' writefile ${ZELLIJ_CONFIG_FILE} "QEMU=${QEMU}\n" appendfile ${ZELLIJ_CONFIG_FILE} "QEMU_OPTS=\"${QEMU_OPTS}\"\n" appendfile ${ZELLIJ_CONFIG_FILE} "QEMU_RUNNER_OPTS=${QEMU_RUNNER_OPTS}\n" appendfile ${ZELLIJ_CONFIG_FILE} "CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY=${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}\n" appendfile ${ZELLIJ_CONFIG_FILE} "TARGET_DTB=${TARGET_DTB}\n" appendfile ${ZELLIJ_CONFIG_FILE} "KERNEL_BIN=${KERNEL_BIN}\n" ''' ] install_crate = { crate_name = "zellij", binary = "zellij", test_arg = ["--help"] } [tasks.openocd] script = [ "${OPENOCD} -f interface/jlink.cfg -f ../ocd/${TARGET_BOARD}_target.cfg" ] [tasks.sdeject] dependencies = ["sdcard"] script = [ "diskutil unmount ${VOLUME}" ] [tasks.chainboot] dependencies = ["build", "kernel-binary"] command = "echo" args = ["\n***===***\n", "Run the following command in your terminal:\n", " ${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/target/debug/chainofcommand ${CHAINBOOT_SERIAL} ${CHAINBOOT_BAUD} --kernel ${KERNEL_BIN}\n", "***===***\n\n"]