본 프로젝트는 aarch64를 타겟으로 하는 rust로 작성된 os를 제작하는 것이다.

이번에는 간단하게 부팅되는 더미커널만을 제작하는 것을 목표로 하였다.

Building Freestanding Rust Binary (or Dummy Kernel)

Create Project

cargo new cosmos

Disable Standard Library

// src/main.rs
#![no_std]

Panic Handling

Implement Panic Handler

// src/main.rs
 
#[panic_handler]
fn handle_panic(_info: &PanicInfo) -> ! {
	loop{}
}

Disable stack unwinding

# Cargo.toml
 
[profile.dev]
panic = "abort"
 
[profile.release]
panic = "abort"

Unless..

   Compiling cosmo-kernel v0.1.0 (/home/parkjb/cosmo-kernel)
error: language item required, but not found: `eh_personality`
  |
  = note: this can occur when a binary crate with `#![no_std]` is compiled for a target where `eh_personality` is defined in the standard library
  = help: you may be able to compile for a target that doesn't need `eh_personality`, specify a target with `--target` or in `.cargo/config`
 
error: could not compile `cosmo-kernel` (bin "cosmo-kernel") due to previous error

eh_personality is for implementing stack unwinding to run the destructors of all live stack variables in case of panic.

This ensures all memory used is freed and allows parent thread to catch the panic and continue execution.

Drawbacks: increases the size of the executable.. abort on panic option can be useful instead.

Add Compile Target

rustup target add aarch64-unknown-none

Platform Support: https://doc.rust-lang.org/nightly/rustc/platform-support.html

Entry Point

Disable main entry point

#![no_main]
// -- fn main()

Entry Point: _start

#[no_mangle]
pub extern "C" fn _start() -> ! {
    loop {}
}

no_mangle

no_mangle은 컴파일러에게 함수의 이름을 바꾸지 않도록 지시하는 어노테이션이다. _start 함수가 mangling 된다면, 엔트리 포인트를 찾지 못하여 커널을 정상적으로 시작할 수 없게된다.

https://doc.rust-kr.org/ch19-01-unsafe-rust.html#다른-언어에서-러스트-함수-호출하기

Unless..

   Compiling cosmos v0.1.0 (/home/parkjb/cosmos)
error: requires `start` lang_item
 
error: could not compile `cosmos` (bin "cosmos") due to 1 previous error

Useful Tools

Install

cargo install cargo-binutils
rustup component add llvm-tools

rust-nm: List Symbols

rust-nm target/aarch64-unknown-none/debug/kernel
0000000000210120 T _start

rust-objdump: Inspect ELF File

  • ELF: Executable & Linkable File

File Headers: -f

rust-objdump -f target/aarch64-unknown-none/debug/kernel
target/aarch64-unknown-none/debug/kernel:	file format elf64-littleaarch64
architecture: aarch64
start address: 0x0000000000210120

Sections: -h

rust-objdump -h target/aarch64-unknown-none/debug/kernel
target/aarch64-unknown-none/debug/kernel:	file format elf64-littleaarch64

Sections:
Idx Name           Size     VMA              Type
  0                00000000 0000000000000000
  1 .text          00000008 0000000000210120 TEXT
  2 .debug_abbrev  00000133 0000000000000000 DEBUG
  3 .debug_info    000005f3 0000000000000000 DEBUG
  4 .debug_aranges 00000040 0000000000000000 DEBUG
  5 .debug_ranges  00000030 0000000000000000 DEBUG
  6 .debug_str     00000499 0000000000000000 DEBUG
  7 .comment       00000040 0000000000000000
  8 .debug_frame   00000050 0000000000000000 DEBUG
  9 .debug_line    00000058 0000000000000000 DEBUG
 10 .symtab        00000120 0000000000000000
 11 .shstrtab      00000085 0000000000000000
 12 .strtab        00000047 0000000000000000

Disassembling: -d

rust-objdump -d target/aarch64-unknown-none/debug/kernel
target/aarch64-unknown-none/debug/kernel:	file format elf64-littleaarch64

Disassembly of section .text:

0000000000210120 <_start>:
  210120: 14000001     	b	0x210124 <_start+0x4>
  210124: 14000000     	b	0x210124 <_start+0x4>

rust-strip

rust-strip target/aarch64-unknown-none/debug/kernel
  • removes debug information

Reference