Skip to content
Snippets Groups Projects
Unverified Commit b65e7e58 authored by bors[bot]'s avatar bors[bot] Committed by GitHub
Browse files

Merge #380

380: Readme: Remove project-specifcs r=jounathaen a=mkroening

See https://github.com/hermitcore/rusty-loader/pull/176

.

Co-authored-by: default avatarMartin Kröning <mkroening@posteo.net>
parents 4b6892bc 4a327d3e
No related branches found
No related tags found
No related merge requests found
Pipeline #857453 failed
......@@ -37,193 +37,8 @@ Rust applications that use the Rust runtime and do not directly use OS services
## Building your own applications
To give you an example on how to build your application with RustyHermit, lets create a new cargo project:
A more comprehensive version of the example project is published at [rusty-demo](https://github.com/hermitcore/rusty-demo).
Have a look at [rusty-demo](https://github.com/hermitcore/rusty-demo).
```sh
cargo new hello_world
cd hello_world
```
To bind the library operating system to the application, add the crate [hermit-sys](https://crates.io/crates/hermit-sys) to the dependencies in the file *Cargo.toml*.
It is important to use at least the _optimization level 1_.
Consequently, it is required to **extend** *Cargo.toml* with following lines:
```toml
# Cargo.toml
[target.'cfg(target_os = "hermit")'.dependencies]
hermit-sys = "0.2.*"
```
To link the application with RustyHermit, declare `hermit_sys` an `external crate` in the main file of your application.
```rust
// src/main.rs
#[cfg(target_os = "hermit")]
use hermit_sys as _;
fn main() {
println!("Hello World!");
}
```
The final step is building the application as follows:
```sh
cargo build -Zbuild-std=std,core,alloc,panic_abort --target x86_64-unknown-hermit
```
(You can set an easy alias for this in the `.cargo/config` file. Take a look at the [demo](https://github.com/hermitcore/rusty-demo/blob/master/.cargo/config))
The resulting "hypervisor-ready" binary then can be found in `target/x86_64-unknown-hermit/debug`.
## Running RustyHermit
RustyHermit binaries can be run on either uhyve or qemu.
### Using uhyve as Hypervisor
RustyHermit can run within our own hypervisor [*uhyve*](https://github.com/hermitcore/uhyve) , which requires [KVM](https://www.linux-kvm.org/) to create a virtual machine.
Please install the hypervisor as follows:
```sh
cargo +nightly install uhyve --locked
```
Afterwards, your are able to start RustyHermit applications within our hypervisor:
```sh
uhyve target/x86_64-unknown-hermit/debug/hello_world
```
More details can be found in the [uhyve README](https://github.com/hermitcore/uhyve).
### Using Qemu as Hypervisor
It is also possible to run RustyHermit within [Qemu](https://www.qemu.org).
RustyHermit produces 64-bit binaries, but Qemu's x86 emulation cannot boot them directly.
Therefore, the loader [rusty-loader](https://github.com/hermitcore/rusty-loader) is required to boot the application.
A prebuilt loader binary can be found at [rusty-loader releases](https://github.com/hermitcore/rusty-loader/releases).
The unikernel application `app` can be booted with the following command:
```bash
qemu-system-x86_64 -smp 1 \
-cpu qemu64,apic,fsgsbase,rdtscp,xsave,xsaveopt,fxsr \
-device isa-debug-exit,iobase=0xf4,iosize=0x04 \
-display none -m 64M -serial stdio -enable-kvm \
-kernel path_to_loader/rusty-loader-x86_64 \
-initrd path_to_app/app
```
It is important to enable the processor features _fsgsbase_ and _rdtscp_ because it is a prerequisite to boot RustyHermit.
You can provide arguments to the application via the kernel commandline, which you can set with qemu's `-append` option. Since both the kernel and the application can have parameters, they are separated with `--`:
```bash
qemu-system-x86_64 ... -append "kernel-arguments -- application-arguments"
```
### Using Qemu as microVM
Qemu provides [microvm virtual platform](https://qemu.readthedocs.io/en/latest/system/i386/microvm.html), which is a minimalist machine type without PCI nor ACPI support.
In comparison to a common hypervisor, it has a clearly smaller memory footprint and a faster boot time.
To use this VM type, all default features of RustyHermit has to be disabled (especially PCI and ACPI support).
For instance, the following command builds the smallest version of the [`hello_world` example](https://github.com/hermitcore/rusty-hermit/tree/master/examples/hello_world):
```bash
cargo build -Zbuild-std=core,alloc,std,panic_abort --target x86_64-unknown-hermit --no-default-features -p hello_world --release
```
Afterwards, this minimal example can be loaded with the same boot loader like the common Qemu machine type:
```bash
qemu-system-x86_64 \
-M microvm,x-option-roms=off,pit=off,pic=off,rtc=on,auto-kernel-cmdline=off \
-nodefaults -no-user-config -display none -smp 1 -m 512M -serial stdio \
-kernel path_to_loader/rusty-loader \
-initrd path_to_hello_world/hello_world \
-cpu qemu64,apic,fsgsbase,rdtscp,xsave,xsaveopt,fxsr \
-device isa-debug-exit,iobase=0xf4,iosize=0x04 \
-append "-freq 2800"
```
Depending on the virtualized processor, the processor frequency has to pass as kernel argument (`-freq`) to the kernel.
MHz is used as unit of frequency here.
Kernel features like TCP/IP support can be reenabled manually.
For instance, the following command creates a [minimal web-server](https://github.com/hermitcore/rusty-hermit/tree/master/examples/httpd) for Qemu's microvm platform:
```bash
cargo build -Zbuild-std=core,alloc,std,panic_abort --target x86_64-unknown-hermit --no-default-features --features tcp -p httpd --release
```
## Advanced Features
You are not happy with `Hello World` yet?
### Controlling kernel message verbosity
RustyHermit uses the lightweight logging crate [log](https://github.com/rust-lang/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](https://docs.rs/log/0.4.8/log/enum.LevelFilter.html), 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 builds RustyHermit with debug messages:
```sh
HERMIT_LOG_LEVEL_FILTER=Debug cargo build -Zbuild-std=core,alloc,std,panic_abort --target x86_64-unknown-hermit
```
### Network support
To enable an ethernet device, we have to setup a tap device on the
host system. For instance, the following command establish the tap device
`tap10` on Linux:
```bash
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 `tcp` in the `Cargo.toml`. This includes the network stack [smoltcp](https://github.com/smoltcp-rs/smoltcp) and offers TCP/UDP communication.
`hermi-sys` dependency has to be factored out of `[target.'cfg(target_os = "hermit")'.dependencies]` because it requires features selection for network support to work thus this snippet should be added to `Cargo.toml`
```toml
# Cargo.toml
[target.'cfg(target_os = "hermit")'.dependencies.hermit-sys]
version = "0.2.*"
default-features = false
features = ["tcp", "pci"]
```
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`.
```sh
HERMIT_IP="10.0.5.100" cargo build -Zbuild-std=core,alloc,std,panic_abort --target x86_64-unknown-hermit
```
Currently, RustyHermit does only support network interfaces through [virtio](https://www.redhat.com/en/blog/introduction-virtio-networking-and-vhost-net).
To use it, you have to start RustyHermit in Qemu with following command:
```bash
$ qemu-system-x86_64 -cpu qemu64,apic,fsgsbase,rdtscp,xsave,xsaveopt,fxsr \
-enable-kvm -display none -smp 1 -m 1G -serial stdio \
-device isa-debug-exit,iobase=0xf4,iosize=0x04 \
-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
```
You can now access the files in SHARED_DIRECTORY under the virtiofs tag like `/myfs/testfile`.
## Use RustyHermit for C/C++, Go, and Fortran applications
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment