Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions rs-hello/.cargo/config.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[build]
target = ["x86_64-unknown-none"]
2 changes: 2 additions & 0 deletions rs-hello/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/workdir/
/target
7 changes: 7 additions & 0 deletions rs-hello/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 12 additions & 0 deletions rs-hello/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[package]
name = "rs-hello"
version = "0.1.0"
edition = "2021"

[profile.dev]
panic = "abort"

[profile.release]
panic = "abort"

[dependencies]
13 changes: 13 additions & 0 deletions rs-hello/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
UK_ROOT ?= $(PWD)/workdir/unikraft
UK_BUILD ?= $(PWD)/workdir/build
UK_APP ?= $(PWD)
LIBS_BASE = $(PWD)/workdir/libs
UK_LIBS ?=

.PHONY: all

all:
@$(MAKE) -C $(UK_ROOT) L=$(UK_LIBS) A=$(UK_APP) O=$(UK_BUILD)

$(MAKECMDGOALS):
@$(MAKE) -C $(UK_ROOT) L=$(UK_LIBS) A=$(UK_APP) O=$(UK_BUILD) $(MAKECMDGOALS)
3 changes: 3 additions & 0 deletions rs-hello/Makefile.uk
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
$(eval $(call addlib,apprshello))

APPRSHELLO_OBJS-y += $(APPRSHELLO_BASE)/target/x86_64-unknown-none/debug/deps/rs_hello-*.o
195 changes: 195 additions & 0 deletions rs-hello/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
# Rust Hello on Unikraft

Build and run a `std` independent Rust Hello program on Unikraft.
Follow the instructions below to set up, configure, build and run Rust Hello.
Make sure you installed the [requirements](../README.md#requirements) and the [Rust toolchain channel through Rustup](https://www.rust-lang.org/tools/install).

## Quick Setup (aka TLDR)

For a quick setup, run the commands below.
Note that you still need to install the [requirements](../README.md#requirements) and the [Rust toolchain](https://www.rust-lang.org/tools/install).
Before everything, make sure you run the [top-level `setup.sh` script](../setup.sh).

To build and run the application for `x86_64`, use the commands below:

```console
./setup.sh
make distclean
rustup target add x86_64-unknown-none
cargo +stable rustc -- --emit=obj
wget -O /tmp/defconfig https://raw.githubusercontent.com/unikraft/catalog-core/refs/heads/scripts/rs-hello/scripts/defconfig/qemu.x86_64
UK_DEFCONFIG=/tmp/defconfig make defconfig
make -j $(nproc)
qemu-system-x86_64 -nographic -m 8 -cpu max -kernel workdir/build/rs-hello_qemu-x86_64
```

This will configure, build and run the application, resulting in a `Hello from Unikraft!` message being printed.

Information about every step is detailed below.

## Set Up

Set up the required repositories.
For this, you have two options:

1. Use the `setup.sh` script:

```console
./setup.sh
```

It will create symbolic links to the required repositories in `../repos/`.
Be sure to run the [top-level `setup.sh` script](../setup.sh).

If you want use a custom variant of repositories (e.g. apply your own patch, make modifications), update it accordingly in the `../repos/` directory.

1. Have your custom setup of repositories in the `workdir/` directory.
Clone, update and customize repositories to your own needs.

## Clean

While not strictly required, it is safest to clean the previous build artifacts:

```console
make distclean
```

## Compile Rust source file

To generate the object file of the Rust source file, use:

```
rustup target add x86_64-unknown-none
cargo +stable rustc -- --emit=obj
```

## Configure

To configure the kernel, use:

```console
make menuconfig
```

In the console menu interface, choose the target architecture (x86_64) and platform (KVM/QEMU).

The end result will be the creation of the `.config` configuration file.

## Build

Build the application for the current configuration:

```console
make -j $(nproc)
```

This results in the creation of the `workdir/build/` directory storing the build artifacts.
The unikernel application image file is `workdir/build/rs-hello_<plat>-<arch>`, where `<plat>` is the platform name (`qemu`), and `<arch>` is the architecture (`x86_64`).

### Use a Different Compiler

If you want to use a different compiler, such as a Clang or a different GCC version, pass the `CC` variable to `make`.

To build with Clang, use the commands below:

```console
make properclean
make CC=clang -j $(nproc)
```

Note that Clang >= 14 is required to build Unikraft.

To build with another GCC version, use the commands below:

```console
make properclean
make CC=gcc-<version> -j $(nproc)
```

where `<version>` is the GCC version, such as `11`, `12`.

Note that GCC >= 8 is required to build Unikraft.

## Run

Run the resulting image using the corresponding platform tool.

A successful run will show a message such as the one below:

```text
Booting from ROM..Powered by
o. .o _ _ __ _
Oo Oo ___ (_) | __ __ __ _ ' _) :_
oO oO ' _ `| | |/ / _)' _` | |_| _)
oOo oOO| | | | | (| | | (_) | _) :_
OoOoO ._, ._:_:_,\_._, .__,_:_, \___)
Helene 0.18.0~12072b5f
Hello from Unikraft!
```

### Run on QEMU/x86_64

```console
qemu-system-x86_64 -nographic -m 8 -cpu max -kernel workdir/build/rs-hello_qemu-x86_64
```

## Clean Up

Doing a new configuration, or a new build may require cleaning up the configuration and build artifacts.

In order to remove the build artifacts, use:

```console
make clean
```

In order to remove fetched files also, that is the removal of the `workdir/build/` directory, use:

```console
make properclean
```

In order to remove the generated `.config` file as well, use:

```console
make distclean
```

In order to remove the generated files by Cargo in the `target` directory, use:

```console
cargo clean
```
## Customize

Rust Hello is the simplest application to be run with Unikraft.
This makes it ideal as a minimal testing ground for new features: it builds fast, it doesn't have dependencies.

### Update the Unikraft Core Code

If updating the Unikraft core code in the `./workdir/unikraft/` directory, you then go through the [configure](#configure), [build](#build) and [run](#run) steps.

### Add Other Object Files

The current configuration use a object file.
If looking to add another file to the build, update the [`Makefile.uk`](Makefile.uk) file.

For example, to add a new object file `support.o` to the build, update the [`Makefile.uk`](Makefile.uk) file to:

```make
$(eval $(call addlib,apprshello))

APPRSHELLO_OBJS-y += $(APPRSHELLO_BASE)/target/x86_64-unknown-none/debug/deps/rs_hello-*.o
APPRSHELLO_OBJS-y += $(APPRSHELLO_BASE)/support.o
```

To include a Rust library, such as `librs_hello.rlib`, update the [`Makefile.uk`](Makefile.uk) file to:

```make
$(eval $(call addlib,apprshello))

APPRSHELLO_OBJS-y += $(APPRSHELLO_BASE)/target/x86_64-unknown-none/debug/deps/rs_hello-*.o
APPRSHELLO_ALIBS-y += $(APPRSHELLO_BASE)/librs_hello.rlib
```

Then go through the [configure](#configure), [build](#build) and [run](#run) steps.
44 changes: 44 additions & 0 deletions rs-hello/scripts/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Scripts for Rust Hello on Unikraft

These are companions instruction to the main instructions in the [`README`](README.md).

Use scripts as quick actions for building and running Rust Hello on Unikraft.

**Note**: Run scripts from the application directory.

## Build for <plat> / <arch>:

```console
./scripts/build/<plat>.<arch>
```

e.g.:

```console
./scripts/build/qemu.x86_64
```

## Build for <plat> / <arch> using a different compiler

```console
CC=/path/to/compiler ./scripts/build/<plat>.<arch>
```

e.g.

```console
CC=/usr/bin/gcc-12 ./scripts/build/qemu.x86_64
CC=/usr/bin/clang ./scripts/build/qemu.x86_64
```

## Run on <plat> / <arch>

```console
./scripts/run/<plat>.<arch>
```

e.g.

```console
./scripts/run/qemu.x86_64
```
15 changes: 15 additions & 0 deletions rs-hello/scripts/build/qemu.x86_64
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#!/bin/sh

make distclean
cargo clean
rustup target add x86_64-unknown-none
cargo +stable rustc -- --emit=obj
UK_DEFCONFIG=$(pwd)/scripts/defconfig/qemu.x86_64 make defconfig
touch Makefile.uk
make prepare
if test -z "$CC"; then
make -j $(nproc)
else
make CC="$CC" -j $(nproc)
fi

4 changes: 4 additions & 0 deletions rs-hello/scripts/defconfig/qemu.x86_64
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
CONFIG_PLAT_KVM=y
CONFIG_KVM_VMM_QEMU=y
CONFIG_ARCH_X86_64=y

14 changes: 14 additions & 0 deletions rs-hello/scripts/run/qemu.x86_64
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#!/bin/sh

if test ! -f "workdir/build/rs-hello_qemu-x86_64"; then
echo "No kernel file workdir/build/rs-hello_qemu-x86_64." 1>&2
echo "Did you run ./build.qemu.x86_64 ?" 1>&2
exit 1
fi

qemu-system-x86_64 \
-nographic \
-m 8 \
-cpu max \
-kernel workdir/build/rs-hello_qemu-x86_64

2 changes: 2 additions & 0 deletions rs-hello/scripts/test/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/log/

15 changes: 15 additions & 0 deletions rs-hello/scripts/test/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Testing Rust Hello on Unikraft

These are companion instructions to the main instructions in the [`README`](../../README.md) and to the scripted run instructions in the [`scripts/README`](../README.md).
Use these scripts to test Rust Hello on Unikraft.

**Note**: Run scripts from the application directory.

Use the `all.sh` script to test all builds and all available runs:

```console
./scripts/test/all.sh
```

Logs are stored in the `./scripts/test/log/` directory.

31 changes: 31 additions & 0 deletions rs-hello/scripts/test/all.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#!/bin/sh

test_build()
{
printf "%-46s ... " build."$1"
./scripts/build/"$1" > ./scripts/test/log/build."$1" 2>&1
if test $? -eq 0; then
echo "PASSED"
else
echo "FAILED"
fi
}

test_build_run()
{
printf "%-46s ... " build."$1"
./scripts/build/"$1" > ./scripts/test/log/build."$1" 2>&1
if test $? -eq 0; then
echo "PASSED"
else
echo "FAILED"
fi

printf " %-42s ... " run."$1"
./scripts/test/wrapper.sh ./scripts/run/"$1" 2> ./scripts/test/log/run."$1"
}

./setup.sh
test -d ./scripts/test/log || mkdir ./scripts/test/log
test_build_run qemu.x86_64

Loading