One of the common questions to provide a safe Linux is to make the switches between computational contexts e.g. processes reliable, deterministic and in (hard) real-time. Having this managed the switch between user and kernel level remains. Maybe a better approach is to facilitate the increasing amount of (specialized) CPU kernel e.g., one kernel per task. Having a bare-metal hypervisor in place, modern SoC could be best facilitated by this approach. But how can we keep the comfort of
- platform abstraction,
- system modularity,
- POSIX API,
- huge development community and
- statically linked code (remove unused code).
One promising approach comes with UNIKRAFT (external link).
The practical usage is simple. Compare https://unikraft.org/docs/getting-started/ (external link) First a filesystem layout ,with the following folders is required:
apps – This is where you would normally place existing app builds
archs – Here we place our custom arch’s files
libs – This is where the build system looks for external library pool sources
plats – The files for our custom plats are placed here
unikraft – The core source code of the Unikraft Unikernel
mkdir myproject
cd myproject
git clone https://github.com/unikraft/unikraft
mkdir libs
mkdir apps
cd apps
git clone https://github.com/unikraft/app-helloworld
cd app-helloworld
make menuconfig
make
Instead of the “app-helloworld” any viable code could be introduced, beside a UNIKERNEL specific Makefile. For libs and apps many predefined schemas are available: https://github.com/orgs/unikraft/repositories?q=app&type=all&language=&sort= (external link).
After the “make” command the bootable image can be tested as follows:
qemu-system-x86_64 -kernel apps/app-helloworld/build/app-helloworld_kvm-x86_64