Menyiapkan lingkungan. Biner telanjang, atau Dapat dijalankan tanpa main ()
Langkah pertama dalam menulis OS Anda sendiri adalah membuat biner yang tidak bergantung pada pustaka standar, ini memungkinkan untuk menjalankan kode tanpa OS - kami menulisnya sendiri.
Blog asli sedang dikembangkan di GitHub . Tinggalkan komentar Anda ke aslinya pada halaman Masalah dari repositori di atas, dan ke terjemahan - di PM, komentar atau di sini . Kode yang ditulis dalam artikel ini terkandung di post-01.
pengantar
Untuk menulis OS kita sendiri, kita membutuhkan kode yang tidak bergantung pada pustaka atau fungsi sistem operasi lain. Ini berarti kita tidak dapat menggunakan utas, file, memori heap, jaringan, output terminal, dan sebagainya. Tapi ini bisa diatasi dengan menulis OS dan driver Anda sendiri.
Kami tidak dapat menggunakan sebagian besar pustaka standar Rust , tetapi ada juga banyak fungsi yang dapat kami gunakan. Misalnya iterator , closure , pattern matching , Option dan Result , format string , dan tentunya konsep kepemilikan . Ini memungkinkan Anda untuk menulis kernel dengan gaya tingkat tinggi tanpa mengkhawatirkan perilaku yang tidak ditentukan atau keamanan memori .
Artikel ini menjelaskan cara membuat file eksekusi mandiri dan mengapa Anda membutuhkannya. Jika Anda hanya menginginkan contoh, Anda dapat menggulir ke bagian Kesimpulan.
Menonaktifkan perpustakaan standar
, , , .. : 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
. . , , . -, .