Escribir un sistema operativo en Rust. Configurando el medio ambiente. Binario para hierro "desnudo"

Configurando el medio ambiente. Archivo binario desnudo o ejecutable sin main ()



El primer paso para escribir su propio sistema operativo es crear un binario que no dependa de las bibliotecas estándar, esto hace posible ejecutar código sin un sistema operativo; estamos escribiendo el nuestro.



El blog original se está desarrollando en GitHub . Deje sus comentarios al original en la página Problemas del repositorio anterior y a la traducción: en PM, comentarios o aquí . El código escrito en este artículo está contenido en post-01.



Introducción



Para escribir nuestro propio sistema operativo, necesitamos un código que no dependa de bibliotecas o funciones de otro sistema operativo. Esto significa que no podemos usar subprocesos, archivos, memoria de pila, redes, salida de terminal, etc. Pero esto puede superarse escribiendo su propio sistema operativo y controladores.



No podemos usar la mayor parte de la biblioteca estándar de Rust , pero también hay muchas funciones que podemos utilizar. Por ejemplo , iteradores , cierres , coincidencia de patrones , opción y resultado , formato de cadena y, por supuesto, el concepto de propiedad . Esto le permitirá escribir su kernel en un estilo de alto nivel sin preocuparse por el comportamiento indefinido o la seguridad de la memoria .



Este artículo explica cómo crear un archivo ejecutable independiente y por qué lo necesita. Si solo desea un ejemplo, puede desplazarse a la sección Conclusión.



Deshabilitar la biblioteca estándar



, , , .. : libc, . , , . no_std.



Cargo. :



cargo new os-in-rust --bin --edition 2018


os-in-rust ( ), . --bin , , , . --edition 2018 , Rust 2018. Cargo :



os-in-rust
├── Cargo.toml
└── src
    └── main.rs


Cargo.toml : , , . src/main.rs , , . cargo build, target/debug.



no_std



. no_std:



// main.rs
#![no_std]

fn main() {
  println!("Hello, world!");
}


, :



error: cannot find macro `println!` in this scope
 --> src/main.rs:4:5
  |
4 |     println!("Hello, world!");
  |     ^^^^^^^


, println — Rust, . , . , , . :(



:



// main.rs
#![no_std]

fn main() {}


> cargo build
error: `#[panic_handler]` function required, but not found
error: language item required, but not found: `eh_personality`


panic!()



panic_handler , , ( panic!()). , no_std :



// main.rs

#[panic_handler]
fn panic(_info: &PanicInfo) -> ! {
  loop {}
}


PanicInfo , , () . , — ! (never). , .



eh_personality



eh_personality — " ", , . , Copy — , , . , #[lang = "copy"], .



, , , , ! , .



eh_personality , "" . Rust , . , , (libunwind Linux Windows), .





Rust . , . , . — Cargo.toml:



[profile.dev]
panic = "abort"

[profile.release]
panic = "abort"


abort dev ( cargo build), release (cargo build --release). eh_personality.



. :



> cargo build
error: requires `start` lang_item


start



, main . . , (Java, C#, JavaScript...) (, Go). main .



Rust , crt0, . , , . Rust , start, Rust , main().



, crt0, . crt0.





, , #![no_main].



#![no_std]
#![no_main]

use core::panic::PanicInfo;

#[panic_handler]
fn panic(_info: &PanicInfo) -> ! {
    loop {}
}


main(), . _start:



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


#[no_mangle], , _start, , , _ZN3blog_os4_start7hb173fedf945531caE. , .



extern "C", , , Rust ( , , , ). , .



, , , !, , . , , , ( ).



, cargo build, .





— , , , . , , .



, , , . 2 : , .



""



Rust . Windows x86-64, Rust .exe x86-64. .



Rust ( ) target triples. , rustc --version --verbose:



rustc 1.47.0-nightly (576d27c5a 2020-08-12)
binary: rustc
commit-hash: 576d27c5a6c80cd39ef57d7398831d8e177573cc
commit-date: 2020-08-12
host: x86_64-unknown-linux-gnu
release: 1.47.0-nightly
LLVM version: 10.0


(Linux x86-64). , — host. , :



  • x86-64,
  • : Linux,
  • ABI: GNU


, Rust , - ( , Linux) (libc, libunwind ). , .



thumbv7em-none-eabihf, ARM. , , (none). , Rustup:



rustup target add thumbv7em-none-eabihf


:



cargo build --target thumbv7em-none-eabihf


--target, - . , , .



, . thumbv7em-none-eabihf x86-64. ( ), . , m1rko, ( ).





, :



src/main.rs:



#![no_std] // don't link the Rust standard library
#![no_main] // disable all Rust-level entry points

use core::panic::PanicInfo;

#[no_mangle] // don't mangle the name of this function
pub extern "C" fn _start() -> ! {
  // this function is the entry point, since the linker looks for a function
  // named `_start` by default
  loop {}
}

/// This function is called on panic.
#[panic_handler]
fn panic(_info: &PanicInfo) -> ! {
  loop {}
}


Cargo.toml:



[package]
name = "crate_name"
version = "0.1.0"
authors = ["Author Name <author@example.com>"]

# the profile used for `cargo build`
[profile.dev]
panic = "abort" # disable stack unwinding on panic

# the profile used for `cargo build --release`
[profile.release]
panic = "abort" # disable stack unwinding on panic


— :



cargo build --target thumbv7em-none-eabihf


. . , , . -, .




All Articles