Accelerate OS development with Asterinas OSDK
What is it?
OSDK (short for Operating System Development Kit) is designed to simplify the development of Rust operating systems. It aims to streamline the process by leveraging the framekernel architecture, originally proposed by Asterinas.
cargo-osdk
is a command-line tool that facilitates project management for those developed on the framekernel architecture. Much like Cargo for Rust projects, cargo-osdk
enables building, running, and testing projects conveniently.
Install the tool
Requirements
Currenly, cargo-osdk
only supports x86_64 ubuntu system.
cargo-osdk
requires the following tools to be installed:
- Rust >= 1.75.0
- Gcc compiler
About how to install Rust, you can refer to the official site.
Gcc compiler can be installed by
apt install build-essential
Install
Then, cargo-osdk
can be installed by
cargo install cargo-osdk
Upgrade
If cargo-osdk
is already installed, the tool can be upgraded by
cargo install --force cargo-osdk
Get start
Here we provide a simple demo to demonstrate how to create and run a simple kernel with cargo-osdk
.
Suppose you are on a x86_64 ubuntu machine, to run a kernel with QEMU, the following tools should be installed:
- qemu-system-x86_64
- grub-mkrescue
- ovmf
- xorriso
If these tools are missing, they can be installed by
apt install grub2-common qemu-system-x86 ovmf xorriso
With cargo-osdk
, a kernel project can be created by one command
cargo osdk new --kernel my-first-os
Then, you can run the kernel with
cd my-first-os && cargo osdk run
You will see Hello world from guest kernel!
from your console.
Basic usage
The basic usage of cargo-osdk
is
cargo osdk <COMMAND>
Currently we support following commands:
- new: Create a new kernel package or library package
- build: Compile the project and its dependencies
- run: Run the kernel with a VMM
- test: Execute kernel mode unit test by starting a VMM
- check: Analyze the current package and report errors
- clippy: Check the current package and catch common mistakes
The following command can be used to discover the available options for each command.
cargo osdk help <COMMAND>
The configuration file
cargo-osdk
utilizes a configuration file to define its precise behavior. Typically, the configuration file is named OSDK.toml
and is placed in the root directory of the workspace (the same directory as the workspace's Cargo.toml
). If there is only one crate and no workspace, the file is placed in the crate's root directory. Below, you will find a comprehensive version of the available configuration options.
kcmd_args = ["init=/bin/busybox", "path=/usr/local/bin"] # <1>
init_args = ["sh", "-l"] # <2>
initramfs="./build/initramfs.cpio.gz" # <3>
[boot]
loader = "grub" # <4>
protocol = "multiboot2" # <5>
grub-mkrescue = "/usr/bin/grub-mkrescue" # <6>
ovmf = "/usr/bin/ovmf" # <7>
[qemu]
path = "/usr/bin/qemu-system-x86_64" # <8>
machine = "q35" # <9>
args = [ # <10>
"--enable-kvm",
"-m 2G",
"--device virtio-keyboard-pci,disable-legacy=on,disable-modern=off"
]
[qemu.'cfg(feature="iommu")'] # <11>
path = "/usr/local/sbin/qemu-kvm" # <8>
machine = "q35" # <9>
args = [ # <10>
"-device virtio-keyboard-pci,disable-legacy=on,disable-modern=off,iommu_platform=on,ats=on",
"-device intel-iommu,intremap=on,device-iotlb=on"
]
- The arguments provided will be passed to the guest kernel.
Optional. The default value is empty.
Each argument should be in one of the following two forms:KEY=VALUE
orKEY
if no value is required. EachKEY
can appear at most once. - The arguments provided will be passed to the init process, usually, the init shell.
Optional. The default value is empty. - The path to the built initramfs.
Optional. The default value is empty. - The bootloader used to boot the kernel.
Optional. The default value isgrub
.
The allowed values aregrub
andqemu
(qemu
indicates that QEMU directly boots the kernel). - The boot protocol used to boot the kernel.
Optional. The default value ismultiboot2
.
The allowed values arelinux-efi-handover64
,linux-legacy32
,multiboot
, andmultiboot2
. - The path of
grub-mkrescue
, which is used to create a GRUB CD_ROM.
Optional. The default value is system path, determined usingwhich grub-mkrescue
.
This argument only takes effect when the bootloader isgrub
. - The path of OVMF. OVMF enables UEFI support for QEMU.
Optional. The default value is empty.
This argument only takes effect when the boot protocol islinux-efi-handover64
. - The path of QEMU.
Optional. The default value is system path, determined usingwhich qemu-system-x86_64
. - The machine type of QEMU.
Optional. Default isq35
.
The allowed values areq35
andmicrovm
. - Additional arguments passed to QEMU.
Optional. The default value is empty.
Each argument should be in the formKEY VALUE
(separated by space), orKEY
if no value is required. Some keys can appear multiple times (e.g.,--device
,--netdev
), while other keys can appear at most once. Certain keys, such as-cpu
and-machine
, are not allowed to be set here as they may conflict with the internal settings ofcargo-osdk
. - Conditional QEMU settings.
Optional. The default value is empty.
Conditional QEMU settings allow for a condition to be specified afterqemu
. Currently,cargo-osdk
only supports the conditioncfg(feature="FEATURE")
, which activates the QEMU settings only if theFEATURE
is set. TheFEATURE
must be defined in the project'sCargo.toml
. At most one conditional setting can be activated at a time. If multiple conditional settings can be activated simultaneously,cargo-osdk
will report an error. In the future,cargo-osdk
will support all possible conditions that Rust conditional compilation supports.
The framekernel architecture
The architecture divides the OS development into two distinct realms: the safe world and the unsafe world. In the safe world, only safe Rust code is allowed, while the unsafe world can tap into the power of the unsafe keyword. At the heart of the unsafe world lies aster-frame
, a compact framework with limited functionalities. It encapsulates essential OS operations such as booting, physical memory management, context switching, and more.
With aster-frame
as the foundation, higher-level OS functionalities like process management, file systems, network protocols, and even device drivers can be built upon it using only safe Rust. This segregation ensures that critical operations are handled securely in the unsafe realm while allowing for the development of complex and feature-rich OS components.
In addition to OS functionalities, aster-frame
also provides development utilities, including kernel mode unit test support. The shared base of crates built on aster-frame
allows for easy reuse and facilitates the creation of sophisticated operating systems with rich features.
Overall, this architectural approach promotes safety and modularity, empowering developers to build robust and advanced OS systems using Rust.