-
Notifications
You must be signed in to change notification settings - Fork 86
Advanced Configuration Features
The library operating system RustyHernit provides following features, which can be configured implicitly by the configuration of hermit-sys
:
-
smp
: By selecting thesmp
feature, the kernel is able to run on a symmetric multiprocessing system, otherwise it is only working on a single-processor systems. -
fsgsbase
: FSGSBASE is an Intel Architecture extension that allows applications to directly write to the FS / GS segment registers. This allows fast switching to different threads in user applications. Please selectfsgsbase
to improve the performance if the processor is has such an extension. - vga: By selecting the
via
feature, the kernel uses also a video graphic card to show the results. - smoltcp: The TCP/IP stack [https://github.com/smoltcp-rs/smoltcp] will be integrated if the feature
smoltcp
will be selected. - dhcpv4: Per default, DHCPv4 isn't supported. If the feature will be selected, RustyHermit is able to integrate a DHCPv4 client.
For instance, the following configuration of hermit-sys
activates the TCP/IP stack with DHCPv4 support:
[target.'cfg(all(any(target_arch = "x86_64", target_arch = "aarch64"), target_os = "hermit"))'.dependencies.hermit-sys]
features = ["smoltcp", "dhcpv4"]
If the configuration file .cargo/config
is created in the project folder as follows, it is possible to build RustyHermit with common cargo commands.
[unstable]
build-std = ["std", "core", "alloc", "panic_abort"]
build-std-features = ["compiler-builtins-mem", "compiler-builtins-asm"]
[build]
target = "x86_64-unknown-hermit"
[target.x86_64-unknown-hermit]
runner = "uhyve -v"
Now, the default target is defined as x86_64-unknown-hermit
, which represents RustyHermit.
The default runner for RustyHermit application is defined as uhyve.
Consequently, the command cargo run --bin rusty_demo
builds a RustyHermit application and start it within in uhyve.
To enable Link Time Optimization (LTO), please extend the release configuration in Cargo.toml as follows:
# Cargo.toml
[profile.release]
opt-level = 3
lto = "thin"
In addition, the Linker-plugin LTO have to be enabled by setting the compiler flag linker-plugin-lto
.
In this case, the release version have to build as follows:
RUSTFLAGS="-Clinker-plugin-lto" cargo build -Z build-std=std,core,alloc,panic_abort --target x86_64-unknown-hermit --release
RustyHermit uses the lightweight logging crate log to print kernel messages.
If the environment variable HERMIT_LOG_LEVEL_FILTER
is set at compile time to a string matching the name of a LevelFilter, then that value is used for the LevelFilter.
If the environment variable is not set, or the name doesn't match, then LevelFilter::Info is used by default, which is the same as it was before.
For instance, the following command build RustyHermit with debug messages:
$ HERMIT_LOG_LEVEL_FILTER=Debug cargo build -Z build-std=std,core,alloc,panic_abort --target x86_64-unknown-hermit
One option to enable ethernet support is to setup a tap device on the
host system. For instance, the following command establish the tap device
tap10
on Linux:
$ sudo ip tuntap add tap10 mode tap
$ sudo ip addr add 10.0.5.1/24 broadcast 10.0.5.255 dev tap10
$ sudo ip link set dev tap10 up
$ sudo bash -c 'echo 1 > /proc/sys/net/ipv4/conf/tap10/proxy_arp'
Add the feature smoltcp
in the Cargo.toml
. This includes the network stack smoltcp and offers TCP/UDP communication.
# Cargo.toml
[target.'cfg(target_os = "hermit")'.dependencies]
hermit-sys = "0.1.*"
default-features = false
features = ["smoltcp"]
Per default, RustyHermit's network interface uses 10.0.5.3
as IP address, 10.0.5.1
for the gateway and 255.255.255.0
as network mask.
The default configuration could be overloaded at compile time by the environment variables
HERMIT_IP
, HERMIT_GATEWAY
and HERMIT_MASK
.
For instance, the following command sets the IP address to 10.0.5.100
.
$ HERMIT_IP="10.0.5.100" cargo build -Z build-std=std,core,alloc,panic_abort --target x86_64-unknown-hermit
Currently, RustyHermit does only support network interfaces through virtio. To use it, you have to start RustyHermit in Qemu with following command:
$ qemu-system-x86_64 -cpu qemu64,apic,fsgsbase,rdtscp,xsave,fxsr \
-enable-kvm -display none -smp 1 -m 1G -serial stdio \
-kernel path_to_loader/rusty-loader \
-initrd path_to_app/app \
-netdev tap,id=net0,ifname=tap10,script=no,downscript=no,vhost=on \
-device virtio-net-pci,netdev=net0,disable-legacy=on
If DHCP support is required, the support must be activated in hermit-sys
.
Add the feature smoltcp
and dhcpv4
in the file Cargo.toml
.
This includes the network stack smoltcp and enables DHCPv4 support.
# Cargo.toml
[target.'cfg(target_os = "hermit")'.dependencies]
hermit-sys = "0.1.*"
default-features = false
features = ["smoltcp", "dhcpv4"]
In this case, the usage of Qemu's user networking is possible. For the example, the small example web server can be started with following command:
$ qemu-system-x86_64 -smp 1 -m 256M -kernel lpath_to_loader/rusty-loader -initrd path_to_hhtpd/httpd -display none -serial stdio -netdev user,id=u1,hostfwd=tcp::9975-:9975 -device rtl8139,netdev=u1 --enable-kvm -cpu host
In case of the usage of Qemu's user networking, the network interface RTL 8139 must be used. The command already open with hostfwd=tcp::9975-:9975 the port of the web server. In this case, Qemu is listening on the local port 9975 and forward all requests to the guest server, which is also listening at port 9975.
By adding -object filter-dump,id=f1,netdev=u1,file=dump.dat
to the command line, the network traffic can be captured and stored in the file dump.dat.
Afterwards, the traffic can be analyzed by Wirehshark.
For instance, the following command dump the network traffic in a readable text form.
tshark -r ./dump.dat
It is possible to share the host file system with RustyHermit when using Qemu, but you must use QEMU with VirtioFS support to do this.
- Download the source code from the VirtioFS project:
git clone https://gitlab.com/virtio-fs/qemu.git
cd qemu
- Switch to the branch with VirtioFS and DAX support:
git checkout qemu5.0-virtiofs-dax
mkdir build && cd build
- Configure source code:
../configure --prefix=$PATH_TO_INSTALL_DIRECTORY --target-list=x86_64-softmmu
- Please check if VirtioFS support is activated
- Build Qemu:
make -j 4
- Install Qemu:
make install
- Prepare a filesystem for the guest. For instance, create a directory within
/tmp
, which will serve as the mountable directory within the guest, e.g. executemkdir /tmp/guestfs
- Start the VirtioFS daemon and export the current working directory to the guest:
sudo virtiofsd --thread-pool-size=1 --socket-path=/tmp/vhostqemu -o source=/tmp/guestfs --daemonize &
- Give non-root-users access to the socket:
sudo chmod 777 /tmp/vhostqemu
- Start the application, e.g. the following will execute the RustyHermit demo:
qemu-system-x86_64 -enable-kvm -cpu host -display none -smp 1 -m 256M -serial stdio -kernel loader/target/x86_64-unknown-hermit-loader/debug/rusty-loader -initrd target/x86_64-unknown-hermit/debug/rusty_demo -chardev socket,id=char0,path=/tmp/vhostqemu -device vhost-user-fs-pci,queue-size=1024,chardev=char0,tag=root -object memory-backend-file,id=mem,size=256M,mem-path=/dev/shm,share=on -numa node,memdev=mem
These commands mount the host directory /tmp/guestfs
in the guest as /root
. Per default /root
is the working directory of RustyHermit. The working directory can changed by setting the environment variable HERMIT_WD
before compiling RustyHermit. In addition, the tag root
in argument list of Qemu specifies the path within the guest.
Note: The demo application will try to read /etc/hostname
, which still fails because the directory etc
isn't mounted within the quest.
DAX mapping allows RustyHermit direct access to file content from the host file cache.
The device section of the Qemu command line must be changed as follows: qemu-system-x86_64 -enable-kvm -cpu host -display none -smp 1 -m 256M -serial stdio -kernel loader/target/x86_64-unknown-hermit-loader/debug/rusty-loader -initrd target/x86_64-unknown-hermit/debug/rusty_demo -chardev socket,id=char0,path=/tmp/vhostqemu -device vhost-user-fs-pci,queue-size=1024,chardev=char0,tag=root,cache-size=256M -object memory-backend-file,id=mem,size=256M,mem-path=/dev/shm,share=on -numa node,memdev=mem