Skip to content

Commit e7781fe

Browse files
authored
Merge pull request #38 from rust-osdev/showcase
Add a new 'Showcase' section
2 parents a106931 + f3f6c54 commit e7781fe

File tree

12 files changed

+269
-10
lines changed

12 files changed

+269
-10
lines changed

content/showcase/_index.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
+++
2+
title = "Showcase"
3+
sort_by = "date"
4+
page_template = "showcase.html"
5+
+++
6+
7+
In this section, we present interesting operating system projects written in Rust. Feel free to add your own project by [creating a pull request](https://github.com/rust-osdev/homepage/pulls).
63.6 KB
Loading
41.4 KB
Loading
Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
+++
2+
title = "The <code>RustyHermit</code> Unikernel"
3+
date = 2021-01-22
4+
5+
[extra]
6+
authors = ["stlankes"]
7+
+++
8+
9+
[RustyHermit](https://github.com/hermitcore/rusty-hermit) is a unikernel, which is completely written Rust. [Unikernels](http://unikernel.org/) are application images that directly contain the kernel as a library, so they do not require an installed operating system (OS). They are typical used in virtualized environments, which build the backbone of typical cloud / edge infrastructures.
10+
11+
<!-- more -->
12+
13+
<!-- showcase-intro -->
14+
15+
## Virtualization Designs
16+
17+
Common virtualized environments are based on classical **_virtual machines_**. In this case, complete machines are emulated or virtualized and common operating systems are running on both host and guest site:
18+
19+
![Structure of a common virtualitation environment](common_vm.png)
20+
21+
This technique is established (VMware, Hyper-V, etc.) and widely used. However, it introduces additional overhead especially regarding memory consumption and performance.
22+
23+
An alternative approach to common virtual machines is **_OS-level
24+
virtualization_**, where the kernel allows the existence of multiple
25+
isolated user space instances. These isolated instances are also known
26+
as container. A typical representative is LXC or Docker and promise less
27+
overhead in comparison to common virtual machines. However, the
28+
isolation between the processes is weaker and may provide less security.
29+
30+
## Unikernels
31+
32+
Often only one application (e.g. a web server) is running in the container or the virtual machine. In this case, a _unikernel_ is an attractive solution. The kernel is provided as static library and linked to the application. As the images directly contain the OS kernel, unikernels can directly be booted inside a virtual machine and do not require the typical software stack containing a Linux kernel and its userland within the VM.
33+
34+
Unikernels do not provide system calls in the classical sense, as everything is running with the privilege level of a kernel and what is typically done via system calls is provided via a common function call. At first glance, this sounds more insecure than previous approaches. However, these kernels are expected to run within a virtual machine, which isolates the application from the real system. In addition, common compiler analysis is used to check the complete software stack and unneeded components can even be removed, which can reduce the attack surface of the application.
35+
36+
![Structure of a library operating system](libos.png)
37+
38+
Well known unikernels are kernels such as [MirageOS](https://mirage.io/)
39+
and [Unikraft](http://www.unikraft.org/). MirageOS is written in OCaml,
40+
while Unikraft still uses C as programming language. In contrast to these
41+
kernels, RustyHermit is completely written in Rust to benefit from
42+
Rust's performance and security behavior.
43+
44+
## RustyHermit
45+
46+
In principle, every existing
47+
Rust application can be built on top of RustyHermit. However, unikernels
48+
are a single tasking operating system. Consequently, the support of the
49+
system call `fork` and inter-process communication are missing. In
50+
addition, a classical C library is missing, which is typical used as
51+
interface to the operating system. Every crate, which bypasses the
52+
standard runtime and tries to communicate directly to operating system
53+
does not work without modifications. However, many applications do not
54+
depend on these features and work on RustyHermit.
55+
56+
### Performance
57+
58+
Unikernels can be highly optimized. For instance, we optimized the
59+
network stack of RustyHermit. RustyHermit uses
60+
[smoltcp](https://github.com/smoltcp-rs/smoltcp) as network stack, which
61+
is completely written in Rust. As interface between guest and host
62+
operating system, we use
63+
[Virtio](https://www.linux-kvm.org/page/Virtio), which is in a
64+
para-virtualized driver for KVM and widely used in virtualized Linux
65+
environments.
66+
67+
The following figure compares Linux with RustyHermit,
68+
where both are running as guests inside a virtual machine running on top
69+
of a Linux-based host system:
70+
71+
![Bandwidth of the RustyHermit's exerimental network interface](bandwidth.png)
72+
73+
Especially for small messages RustHermit
74+
is faster in than Linux.
75+
76+
### Research
77+
78+
RustyHermit is also a research project to evaluate new operating
79+
system designs, which improves the scalability and the security of operating systems in cloud environments. For instance, RustyHermit provides classical
80+
techniques to improve the security behavior like stack guards and
81+
separating the application stack from the libOS stack. However, a
82+
library operating system typically uses a common function call to enter
83+
the kernel. A classical separation of user- and kernel space by
84+
entering a higher privilege level is missing.
85+
86+
We presented in a
87+
[paper](https://www.ssrg.ece.vt.edu/papers/vee20-mpk.pdf) a modified
88+
version of RustyHermit, which provides an intra-unikernel isolation with
89+
_Intel Memory Protection Keys_ (MPK). MPK is a relatively new hardware
90+
primitive that provides per-thread permission control over groups of
91+
pages in a single address space with [negligible switching overhead](https://www.usenix.org/conference/atc19/presentation/park-soyeon),
92+
making it a compelling candidate for use in unikernels.
93+
94+
MPK is requiring modification of page tables at a small performance cost. Four previously-unused bits of each page table entry (the 62nd to the 59th on x86-64) are exploited by MPK. Since MPK exploits four bits of the page table entry, it supports up to 15 protection keys.
95+
MPK controls per-thread permission on groups of pages. Each core has a PKRU register (32 bits) containing a permission value. The value of the PKRU register defines the permission of the thread currently running on that core for each group of pages containing a protection key in their page table entries. Unlike page-table-level permission, MPK provides thread-local memory permission.
96+
97+
We provide user / kernel separation so we simply see the entire application as an untrusted component, independently of application-specific characteristics such as the language it is written in or the level of skill of the application’s programmer. In addition, we divide the kernel code into trusted and untrusted components. Trusted kernel components represent pieces of code written with a memory-safe language, i.e., offering strong security guarantees. Untrusted kernel components correspond to code written either in memory-unsafe languages or in unsafe Rust code blocks.
98+
99+
By entering the library operating system through the application binary interface the protection keys will be automatically changed, which allows access to the kernel stack and the kernel heap. Unauthorized access from within the application will trigger a pagefault, which will be handled by the library operating system.
100+
101+
### Example Project
102+
103+
To give you an example on how to build an RustyHermit application, lets create a new cargo project:
104+
105+
```sh
106+
cargo new hello_world
107+
cd hello_world
108+
```
109+
110+
RustyHermit currently requires the nightly versions of the Rust toolchain.
111+
To simplify the workflow, we recommend to create the configuration
112+
_rust-toolchain_ as follows to define the required components and to
113+
tested version of nightly compiler:
114+
115+
```toml
116+
[toolchain]
117+
channel = "nightly-2020-12-23"
118+
components = [ "rustfmt", "rust-src", "llvm-tools-preview"]
119+
targets = [ "x86_64-unknown-hermit" ]
120+
```
121+
122+
The configuration file specifies the required components and the version of the nightly compiler to use.
123+
124+
The RustyHermit's target `x86_64-unknown-hermit` is part of Rust
125+
supported platforms, but doesn't belong to the *tier 1* platforms,
126+
which means that official binary releases aren't available and the
127+
standard runtime must be build from scratch.
128+
To simplify this build process, we recommend to create the configuration
129+
file `.cargo/config` as follows:
130+
131+
```toml
132+
[unstable]
133+
build-std = ["std", "core", "alloc", "panic_abort"]
134+
135+
[build]
136+
target = "x86_64-unknown-hermit"
137+
```
138+
139+
To bind the library operating system to the application, we have to add the crate [`hermit-sys`](https://crates.io/crates/hermit-sys) to the dependencies in the file `Cargo.toml`:
140+
141+
```toml
142+
# Cargo.toml
143+
144+
[target.'cfg(target_os = "hermit")'.dependencies]
145+
hermit-sys = "0.1.*"
146+
features = ["smoltcp"]
147+
```
148+
149+
The feature `smoltcp` is required if your application tries
150+
to establish a TCP connection. In this case, the library operating systems
151+
includes the TCP/stack [smoltcp](https://github.com/smoltcp-rs/smoltcp).
152+
In addition _hermit-sys_ depends on the tool [cargo-download](https://crates.io/crates/cargo-download) to download required components and must be installed with the command `cargo install cargo-download`.
153+
Finally, the application can be build with the common command `cargo build`.
154+
155+
The result is a 64-bit excutable in the [executable link format](https://refspecs.linuxfoundation.org/elf/elf.pdf) (ELF).
156+
To start the application within a common virtual machine, a loader is required, which initialize the processor and start the applications.
157+
We provide a simple loader on [GitHub](https://github.com/hermitcore/rusty-loader).
158+
A makefile to build the loader is part of the project.
159+
After that, Qemu can be used to start RustyHermit in a VM as follows:
160+
161+
```sh
162+
qemu-system-x86_64 -display none -smp 1 -m 64M -serial stdio -kernel path_to_loader/rusty-loader -initrd path_to_app/app -cpu qemu64,apic,fsgsbase,rdtscp,xsave,fxsr
163+
```
164+
165+
To improve the performance, KVM can be used to use the virtualization extension of modern processors.
166+
167+
```sh
168+
qemu-system-x86_64 -display none -smp 1 -m 64M -serial stdio -kernel path_to_loader/rusty-loader -initrd path_to_hello_world/hello_world -enable-kvm -cpu host
169+
```
170+
171+
### Roadmap
172+
173+
For the near future, we plan to stabilize the interface to the hardware.
174+
For instance, the support of [Virtio-fs](https://virtio-fs.gitlab.io/)
175+
is in an early stage. In addition, the integration into Rust standard
176+
library isn't finalized yet and the current version runs only on x86. In the
177+
future, we want to also support aarch64 as processor architecture.
44.7 KB
Loading

content/this-month/_index.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
+++
22
title = "This Month in Rust OSDev"
3-
template = "section.html"
43
sort_by = "date"
5-
description = "These posts give a regular overview of the most important changes to the RustOSDev tools and libraries."
64
render = false
75
+++
6+
7+
These posts give a regular overview of the most important changes to the RustOSDev tools and libraries.

static/css/main.css

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,17 @@ h1 code, h2 code, h3 code, h4 code, h5 code, h6 code {
2525
font-size: 95%;
2626
background-color: inherit;
2727
}
28+
29+
.post-summary p:last-of-type{
30+
display: inline;
31+
}
32+
33+
.read-more {
34+
margin-left: 5px;
35+
}
36+
37+
.showcase-post-intro {
38+
color: gray;
39+
font-style: italic;
40+
margin-left: 1rem;
41+
}

templates/index.html

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,24 @@
66

77
<h1 style="visibility: hidden; height: 0px; margin: 0px; padding: 0px;">Rust OSDev</h1>
88

9-
<h2>This Month in Rust OSDev</h2>
10-
{% set section = get_section(path = "this-month/_index.md") %}
11-
<p>{{ section.description }}</p>
9+
{% set this_month = get_section(path = "this-month/_index.md") %}
10+
<h2>{{ this_month.title }}</h2>
11+
{{ this_month.content | safe }}
1212
<ul>
13-
{% for page in section.pages %}
13+
{% for page in this_month.pages %}
1414
<li><a href="{{ page.path | safe }}">{{ page.extra.month }}</a></li>
1515
{% endfor %}
1616
</ul>
1717

18+
{% set showcase = get_section(path = "showcase/_index.md") %}
19+
<h2>{{ showcase.title }}</h2>
20+
{{ showcase.content | safe }}
21+
<ul>
22+
{% for page in showcase.pages %}
23+
<li><a href="{{ page.path | safe }}">{{ page.title | safe }}</a></li>
24+
{% endfor %}
25+
</ul>
26+
1827
{% endblock main %}
1928

2029
{% block after_main %}

templates/page.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
{% extends "base.html" %}
22

3-
{% block title %}{{ page.title }} | {{ config.title }}{% endblock title %}
3+
{% block title %}{{ page.title | striptags }} | {{ config.title }}{% endblock title %}
44

55
{% block main %}
6-
<h1>{{ page.title }}</h1>
6+
<h1>{{ page.title | safe}}</h1>
77

88
<span class="post-authors post-date">Written by
99
{% for author in page.extra.authors -%}

templates/section.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,12 @@
77
<h1>{{ section.title }}</h1>
88

99
{% block introduction %}
10-
<p>{{ section.description }}</p>
10+
<p>{{ section.content | safe }}</p>
1111
{% endblock introduction %}
1212

1313
<div class="posts">
1414
{% for page in section.pages %}
15-
<h2 class="post-title"><a href="{{ page.path | safe }}">{{ page.title }}</a></h2>
15+
<h2 class="post-title"><a href="{{ page.path | safe }}">{{ page.title | safe}}</a></h2>
1616
<div class="post-summary">
1717
{{ page.summary | safe }}
1818
<a class="read-more" href="{{ page.path | safe }}"><em>read&nbsp;more&nbsp;»</em></a>

0 commit comments

Comments
 (0)