SlideShare a Scribd company logo
1 of 49
Download to read offline
rrxv6: Build a RISC-V xv6 Kernel in Rust
Author: Yodalee
<lc85301@gmail.com>
Outline
1. Background Introduction
2. rrxv6 Overview
3. Inside rrxv6
4. Conclusion
Outline
1. Background Introduction
2. rrxv6 Overview
3. Inside rrxv6
4. Conclusion
There won't be much details about
xv6, RISC-V, or Operating System
● A re-implementation of Dennis Ritchie's and Ken Thompson's Unix
Version 6 (v6)
● Migrate from x86 to RISC-V multiprocessor using ANSI C
● Now used in operating systems courses at many universities.
Introduction to xv6
Introduction to RISC-V
● Open RISC standard Instruction Set Architecture (ISA) CPU
● Began in 2010 at the University of California, Berkeley.
● Alternatives to proprietary architecture like x86, ARM, etc.
https://github.com/riscvarchive/riscv-cores-list
rrxv6 Overview
Star Me on Github!
Note: (Traditional Chinese)
https://yodalee.me/series/rrxv6/
Source Code
https://github.com/yodalee/rrxv6
rrxv6 Overview (so far)
RISC-V 64 bits Hardware (on qemu)
Application
rv64
(csr operation abstraction)
Kernel
Virtual Memory
PLIC
UART Scheduler
Memory Allocator
rrxv6 Hello World
qemu-system-riscv64 -machine virt -bios none -m 128M -smp 4 -nographic -s
-kernel target/riscv64imac-unknown-none-elf/debug/rrxv6
Required Toolchain
1. Use rustup to install rust toolchain riscv64imac-unknown-none-elf (lp64)
Set target in .cargo/config
2. Install riscv gcc for linking riscv64-unknown-elf-gcc
3. Install qemu-system-riscv to emulate the hardware
// .cargo/config
[build]
target = "riscv64imac-unknown-none-elf"
[target.riscv64imac-unknown-none-elf]
rustflags = ["-C", "link-arg=-Tlinker.ld"]
rrxv6 Source Structure
Assembly:
entry.S, switch.S
…
Rust kernel
kalloc.rs, kvm.rs
scheduler.rs …
Build script:
build.rs
linker.ld
User initcode.S
kernel binary
// build.rs
use cc::Build;
fn main() -> Result<(), Box<dyn Error>> {
Build::new().file("src/entry.S").compile("asm");
Ok(())
}
Inside the rrxv6
Inside the Cargo.toml
bit_field get_bit, set_bit, get_bits, set_bits
bitflags bitmask generator
volatile-register volatile read, write memory address
mvdnes / spin-rs spinlock on static variable
lazy_static create static variable easily
rust-osdev /
linked-list-allocator
memory allocation
Going std-less
Rust does not have std in RISC-V target.
// main.rs
#![no_std]
#![no_main]
use core::panic::PanicInfo;
static STACK0: [u8;STACK_SIZE * NCPU] = [0;STACK_SIZE * NCPU];
#[no_mangle]
fn start() -> ! { loop{} }
#[panic_handler]
fn panic(_panic: &PanicInfo<'_>) -> ! {
loop {}
}
.global _entry
_entry:
# sp = STACK0 + (hartid * 4096)
la sp, STACK0
li a0, STACK_SIZE
csrr a1, mhartid
addi a1, a1, 1
mul a0, a0, a1
add sp, sp, a0
call start
What we have?
● The Core library: https://doc.rust-lang.org/core/index.html
● Actually most std just re-export modules coming from core
○ Core::alloc
○ Core::ptr
○ Core::panic
○ Core::mem
rv64: CSR Abstraction
// set M Previous Privilege mode to Supervisor, for mret.
unsigned long x = r_mstatus();
x &= ~MSTATUS_MPP_MASK ;
x |= MSTATUS_MPP_S ;
w_mstatus(x);
// set M Exception Program Counter to main, for mret.
// requires gcc -mcmodel=medany
w_mepc((uint64)main);
// disable paging for now.
w_satp(0);
// delegate all interrupts and exceptions to supervisor mode.
w_medeleg(0xffff);
w_mideleg(0xffff);
w_sie(r_sie() | SIE_SEIE | SIE_STIE | SIE_SSIE);
rv64: CSR Abstraction
In OS, we need to set processor by program the CSR. To read/write a CSR, we
need assembly csrr and csrw instructions.
Calling assembly is unsafe in Rust.
let mut x: u64;
unsafe { asm!("csrr {}, sie", out(reg) x); }
x |= (1 << 1) | (1 << 5) | (1 << 9);
unsafe { asm!("csrw sie, {}", in(reg) x); }
rv64: CSR Abstraction
pub struct Sie {
bits: u64
}
impl Sie {
pub fn from_read() -> Self {
let bits: u64;
csrr!("sie", bits);
Self { bits }
}
pub fn write(self) {
csrw!("sie", self.bits);
}
}
pub enum Interrupt {
SoftwareInterrupt,
TimerInterrupt,
ExternalInterrupt,
}
impl Sie {
pub fn set_supervisor_enable(&mut self,
interrupt: Interrupt) {
self.bits |= match interrupt {
Interrupt::SoftwareInterrupt => (1 << 1),
Interrupt::TimerInterrupt => (1 << 5),
Interrupt::ExternalInterrupt => (1 << 9),
}
}
}
rv64: CSR Abstraction
let mut sie = Sie::from_read();
sie.set_supervisor_enable(Interrupt::SoftwareInterrupt);
sie.set_supervisor_enable(Interrupt::TimerInterrupt);
sie.set_supervisor_enable(Interrupt::ExternalInterrupt);
sie.write();
● Now the code is meaningful and readable, without the noisy unsafe.
● Also, the abstraction is zero-cost.
80001c24: csrr a0,sie
80001c28: ori a0,a0,546 (0x222)
80001c2c: csrw sie,a0
MemoryAllocator
We cannot allocate memory if we are #![no_std].
All the memory allocation defined in alloc will cause panic!
Box::new(16)
Rc::new(32)
string::from_utf8()
format!("{}", 64)
vec![1,2,3,4,5]
Arc::new(48)
MemoryAllocator
We have to provide the #[global_allocator], which should implement the
GlobalAlloc Trait.
pub unsafe trait GlobalAlloc {
unsafe fn alloc(&self, layout: Layout) -> *mut u8;
unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout);
// optional
unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8;
unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8;
}
MemoryAllocator -Dummy Implementation
struct DummyAllocator;
unsafe impl GlobalAlloc for DummyAllocator {
unsafe fn alloc(&self, _layout: Layout) -> *mut u8 { null_mut() }
unsafe fn dealloc(&self, _ptr: *mut u8, _layout: Layout) {}
}
#[global_allocator]
static ALLOCATOR: DummyAllocator = DummyAllocator {};
MemoryAllocator
#[global_allocator]
static ALLOCATOR: LockedHeap = LockedHeap::empty();
pub const KERNELBASE : u64 = 0x8000_0000;
pub const PHYSTOP : u64 = KERNELBASE + 128 * 1024 * 1024;
pub fn init_kvm() {
ALLOCATOR
.lock()
.init(KERNELBASE, PHYSTOP)
}
I use rust-osdev / linked-list-allocator (and submit a patch to it)
Mutable Static
In Kernel, there are static data that must be mutable.
For example:
● The UART module
● The Scheduler module
● The CPU register data
Mutable Static
Accessing mutable static is unsafe in Rust. (what a surprise)
static mut DATA: u32 = 0;
println("{}", DATA);
error[E0133]: use of mutable static is unsafe and requires unsafe
function or block
--> a.rs:4:20
|
4 | println!("{}", DATA);
| ^^^^ use of mutable static
Mutable Static Solution 1: Unsafe
Just add unsafe whenever you access static.
Not suggested, it makes code ugly and unreadable.
static mut DATA: u32 = 0;
unsafe {
println("{}", DATA);
DATA = 1;
println!("{}", DATA);
}
Mutable Static Solution 2: Hide Inside Option
Declare as None static mut SCHEDULER: Option<Scheduler> = None;
Add initializer that
replaces it with Some.
pub fn init_scheduler() {
unsafe {
SCHEDULER = Some(Scheduler::new());
}
}
Add a getter pub fn get_scheduler() -> &'static mut Scheduler {
unsafe {
SCHEDULER.as_mut().unwrap()
}
}
Mutable Static Solution 3: Use Lock
pub struct SpinMutex<T: ?Sized,
R = Spin> {
pub(crate) lock: AtomicBool,
data: UnsafeCell<T>,
}
I use spin-rs in rrxv6 and as example.
pub struct SpinMutexGuard<'a, T:
?Sized + 'a> {
lock: &'a AtomicBool,
data: &'a mut T,
}
fn lock() -> SpinMutexGuard
Atomic change lock to true
impl Drop::drop()
Atomic change lock to false
impl Deref::deref() -> &T
self.data
Limitation: be careful not to create deadlock.
Once I put process infomations in a lock: Mutex<PROCESS[16]>
Mutable Static Solution 3: Use Lock
scheduler process[0]
Context switch
lock() and get
process[0]
Timer interrupt
Deadlock
Mutable Static Solution Comparison
Pros Cons
Unsafe Easy to use Readability
Option Easy to use Not thread-safe
Lock Thread safe Deadlock
Usually I use:
1. struct with field of Mutex<data>
2. static struct using Option
Rust have (unsmart) pointer, but we seldom use it.
In rrxv6, there are two kinds of pointers being used.
1. Raw pointer -> memory allocator, virtual memory, scheduler
2. NonNull pointer -> process trapframe and page table
Pointer
The type notation is *const T or *mut T.
The bridge between address and reference. Usually you can only change type in
Rust with:
1. primitive type: like u32 as u64
2. trait object between base/derive
The raw pointer can break this limitation.
Raw Pointer
Raw Pointer -Type Conversion
Data: T
Reference data: &T, &mut T
Raw pointer: *const T, *mut T
Data Address: u64
&
as
as
*
as
Raw pointer: *const S, *mut S as
Raw Pointer -Type Conversion
let next_table: &mut PageTable = unsafe { &mut *(pte.addr() as *mut PageTable) };
free_pagetable(next_table, …);
Data: T
Reference data: &T, &mut T
Raw pointer: *const T, *mut T Data Address: u64
&
as
as
*
as
A better pointer compared to raw pointer, must be non-zero and covariant.
Usually Option<NonNull<T>> is used.
It is still dangerous if you dereference NonNull that is not properly initialized.
For example NonNull created by NonNull::dangling()
NonNull Pointer
NonNull Pointer -Type Conversion
Reference data: &T, &mut T
NonNull<T>
as_mut()
Raw pointer: *mut T
let mut page_table_ptr = NonNull::new(kalloc() as *mut PageTable)?;
let page_table = unsafe { page_table_ptr.as_mut() };
map_pages(page_table, …)
NonNull::new()
Summary-Why Rust?
1. Rust force you to do thing in a safe way (no excuse)
-> It takes more time for Rust to build the foundation.
2. Rust give the level of abstraction - PageTableVisitor, Iterator function, etc.
// lock in xv6
struct spinlock {
uint locked;
};
struct spinlock tickslock;
uint ticks;
{
acquire(&tickslock);
ticks++;
release(&tickslock);
}
// lock in rrxv6
static ref TICK: Mutex<u64> = Mutex::new(0);
let mut tick = TICK.lock();
*tick += 1;
Conclusion
Conclusion
1. It is possible to build a kernel using Rust without std.
2. Kernel is unsafe.
3. It is all about encapsulation:
a. To create the correct type and hide the unsafe operations.
b. To convince the compiler that your program is safe.
Future Work
Features to implement:
● Virtio
● IPC
● User space program in Rust
○ If we get system call right, C program should also work.
Reference
1. xv6-riscv: https://github.com/mit-pdos/xv6-riscv
2. RISC-V specification: https://riscv.org/technical/specifications/
3. Rust bare-metal: https://docs.rust-embedded.org/book/
4. Tock-os: https://github.com/tock/tock
5. blog_os: https://github.com/phil-opp/blog_os
Keep the Spirit
Thanks for Listening

More Related Content

What's hot

JavaScript難読化読経
JavaScript難読化読経JavaScript難読化読経
JavaScript難読化読経Yosuke HASEGAWA
 
Rust で RTOS を考える
Rust で RTOS を考えるRust で RTOS を考える
Rust で RTOS を考えるryuz88
 
Cortex-M0プロセッサから自作して Lチカをやってみた
Cortex-M0プロセッサから自作してLチカをやってみたCortex-M0プロセッサから自作してLチカをやってみた
Cortex-M0プロセッサから自作して LチカをやってみたJunichi Akita
 
XSSフィルターを利用したXSS攻撃 by Masato Kinugawa
XSSフィルターを利用したXSS攻撃 by Masato KinugawaXSSフィルターを利用したXSS攻撃 by Masato Kinugawa
XSSフィルターを利用したXSS攻撃 by Masato KinugawaCODE BLUE
 
Format string Attack
Format string AttackFormat string Attack
Format string Attackicchy
 
パターンでわかる! .NET Coreの非同期処理
パターンでわかる! .NET Coreの非同期処理パターンでわかる! .NET Coreの非同期処理
パターンでわかる! .NET Coreの非同期処理Kouji Matsui
 
RSA暗号運用でやってはいけない n のこと #ssmjp
RSA暗号運用でやってはいけない n のこと #ssmjpRSA暗号運用でやってはいけない n のこと #ssmjp
RSA暗号運用でやってはいけない n のこと #ssmjpsonickun
 
30分で分かる!OSの作り方
30分で分かる!OSの作り方30分で分かる!OSの作り方
30分で分かる!OSの作り方uchan_nos
 
暗号技術入門 秘密の国のアリス 総集編
暗号技術入門 秘密の国のアリス 総集編暗号技術入門 秘密の国のアリス 総集編
暗号技術入門 秘密の国のアリス 総集編京大 マイコンクラブ
 
なんたらアジャイルその前に
なんたらアジャイルその前になんたらアジャイルその前に
なんたらアジャイルその前にTakaesu Makoto
 
ぼくのかんがえたさいきょうのうぇぶあぷりけーしょんふれーむわーく - YAPC Asia 2011
ぼくのかんがえたさいきょうのうぇぶあぷりけーしょんふれーむわーく - YAPC Asia 2011ぼくのかんがえたさいきょうのうぇぶあぷりけーしょんふれーむわーく - YAPC Asia 2011
ぼくのかんがえたさいきょうのうぇぶあぷりけーしょんふれーむわーく - YAPC Asia 2011Hiroh Satoh
 
標的型攻撃からどのように身を守るのか
標的型攻撃からどのように身を守るのか標的型攻撃からどのように身を守るのか
標的型攻撃からどのように身を守るのかabend_cve_9999_0001
 
WPSCanによるWordPressの脆弱性スキャン
WPSCanによるWordPressの脆弱性スキャンWPSCanによるWordPressの脆弱性スキャン
WPSCanによるWordPressの脆弱性スキャンOWASP Nagoya
 
CVE、JVN番号の取得経験者になろう!
CVE、JVN番号の取得経験者になろう!CVE、JVN番号の取得経験者になろう!
CVE、JVN番号の取得経験者になろう!kazkiti
 
C# 8.0 非同期ストリーム
C# 8.0 非同期ストリームC# 8.0 非同期ストリーム
C# 8.0 非同期ストリーム信之 岩永
 
x86とコンテキストスイッチ
x86とコンテキストスイッチx86とコンテキストスイッチ
x86とコンテキストスイッチMasami Ichikawa
 
CTF for ビギナーズ バイナリ講習資料
CTF for ビギナーズ バイナリ講習資料CTF for ビギナーズ バイナリ講習資料
CTF for ビギナーズ バイナリ講習資料SECCON Beginners
 
Wavelet matrix implementation
Wavelet matrix implementationWavelet matrix implementation
Wavelet matrix implementationMITSUNARI Shigeo
 
今風なデスクトップアプリのモダンインストーラー開発
今風なデスクトップアプリのモダンインストーラー開発今風なデスクトップアプリのモダンインストーラー開発
今風なデスクトップアプリのモダンインストーラー開発Kaoru Nakajima
 
OpenStack超入門シリーズ いまさら聞けないNeutronの使い方
OpenStack超入門シリーズ いまさら聞けないNeutronの使い方OpenStack超入門シリーズ いまさら聞けないNeutronの使い方
OpenStack超入門シリーズ いまさら聞けないNeutronの使い方Toru Makabe
 

What's hot (20)

JavaScript難読化読経
JavaScript難読化読経JavaScript難読化読経
JavaScript難読化読経
 
Rust で RTOS を考える
Rust で RTOS を考えるRust で RTOS を考える
Rust で RTOS を考える
 
Cortex-M0プロセッサから自作して Lチカをやってみた
Cortex-M0プロセッサから自作してLチカをやってみたCortex-M0プロセッサから自作してLチカをやってみた
Cortex-M0プロセッサから自作して Lチカをやってみた
 
XSSフィルターを利用したXSS攻撃 by Masato Kinugawa
XSSフィルターを利用したXSS攻撃 by Masato KinugawaXSSフィルターを利用したXSS攻撃 by Masato Kinugawa
XSSフィルターを利用したXSS攻撃 by Masato Kinugawa
 
Format string Attack
Format string AttackFormat string Attack
Format string Attack
 
パターンでわかる! .NET Coreの非同期処理
パターンでわかる! .NET Coreの非同期処理パターンでわかる! .NET Coreの非同期処理
パターンでわかる! .NET Coreの非同期処理
 
RSA暗号運用でやってはいけない n のこと #ssmjp
RSA暗号運用でやってはいけない n のこと #ssmjpRSA暗号運用でやってはいけない n のこと #ssmjp
RSA暗号運用でやってはいけない n のこと #ssmjp
 
30分で分かる!OSの作り方
30分で分かる!OSの作り方30分で分かる!OSの作り方
30分で分かる!OSの作り方
 
暗号技術入門 秘密の国のアリス 総集編
暗号技術入門 秘密の国のアリス 総集編暗号技術入門 秘密の国のアリス 総集編
暗号技術入門 秘密の国のアリス 総集編
 
なんたらアジャイルその前に
なんたらアジャイルその前になんたらアジャイルその前に
なんたらアジャイルその前に
 
ぼくのかんがえたさいきょうのうぇぶあぷりけーしょんふれーむわーく - YAPC Asia 2011
ぼくのかんがえたさいきょうのうぇぶあぷりけーしょんふれーむわーく - YAPC Asia 2011ぼくのかんがえたさいきょうのうぇぶあぷりけーしょんふれーむわーく - YAPC Asia 2011
ぼくのかんがえたさいきょうのうぇぶあぷりけーしょんふれーむわーく - YAPC Asia 2011
 
標的型攻撃からどのように身を守るのか
標的型攻撃からどのように身を守るのか標的型攻撃からどのように身を守るのか
標的型攻撃からどのように身を守るのか
 
WPSCanによるWordPressの脆弱性スキャン
WPSCanによるWordPressの脆弱性スキャンWPSCanによるWordPressの脆弱性スキャン
WPSCanによるWordPressの脆弱性スキャン
 
CVE、JVN番号の取得経験者になろう!
CVE、JVN番号の取得経験者になろう!CVE、JVN番号の取得経験者になろう!
CVE、JVN番号の取得経験者になろう!
 
C# 8.0 非同期ストリーム
C# 8.0 非同期ストリームC# 8.0 非同期ストリーム
C# 8.0 非同期ストリーム
 
x86とコンテキストスイッチ
x86とコンテキストスイッチx86とコンテキストスイッチ
x86とコンテキストスイッチ
 
CTF for ビギナーズ バイナリ講習資料
CTF for ビギナーズ バイナリ講習資料CTF for ビギナーズ バイナリ講習資料
CTF for ビギナーズ バイナリ講習資料
 
Wavelet matrix implementation
Wavelet matrix implementationWavelet matrix implementation
Wavelet matrix implementation
 
今風なデスクトップアプリのモダンインストーラー開発
今風なデスクトップアプリのモダンインストーラー開発今風なデスクトップアプリのモダンインストーラー開発
今風なデスクトップアプリのモダンインストーラー開発
 
OpenStack超入門シリーズ いまさら聞けないNeutronの使い方
OpenStack超入門シリーズ いまさら聞けないNeutronの使い方OpenStack超入門シリーズ いまさら聞けないNeutronの使い方
OpenStack超入門シリーズ いまさら聞けないNeutronの使い方
 

Similar to rrxv6 Build a Riscv xv6 Kernel in Rust.pdf

Rust LDN 24 7 19 Oxidising the Command Line
Rust LDN 24 7 19 Oxidising the Command LineRust LDN 24 7 19 Oxidising the Command Line
Rust LDN 24 7 19 Oxidising the Command LineMatt Provost
 
C aptitude questions
C aptitude questionsC aptitude questions
C aptitude questionsSrikanth
 
C - aptitude3
C - aptitude3C - aptitude3
C - aptitude3Srikanth
 
Analysis of Haiku Operating System (BeOS Family) by PVS-Studio. Part 2
Analysis of Haiku Operating System (BeOS Family) by PVS-Studio. Part 2Analysis of Haiku Operating System (BeOS Family) by PVS-Studio. Part 2
Analysis of Haiku Operating System (BeOS Family) by PVS-Studio. Part 2PVS-Studio
 
ExperiencesSharingOnEmbeddedSystemDevelopment_20160321
ExperiencesSharingOnEmbeddedSystemDevelopment_20160321ExperiencesSharingOnEmbeddedSystemDevelopment_20160321
ExperiencesSharingOnEmbeddedSystemDevelopment_20160321Teddy Hsiung
 
GPU Programming on CPU - Using C++AMP
GPU Programming on CPU - Using C++AMPGPU Programming on CPU - Using C++AMP
GPU Programming on CPU - Using C++AMPMiller Lee
 
20140531 serebryany lecture02_find_scary_cpp_bugs
20140531 serebryany lecture02_find_scary_cpp_bugs20140531 serebryany lecture02_find_scary_cpp_bugs
20140531 serebryany lecture02_find_scary_cpp_bugsComputer Science Club
 
C++ amp on linux
C++ amp on linuxC++ amp on linux
C++ amp on linuxMiller Lee
 
Степан Кольцов — Rust — лучше, чем C++
Степан Кольцов — Rust — лучше, чем C++Степан Кольцов — Rust — лучше, чем C++
Степан Кольцов — Rust — лучше, чем C++Yandex
 
Toonz code leaves much to be desired
Toonz code leaves much to be desiredToonz code leaves much to be desired
Toonz code leaves much to be desiredPVS-Studio
 
RISC-V : Berkeley Boot Loader & Proxy Kernelのソースコード解析
RISC-V : Berkeley Boot Loader & Proxy Kernelのソースコード解析RISC-V : Berkeley Boot Loader & Proxy Kernelのソースコード解析
RISC-V : Berkeley Boot Loader & Proxy Kernelのソースコード解析Mr. Vengineer
 
Simple, fast, and scalable torch7 tutorial
Simple, fast, and scalable torch7 tutorialSimple, fast, and scalable torch7 tutorial
Simple, fast, and scalable torch7 tutorialJin-Hwa Kim
 
In Class AssignmetzCST280W13a-1.pdfCST 280 In-Class Pract.docx
In Class AssignmetzCST280W13a-1.pdfCST 280 In-Class Pract.docxIn Class AssignmetzCST280W13a-1.pdfCST 280 In-Class Pract.docx
In Class AssignmetzCST280W13a-1.pdfCST 280 In-Class Pract.docxbradburgess22840
 
The following code is an implementation of the producer consumer pro.pdf
The following code is an implementation of the producer consumer pro.pdfThe following code is an implementation of the producer consumer pro.pdf
The following code is an implementation of the producer consumer pro.pdfmarketing413921
 
Embedded systemsproject_2020
Embedded systemsproject_2020Embedded systemsproject_2020
Embedded systemsproject_2020Nikos Mouzakitis
 
Rust: код может быть одновременно безопасным и быстрым, Степан Кольцов
Rust: код может быть одновременно безопасным и быстрым, Степан КольцовRust: код может быть одновременно безопасным и быстрым, Степан Кольцов
Rust: код может быть одновременно безопасным и быстрым, Степан КольцовYandex
 

Similar to rrxv6 Build a Riscv xv6 Kernel in Rust.pdf (20)

Rust LDN 24 7 19 Oxidising the Command Line
Rust LDN 24 7 19 Oxidising the Command LineRust LDN 24 7 19 Oxidising the Command Line
Rust LDN 24 7 19 Oxidising the Command Line
 
C aptitude questions
C aptitude questionsC aptitude questions
C aptitude questions
 
C - aptitude3
C - aptitude3C - aptitude3
C - aptitude3
 
Analysis of Haiku Operating System (BeOS Family) by PVS-Studio. Part 2
Analysis of Haiku Operating System (BeOS Family) by PVS-Studio. Part 2Analysis of Haiku Operating System (BeOS Family) by PVS-Studio. Part 2
Analysis of Haiku Operating System (BeOS Family) by PVS-Studio. Part 2
 
ExperiencesSharingOnEmbeddedSystemDevelopment_20160321
ExperiencesSharingOnEmbeddedSystemDevelopment_20160321ExperiencesSharingOnEmbeddedSystemDevelopment_20160321
ExperiencesSharingOnEmbeddedSystemDevelopment_20160321
 
GPU Programming on CPU - Using C++AMP
GPU Programming on CPU - Using C++AMPGPU Programming on CPU - Using C++AMP
GPU Programming on CPU - Using C++AMP
 
20140531 serebryany lecture02_find_scary_cpp_bugs
20140531 serebryany lecture02_find_scary_cpp_bugs20140531 serebryany lecture02_find_scary_cpp_bugs
20140531 serebryany lecture02_find_scary_cpp_bugs
 
C++ amp on linux
C++ amp on linuxC++ amp on linux
C++ amp on linux
 
Степан Кольцов — Rust — лучше, чем C++
Степан Кольцов — Rust — лучше, чем C++Степан Кольцов — Rust — лучше, чем C++
Степан Кольцов — Rust — лучше, чем C++
 
Toonz code leaves much to be desired
Toonz code leaves much to be desiredToonz code leaves much to be desired
Toonz code leaves much to be desired
 
Writing MySQL UDFs
Writing MySQL UDFsWriting MySQL UDFs
Writing MySQL UDFs
 
RISC-V : Berkeley Boot Loader & Proxy Kernelのソースコード解析
RISC-V : Berkeley Boot Loader & Proxy Kernelのソースコード解析RISC-V : Berkeley Boot Loader & Proxy Kernelのソースコード解析
RISC-V : Berkeley Boot Loader & Proxy Kernelのソースコード解析
 
Quiz 9
Quiz 9Quiz 9
Quiz 9
 
CPP Homework Help
CPP Homework HelpCPP Homework Help
CPP Homework Help
 
Simple, fast, and scalable torch7 tutorial
Simple, fast, and scalable torch7 tutorialSimple, fast, and scalable torch7 tutorial
Simple, fast, and scalable torch7 tutorial
 
In Class AssignmetzCST280W13a-1.pdfCST 280 In-Class Pract.docx
In Class AssignmetzCST280W13a-1.pdfCST 280 In-Class Pract.docxIn Class AssignmetzCST280W13a-1.pdfCST 280 In-Class Pract.docx
In Class AssignmetzCST280W13a-1.pdfCST 280 In-Class Pract.docx
 
Interpreter, Compiler, JIT from scratch
Interpreter, Compiler, JIT from scratchInterpreter, Compiler, JIT from scratch
Interpreter, Compiler, JIT from scratch
 
The following code is an implementation of the producer consumer pro.pdf
The following code is an implementation of the producer consumer pro.pdfThe following code is an implementation of the producer consumer pro.pdf
The following code is an implementation of the producer consumer pro.pdf
 
Embedded systemsproject_2020
Embedded systemsproject_2020Embedded systemsproject_2020
Embedded systemsproject_2020
 
Rust: код может быть одновременно безопасным и быстрым, Степан Кольцов
Rust: код может быть одновременно безопасным и быстрым, Степан КольцовRust: код может быть одновременно безопасным и быстрым, Степан Кольцов
Rust: код может быть одновременно безопасным и быстрым, Степан Кольцов
 

More from Yodalee

COSCUP2023 RSA256 Verilator.pdf
COSCUP2023 RSA256 Verilator.pdfCOSCUP2023 RSA256 Verilator.pdf
COSCUP2023 RSA256 Verilator.pdfYodalee
 
Gameboy emulator in rust and web assembly
Gameboy emulator in rust and web assemblyGameboy emulator in rust and web assembly
Gameboy emulator in rust and web assemblyYodalee
 
Make A Shoot ‘Em Up Game with Amethyst Framework
Make A Shoot ‘Em Up Game with Amethyst FrameworkMake A Shoot ‘Em Up Game with Amethyst Framework
Make A Shoot ‘Em Up Game with Amethyst FrameworkYodalee
 
Build Yourself a Nixie Tube Clock
Build Yourself a Nixie Tube ClockBuild Yourself a Nixie Tube Clock
Build Yourself a Nixie Tube ClockYodalee
 
Use PEG to Write a Programming Language Parser
Use PEG to Write a Programming Language ParserUse PEG to Write a Programming Language Parser
Use PEG to Write a Programming Language ParserYodalee
 
Introduction to nand2 tetris
Introduction to nand2 tetrisIntroduction to nand2 tetris
Introduction to nand2 tetrisYodalee
 
Office word skills
Office word skillsOffice word skills
Office word skillsYodalee
 
Git: basic to advanced
Git: basic to advancedGit: basic to advanced
Git: basic to advancedYodalee
 

More from Yodalee (8)

COSCUP2023 RSA256 Verilator.pdf
COSCUP2023 RSA256 Verilator.pdfCOSCUP2023 RSA256 Verilator.pdf
COSCUP2023 RSA256 Verilator.pdf
 
Gameboy emulator in rust and web assembly
Gameboy emulator in rust and web assemblyGameboy emulator in rust and web assembly
Gameboy emulator in rust and web assembly
 
Make A Shoot ‘Em Up Game with Amethyst Framework
Make A Shoot ‘Em Up Game with Amethyst FrameworkMake A Shoot ‘Em Up Game with Amethyst Framework
Make A Shoot ‘Em Up Game with Amethyst Framework
 
Build Yourself a Nixie Tube Clock
Build Yourself a Nixie Tube ClockBuild Yourself a Nixie Tube Clock
Build Yourself a Nixie Tube Clock
 
Use PEG to Write a Programming Language Parser
Use PEG to Write a Programming Language ParserUse PEG to Write a Programming Language Parser
Use PEG to Write a Programming Language Parser
 
Introduction to nand2 tetris
Introduction to nand2 tetrisIntroduction to nand2 tetris
Introduction to nand2 tetris
 
Office word skills
Office word skillsOffice word skills
Office word skills
 
Git: basic to advanced
Git: basic to advancedGit: basic to advanced
Git: basic to advanced
 

Recently uploaded

GOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdfGOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdfAlina Yurenko
 
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptxKnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptxTier1 app
 
Xen Safety Embedded OSS Summit April 2024 v4.pdf
Xen Safety Embedded OSS Summit April 2024 v4.pdfXen Safety Embedded OSS Summit April 2024 v4.pdf
Xen Safety Embedded OSS Summit April 2024 v4.pdfStefano Stabellini
 
How to Track Employee Performance A Comprehensive Guide.pdf
How to Track Employee Performance A Comprehensive Guide.pdfHow to Track Employee Performance A Comprehensive Guide.pdf
How to Track Employee Performance A Comprehensive Guide.pdfLivetecs LLC
 
What is Advanced Excel and what are some best practices for designing and cre...
What is Advanced Excel and what are some best practices for designing and cre...What is Advanced Excel and what are some best practices for designing and cre...
What is Advanced Excel and what are some best practices for designing and cre...Technogeeks
 
What is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need ItWhat is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need ItWave PLM
 
Implementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with AzureImplementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with AzureDinusha Kumarasiri
 
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样umasea
 
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...OnePlan Solutions
 
CRM Contender Series: HubSpot vs. Salesforce
CRM Contender Series: HubSpot vs. SalesforceCRM Contender Series: HubSpot vs. Salesforce
CRM Contender Series: HubSpot vs. SalesforceBrainSell Technologies
 
Unveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML DiagramsUnveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML DiagramsAhmed Mohamed
 
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASEBATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASEOrtus Solutions, Corp
 
Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024Andreas Granig
 
What are the key points to focus on before starting to learn ETL Development....
What are the key points to focus on before starting to learn ETL Development....What are the key points to focus on before starting to learn ETL Development....
What are the key points to focus on before starting to learn ETL Development....kzayra69
 
Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)
Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)
Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)jennyeacort
 
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...Matt Ray
 
Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)OPEN KNOWLEDGE GmbH
 
Introduction Computer Science - Software Design.pdf
Introduction Computer Science - Software Design.pdfIntroduction Computer Science - Software Design.pdf
Introduction Computer Science - Software Design.pdfFerryKemperman
 
Buds n Tech IT Solutions: Top-Notch Web Services in Noida
Buds n Tech IT Solutions: Top-Notch Web Services in NoidaBuds n Tech IT Solutions: Top-Notch Web Services in Noida
Buds n Tech IT Solutions: Top-Notch Web Services in Noidabntitsolutionsrishis
 
Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...Velvetech LLC
 

Recently uploaded (20)

GOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdfGOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
 
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptxKnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
 
Xen Safety Embedded OSS Summit April 2024 v4.pdf
Xen Safety Embedded OSS Summit April 2024 v4.pdfXen Safety Embedded OSS Summit April 2024 v4.pdf
Xen Safety Embedded OSS Summit April 2024 v4.pdf
 
How to Track Employee Performance A Comprehensive Guide.pdf
How to Track Employee Performance A Comprehensive Guide.pdfHow to Track Employee Performance A Comprehensive Guide.pdf
How to Track Employee Performance A Comprehensive Guide.pdf
 
What is Advanced Excel and what are some best practices for designing and cre...
What is Advanced Excel and what are some best practices for designing and cre...What is Advanced Excel and what are some best practices for designing and cre...
What is Advanced Excel and what are some best practices for designing and cre...
 
What is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need ItWhat is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need It
 
Implementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with AzureImplementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with Azure
 
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
 
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
 
CRM Contender Series: HubSpot vs. Salesforce
CRM Contender Series: HubSpot vs. SalesforceCRM Contender Series: HubSpot vs. Salesforce
CRM Contender Series: HubSpot vs. Salesforce
 
Unveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML DiagramsUnveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML Diagrams
 
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASEBATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
 
Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024
 
What are the key points to focus on before starting to learn ETL Development....
What are the key points to focus on before starting to learn ETL Development....What are the key points to focus on before starting to learn ETL Development....
What are the key points to focus on before starting to learn ETL Development....
 
Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)
Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)
Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)
 
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
 
Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)
 
Introduction Computer Science - Software Design.pdf
Introduction Computer Science - Software Design.pdfIntroduction Computer Science - Software Design.pdf
Introduction Computer Science - Software Design.pdf
 
Buds n Tech IT Solutions: Top-Notch Web Services in Noida
Buds n Tech IT Solutions: Top-Notch Web Services in NoidaBuds n Tech IT Solutions: Top-Notch Web Services in Noida
Buds n Tech IT Solutions: Top-Notch Web Services in Noida
 
Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...
 

rrxv6 Build a Riscv xv6 Kernel in Rust.pdf

  • 1. rrxv6: Build a RISC-V xv6 Kernel in Rust Author: Yodalee <lc85301@gmail.com>
  • 2. Outline 1. Background Introduction 2. rrxv6 Overview 3. Inside rrxv6 4. Conclusion
  • 3. Outline 1. Background Introduction 2. rrxv6 Overview 3. Inside rrxv6 4. Conclusion There won't be much details about xv6, RISC-V, or Operating System
  • 4. ● A re-implementation of Dennis Ritchie's and Ken Thompson's Unix Version 6 (v6) ● Migrate from x86 to RISC-V multiprocessor using ANSI C ● Now used in operating systems courses at many universities. Introduction to xv6
  • 5. Introduction to RISC-V ● Open RISC standard Instruction Set Architecture (ISA) CPU ● Began in 2010 at the University of California, Berkeley. ● Alternatives to proprietary architecture like x86, ARM, etc. https://github.com/riscvarchive/riscv-cores-list
  • 7. Star Me on Github! Note: (Traditional Chinese) https://yodalee.me/series/rrxv6/ Source Code https://github.com/yodalee/rrxv6
  • 8. rrxv6 Overview (so far) RISC-V 64 bits Hardware (on qemu) Application rv64 (csr operation abstraction) Kernel Virtual Memory PLIC UART Scheduler Memory Allocator
  • 9. rrxv6 Hello World qemu-system-riscv64 -machine virt -bios none -m 128M -smp 4 -nographic -s -kernel target/riscv64imac-unknown-none-elf/debug/rrxv6
  • 10. Required Toolchain 1. Use rustup to install rust toolchain riscv64imac-unknown-none-elf (lp64) Set target in .cargo/config 2. Install riscv gcc for linking riscv64-unknown-elf-gcc 3. Install qemu-system-riscv to emulate the hardware // .cargo/config [build] target = "riscv64imac-unknown-none-elf" [target.riscv64imac-unknown-none-elf] rustflags = ["-C", "link-arg=-Tlinker.ld"]
  • 11. rrxv6 Source Structure Assembly: entry.S, switch.S … Rust kernel kalloc.rs, kvm.rs scheduler.rs … Build script: build.rs linker.ld User initcode.S kernel binary // build.rs use cc::Build; fn main() -> Result<(), Box<dyn Error>> { Build::new().file("src/entry.S").compile("asm"); Ok(()) }
  • 13. Inside the Cargo.toml bit_field get_bit, set_bit, get_bits, set_bits bitflags bitmask generator volatile-register volatile read, write memory address mvdnes / spin-rs spinlock on static variable lazy_static create static variable easily rust-osdev / linked-list-allocator memory allocation
  • 14. Going std-less Rust does not have std in RISC-V target. // main.rs #![no_std] #![no_main] use core::panic::PanicInfo; static STACK0: [u8;STACK_SIZE * NCPU] = [0;STACK_SIZE * NCPU]; #[no_mangle] fn start() -> ! { loop{} } #[panic_handler] fn panic(_panic: &PanicInfo<'_>) -> ! { loop {} } .global _entry _entry: # sp = STACK0 + (hartid * 4096) la sp, STACK0 li a0, STACK_SIZE csrr a1, mhartid addi a1, a1, 1 mul a0, a0, a1 add sp, sp, a0 call start
  • 15. What we have? ● The Core library: https://doc.rust-lang.org/core/index.html ● Actually most std just re-export modules coming from core ○ Core::alloc ○ Core::ptr ○ Core::panic ○ Core::mem
  • 16. rv64: CSR Abstraction // set M Previous Privilege mode to Supervisor, for mret. unsigned long x = r_mstatus(); x &= ~MSTATUS_MPP_MASK ; x |= MSTATUS_MPP_S ; w_mstatus(x); // set M Exception Program Counter to main, for mret. // requires gcc -mcmodel=medany w_mepc((uint64)main); // disable paging for now. w_satp(0); // delegate all interrupts and exceptions to supervisor mode. w_medeleg(0xffff); w_mideleg(0xffff); w_sie(r_sie() | SIE_SEIE | SIE_STIE | SIE_SSIE);
  • 17. rv64: CSR Abstraction In OS, we need to set processor by program the CSR. To read/write a CSR, we need assembly csrr and csrw instructions. Calling assembly is unsafe in Rust. let mut x: u64; unsafe { asm!("csrr {}, sie", out(reg) x); } x |= (1 << 1) | (1 << 5) | (1 << 9); unsafe { asm!("csrw sie, {}", in(reg) x); }
  • 18. rv64: CSR Abstraction pub struct Sie { bits: u64 } impl Sie { pub fn from_read() -> Self { let bits: u64; csrr!("sie", bits); Self { bits } } pub fn write(self) { csrw!("sie", self.bits); } } pub enum Interrupt { SoftwareInterrupt, TimerInterrupt, ExternalInterrupt, } impl Sie { pub fn set_supervisor_enable(&mut self, interrupt: Interrupt) { self.bits |= match interrupt { Interrupt::SoftwareInterrupt => (1 << 1), Interrupt::TimerInterrupt => (1 << 5), Interrupt::ExternalInterrupt => (1 << 9), } } }
  • 19. rv64: CSR Abstraction let mut sie = Sie::from_read(); sie.set_supervisor_enable(Interrupt::SoftwareInterrupt); sie.set_supervisor_enable(Interrupt::TimerInterrupt); sie.set_supervisor_enable(Interrupt::ExternalInterrupt); sie.write(); ● Now the code is meaningful and readable, without the noisy unsafe. ● Also, the abstraction is zero-cost. 80001c24: csrr a0,sie 80001c28: ori a0,a0,546 (0x222) 80001c2c: csrw sie,a0
  • 20. MemoryAllocator We cannot allocate memory if we are #![no_std]. All the memory allocation defined in alloc will cause panic! Box::new(16) Rc::new(32) string::from_utf8() format!("{}", 64) vec![1,2,3,4,5] Arc::new(48)
  • 21. MemoryAllocator We have to provide the #[global_allocator], which should implement the GlobalAlloc Trait. pub unsafe trait GlobalAlloc { unsafe fn alloc(&self, layout: Layout) -> *mut u8; unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout); // optional unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8; unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8; }
  • 22. MemoryAllocator -Dummy Implementation struct DummyAllocator; unsafe impl GlobalAlloc for DummyAllocator { unsafe fn alloc(&self, _layout: Layout) -> *mut u8 { null_mut() } unsafe fn dealloc(&self, _ptr: *mut u8, _layout: Layout) {} } #[global_allocator] static ALLOCATOR: DummyAllocator = DummyAllocator {};
  • 23. MemoryAllocator #[global_allocator] static ALLOCATOR: LockedHeap = LockedHeap::empty(); pub const KERNELBASE : u64 = 0x8000_0000; pub const PHYSTOP : u64 = KERNELBASE + 128 * 1024 * 1024; pub fn init_kvm() { ALLOCATOR .lock() .init(KERNELBASE, PHYSTOP) } I use rust-osdev / linked-list-allocator (and submit a patch to it)
  • 24. Mutable Static In Kernel, there are static data that must be mutable. For example: ● The UART module ● The Scheduler module ● The CPU register data
  • 25. Mutable Static Accessing mutable static is unsafe in Rust. (what a surprise) static mut DATA: u32 = 0; println("{}", DATA); error[E0133]: use of mutable static is unsafe and requires unsafe function or block --> a.rs:4:20 | 4 | println!("{}", DATA); | ^^^^ use of mutable static
  • 26. Mutable Static Solution 1: Unsafe Just add unsafe whenever you access static. Not suggested, it makes code ugly and unreadable. static mut DATA: u32 = 0; unsafe { println("{}", DATA); DATA = 1; println!("{}", DATA); }
  • 27. Mutable Static Solution 2: Hide Inside Option Declare as None static mut SCHEDULER: Option<Scheduler> = None; Add initializer that replaces it with Some. pub fn init_scheduler() { unsafe { SCHEDULER = Some(Scheduler::new()); } } Add a getter pub fn get_scheduler() -> &'static mut Scheduler { unsafe { SCHEDULER.as_mut().unwrap() } }
  • 28. Mutable Static Solution 3: Use Lock pub struct SpinMutex<T: ?Sized, R = Spin> { pub(crate) lock: AtomicBool, data: UnsafeCell<T>, } I use spin-rs in rrxv6 and as example. pub struct SpinMutexGuard<'a, T: ?Sized + 'a> { lock: &'a AtomicBool, data: &'a mut T, } fn lock() -> SpinMutexGuard Atomic change lock to true impl Drop::drop() Atomic change lock to false impl Deref::deref() -> &T self.data
  • 29. Limitation: be careful not to create deadlock. Once I put process infomations in a lock: Mutex<PROCESS[16]> Mutable Static Solution 3: Use Lock scheduler process[0] Context switch lock() and get process[0] Timer interrupt Deadlock
  • 30. Mutable Static Solution Comparison Pros Cons Unsafe Easy to use Readability Option Easy to use Not thread-safe Lock Thread safe Deadlock Usually I use: 1. struct with field of Mutex<data> 2. static struct using Option
  • 31. Rust have (unsmart) pointer, but we seldom use it. In rrxv6, there are two kinds of pointers being used. 1. Raw pointer -> memory allocator, virtual memory, scheduler 2. NonNull pointer -> process trapframe and page table Pointer
  • 32. The type notation is *const T or *mut T. The bridge between address and reference. Usually you can only change type in Rust with: 1. primitive type: like u32 as u64 2. trait object between base/derive The raw pointer can break this limitation. Raw Pointer
  • 33. Raw Pointer -Type Conversion Data: T Reference data: &T, &mut T Raw pointer: *const T, *mut T Data Address: u64 & as as * as Raw pointer: *const S, *mut S as
  • 34. Raw Pointer -Type Conversion let next_table: &mut PageTable = unsafe { &mut *(pte.addr() as *mut PageTable) }; free_pagetable(next_table, …); Data: T Reference data: &T, &mut T Raw pointer: *const T, *mut T Data Address: u64 & as as * as
  • 35. A better pointer compared to raw pointer, must be non-zero and covariant. Usually Option<NonNull<T>> is used. It is still dangerous if you dereference NonNull that is not properly initialized. For example NonNull created by NonNull::dangling() NonNull Pointer
  • 36. NonNull Pointer -Type Conversion Reference data: &T, &mut T NonNull<T> as_mut() Raw pointer: *mut T let mut page_table_ptr = NonNull::new(kalloc() as *mut PageTable)?; let page_table = unsafe { page_table_ptr.as_mut() }; map_pages(page_table, …) NonNull::new()
  • 37. Summary-Why Rust? 1. Rust force you to do thing in a safe way (no excuse) -> It takes more time for Rust to build the foundation. 2. Rust give the level of abstraction - PageTableVisitor, Iterator function, etc. // lock in xv6 struct spinlock { uint locked; }; struct spinlock tickslock; uint ticks; { acquire(&tickslock); ticks++; release(&tickslock); } // lock in rrxv6 static ref TICK: Mutex<u64> = Mutex::new(0); let mut tick = TICK.lock(); *tick += 1;
  • 39. Conclusion 1. It is possible to build a kernel using Rust without std. 2. Kernel is unsafe. 3. It is all about encapsulation: a. To create the correct type and hide the unsafe operations. b. To convince the compiler that your program is safe.
  • 40. Future Work Features to implement: ● Virtio ● IPC ● User space program in Rust ○ If we get system call right, C program should also work.
  • 41. Reference 1. xv6-riscv: https://github.com/mit-pdos/xv6-riscv 2. RISC-V specification: https://riscv.org/technical/specifications/ 3. Rust bare-metal: https://docs.rust-embedded.org/book/ 4. Tock-os: https://github.com/tock/tock 5. blog_os: https://github.com/phil-opp/blog_os
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.