CantripOS includes a multi-platform build framework. This framwork leverages make, cmake, and cargo. To get started follow these steps:
mkdir sparrow cd sparrow repo init -u https://github.com/AmbiML/sparrow-manifest -m sparrow-manifest.xml repo sync -j$(nproc) export PLATFORM=rpi3 source build/setup.sh m prereqs m simulate
[Beware that if your repo tool is out of date you may need to supply -b main
to the init request as older versions of repo only check for a master
branch.]
Note the above assumes you have the follow prerequisites installed on your system and in your shell's search path:
CANTRIP_RUST_VERSION
in each shell where you work. Beware that we use various nightly-only features that are not supported by stable versions of Rust (e.g. to override the default TLS model).The m prereqs
step installs required python packages using the pip
tool. At the moment this mostly sets up a virtual environment for the project.
Because Shodan is a CAmkES project you also need CAmkES dependencies.
Sparrow uses repo to download and piece together Sparrow git repositories as well as dependent projects / repositories such as seL4.
$ repo init -u https://github.com/AmbiML/sparrow-manifest -m sparrow-manifest.xml Downloading Repo source from https://gerrit.googlesource.com/git-repo repo has been initialized in <your-directory>/sparrow/ If this is not the directory in which you want to initialize repo, please run: rm -r <your-directory>/sparrow//.repo and try again. $ repo sync -j12 Fetching: 100% (23/23), done in 9.909s Garbage collecting: 100% (23/23), done in 0.218s Checking out: 100% (23/23), done in 0.874s repo sync has finished successfully. $ export PLATFORM=rpi3 $ export CANTRIP_RUST_VERSION=nightly $ source build/setup.sh ======================================== ROOTDIR=/<your-directory>/sparrow OUT=/<your-directory>/sparrow/out PLATFORM=rpi3 PYTHON_SPARROW_ENV=<your-directory>/sparrow/cache/rpi3-venv ======================================== Type 'm [target]' to build. Targets available are: ... cantrip cantrip-build-debug-prepare cantrip-build-release-prepare cantrip-builtins cantrip-builtins-debug cantrip-builtins-release cantrip-bundle-debug cantrip-bundle-release cantrip-clean cantrip-clean-headers cantrip-clippy cantrip-component-headers ... $ m prereqs <your-directory>/sparrow/scripts/install-prereqs.sh \ -p "<your-directory>/sparrow/scripts/python-requirements.txt \ " \ -a "" Installing apt package dependencies... Installing python package dependencies... Creating virtual python environment <your-directory>/sparrow/cache/rpi3-venv ... Installation complete. $ m simulate ... info: component 'rust-std' for target 'aarch64-unknown-none' is up to date loading initial cache file <your-directory>/sparrow/cantrip/projects/camkes/settings.cmake -- Set platform details from PLATFORM=rpi3 -- KernelPlatform: bcm2837 -- KernelARMPlatform: rpi3 -- Setting from flags KernelSel4Arch: aarch64 -- Found seL4: <your-directory>/sparrow/kernel -- The C compiler identification is GNU 11.2.1 ... [291/291] Generating images/capdl-loader-image-arm-bcm2837 ... qemu-system-aarch64 -machine raspi3b -nographic -serial null -serial mon:stdio -m size=1024M -s \ -kernel /<your-directory>/sparrow/out/cantrip/aarch64-unknown-elf/release/capdl-loader-image \ --mem-path /<your-directory>/sparrow/out/cantrip/aarch64-unknown-elf/release/cantrip.mem ELF-loader started on CPU: ARM Ltd. Cortex-A53 r0p4 paddr=[8bd000..fed0ff] No DTB passed in from boot loader. Looking for DTB in CPIO archive...found at 9b3ef8. Loaded DTB from 9b3ef8. paddr=[23c000..23ffff] ELF-loading image 'kernel' to 0 paddr=[0..23bfff] vaddr=[ffffff8000000000..ffffff800023bfff] virt_entry=ffffff8000000000 ELF-loading image 'capdl-loader' to 240000 paddr=[240000..4c0fff] vaddr=[400000..680fff] virt_entry=4009e8 Enabling MMU and paging Jumping to kernel-image entry point... Warning: gpt_cntfrq 62500000, expected 19200000 Bootstrapping kernel Booting all finished, dropped to user space cantrip_os_rootserver::Bootinfo: (1969, 131072) empty slots 1 nodes (15, 83) untyped 131072 cnode slots cantrip_os_rootserver::Model: 1821 objects 1 irqs 0 untypeds 2 asids cantrip_os_rootserver::capDL spec: 0.39 Mbytes cantrip_os_rootserver::CAmkES components: 5.85 Mbytes cantrip_os_rootserver::Rootserver executable: 1.07 Mbytes <<seL4(CPU 0) [decodeARMFrameInvocation/2137 T0xffffff80004c7400 "rootserver" @44373c]: ARMPageMap: Attempting to remap a frame that does not belong to the passed address space>> ... <<seL4(CPU 0) [decodeCNodeInvocation/107 T0xffffff80009a3400 "rootserver" @4268a0]: CNode Copy/Mint/Move/Mutate: Source slot invalid or empty.>> ... CANTRIP> builtins autostart.repl 336 hello.app 1084 keyval.app 32276 logtest.app 26948 panic.app 25688 timer.app 33060 CANTRIP> install hello.app cantrip_memory_manager::Global memory: 0 allocated 130543360 free, reserved: 2273280 kernel 1359872 user Collected 1084 bytes of data, crc32 5b847193 Application "hello" installed CANTRIP> start hello Bundle "hello" started. CANTRIP> install keyval.app I am a C app! Done, sleeping in WFI loop Collected 32276 bytes of data, crc32 bcf05273 Application "keyval" installed CANTRIP> start keyval Bundle "keyval" started. ... CANTRIP> mstats 48 bytes in-use, 130543312 bytes free, 720512 bytes requested, 1359872 overhead 2 objs in-use, 196 objs requested CANTRIP> EOF
The m simulate
command can be run repeatedly. If you need to reset your setup just remove the build tree and re-run m simulate
; e.g.
$ cd sparrow
$ m clean
$ m simulate
The setup procedure required:
$ export PLATFORM=rpi3 $ export CANTRIP_RUST_VERSION=nightly # force use of "nightly" channel $ source build/setup.sh
This defined various shell functions/aliases for working with CantripOS. In particular the m
command is the primary mechanism for building and running simulations. The default target command is simulate
so these are equivalent:
$ m simulate $ m # default target is simulate
As seen above, another useful target is m simulate-debug
which builds a debug version of the system and starts up a simulator. In this case the simulator (platform-dependent) supports connecting GDB with scripts/kgdb.sh in a separate window/terminal. For more information on using GDB with seL4 check here.
There is tab completion for build targets depending on your shell; e.g.
$ m <TAB> cargo_test_debugconsole_zmodem kata-gen-headers cargo_test_kata keyval_debug cargo_test_kata_os_common_logger keyval_release cargo_test_kata_os_common_slot_allocator logtest_debug cargo_test_kata_proc_interface logtest_release cargo_test_kata_proc_manager matcha_tock_clean clean matcha_tock_debug collate_kata_rust_toolchain matcha_tock_release collate_matcha_rust_toolchain minisel_debug collate_rust_toolchains minisel_release elfconvert multihart_boot_rom fibonacci_debug multihart_boot_rom_clean fibonacci_release panic_debug flatbuffers panic_release flatbuffers-clean prereqs ...
There is also a hmm
command that can display help information for a build target. For example,
$ hmm sel4test sel4test: (defined in build/platforms/shodan/sim_sel4test.mk) C-based libsel4 syscall api wrappers. The result is run under Renode.
The build system supports multiple target platforms. But at the moment there are only two platforms--shodan & rpi3--so this is less exciting. The current platform is kept in your shell's environmnet so after a default setup you will see:
$ source build/setup.sh $ printenv PLATFORM shodan
But this also means that you need to source build/setup.sh
in each shell where you work on the software.
To switch the current platform use the set-platform
shell function:
$ set-platform rpi3 $ printenv PLATFORM rpi3
There is also a list-platforms
shell function that you can use in lieu of tab completion with the set-platform
command.
Most of the time m simulate
or m simulate-debug
is all you need to do work: make dependencies will cause only necessary operations to be done. But sometimes it's necessary to remove build artifacts (e.g. because depeencies are incorrect or the dependencies are overly conservative resulting in excessive build steps). Therre are many targets that selectively clear out unwanted artifacts but most of the time you will just want to use:
$ m cantrip-clean
which removes all build artifacts for the current platform, or
$ m clean
which removes all build artifacts for all platforms.