Skip to content

Latest commit

 

History

History
403 lines (335 loc) · 11 KB

phase2-record.org

File metadata and controls

403 lines (335 loc) · 11 KB

第二阶段训练学习记录

实验记录 [2023-04-09 Sun 16:30]

HeadlineTime
Total time4:27
实验记录 [2023-04-09 Sun 16:30]4:27
\_ 第零章:操作系统概述1:43
\_ 第一章:应用程序与基本执行环境 [2023-04-10 Mon 23:16]2:44

第零章:操作系统概述

环境配置 [2023-04-09 Sun 20:54]

docker 安装 [2023-04-09 Sun 20:55]

yay -Syy
yay -S docker
sudo usermod -aG docker $USER
newgrp docker
sudo systemctl enable docker
sudo systemctl start docker

OS 开发环境配置 [2023-04-09 Sun 21:04]

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

wsl 下开发环境配置 [2023-04-10 Mon 23:53]

qemu 模拟器安装 [2023-04-10 Mon 23:53]
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"

第一章:应用程序与基本执行环境 [2023-04-10 Mon 23:16]

如果在 docker 容器外使用 git checkout ch1 命令,docker 容器内再使用 git 会报错: [2023-04-10 Mon 23:50]

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

移除 println! 宏

$ 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

提供语义项 panic_handler

// 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

移除 main 函数

// 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

构建裸机执行环境 [2023-04-12 Wed 01:20]

实现关机功能

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(())
}