[英]How to compile a Rust kernel with an Assembly (NASM) bootloader
我有一個用 NASM 編寫的簡單的兩階段引導加載程序,我想繼續使用 Rust 的操作系統內核。
所以我用 Cargo 創建了一個每晚的 Rust 項目,並在 src/main.rs 文件中禁用了 std。 現在我試圖將 Assembly 文件與 Cargo 項目鏈接起來,但沒有成功。
我應該如何編譯 NASM 引導加載程序並將其與 Rust 內核鏈接?
幾個小時后,我編譯了代碼。
解決方案是(如Michael Petch建議的那樣),將匯編代碼編譯為靜態.o
文件,然后使用xargo
和自定義目標編譯rust代碼。 我將Rust代碼編譯為靜態庫,而不是二進制庫,因此輸出是.a
目標文件,而不是可執行文件。
然后,我使用了帶有鏈接描述文件的gcc
將目標文件鏈接在一起,並將結果輸出為ELF文件。 之后,我將objcopy
與-O binary
標志一起使用以將ELF文件復制到.bin文件。 最后,我使用dd
創建了一個映像文件,可以從中啟動。
我如何將 NASM 引導加載程序鏈接到 Rust 內核如下:
我首先用cargo
初始化了一個 Rust 項目並創建了一個類似於此的自定義 i386 Rust 目標
{
"llvm-target": "i386-unknown-none",
"data-layout": "e-m:e-i32:32-f80:128-n8:16:32-S128-p:32:32",
"arch": "x86",
"target-endian": "little",
"target-pointer-width": "32",
"target-c-int-width": "32",
"os": "none",
"executables": true,
"linker-flavor": "ld.lld",
"linker": "rust-lld",
"panic-strategy": "abort",
"disable-redzone": true,
"features": "-mmx,-sse,+soft-float"
}
然后我按照本指南鏈接中的說明在main.rs
文件中編寫了一些 Rust 代碼,必要時指定#[no_mangle]
、 #![no_std]
、 #![no_main]
和#[panic_handler]
。
在我的cargo.toml
中,我指定 Rust 創建一個靜態庫*.a
文件,因為您不能將二進制文件與二進制文件鏈接
[lib]
name = "sapphire" # The name of the target.
path = "src/main.rs" # The source file of the target.
edition = "2021" # The edition of the target.
crate-type = ["staticlib"] # The crate types to generate.
然后我創建了一個.cargo/config.toml
來構建compiler_builtins
、 compiler-builtins-mem
和core
在編寫 Rust 文件后,我用匯編編寫了一個簡單的引導加載程序,按照 OSDev 上的引導順序規范從實模式切換到保護模式。
我寫了一個鏈接器腳本來將 Rust 內核和引導加載程序鏈接在一起,
SECTIONS {
. = 0x7C00;
.text : {
/* *(.text) */
chainloader.elf(.text)
}
.text : {
kernel.a(.text)
}
/DISCARD/ : {
*(.comment)
*(.eh_frame)
*(.rel.eh_frame)
*(.note.gnu.property)
}
}
首先放置引導加載程序並添加引導加載程序服務檢測所需的偏移量
然后,我將引導加載程序構建為 ELF 文件,使用仿真elf_i386
將其鏈接到內核,並使用objcopy
將 ELF 文件轉換為二進制文件。
最后,我使用dd
刷新映像並使用模擬器啟動它。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.