CS3210 Design Operating Systems

Taesoo Kim





Rust 4: Freestanding/Baremetal Rust

Taesoo Kim

Administrivia

Q&A

// Q. what's wrong?
impl RdRand { fn gen_range(..) }

// Q. what's wrong?
impl RngCore for RdRand {
  fn next_u32() { impls::next_u32_via_fill(self); }
}

// Q. what's wrong?
impl RngCore for RdRand {
  fn next_u64(&mut self) -> u64 {
    self.next_u32() as u64
  }
}

Q&A. Error patterns

  1. Not using the lib: e.g., own gen_range() for RdRand
  2. Circular dependency: e.g., using impls::next_u32_via_fill() in next_u32()
  3. Lack of entropy: e.g., RNG_DATA.read_volatile() as u64 in next_u64()

Agenda

Minimal C/Rust

  1. What’s their size (see, size)?
  2. What’s in there (see, objdump)?
  3. What’s the code other than what we wrote (i.e., nothing)?
  4. What are these template code for?
// gcc test.c
int main() {}
// rustc test.rs
fn main() {}

Freestanding binary

Freestanding C

// gcc -nostdlib freestanding.c
void _start() {
  asm volatile ("mov $1, %%rdi\n"
                "mov $0x3c, %%rax\n"
                "syscall"
                :
                :
                :"rax", "rdi");
}

Freestanding Rust

#[no_mangle]
fn _start() {
    unsafe {
        asm!("mov rdi, $$1
              mov rax, $$0x3c
              syscall"
             :
             :
             :"rax"
             :"volatile", "intel");
    }

About libcore, liballoc, libstd

About libcore, liballoc, libstd in OS development

no_std

// extern crate std;
// use std::prelude::v1::*;

#![no_std]

fn plus_one(x: i32) -> i32 {
    x + 1
}

Ref. No stdlib, Rustbook

no_main

#![no_main]

#[no_mangle]
pub extern fn _start() -> ! {
  // your program
}

panic_handler

#[panic_handler]
fn panic(_info: &PanicInfo) -> ! {
  // you will be asked to fill this in lab3
  loop {}
}

Ref. 12. Beneath std, Nomicon

eh_personality

#[lang = "eh_personality"]
fn eh_personality() {
  // ignored for now!
}

Ref. http://llvm.org/docs/ExceptionHandling.html

Note on 1-blinky/phase3 (C)

Note on 1-blinky/phase4 (Rust)

Cargo config and xbuild

[build]
target = "aarch64-unknown-none"

[target.aarch64-unknown-none]
runner = "./qemu.sh"
rustflags = [
    "-C", "target-cpu=cortex-a53",
    "-C", "link-arg=--script=.cargo/layout.ld",
    "-C", "link-arg=--no-dynamic-linker",
]

Running on qemu

$ ./qemu.sh build/blinky.elf -d in_asm
IN:
0x0000000004000000:  d53800a1      mrs x1, (unknown)
0x0000000004000004:  92400421      and x1, x1, #0x3
0x0000000004000008:  b4000061      cbz x1, #+0xc (addr 0x4000014)

IN:
0x0000000004000014:  10ffff61      adr x1, #-0x14 (addr 0x4000000)
0x0000000004000018:  9100003f      mov sp, x1
0x000000000400001c:  94000003      bl #+0xc (addr 0x4000028)

IN: kinit
0x0000000004000028:  90000008      adrp x8, #+0x0 (addr 0x4000000)
0x000000000400002c:  91030108      add x8, x8, #0xc0 (192)
0x0000000004000030:  90000009      adrp x9, #+0x0 (addr 0x4000000)
...

Next lecture

References