Headline | Time | |
---|---|---|
Total time | 4:27 | |
实验记录 [2023-04-09 Sun 16:30] | 4:27 | |
\_ 第零章:操作系统概述 | 1:43 | |
\_ 第一章:应用程序与基本执行环境 [2023-04-10 Mon 23:16] | 2:44 |
yay -Syy
yay -S docker
sudo usermod -aG docker $USER
newgrp docker
sudo systemctl enable docker
sudo systemctl start docker
cd 2023s-rcore-WuTao18
sudo su # 切换到 root 账户
make build_docker
exit # 退出 root 账户
make docker # 进入开发环境
容器退出就删除不太方便,自己配置过的一些环境会丢失,还是保留容器:
docker run -itd -v ${PWD}:/mnt -w /mnt rcore-tutorial-v3 bash
容器内安装 vim, 切换 apt 源。
尝试运行:
git checkout ch1
cd os
make run
yay -S ninja gperf patchutils bc tmux
wget https://download.qemu.org/qemu-7.0.0.tar.xz
# 解压
tar xvJf qemu-7.0.0.tar.xz
# 编译安装并配置 RISC-V 支持
cd qemu-7.0.0
./configure --target-list=riscv64-softmmu,riscv64-linux-user
make -j$(nproc)
编译失败,报错:
/usr/sbin/ld: libcommon.fa.p/ebpf_ebpf_rss.c.o: in function `ebpf_rss_load':
/home/wutao/rust-os-comp-2023/qemu-7.0.0/build/../ebpf/ebpf_rss.c:52: undefined reference to `bpf_program__set_socket_filter'
collect2: error: ld returned 1 exit status
qemu 7.1.0 可以编译 [2023-04-11 Tue 00:16]
加入环境变量:
export PATH="$HOME/rust-os-comp-2023/qemu-7.1.0/build/:$PATH"
export PATH="$HOME/rust-os-comp-2023/qemu-7.1.0/build/riscv64-softmmu:$PATH"
export PATH="$HOME/rust-os-comp-2023/qemu-7.1.0/build/riscv64-linux-user:$PATH"
fatal: detected dubious ownership in repository at '/mnt'
To add an exception for this directory, call:
git config --global --add safe.directory /mnt
根据 git 提示信息可以解决: git config --global --add safe.directory /mnt
感觉使用容器还是不太方便,还是配置一下 wsl 内的开发环境吧 [2023-04-10 Mon 23:51]
$ rustc --version --verbose rustc 1.67.1 (d5a82bbd2 2023-02-07) binary: rustc commit-hash: d5a82bbd26e1ad8b7401f6a718a9c57c96905483 commit-date: 2023-02-07 host: x86_64-unknown-linux-gnu release: 1.67.1 LLVM version: 15.0.6
$ rustc --print target-list | grep riscv riscv32gc-unknown-linux-gnu riscv32gc-unknown-linux-musl riscv32i-unknown-none-elf riscv32im-unknown-none-elf riscv32imac-unknown-none-elf riscv32imac-unknown-xous-elf riscv32imc-esp-espidf riscv32imc-unknown-none-elf riscv64gc-unknown-freebsd riscv64gc-unknown-linux-gnu riscv64gc-unknown-linux-musl riscv64gc-unknown-none-elf riscv64gc-unknown-openbsd riscv64imac-unknown-none-elf
$ cargo run --target riscv64gc-unknown-none-elf Compiling os v0.1.0 (/home/wutao/rust-os-comp-2023/rust-os/os) error[E0463]: can't find crate for `std` | = note: the `riscv64gc-unknown-none-elf` target may not be installed = help: consider downloading the target with `rustup target add riscv64gc-unknown-none-elf` error: cannot find macro `println` in this scope --> src/main.rs:2:5 | 2 | println!("Hello, world!"); | ^^^^^^^ error: requires `sized` lang_item For more information about this error, try `rustc --explain E0463`. error: could not compile `os` due to 3 previous errors
riscv64gc-unknown-none-elf
的 CPU 架构是 riscv64gc,厂商是 unknown,操作系统是 none, elf 表示没有标准的运行时库。没有任何系统调用的封装支持,但可以生成 ELF 格式的执行程序。
rustup target add riscv64gc-unknown-none-elf
$ cargo build Compiling os v0.1.0 (/home/wutao/rust-os-comp-2023/rust-os/os) error: cannot find macro `println` in this scope --> src/main.rs:3:5 | 3 | println!("Hello, world!"); | ^^^^^^^ error: `#[panic_handler]` function required, but not found error: could not compile `os` due to 2 previous errors
// os/src/main.rs
#![no_std]
mod lang_items;
fn main() {
// println!("Hello, world!");
}
// os/src/lang_items.rs
use core::panic::PanicInfo;
#[panic_handler]
fn panic(_info: &PanicInfo) -> ! {
loop {}
}
$ cargo build Compiling os v0.1.0 (/home/wutao/rust-os-comp-2023/rust-os/os) error: requires `start` lang_item error: could not compile `os` due to previous error
// os/src/main.rs
#![no_std]
#![no_main]
mod lang_items;
rustup component add llvm-tools-preview
// os/src/main.rs
#![no_std]
#![no_main]
mod lang_items;
#[no_mangle]
extern "C" fn _start() {
loop{};
}
$ rust-objdump -S target/riscv64gc-unknown-none-elf/debug/os target/riscv64gc-unknown-none-elf/debug/os: file format elf64-littleriscv Disassembly of section .text: 0000000000011120 <_start>: ; loop{}; 11120: 09 a0 j 0x11122 <_start+0x2> 11122: 01 a0 j 0x11122 <_start+0x2>
程序正常退出
$ rust-objdump -S target/riscv64gc-unknown-none-elf/debug/os target/riscv64gc-unknown-none-elf/debug/os: file format elf64-littleriscv Disassembly of section .text: 0000000000011120 <_start>: ; } 11120: 82 80 ret
qemu 运行崩溃:
$ qemu-riscv64 target/riscv64gc-unknown-none-elf/debug/os [1] 32073 segmentation fault (core dumped) qemu-riscv64 target/riscv64gc-unknown-none-elf/debug/os
加入 loop 能运行(死循环)
加入退出机制:
// os/src/main.rs
#![no_std]
#![no_main]
mod lang_items;
const SYSCALL_EXIT: usize = 93;
fn syscall(id: usize, args: [usize; 3]) -> isize {
let mut ret;
unsafe {
core::arch::asm!(
"ecall",
inlateout("x10") args[0] => ret,
in("x11") args[1],
in("x12") args[2],
in("x17") id,
);
}
ret
}
pub fn sys_exit(xstate: i32) -> isize {
syscall(SYSCALL_EXIT, [xstate as usize, 0, 0])
}
#[no_mangle]
extern "C" fn _start() {
sys_exit(9);
}
$ qemu-riscv64 target/riscv64gc-unknown-none-elf/debug/os; echo $? 9
需要补充一下 rust 内联汇编的知识 [2023-04-12 Wed 00:43]
实现输出字符串的相关函数 [2023-04-12 Wed 00:47]
$ cargo build Compiling os v0.1.0 (/home/wutao/rust-os-comp-2023/rust-os/os) Finished dev [unoptimized + debuginfo] target(s) in 0.10s $ qemu-riscv64 target/riscv64gc-unknown-none-elf/debug/os; echo $? Hello, world! 9
实现关机功能
const SBI_SHUTDOWN: usize = 8;
pub fn shutdown() -> ! {
sbi_call(SBI_SHUTDOWN, 0, 0, 0);
panic!("It should shutdown!");
}
$ cargo build --release $ rust-objcopy --binary-architecture=riscv64 target/riscv64gc-unknown-none-elf/release/os --strip-all -O binary target/riscv64gc-unknown-none-elf/release/os.bin $ qemu-system-riscv64 -machine virt -nographic -bios ../bootloader/rustsbi-qemu.bin -device loader,file=target/riscv64gc-unknown-none-elf/release/os.bin,addr=0x80200000 # 死循环,CPU 单核负载占满,按 C-a x 退出
设置正确的程序内存布局 [2023-04-12 Wed 01:38]
正确配置栈空间布局 [2023-04-12 Wed 01:41]
# os/src/entry.asm
.section .text.entry
.globl _start
_start:
la sp, boot_stack_top
call rust_main
.section .bss.stack
.globl boot_stack
boot_stack:
.space 4096 * 16
.globl boot_stack_top
boot_stack_top:
$ qemu-system-riscv64 -machine virt -nographic -bios ../bootloader/rustsbi-qemu.bin -device loader,file=target/riscv64gc-unknown-none-elf/release/os.bin,addr=0x80200000 [rustsbi] RustSBI version 0.3.0-alpha.4, adapting to RISC-V SBI v1.0.0 .______ __ __ _______.___________. _______..______ __ | _ \ | | | | / | | / || _ \ | | | |_) | | | | | | (----`---| |----`| (----`| |_) || | | / | | | | \ \ | | \ \ | _ < | | | |\ \----.| `--' |.----) | | | .----) | | |_) || | | _| `._____| \______/ |_______/ |__| |_______/ |______/ |__| [rustsbi] Implementation : RustSBI-QEMU Version 0.2.0-alpha.2 [rustsbi] Platform Name : riscv-virtio,qemu [rustsbi] Platform SMP : 1 [rustsbi] Platform Memory : 0x80000000..0x88000000 [rustsbi] Boot HART : 0 [rustsbi] Device Tree Region : 0x87e00000..0x87e00f85 [rustsbi] Firmware Address : 0x80000000 [rustsbi] Supervisor Address : 0x80200000 [rustsbi] pmp01: 0x00000000..0x80000000 (-wr) [rustsbi] pmp02: 0x80000000..0x80200000 (---) [rustsbi] pmp03: 0x80200000..0x88000000 (xwr) [rustsbi] pmp04: 0x88000000..0x00000000 (-wr)
清空 .bss 段 [2023-04-12 Wed 01:50]
fn clear_bss() {
extern "C" {
fn sbss();
fn ebss();
}
(sbss as usize..ebss as usize).for_each(|a| {
unsafe { (a as *mut u8).write_volatile(0) }
});
}
添加裸机打印相关函数
// os/src/sbi.rs
pub fn console_putchar(c: usize) {
sbi_call(SBI_CONSOLE_PUTCHAR, c, 0, 0);
}
// os/src/console.rs
fn write_str(&mut self, s: &str) -> fmt::Result {
for c in s.chars() {
console_putchar(c as usize);
}
Ok(())
}