Skip to content

About

An implementation of openkal for FreeBSD, written on the kernel's own system-call interface

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

5 Commits

Folders and files

Repository files navigation

openkal-freebsd

An implementation of openkal for FreeBSD, written on the kernel's own system-call interface.

[target.'cfg(os = "freebsd")'.dependencies]
openkal-freebsd = "0.1.2"

What 0.1.2 changes

The runner is dirun. tools/vm-runner boots the machine by dirun, the one program that runs a command inside a booted disk image, with the image's profile (dirun.toml beside the image, as the package freebsd-disk-image installs it, else tools/freebsd.toml); tools/vm-run.py, a second implementation of the same conversation, is removed. What it did is dirun's: the overlay, the program delivered on a read-only FAT disk and run from its copy, OPENKAL_* and KAL_* passed, and a test runner's events read back from the machine.

The specification by its minor version. The manifest declares openkal = "^0.25.0": an implementation written against a patch release conforms to every later patch of that minor version (openkal clause 8), and a consumer that names openkal 0.25.1 resolves with it.

What it is

FreeBSD's kernel interface is stable: a program built for FreeBSD 14 runs on every later 14.x and, through COMPAT_FREEBSD14, on 15. This implementation issues that interface directly, on amd64 and arm64, and reads no header of a C library. src/sys.h states FreeBSD 14's system-call numbers, flags and structure layouts. They were read from the base system's headers by compiling them for both architectures, where they are identical, and each structure's size is asserted. The kernel reports a failure with the carry flag and the error number in the first result register; okf::call6 folds the two into one value, the result or the error number negated, as openkal-linux's system calls answer.

Two arrangements

Hosted (the default). The program carries a runtime that has received control: FreeBSD's own C library and libthr, as in a program built for x86_64-freebsd or aarch64-freebsd. This implementation borrows what that runtime already does, as openkal-linux does above a C library:

  • the program's arguments and environment, from the (argc, argv, envp) that FreeBSD's run-time linker passes to every .init_array function;
  • a context, which is the runtime's thread (pthread_create), and its stack, which the runtime states (pthread_attr_get_np).

-lthr is named only on those rows.

Standalone (feature standalone). Nothing in the program has received control: either it supplies its own runtime, or it is built above a C library written on openkal (openkal-musl, the rows x86_64-freebsd-musl and aarch64-freebsd-musl). This implementation then:

  • begins the program with _start, which takes the argument block from %rdi or x0, and the auxiliary vector after it;
  • carries the .note.tag ABI brand by which the kernel recognises a FreeBSD image;
  • lays out the image's PT_TLS block and sets the thread pointer (sysarch(AMD64_SET_FSBASE) on amd64, tpidr_el0 on arm64);
  • hands over to a linked C library's __libc_start_main, or else runs the initialisers and calls main;
  • creates contexts with thr_new on stacks it maps with a guard, and joins them on the word thr_exit sets;
  • states the first stack from AT_USRSTACKBASE and AT_USRSTACKLIM.

In both arrangements everything else is a system call:

interface how
openkal.abort exit; SIGABRT at its default disposition
openkal.stream read, write; a terminal is what answers TIOCGETA
openkal.memory size classes carved from mmaped chunks; hw.physmem and the free and inactive page counts from sysctl
openkal.env the recorded vectors; kern.proc.pathname for the image's name
openkal.time clock_gettime, clock_getres, nanosleep
openkal.random getrandom
openkal.fs the *at calls relative to directory descriptors; getdirentries; flock for a lock on a whole file; two preopens, the working directory (__getcwd) and the root
openkal.process pdfork (PD_DAEMON; the descriptor is held while the handle is) and fexecve; wait6; process groups as units; SIGINT, SIGTERM and SIGHUP taken over with sigaction
openkal.task a word waited upon and woken with _umtx_op (UMTX_OP_WAIT_UINT_PRIVATE, UMTX_OP_WAKE_PRIVATE)
openkal.exec mmap, mprotect, never writable and executable at once; a region at an address is MAP_FIXED | MAP_EXCL
openkal.terminal TIOCGETA, TIOCSETAF, TIOCGWINSZ
openkal.timeout ppoll; a program awaited with a bound
openkal.map mmap of a descriptor
openkal.region reserved PROT_NONE mappings backed by mprotect

Absent in 0.1, neither stated nor defined: openkal.space, openkal.net, openkal.datagram, openkal.prof and openkal.debug. Within the stated interfaces, the property words do not claim the following, and the operations answer kal_err_not_supported as clause 6.2 requires:

  • confinement, a bound lifetime and a one-string command line for a started program;
  • the observable units of 0.24, and a unit's usage and limits;
  • a rename that does not replace (FreeBSD has none);
  • the timeout forms of accept and recv_from, whose resources belong to the absent network interfaces.

The stop word is counted and never zero again (openkal 0.25). The handler wakes the word's waiters itself, because a wake is a system call, which a handler may make.

How it is examined

Hosted. openkal's conformance suite is built on Linux for x86_64-freebsd and aarch64-freebsd above FreeBSD's C library, using the base-system sysroots xim:<arch>-freebsd-sysroot@14.5 named by ci/freebsd-platform. It is then run in a FreeBSD virtual machine (vmactions/freebsd-vm; the arm64 machine is emulated). On FreeBSD 14.5 amd64 it reports 334 observations held, none failed, and 12 not observed (interfaces not provided, properties not claimed). The suite's three-way check holds: the manifest's provides-interfaces, kal_interfaces() and the exported names state the same fourteen interfaces.

Standalone. Every source compiles for both architectures from openkal's headers alone, -ffreestanding and without a system header, and the objects carry the brand (tools/check-standalone.sh). The suite in this arrangement runs above openkal-musl on the *-freebsd-musl rows.

  • tools/defer-runner puts the suite and the variables it is run with in a directory, where CI runs it inside a FreeBSD VM.
  • tools/vm-runner runs a program in a local FreeBSD VM image for development (OKF_VM_IMAGE), by dirun. It passes OPENKAL_* and KAL_*, and a test runner's events come back from the machine. Each run boots a temporary overlay of the image, so the image is never written to and two runs at once do not meet.

The runner declaration

A program built for FreeBSD on another host is run in a virtual machine by tools/vm-runner, which a runner declaration names:

[target.x86_64-freebsd]
runner = ["/path/to/openkal-freebsd/tools/vm-runner", "{}"]

The declaration's {} is the built artefact. vm-runner boots the FreeBSD image that OKF_VM_IMAGE names by dirun (under qemu-system-x86_64, KVM where the host has it, the software machine otherwise), delivers the artefact on a read-only FAT disk, runs it as root on the serial console, writes what it writes to the standard output, and answers with its exit status; the temporary overlay it booted from is discarded. The disk is the FreeBSD 14.5-RELEASE boot disk of the xim package freebsd-disk-image (The FreeBSD Project's release, installed from the official installer disc), which installs the profile beside it; dirun, qemu-system-x86_64 and qemu-img are the host's dependencies. Without a declaration, mcpp states the same runner for the FreeBSD rows of an x86_64 Linux or macOS host itself: dirun --profile {pkg:freebsd-disk-image}/dirun.toml -- {}, its packages installed by the first run.

The targets need mcpp 2026.11.10.1 or later.

License

Apache-2.0.

About

An implementation of openkal for FreeBSD, written on the kernel's own system-call interface

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages