Использование QEMU для запуска ядра
В новой версии QEMU встроено программное обеспечение OpenSBI, которое отвечает за инициализацию оборудования и загрузку операционной системы перед запуском операционной системы. Мы используем следующую команду для попытки запуска:
$ qemu-system-riscv64 \
--machine virt \
--nographic \
--bios default
OpenSBI v0.6
/ __ \ / | _ _ | | | | | __ ___ _ __ | ( | |) || | | | | | '_ \ / _ \ '_ \ ___ | _ < | | | || | |) | __/ | | |) | |) || | _/| ./ _|| ||/|____/| | | |_|
Platform Name : QEMU Virt Machine Platform HART Features : RV64ACDFIMSU Platform Max HARTs : 8 Current Hart : 0 Firmware Base : 0x80000000 Firmware Size : 120 KB Runtime SBI Version : 0.2
MIDELEG : 0x0000000000000222 MEDELEG : 0x000000000000b109 PMP0 : 0x0000000080000000-0x000000008001ffff (A) PMP1 : 0x0000000000000000-0xffffffffffffffff (A,R,W,X)
Можно увидеть, что мы запустили программное обеспечение OpenSBI на эмулированном оборудовании QEMU Virt Machine. QEMU можно использовать ctrl+a
(macOS — control+a
) для выхода, а затем нажать клавишу x
.
Чтобы убедиться, что код внутри ядра работает, лучше всего добавить простой вывод в rust_main
:
//! # 全局属性
//! - `#![no_std]`
//! 禁用标准库
#![no_std]
//!
//! - `#![no_main]`
//! 不使用 `main` 函数等全部 Rust-level 入口点来作为程序入口
#![no_main]
//! # 一些 unstable 的功能需要在 crate 层级声明后才可以使用
//! - `#![feature(llvm_asm)]`
//! 内嵌汇编
#![feature(llvm_asm)]
//!
//! - `#![feature(global_asm)]`
//! 内嵌整个汇编文件
#![feature(global_asm)]
// 汇编编写的程序入口,具体见该文件
global_asm!(include_str!("entry.asm"));
use core::panic::PanicInfo;
/// 当 panic 发生时会调用该函数
/// 我们暂时将它的实现为一个死循环
#[panic_handler]
fn panic(_info: &PanicInfo) -> ! {
loop {}
}
/// 在屏幕上输出一个字符,目前我们先不用了解其实现原理
pub fn console_putchar(ch: u8) {
let _ret: usize;
let arg0: usize = ch as usize;
let arg1: usize = 0;
let arg2: usize = 0;
let which: usize = 1;
unsafe {
llvm_asm!("ecall"
: "={x10}" (_ret)
: "{x10}" (arg0), "{x11}" (arg1), "{x12}" (arg2), "{x17}" (which)
: "memory"
: "volatile"
);
}
}
/// Rust 的入口函数
///
/// 在 `_start` 为我们进行了一系列准备之后,这是第一个被调用的 Rust 函数
#[no_mangle]
pub extern "C" fn rust_main() -> ! {
// 在屏幕上输出 "OK\n" ,随后进入死循环
console_putchar(b'O');
console_putchar(b'K');
console_putchar(b'\n');
loop {}
}
Если после загрузки образа ядра на экране появится «OK», это означает, что предыдущие шаги были выполнены правильно.
Теперь мы создаём образ ядра с помощью нескольких команд. Мы можем упростить этот процесс, создав Makefile в каталоге os:
TARGET := riscv64imac-unknown-none-elf
MODE := debug
KERNEL_FILE := target/$(TARGET)/$(MODE)/os
BIN_FILE := target/$(TARGET)/$(MODE)/kernel.bin
OBJDUMP := rust-objdump --arch-name=riscv64
OBJCOPY := rust-objcopy --binary-architecture=riscv64
.PHONY: doc kernel build clean qemu run
# 默认 build 为输出二进制文件
build: $(BIN_FILE)
# 通过 Rust 文件中的注释生成 os 的文档
doc:
@cargo doc --document-private-items
# 编译 kernel
kernel:
@cargo build
# 生成 kernel 的二进制文件
$(BIN_FILE): kernel
@$(OBJCOPY) $(KERNEL_FILE) --strip-all -O binary $@
# 查看反汇编结果
asm:
@$(OBJDUMP) -d $(KERNEL_FILE) | less
# 清理编译出的文件
clean:
@cargo clean
# 运行 QEMU
qemu: build
@qemu-system-riscv64 \
-machine virt \
-nographic \
-bios default \
-device loader,file=$(BIN_FILE),addr=0x80200000
# 一键运行
run: build qemu
Здесь мы используем параметр -device
, чтобы загрузить образ ядра в QEMU. Мы указываем файл образа ядра и сообщаем OpenSBI перейти к адресу входа 0x80200000.
Наконец, мы можем использовать make run
, чтобы запустить Qemu, загрузить образ ядра и запустить его. После быстрого просмотра длинного вывода OpenSBI мы видим «ОК»! Итак, после всех трудностей мы наконец запустили наше ядро!
В следующем разделе мы реализуем форматированный вывод, чтобы сделать отладку ядра более удобной.
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Опубликовать ( 0 )