Giter Site home page Giter Site logo

rcore-os / rcore-tutorial-v3 Goto Github PK

View Code? Open in Web Editor NEW
1.5K 20.0 413.0 46.35 MB

Let's write an OS which can run on RISC-V in Rust from scratch!

Home Page: https://rcore-os.github.io/rCore-Tutorial-Book-v3/index.html

License: GNU General Public License v3.0

Rust 96.83% Makefile 1.17% Assembly 0.97% Dockerfile 0.83% Shell 0.04% Python 0.15%
rust risc-v rcore operating-system k210

rcore-tutorial-v3's Introduction

rCore-Tutorial-v3

rCore-Tutorial version 3.6. See the Documentation in Chinese.

rCore-Tutorial API Docs. See the API Docs of Ten OSes

If you don't know Rust Language and try to learn it, please visit Rust Learning Resources

Official QQ group number: 735045051

news

  • 23/06/2022: Version 3.6.0 is on the way! Now we directly update the code on chX branches, please periodically check if there are any updates.

Overview

This project aims to show how to write an Unix-like OS running on RISC-V platforms from scratch in Rust for beginners without any background knowledge about computer architectures, assembly languages or operating systems.

Features

  • Platform supported: qemu-system-riscv64 simulator or dev boards based on Kendryte K210 SoC such as Maix Dock
  • OS
    • concurrency of multiple processes each of which contains mutiple native threads
    • preemptive scheduling(Round-Robin algorithm)
    • dynamic memory management in kernel
    • virtual memory
    • a simple file system with a block cache
    • an interactive shell in the userspace
  • only 4K+ LoC
  • A detailed documentation in Chinese in spite of the lack of comments in the code(English version is not available at present)

Prerequisites

Install Rust

See official guide.

Install some tools:

$ rustup target add riscv64gc-unknown-none-elf
$ cargo install cargo-binutils --vers =0.3.3
$ rustup component add llvm-tools-preview
$ rustup component add rust-src

Install Qemu

Here we manually compile and install Qemu 7.0.0. For example, on Ubuntu 18.04:

# install dependency packages
$ sudo apt install autoconf automake autotools-dev curl libmpc-dev libmpfr-dev libgmp-dev \
              gawk build-essential bison flex texinfo gperf libtool patchutils bc \
              zlib1g-dev libexpat-dev pkg-config  libglib2.0-dev libpixman-1-dev git tmux python3 python3-pip ninja-build
# download Qemu source code
$ wget https://download.qemu.org/qemu-7.0.0.tar.xz
# extract to qemu-7.0.0/
$ tar xvJf qemu-7.0.0.tar.xz
$ cd qemu-7.0.0
# build
$ ./configure --target-list=riscv64-softmmu,riscv64-linux-user
$ make -j$(nproc)

Then, add following contents to ~/.bashrc(please adjust these paths according to your environment):

export PATH=$PATH:/path/to/qemu-7.0.0/build

Finally, update the current shell:

$ source ~/.bashrc

Now we can check the version of Qemu:

$ qemu-system-riscv64 --version
QEMU emulator version 7.0.0
Copyright (c) 2003-2020 Fabrice Bellard and the QEMU Project developers

Install RISC-V GNU Embedded Toolchain(including GDB)

Download the compressed file according to your platform From Sifive website(Ctrl+F 'toolchain').

Extract it and append the location of the 'bin' directory under its root directory to $PATH.

For example, we can check the version of GDB:

$ riscv64-unknown-elf-gdb --version
GNU gdb (SiFive GDB-Metal 10.1.0-2020.12.7) 10.1
Copyright (C) 2020 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Install serial tools(Optional, if you want to run on K210)

$ pip3 install pyserial
$ sudo apt install python3-serial

Run our project

Qemu

$ git clone https://github.com/rcore-os/rCore-Tutorial-v3.git
$ cd rCore-Tutorial-v3/os
$ make run

After outputing some debug messages, the kernel lists all the applications available and enter the user shell:

/**** APPS ****
mpsc_sem
usertests
pipetest
forktest2
cat
initproc
race_adder_loop
threads_arg
race_adder_mutex_spin
race_adder_mutex_blocking
forktree
user_shell
huge_write
race_adder
race_adder_atomic
threads
stack_overflow
filetest_simple
forktest_simple
cmdline_args
run_pipe_test
forktest
matrix
exit
fantastic_text
sleep_simple
yield
hello_world
pipe_large_test
sleep
phil_din_mutex
**************/
Rust user shell
>> 

You can run any application except for initproc and user_shell itself. To run an application, just input its filename and hit enter. usertests can run a bunch of applications, thus it is recommended.

Type Ctrl+a then x to exit Qemu.

K210

Before chapter 6, you do not need a SD card:

$ git clone https://github.com/rcore-os/rCore-Tutorial-v3.git
$ cd rCore-Tutorial-v3/os
$ make run BOARD=k210

From chapter 6, before running the kernel, we should insert a SD card into PC and manually write the filesystem image to it:

$ cd rCore-Tutorial-v3/os
$ make sdcard

By default it will overwrite the device /dev/sdb which is the SD card, but you can provide another location. For example, make sdcard SDCARD=/dev/sdc.

After that, remove the SD card from PC and insert it to the slot of K210. Connect the K210 to PC and then:

$ git clone https://github.com/rcore-os/rCore-Tutorial-v3.git
$ cd rCore-Tutorial-v3/os
$ make run BOARD=k210

Type Ctrl+] to disconnect from K210.

Show runtime debug info of OS kernel version

The branch of ch9-log contains a lot of debug info. You could try to run rcore tutorial for understand the internal behavior of os kernel.

$ git clone https://github.com/rcore-os/rCore-Tutorial-v3.git
$ cd rCore-Tutorial-v3/os
$ git checkout ch9-log
$ make run
......
[rustsbi] RustSBI version 0.2.0-alpha.10, adapting to RISC-V SBI v0.3
.______       __    __      _______.___________.  _______..______   __
|   _  \     |  |  |  |    /       |           | /       ||   _  \ |  |
|  |_)  |    |  |  |  |   |   (----`---|  |----`|   (----`|  |_)  ||  |
|      /     |  |  |  |    \   \       |  |      \   \    |   _  < |  |
|  |\  \----.|  `--'  |.----)   |      |  |  .----)   |   |  |_)  ||  |
| _| `._____| \______/ |_______/       |__|  |_______/    |______/ |__|

[rustsbi] Implementation: RustSBI-QEMU Version 0.0.2
[rustsbi-dtb] Hart count: cluster0 with 1 cores
[rustsbi] misa: RV64ACDFIMSU
[rustsbi] mideleg: ssoft, stimer, sext (0x222)
[rustsbi] medeleg: ima, ia, bkpt, la, sa, uecall, ipage, lpage, spage (0xb1ab)
[rustsbi] pmp0: 0x10000000 ..= 0x10001fff (rw-)
[rustsbi] pmp1: 0x2000000 ..= 0x200ffff (rw-)
[rustsbi] pmp2: 0xc000000 ..= 0xc3fffff (rw-)
[rustsbi] pmp3: 0x80000000 ..= 0x8fffffff (rwx)
[rustsbi] enter supervisor 0x80200000
[KERN] rust_main() begin
[KERN] clear_bss() begin
[KERN] clear_bss() end
[KERN] mm::init() begin
[KERN] mm::init_heap() begin
[KERN] mm::init_heap() end
[KERN] mm::init_frame_allocator() begin
[KERN] mm::frame_allocator::lazy_static!FRAME_ALLOCATOR begin
......

Rustdoc

Currently it can only help you view the code since only a tiny part of the code has been documented.

You can open a doc html of os using cargo doc --no-deps --open under os directory.

OS-API-DOCS

The API Docs for Ten OS

  1. Lib-OS API doc
  2. Batch-OS API doc
  3. MultiProg-OS API doc
  4. TimeSharing-OS API doc
  5. AddrSpace-OS API doc
  6. Process-OS API doc
  7. FileSystem-OS API doc
  8. IPC-OS API doc
  9. SyncMutex-OS API doc
  10. IODevice-OS API doc

Working in progress

Our first release 3.6.0 (chapter 1-9) has been published, and we are still working on it.

  • chapter 9: need more descripts about different I/O devices

Here are the updates since 3.5.0:

Completed

  • automatically clean up and rebuild before running our project on a different platform
  • fix power series application in early chapters, now you can find modulus in the output
  • use UPSafeCell instead of RefCell or spin::Mutex in order to access static data structures and adjust its API so that it cannot be borrowed twice at a time(mention & .exclusive_access().task[0] in run_first_task)
  • move TaskContext into TaskControlBlock instead of restoring it in place on kernel stack(since ch3), eliminating annoying task_cx_ptr2
  • replace llvm_asm! with asm!
  • expand the fs image size generated by rcore-fs-fuse to 128MiB
  • add a new test named huge_write which evaluates the fs performance(qemu~500KiB/s k210~50KiB/s)
  • flush all block cache to disk after a fs transaction which involves write operation
  • replace spin::Mutex with UPSafeCell before SMP chapter
  • add codes for a new chapter about synchronization & mutual exclusion(uniprocessor only)
  • bug fix: we should call find_pte rather than find_pte_create in PageTable::unmap
  • clarify: "check validity of level-3 pte in find_pte instead of checking it outside this function" should not be a bug
  • code of chapter 8: synchronization on a uniprocessor
  • switch the code of chapter 6 and chapter 7
  • support signal mechanism in chapter 7/8(only works for apps with a single thread)
  • Add boards/ directory and support rustdoc, for example you can use cargo doc --no-deps --open to view the documentation of a crate
  • code of chapter 9: device drivers based on interrupts, including UART, block, keyboard, mouse, gpu devices
  • add CI autotest and doc in github

Todo(High priority)

  • review documentation, current progress: 8/9
  • use old fs image optionally, do not always rebuild the image
  • shell functionality improvement(to be continued...)
  • give every non-zero process exit code an unique and clear error type
  • effective error handling of mm module
  • add more os functions for understanding os conecpts and principles

Todo(Low priority)

  • rewrite practice doc and remove some inproper questions
  • provide smooth debug experience at a Rust source code level
  • format the code using official tools

Crates

We will add them later.

rcore-tutorial-v3's People

Contributors

chyyuu avatar cl-a11y avatar cndoit18 avatar cuishuang avatar cyyself avatar deathwish5 avatar direktor799 avatar felixonmars avatar jiegec avatar jklincn avatar justxuewei avatar n9w-x avatar spxg avatar wyfcyx avatar ydrmaster avatar yfblock avatar yuoo655 avatar zhanghandong avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

rcore-tutorial-v3's Issues

RustSBI panic with QEMU 6.1.0

在QEMU 6.1.0版本上运行项目会出现无效指令错误,经测试使用RustSBI 0.2.0-alpha.6可以解决,是否考虑将bootloader下的文件更新或者在文档中增加提示?

[rustsbi] RustSBI version 0.2.0-alpha.1
.______       __    __      _______.___________.  _______..______   __
|   _  \     |  |  |  |    /       |           | /       ||   _  \ |  |
|  |_)  |    |  |  |  |   |   (----`---|  |----`|   (----`|  |_)  ||  |
|      /     |  |  |  |    \   \       |  |      \   \    |   _  < |  |
|  |\  \----.|  `--'  |.----)   |      |  |  .----)   |   |  |_)  ||  |
| _| `._____| \______/ |_______/       |__|  |_______/    |______/ |__|

[rustsbi] Platform: QEMU (Version 0.2.0)
[rustsbi] misa: RV64ACDFIMSU
[rustsbi] mideleg: 0x222
[rustsbi] medeleg: 0xb1ab
[rustsbi-dtb] Hart count: cluster0 with 1 cores
[rustsbi] Kernel entry: 0x80200000
[rustsbi-panic] hart 0 panicked at 'invalid instruction, mepc: 000000008000004c, instruction: 0000000030200073', platform/qemu/src/main.rs:484:17
[rustsbi-panic] system shutdown scheduled due to RustSBI panic

[chp 2 & rust] 是否可以将其在cargo工作空间重构?

在做chp2的实验时,我尝试将user和os都置于cargo工作空间下,试图重构(非linux,macOS环境下)。但是遇到了如下问题:

.cargo/config.toml文件如果分别置于members目录(此处为/osuser)的话,无法编译通过。但如果将.cargo/config.toml置于根目录的话user可以编译通过。

我的代码在这里,刚入门rust和学习操作系统,望指教。

第五章的内核代码好像有点问题

测试程序:
hello_world0.rs:

#![no_std]
#![no_main]

#[macro_use]
extern crate user_lib;

use user_lib::{fork, exec};

#[no_mangle]
pub fn main() -> i32 {
    let p = fork();
    for i in 0..10 {
        if p == 0 {
            println!("Program[0] print{}", i);
        } else {
            println!("Program[1] print{}", i);
        }
    }
    if p == 0 {
        exec("hello_world2");
    } else {
        exec("hello_world1");
    }
    0
}

hello_world1.rs:

#![no_std]
#![no_main]

#[macro_use]
extern crate user_lib;

#[no_mangle]
pub fn main() -> i32 {
    for i in 0..10 {
        println!("Program[1] print{}", i);
    }
    0
}

hello_world2.rs:

#![no_std]
#![no_main]

#[macro_use]
extern crate user_lib;

#[no_mangle]
pub fn main() -> i32 {
    for i in 0..10 {
        println!("Program[2] print{}", i);
    }
    0
}

第五章分支下的rCore运行hello_world0只输出了调用exec前应该输出的内容,没有输出exec后hello_world1和hello_world2应该输出的内容,不清楚是什么原因。

make run编译错误,提示this struct takes 1 generic argument but 0 generic arguments were supplied

rustc版本为rustc 1.64.0-nightly (9a7b7d5e5 2022-07-19)
在os目录下执行make run以后,提示以下错误:

error[E0107]: this struct takes 1 generic argument but 0 generic arguments were supplied
  --> src/drivers/block/virtio_blk.rs:18:32
   |
18 |     virtio_blk: UPIntrFreeCell<VirtIOBlk<'static>>,
   |                                ^^^^^^^^^ expected 1 generic argument
   |
note: struct defined here, with 1 generic parameter: `H`
  --> /home/ruiqurm/.cargo/git/checkouts/virtio-drivers-4fdfaa862bcdc399/4ee80e5/src/blk.rs:13:12
   |
13 | pub struct VirtIOBlk<'a, H: Hal> {
   |            ^^^^^^^^^     -
help: add missing generic argument
   |
18 |     virtio_blk: UPIntrFreeCell<VirtIOBlk<'static, H>>,
   |                                                 +++

error[E0107]: this struct takes 1 generic argument but 0 generic arguments were supplied
  --> src/drivers/gpu/mod.rs:19:25
   |
19 |     gpu: UPIntrFreeCell<VirtIOGpu<'static>>,
   |                         ^^^^^^^^^ expected 1 generic argument
   |
note: struct defined here, with 1 generic parameter: `H`
  --> /home/ruiqurm/.cargo/git/checkouts/virtio-drivers-4fdfaa862bcdc399/4ee80e5/src/gpu.rs:15:12
   |
15 | pub struct VirtIOGpu<'a, H: Hal> {
   |            ^^^^^^^^^     -
help: add missing generic argument
   |
19 |     gpu: UPIntrFreeCell<VirtIOGpu<'static, H>>,
   |                                          +++

error[E0107]: this struct takes 1 generic argument but 0 generic arguments were supplied
  --> src/drivers/input/mod.rs:21:35
   |
21 | struct VirtIOINPUT(UPIntrFreeCell<VirtIOInput<'static>>);
   |                                   ^^^^^^^^^^^ expected 1 generic argument
   |
note: struct defined here, with 1 generic parameter: `H`
  --> /home/ruiqurm/.cargo/git/checkouts/virtio-drivers-4fdfaa862bcdc399/4ee80e5/src/input.rs:12:12
   |
12 | pub struct VirtIOInput<'a, H: Hal> {
   |            ^^^^^^^^^^^     -
help: add missing generic argument
   |
21 | struct VirtIOINPUT(UPIntrFreeCell<VirtIOInput<'static, H>>);
   |                                                      +++

the method `configure` exists for struct `k210_pac::UARTHS`, but its trait bounds were not satisfied

当我参考 https://rcore-os.github.io/rCore-Tutorial-Book-v3/chapter0/5setup-devel-env.html 配置环境完成之后进行编译,报错如下:

error[E0599]: the method `configure` exists for struct `k210_pac::UARTHS`, but its trait bounds were not satisfied
    --> src/drivers/block/sdcard.rs:725:24
     |
725  |     peripherals.UARTHS.configure(115_200.bps(), &clocks);
     |                        ^^^^^^^^^ method cannot be called on `k210_pac::UARTHS` due to unsatisfied trait bounds
     |
    ::: /home/wang/.cargo/git/checkouts/k210-pac-19d36f600eb54ac3/8f99c1c/src/lib.rs:1028:1
     |
1028 | pub struct UARTHS {
     | -----------------
     | |
     | doesn't satisfy `k210_pac::UARTHS: SerialExt`
     | doesn't satisfy `k210_pac::UARTHS: serial::closed_trait::UartX`
...
1050 |     pub struct RegisterBlock {
     |     ------------------------
     |     |
     |     doesn't satisfy `_: serial::closed_trait::UartX`
     |     doesn't satisfy `k210_pac::uarths::RegisterBlock: SerialExt`
     |
     = note: the following trait bounds were not satisfied:
             `k210_pac::UARTHS: serial::closed_trait::UartX`
             which is required by `k210_pac::UARTHS: SerialExt`
             `&k210_pac::UARTHS: serial::closed_trait::UartX`
             which is required by `&k210_pac::UARTHS: SerialExt`
             `&mut k210_pac::UARTHS: serial::closed_trait::UartX`
             which is required by `&mut k210_pac::UARTHS: SerialExt`
             `k210_pac::uarths::RegisterBlock: serial::closed_trait::UartX`
             which is required by `k210_pac::uarths::RegisterBlock: SerialExt`
             `&k210_pac::uarths::RegisterBlock: serial::closed_trait::UartX`
             which is required by `&k210_pac::uarths::RegisterBlock: SerialExt`
             `&mut k210_pac::uarths::RegisterBlock: serial::closed_trait::UartX`
             which is required by `&mut k210_pac::uarths::RegisterBlock: SerialExt`

error[E0599]: the method `constrain` exists for struct `k210_pac::SPI0`, but its trait bounds were not satisfied
     --> src/drivers/block/sdcard.rs:728:32
      |
728   |     let spi = peripherals.SPI0.constrain();
      |                                ^^^^^^^^^ method cannot be called on `k210_pac::SPI0` due to unsatisfied trait bounds
      |
     ::: /home/wang/.cargo/git/checkouts/k210-pac-19d36f600eb54ac3/8f99c1c/src/lib.rs:19849:1
      |
19849 | pub struct SPI0 {
      | ---------------
      | |
      | doesn't satisfy `k210_pac::SPI0: SPI01`
      | doesn't satisfy `k210_pac::SPI0: SPIExt`
...
19871 |     pub struct RegisterBlock {
      |     ------------------------
      |     |
      |     doesn't satisfy `k210_pac::spi0::RegisterBlock: SPI01`
      |     doesn't satisfy `k210_pac::spi0::RegisterBlock: SPIExt`
      |
      = note: the following trait bounds were not satisfied:
              `k210_pac::SPI0: SPI01`
              which is required by `k210_pac::SPI0: SPIExt`
              `&k210_pac::SPI0: SPI01`
              which is required by `&k210_pac::SPI0: SPIExt`
              `&mut k210_pac::SPI0: SPI01`
              which is required by `&mut k210_pac::SPI0: SPIExt`
              `k210_pac::spi0::RegisterBlock: SPI01`
              which is required by `k210_pac::spi0::RegisterBlock: SPIExt`
              `&k210_pac::spi0::RegisterBlock: SPI01`
              which is required by `&k210_pac::spi0::RegisterBlock: SPIExt`
              `&mut k210_pac::spi0::RegisterBlock: SPI01`
              which is required by `&mut k210_pac::spi0::RegisterBlock: SPIExt`

error[E0277]: the trait bound `k210_pac::SPI0: SPI01` is not satisfied
   --> src/drivers/block/sdcard.rs:730:19
    |
730 |     let info = sd.init().unwrap();
    |                   ^^^^ the trait `SPI01` is not implemented for `k210_pac::SPI0`
    |
    = note: required because of the requirements on the impl of `SPI` for `SPIImpl<k210_pac::SPI0>`

error[E0277]: the trait bound `k210_pac::SPI0: SPI01` is not satisfied
   --> src/drivers/block/sdcard.rs:729:14
    |
163 |     pub fn new(spi: X, spi_cs: u32, cs_gpionum: u8/*, dmac: &'a DMAC, channel: dma_channel*/) -> Self {
    |     ------------------------------------------------------------------------------------------------- required by `SDCard::<X>::new`
...
729 |     let sd = SDCard::new(spi, SD_CS, SD_CS_GPIONUM);
    |              ^^^^^^^^^^^ the trait `SPI01` is not implemented for `k210_pac::SPI0`
    |
    = note: required because of the requirements on the impl of `SPI` for `SPIImpl<k210_pac::SPI0>`

error[E0599]: the method `read_sector` exists for struct `MutexGuard<'_, SDCard<SPIImpl<k210_pac::SPI0>>>`, but its trait bounds were not satisfied
   --> src/drivers/block/sdcard.rs:748:23
    |
748 |         self.0.lock().read_sector(buf,block_id as u32).unwrap();
    |                       ^^^^^^^^^^^ method cannot be called on `MutexGuard<'_, SDCard<SPIImpl<k210_pac::SPI0>>>` due to unsatisfied trait bounds
    |
   ::: /home/wang/.cargo/git/checkouts/k210-soc-069e4fc1d9165bc2/09a0742/src/spi.rs:52:1
    |
52  | pub struct SPIImpl<IF> {
    | ---------------------- doesn't satisfy `SPIImpl<k210_pac::SPI0>: SPI`
    |
    = note: the following trait bounds were not satisfied:
            `SPIImpl<k210_pac::SPI0>: SPI`

error[E0599]: the method `write_sector` exists for struct `MutexGuard<'_, SDCard<SPIImpl<k210_pac::SPI0>>>`, but its trait bounds were not satisfied
   --> src/drivers/block/sdcard.rs:751:23
    |
751 |         self.0.lock().write_sector(buf,block_id as u32).unwrap();
    |                       ^^^^^^^^^^^^ method cannot be called on `MutexGuard<'_, SDCard<SPIImpl<k210_pac::SPI0>>>` due to unsatisfied trait bounds
    |
   ::: /home/wang/.cargo/git/checkouts/k210-soc-069e4fc1d9165bc2/09a0742/src/spi.rs:52:1
    |
52  | pub struct SPIImpl<IF> {
    | ---------------------- doesn't satisfy `SPIImpl<k210_pac::SPI0>: SPI`
    |
    = note: the following trait bounds were not satisfied:
            `SPIImpl<k210_pac::SPI0>: SPI`

error: aborting due to 6 previous errors

Some errors have detailed explanations: E0277, E0599.
For more information about an error, try `rustc --explain E0277`.
error: could not compile `os`

To learn more, run the command again with --verbose.
make: *** [Makefile:60: kernel] Error 101

Cache coherence

Dear maintainer,
There is a piece of code in ch2, asm!("fence.i") is used to flush I-Cache to maintain cache coherence. But considering the below figure, if we dont't use fence.i after loading code,we may fetch old code from memory. So I consider place fence.i at the end of load_app. Look forward to your response!

println!("[kernel] Loading app_{}", app_id);
// clear icache
asm!("fence.i");
// clear app area
core::slice::from_raw_parts_mut(APP_BASE_ADDRESS as *mut u8, APP_SIZE_LIMIT).fill(0);
let app_src = core::slice::from_raw_parts(
    self.app_start[app_id] as *const u8,
    self.app_start[app_id + 1] - self.app_start[app_id],
);
let app_dst = core::slice::from_raw_parts_mut(APP_BASE_ADDRESS as *mut u8, app_src.len());
app_dst.copy_from_slice(app_src);

make run 出错

Last week I checked out the main branch and run "make run", ererything was fine.

Today I checked out the lastest min branch and run "make run", there is a panic happend:
屏幕截图 2022-01-26 114033

Is there something I missed?

rCore in C

Hi rCore team & community,

Currently I am a TA for 3rd Open-Source Chip Project by University (OSCPU, 一生一芯), considering transplant rCore to my own RV CPU. I'm trying to implement rCore in C such that other students could learn it without rust. I've made some surveys but found that other OS for educational purpose written in C still differ a lot from rCore tutorial v3, e.g., xv6, uCore for RISC-V (https://github.com/DeathWish5/ucore-Tutorial), etc.

Thus, I started to implement rcc (rCore in C, https://github.com/shili2017/rcc), aiming at "copying" rCore from rust to C as much as possible, including general design, key data structure, and even function names & variable names, etc. I have started for a while and just completed chapter 4. There may still exist lots of bugs or flaws in design. If you are interested in developing this project, you are welcome to join, contact me, leave some issues or make some pull requests :) If there's any issue like license, please also notify me.

(Btw, it would be great if OSCPU students can run their own OS on their own CPU in the future, which is really cool.)

Thanks!

关于加入汇编代码的适配性的小疑惑

构建用户态执行环境中第一次加入了汇编代码。

#![feature(llvm_asm)]
#![no_std] // 不链接 Rust 标准库
#![no_main] // 禁用所有 Rust 层级的入口点


use core::panic::PanicInfo;

/// 这个函数将在 panic 时被调用
#[panic_handler]
fn panic(_info: &PanicInfo) -> ! {
    loop {}
}

const SYSCALL_EXIT: usize = 93;

fn syscall(id: usize, args: [usize; 3]) -> isize {
    let mut ret: isize;
    unsafe {
        llvm_asm!("ecall"
            : "={x10}" (ret)
            : "{x10}" (args[0]), "{x11}" (args[1]), "{x12}" (args[2]), "{x17}" (id)
            : "memory"
            : "volatile"
        );
    }
    ret
}

pub fn sys_exit(xstate: i32) -> isize {
    syscall(SYSCALL_EXIT, [xstate as usize, 0, 0])
}

#[no_mangle] // 不重整函数名
pub extern "C" fn _start() {
    // loop {}
    sys_exit(9);
}

然后用 riscv64 架构可以编译运行

[kearney@arch os]$ cargo build --target riscv64gc-unknown-none-elf
   Compiling os v0.1.0 (/home/kearney/Documents/code/rust/os-rust/os)
    Finished dev [unoptimized + debuginfo] target(s) in 0.12s
[kearney@arch os]$ qemu-riscv64 target/riscv64gc-unknown-none-elf/debug/os; echo $?
9

但是当我尝试用其它架构的时候,编译会报错,如 x86_64 和aarch64,是不是说明这个加入的汇编代码是具有架构指向性的,微机原理学的不咋地。。汇编代码使用指令集中的指令写的,而不同架构的指令集各不相同,因此才有了下面的交叉编译的错误,请教是这样的吗?

$ cargo build --target x86_64-unknown-linux-gnu
   Compiling os v0.1.0 (/home/kearney/Documents/code/rust/os-rust/os)
error: couldn't allocate output register for constraint '{x10}'
  --> src/main.rs:19:9
   |
19 |         llvm_asm!("ecall"
   |         ^

error: aborting due to previous error

error: could not compile `os`

$ cargo build --target aarch64-unknown-none-softfloat
   Compiling os v0.1.0 (/home/kearney/Documents/code/rust/os-rust/os)
error: unrecognized instruction mnemonic
  --> src/main.rs:19:9
   |
19 |         llvm_asm!("ecall"
   |         ^
   |
note: instantiated into assembly here
  --> <inline asm>:1:2
   |
1  |     ecall
   |     ^

error: aborting due to previous error

error: could not compile `os`

llvm_asm切换到asm引发的报错

您好,目前我现在在坐第四章的练习,在运行ch4分支的时候报找不到asm!的错误

image

我想可能是因为nightly版本过低(ch4分支里的版本是nightly-2021-01-30),所以我更新为nightly-2021-10-15,现在是不报找不到asm!的错误了,可是又报使用不稳定版本的特性asm,明明我配置的工具链是nightly版本的。

image

main分支也是报这个错

image

报错的地方是项目引用riscv中的一个模块,应该是这个修改:rcore-os/riscv@11d43cf

系统版本是CentOS Linux release 7.6.1810

我需要怎么做才能正常运行啊

build fail

   Compiling riscv v0.6.0
   Compiling riscv v0.6.0 (https://github.com/rcore-os/riscv#0074cbc9)
   Compiling riscv v0.6.0 (https://github.com.cnpmjs.org/rcore-os/riscv#0074cbc9)
   Compiling k210-hal v0.2.0 (https://github.com/wyfcyx/k210-hal#ea121c91)
   Compiling k210-hal v0.2.0 (https://github.com.cnpmjs.org/wyfcyx/k210-hal#ea121c91)
   Compiling k210-soc v0.1.0 (https://github.com.cnpmjs.org/wyfcyx/k210-soc#09a0742c)
error[E0599]: the method `configure` exists for struct `k210_pac::UARTHS`, but its trait bounds were not satisfied
    --> src/drivers/block/sdcard.rs:725:24
     |
725  |     peripherals.UARTHS.configure(115_200.bps(), &clocks);
     |                        ^^^^^^^^^ method cannot be called on `k210_pac::UARTHS` due to unsatisfied trait bounds
     | 
    ::: /home/zhang/.cargo/git/checkouts/k210-pac-34eac973c22ba7ac/8f99c1c/src/lib.rs:1028:1
     |
1028 | pub struct UARTHS {
     | -----------------
     | |
     | doesn't satisfy `k210_pac::UARTHS: SerialExt`
     | doesn't satisfy `k210_pac::UARTHS: serial::closed_trait::UartX`
...
1050 |     pub struct RegisterBlock {
     |     ------------------------
     |     |
     |     doesn't satisfy `_: serial::closed_trait::UartX`
     |     doesn't satisfy `k210_pac::uarths::RegisterBlock: SerialExt`
     |
     = note: the following trait bounds were not satisfied:
             `k210_pac::UARTHS: serial::closed_trait::UartX`
             which is required by `k210_pac::UARTHS: SerialExt`
             `&k210_pac::UARTHS: serial::closed_trait::UartX`
             which is required by `&k210_pac::UARTHS: SerialExt`
             `&mut k210_pac::UARTHS: serial::closed_trait::UartX`
             which is required by `&mut k210_pac::UARTHS: SerialExt`
             `k210_pac::uarths::RegisterBlock: serial::closed_trait::UartX`
             which is required by `k210_pac::uarths::RegisterBlock: SerialExt`
             `&k210_pac::uarths::RegisterBlock: serial::closed_trait::UartX`
             which is required by `&k210_pac::uarths::RegisterBlock: SerialExt`
             `&mut k210_pac::uarths::RegisterBlock: serial::closed_trait::UartX`
             which is required by `&mut k210_pac::uarths::RegisterBlock: SerialExt`

error[E0599]: the method `constrain` exists for struct `k210_pac::SPI0`, but its trait bounds were not satisfied
     --> src/drivers/block/sdcard.rs:728:32
      |
728   |     let spi = peripherals.SPI0.constrain();
      |                                ^^^^^^^^^ method cannot be called on `k210_pac::SPI0` due to unsatisfied trait bounds
      | 
     ::: /home/zhang/.cargo/git/checkouts/k210-pac-34eac973c22ba7ac/8f99c1c/src/lib.rs:19849:1
      |
19849 | pub struct SPI0 {
      | ---------------
      | |
      | doesn't satisfy `k210_pac::SPI0: SPI01`
      | doesn't satisfy `k210_pac::SPI0: SPIExt`
...
19871 |     pub struct RegisterBlock {
      |     ------------------------
      |     |
      |     doesn't satisfy `k210_pac::spi0::RegisterBlock: SPI01`
      |     doesn't satisfy `k210_pac::spi0::RegisterBlock: SPIExt`
      |
      = note: the following trait bounds were not satisfied:
              `k210_pac::SPI0: SPI01`
              which is required by `k210_pac::SPI0: SPIExt`
              `&k210_pac::SPI0: SPI01`
              which is required by `&k210_pac::SPI0: SPIExt`
              `&mut k210_pac::SPI0: SPI01`
              which is required by `&mut k210_pac::SPI0: SPIExt`
              `k210_pac::spi0::RegisterBlock: SPI01`
              which is required by `k210_pac::spi0::RegisterBlock: SPIExt`
              `&k210_pac::spi0::RegisterBlock: SPI01`
              which is required by `&k210_pac::spi0::RegisterBlock: SPIExt`
              `&mut k210_pac::spi0::RegisterBlock: SPI01`
              which is required by `&mut k210_pac::spi0::RegisterBlock: SPIExt`

error[E0277]: the trait bound `k210_pac::SPI0: SPI01` is not satisfied
   --> src/drivers/block/sdcard.rs:730:19
    |
730 |     let info = sd.init().unwrap();
    |                   ^^^^ the trait `SPI01` is not implemented for `k210_pac::SPI0`
    |
    = note: required because of the requirements on the impl of `SPI` for `SPIImpl<k210_pac::SPI0>`

error[E0277]: the trait bound `k210_pac::SPI0: SPI01` is not satisfied
   --> src/drivers/block/sdcard.rs:729:14
    |
163 |     pub fn new(spi: X, spi_cs: u32, cs_gpionum: u8/*, dmac: &'a DMAC, channel: dma_channel*/) -> Self {
    |     ------------------------------------------------------------------------------------------------- required by `SDCard::<X>::new`
...
729 |     let sd = SDCard::new(spi, SD_CS, SD_CS_GPIONUM);
    |              ^^^^^^^^^^^ the trait `SPI01` is not implemented for `k210_pac::SPI0`
    |
    = note: required because of the requirements on the impl of `SPI` for `SPIImpl<k210_pac::SPI0>`

error[E0599]: the method `read_sector` exists for struct `MutexGuard<'_, SDCard<SPIImpl<k210_pac::SPI0>>>`, but its trait bounds were not satisfied
   --> src/drivers/block/sdcard.rs:748:23
    |
748 |         self.0.lock().read_sector(buf,block_id as u32).unwrap();
    |                       ^^^^^^^^^^^ method cannot be called on `MutexGuard<'_, SDCard<SPIImpl<k210_pac::SPI0>>>` due to unsatisfied trait bounds
    | 
   ::: /home/zhang/.cargo/git/checkouts/k210-soc-2d953ceb9d03629e/09a0742/src/spi.rs:52:1
    |
52  | pub struct SPIImpl<IF> {
    | ---------------------- doesn't satisfy `SPIImpl<k210_pac::SPI0>: SPI`
    |
    = note: the following trait bounds were not satisfied:
            `SPIImpl<k210_pac::SPI0>: SPI`

error[E0599]: the method `write_sector` exists for struct `MutexGuard<'_, SDCard<SPIImpl<k210_pac::SPI0>>>`, but its trait bounds were not satisfied
   --> src/drivers/block/sdcard.rs:751:23
    |
751 |         self.0.lock().write_sector(buf,block_id as u32).unwrap();
    |                       ^^^^^^^^^^^^ method cannot be called on `MutexGuard<'_, SDCard<SPIImpl<k210_pac::SPI0>>>` due to unsatisfied trait bounds
    | 
   ::: /home/zhang/.cargo/git/checkouts/k210-soc-2d953ceb9d03629e/09a0742/src/spi.rs:52:1
    |
52  | pub struct SPIImpl<IF> {
    | ---------------------- doesn't satisfy `SPIImpl<k210_pac::SPI0>: SPI`
    |
    = note: the following trait bounds were not satisfied:
            `SPIImpl<k210_pac::SPI0>: SPI`

error: aborting due to 6 previous errors

Some errors have detailed explanations: E0277, E0599.
For more information about an error, try `rustc --explain E0277`.
error: could not compile `os`

To learn more, run the command again with --verbose.
make: *** [Makefile:60: kernel] Error 101

rCore-Tutorial-v3 version is 60477da.

docker make run failed

使用项目下的Dockerfile构建镜像成功,运行起来之后/mnt/os目录下make run报错:

warning: unused borrow that must be used
   --> /mnt/easy-fs/src/layout.rs:419:9
    |
419 |         &mut bytes[..name.len()].copy_from_slice(name.as_bytes());
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the borrow produces a value
    |
    = note: `#[warn(unused_must_use)]` on by default
help: use `let _ = ...` to ignore the resulting value
    |
419 |         let _ = &mut bytes[..name.len()].copy_from_slice(name.as_bytes());
    |         +++++++

   Compiling bare-metal v0.2.5
   Compiling virtio-drivers v0.1.0 (https://github.com/rcore-os/virtio-drivers#2b3c6cfd)
warning: `easy-fs` (lib) generated 1 warning
   Compiling regex v1.5.4
   Compiling riscv-target v0.1.2
   Compiling riscv v0.6.0
   Compiling riscv v0.6.0 (https://github.com/rcore-os/riscv#b6c469f0)
   Compiling k210-hal v0.2.0 (https://github.com/wyfcyx/k210-hal#ea121c91)
error[E0432]: unresolved imports `embedded_hal::digital::OutputPin`, `embedded_hal::digital::StatefulOutputPin`, `embedded_hal::digital::InputPin`, `embedded_hal::digital::ToggleableOutputPin`
 --> /root/.cargo/git/checkouts/k210-hal-1069b16e3180bc3a/ea121c9/src/gpio.rs:8:29
  |
8 | use embedded_hal::digital::{OutputPin, StatefulOutputPin, InputPin, ToggleableOutputPin};
  |                             ^^^^^^^^^  ^^^^^^^^^^^^^^^^^  ^^^^^^^^  ^^^^^^^^^^^^^^^^^^^ no `ToggleableOutputPin` in `digital`
  |                             |          |                  |
  |                             |          |                  no `InputPin` in `digital`
  |                             |          no `StatefulOutputPin` in `digital`
  |                             no `OutputPin` in `digital`

error[E0432]: unresolved imports `embedded_hal::digital::InputPin`, `embedded_hal::digital::OutputPin`
 --> /root/.cargo/git/checkouts/k210-hal-1069b16e3180bc3a/ea121c9/src/gpiohs.rs:6:29
  |
6 | use embedded_hal::digital::{InputPin, OutputPin};
  |                             ^^^^^^^^  ^^^^^^^^^ no `OutputPin` in `digital`
  |                             |
  |                             no `InputPin` in `digital`

error[E0432]: unresolved import `embedded_hal::prelude`
  --> /root/.cargo/git/checkouts/k210-hal-1069b16e3180bc3a/ea121c9/src/lib.rs:30:27
   |
30 |     pub use embedded_hal::prelude::*;
   |                           ^^^^^^^ could not find `prelude` in `embedded_hal`

error[E0405]: cannot find trait `Read` in module `serial`
   --> /root/.cargo/git/checkouts/k210-hal-1069b16e3180bc3a/ea121c9/src/serial.rs:100:14
    |
100 | impl serial::Read<u8> for Rx<UARTHS> {
    |              ^^^^ not found in `serial`
    |
help: consider importing one of these items
    |
9   | use crate::serial::serial::nb::Read;
    |
9   | use embedded_hal::i2c::blocking::Read;
    |
9   | use embedded_hal::serial::nb::Read;
    |

error[E0405]: cannot find trait `Write` in module `serial`
   --> /root/.cargo/git/checkouts/k210-hal-1069b16e3180bc3a/ea121c9/src/serial.rs:114:14
    |
114 | impl serial::Write<u8> for Tx<UARTHS> {
    |              ^^^^^ not found in `serial`
    |
help: consider importing one of these items
    |
9   | use core::fmt::Write;
    |
9   | use crate::serial::serial::blocking::Write;
    |
9   | use crate::serial::serial::nb::Write;
    |
9   | use crate::stdout::Write;
    |
      and 4 other candidates

error[E0405]: cannot find trait `Read` in module `serial`
   --> /root/.cargo/git/checkouts/k210-hal-1069b16e3180bc3a/ea121c9/src/serial.rs:200:27
    |
200 | impl<UART: UartX> serial::Read<u8> for Rx<UART> {
    |                           ^^^^ not found in `serial`
    |
help: consider importing one of these items
    |
9   | use crate::serial::serial::nb::Read;
    |
9   | use embedded_hal::i2c::blocking::Read;
    |
9   | use embedded_hal::serial::nb::Read;
    |

error[E0405]: cannot find trait `Write` in module `serial`
   --> /root/.cargo/git/checkouts/k210-hal-1069b16e3180bc3a/ea121c9/src/serial.rs:215:27
    |
215 | impl<UART: UartX> serial::Write<u8> for Tx<UART> {
    |                           ^^^^^ not found in `serial`
    |
help: consider importing one of these items
    |
9   | use core::fmt::Write;
    |
9   | use crate::serial::serial::blocking::Write;
    |
9   | use crate::serial::serial::nb::Write;
    |
9   | use crate::stdout::Write;
    |
      and 4 other candidates

error[E0405]: cannot find trait `FullDuplex` in module `embedded_hal::spi`
  --> /root/.cargo/git/checkouts/k210-hal-1069b16e3180bc3a/ea121c9/src/spi.rs:69:25
   |
69 | impl embedded_hal::spi::FullDuplex<u8> for Spi<SPI0> {
   |                         ^^^^^^^^^^ not found in `embedded_hal::spi`
   |
help: consider importing this trait
   |
3  | use embedded_hal::spi::nb::FullDuplex;
   |

error[E0405]: cannot find trait `Write` in module `embedded_hal::serial`
  --> /root/.cargo/git/checkouts/k210-hal-1069b16e3180bc3a/ea121c9/src/stdout.rs:11:30
   |
11 |     T: embedded_hal::serial::Write<u8>,
   |                              ^^^^^ not found in `embedded_hal::serial`
   |
help: consider importing one of these items
   |
2  | use core::fmt::Write;
   |
2  | use embedded_hal::i2c::blocking::Write;
   |
2  | use embedded_hal::serial::blocking::Write;
   |
2  | use embedded_hal::serial::nb::Write;
   |
     and 1 other candidate

Some errors have detailed explanations: E0405, E0432.
For more information about an error, try `rustc --explain E0405`.
error: could not compile `k210-hal` due to 9 previous errors
Makefile:58: recipe for target 'kernel' failed
make: *** [kernel] Error 101

ch3-lab分支代码缺失,需要完善实验框架及相应测试用例

ch3-lab分支代码缺失,需要完善实验框架及相应测试用例

在 rCore-Tutorial-Book-v3 中关于第三章实践作业有如下引用所示的表述,但是查看rCore-Tutorial-v3 ch3-lab分支,发现并没有给出同rCore-Tutorial-Code-2022S/ch3rust-based-os-comp2022 main/os3-ref/一样的框架

  • 说明:
    • 相关结构已在框架中给出,只需添加逻辑实现功能需求即可。

且也没有测试任务中要求的新增系统调用fn sys_task_info(ti: *mut TaskInfo) -> isize相关的测试用例,
需要添加测试用例包括但不限于如rCore-Tutorial-Test-2022A main/user/src/bin/ch3_taskinfo.rs等。

feat(lab3/Time-sharing OS): Add an syscall named sys_task_info这是我在ch3 TimeSharing OS的基础上完成第三章Lab的 commit,希望在ch3-lab分支需要哪些文件新增哪些内容方面有所帮助

相关issue:第三章实验的文档表述相关问题

ch2练习求教

题目要求检查sys_write的访问物理地址合法性,在检查02power的物理地址的时候发现所有数字的物理地址都在内核的rodata段内,请问这是为什么?
image
如图所示,当OS在打印3的时候,指针指向了kernel的.rodata段。

尽量避免显式drop

目前各分支上仍存在一些手动drop,其中有些是不必要的,与调度相关的必要的drop也可以通过类似于ch9分支上的exclusive_session接口来规避。无需手动drop是Rust相比C语言的一大优势,要考虑或借鉴一种更好的设计达成这一目标。

Mac上qemu-riscv64疑问

编译完qemu后,似乎mac上是没有qemu-riscv64的,有使用Mac完成lab的同学吗。

ch8 exit实现存在bug

https://rcore-os.github.io/rCore-Tutorial-Book-v3/chapter8/1thread-kernel.html 中说

如果进程/主线程先调用了 exit 系统调用来退出,那么整个进程(包括所属的所有线程)都会退出

但示例代码显然不能做到终止其他线程的运行,不用运行任何测试就能直接读出来。

当然这也可以用测试来验证。基于commit 9ad3bb4 ,运行如下测试:

#![no_std]
#![no_main]

#[macro_use]
extern crate user_lib;
extern crate alloc;

use user_lib::{thread_create, exit};
use alloc::vec::Vec;

pub fn thread_a() -> ! {
    for i in 0..1000 { print!("{}", i); }
    exit(1)
}

#[no_mangle]
pub fn main() -> i32 {
    thread_create(thread_a as usize, 0);
    println!("main thread exited.");
    exit(0)
}

可能的输出为:

>> exit_test
main thread exited.
[kernel] Panicked at src/sync/up.rs:27 already borrowed: BorrowMutError
[kernel] Panicked at src/task/processor.rs:94 called `Option::unwrap()` on a `None` value
[kernel] Panicked at src/task/processor.rs:94 called `Option::unwrap()` on a `None` value
[kernel] Panicked at src/task/processor.rs:94 called `Option::unwrap()` on a `None` value
...

虽然这段代码不太符合通常的正确代码的模式,但它也不应该让内核crash。

[rustsbi-panic] system shutdown scheduled due to RustSBI panic

个人环境

$ uname -a
Linux arch 5.12.5-arch1-1 #1 SMP PREEMPT Wed, 19 May 2021 10:32:40 +0000 x86_64 GNU/Linux

$ rustc --version
rustc 1.54.0-nightly (1c6868aa2 2021-05-27)

$ qemu-riscv64 -version
qemu-riscv64 version 6.0.0

$ qemu-system-riscv64 -version
QEMU emulator version 6.0.0

配置过程参考了文档 第零章:操作系统概述 » 实验环境配置

rust 配置了nightly 版本,相应的工具已经安装(riscv64gc-unknown-none-elf, cargo-binutils --vers ~0.2, llvm-tools-preview, rust-src),有一个小小的问题是 那个 cargo-binutils 的版本一定要是 0.2 吗?虽然不知道为什么,但我还是按照文档的要求装了0.2 版的

qemu-riscv64 的版本比文档的高,文档为 5.0.0

错误描述

重现步骤

$ git clone [email protected]:rcore-os/rCore-Tutorial-v3.git
$ cd rCore-Tutorial-v3/os
$ make run

错误输出

known-linux-gnu (installed)
[kearney@arch os]$ make run
(rustup target list | grep "riscv64gc-unknown-none-elf (installed)") || rustup target add riscv64gc-unknown-none-elf
riscv64gc-unknown-none-elf (installed)
cargo install cargo-binutils --vers ~0.2
    Updating `https://mirrors.tuna.tsinghua.edu.cn/git/crates.io-index.git` index
     Ignored package `cargo-binutils v0.2.0` is already installed, use --force to override
rustup component add rust-src
info: component 'rust-src' is up to date
rustup component add llvm-tools-preview
info: component 'llvm-tools-preview' for target 'x86_64-unknown-linux-gnu' is up to date
Platform: qemu
    Finished release [optimized] target(s) in 0.01s
[rustsbi] RustSBI version 0.2.0-alpha.1
.______       __    __      _______.___________.  _______..______   __
|   _  \     |  |  |  |    /       |           | /       ||   _  \ |  |
|  |_)  |    |  |  |  |   |   (----`---|  |----`|   (----`|  |_)  ||  |
|      /     |  |  |  |    \   \       |  |      \   \    |   _  < |  |
|  |\  \----.|  `--'  |.----)   |      |  |  .----)   |   |  |_)  ||  |
| _| `._____| \______/ |_______/       |__|  |_______/    |______/ |__|

[rustsbi] Platform: QEMU (Version 0.2.0)
[rustsbi] misa: RV64ACDFIMSU
[rustsbi] mideleg: 0x222
[rustsbi] medeleg: 0xb1ab
[rustsbi-dtb] Hart count: cluster0 with 1 cores
[rustsbi] Kernel entry: 0x80200000
[rustsbi-panic] hart 0 panicked at 'invalid instruction, mepc: 000000008000004c, instruction: 0000000030200073', platform/qemu/src/main.rs:484:17
[rustsbi-panic] system shutdown scheduled due to RustSBI panic

正常的结果

文档里的 GIF 图显示 make run 之后会加载内核,进入用户 shell

期望的结果

正常加载内核,进入 shell

第9章之后easy-fs仍然使用自旋锁而非关中断锁

问题:第9章开始,内核在执行系统调用的时候打开中断,因此内核自身的同步设施需要从单核独占访问UPSafeCell换成关中断版本的UPIntrFreeCell。然而,文件系统模块easy-fs仍然使用自旋锁spin::Mutex,就有可能在持有锁进行文件系统操作的时候,进入中断并再次尝试获取文件系统的锁而造成死锁。
触发方法:比如这种并发进行多个fork+exec的情况。
解决方案:将UPIntrFreeCell分离到一个独立的crate中,使得内核本体和easy-fs均依赖它。

error[E0658]: use of unstable library feature 'asm'

I meet an error when I excuted "make run":
error[E0658]: use of unstable library feature 'asm': inline assembly is not stable enough for use and is subject to change
--> ~/.cargo/git/checkouts/riscv-ab2abd16c438337b/11d43cf/src/asm.rs:10:23

ch4练习求助

[DEBUG] [kernel] run first task ch4_mmap0
[TRACE] [kernel] trap: scause=Interrupt(SupervisorTimer), stval=0x0
[TRACE] [kernel] run next task ch4_mmap0 with stride=4095
[TRACE] [kernel] trap: scause=Exception(UserEnvCall), stval=0x0
[TRACE] [kernel] syscall: code=222, args=[0x10000000, 0x1000, 0x3]
[DEBUG] MemorySet insert_framed_area start_va:0x10000000, end_va:0x10001000, permission:6
[TRACE] [kernel] find_pte_create vpn=0x10000, pte=0x20150801, level=0
[TRACE] [kernel] find_pte_create vpn=0x10000, pte=0x20150c01, level=1
[TRACE] [kernel] trap: scause=Exception(StorePageFault), stval=0x10000000
[ERROR] [kernel] PageFault in application, bad addr = 0x10000000, bad instruction = 0x80400098, core dumped.
[TRACE] [kernel] find_pte vpn=0x10000, pte=0x20150801, level=0
[TRACE] [kernel] find_pte vpn=0x10000, pte=0x20150c01, level=1
[TRACE] [kernel] find_pte vpn=0x10000, pte=0x20150407, level=2
[DEBUG] [kernel] Task ch4_mmap0 access page 0x10000000: ppn=0x80541, valid=true, readable=true, writable=true, executable=false
[DEBUG] [kernel] write address 0x80541000

我在实现mmap方法时遇到应用程序无法访问map后的内存,但在内核中使用对应的memory_set进行软件translate得到的ppn是可以正常访问的,我使用的是DeathWish5/rCore_tutorial_tests下的测试用例,ch4的用例都能正常运行,实在想不出如何来解决,求教各路大神指点迷津。

初始make run时出错

使用提供的虚拟机镜像,clone发布此issue时的仓库,在os中make run会出现以下错误:
image

Build failed in docker

At least on branch ch2/3/4, after make docker and cd mnt/os && make run, the output was:

error[E0433]: failed to resolve: could not find `addr_of` in `ptr`
   --> /root/.cargo/registry/src/mirrors.ustc.edu.cn-61ef6e0cd06fb9b8/anyhow-1.0.40/src/error.rs:606:14
    |
606 |         ptr::addr_of!((*unerased.as_ptr())._object) as *mut E,
    |              ^^^^^^^ could not find `addr_of` in `ptr`

error[E0433]: failed to resolve: could not find `addr_of` in `ptr`
   --> /root/.cargo/registry/src/mirrors.ustc.edu.cn-61ef6e0cd06fb9b8/anyhow-1.0.40/src/error.rs:647:22
    |
647 |                 ptr::addr_of!((*unerased.as_ptr())._object) as *mut E,
    |                      ^^^^^^^ could not find `addr_of` in `ptr`

error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0433`.
error: could not compile `anyhow`

To learn more, run the command again with --verbose.
warning: build failed, waiting for other jobs to finish...
error: failed to compile `cargo-binutils v0.3.3`, intermediate artifacts can be found at `/tmp/cargo-install1P2s9x`

Caused by:
  build failed
Makefile:35: recipe for target 'env' failed
make: *** [env] Error 101
root@efcfb21d8281:/mnt/os# 

It seemed that some errors occured when compiling anyhow 1.0.40.
However on Ubuntu18.04 it still worked.

syscall调用号增加建议

起因是这样的,我在为RustUserShell增加TAB键补全功能,但是发现对于FS的操作中没有列出文件的接口,我想增加一个枚举,让Read功能可以读取列表并以“文件”形式返回。但对于该枚举的取值,我需要你们的建议,或者以其他的方式去实现也行,我可以为此Issue提交PR,谢谢同学们!
我想加一行这个:
const SYSCALL_FS_LS: usize = 65;

疑问,第一章中实践篇的每两指令地址相差为什么不是8

(gdb) x/10i $pc
=> 0x1000:  auipc   t0,0x0
0x1004:     addi    a1,t0,32
0x1008:     csrr    a0,mhartid
0x100c:     ld      t0,24(t0)
0x1010:     jr      t0
0x1014:     unimp
0x1016:     unimp
0x1018:     unimp
0x101a:     0x8000
0x101c:     unimp

这段内容来自 http://rcore-os.cn/rCore-Tutorial-Book-v3/chapter1/4first-instruction-in-kernel2.html#gdb

riscv64的每条指令都是64位,于是每条指令指令相差8个字节即64位。为什么教材和实际调式中看到的是相差4个字节?我遗漏了什么?

Get `Could not allocate dynamic translator buffer` on Ubuntu 18.04/20.04 with `make docker`

Any ideas?

Ubuntu 20.04 was installed by multipass as a vm.
Logs:

root@eternal-buck:/home/ubuntu/rCore-Tutorial-v3# cat /etc/issue
Ubuntu 20.04.2 LTS \n \l

root@eternal-buck:/home/ubuntu/rCore-Tutorial-v3# make docker
docker run --rm -it --mount type=bind,source=/home/ubuntu/rCore-Tutorial-v3,destination=/mnt dinghao188/rcore-tutorial
root@9f61a9655d71:/# cd mnt
root@9f61a9655d71:/mnt# cd os

root@9f61a9655d71:/mnt/os# make run
info: syncing channel updates for 'nightly-2021-01-30-x86_64-unknown-linux-gnu'
info: latest update on 2021-01-30, rust version 1.51.0-nightly (b12290861 2021-01-29)
.....

Could not allocate dynamic translator buffer
Makefile:67: recipe for target 'run-inner' failed
make: *** [run-inner] Error 1

root@e4fb5cbf909a:/mnt/os# qemu-system-riscv64 --version
QEMU emulator version 5.0.0
Copyright (c) 2003-2020 Fabrice Bellard and the QEMU Project developers

chp3之前用户态 println! 有问题

(我目前在写 chp3。
背景:“锯齿螈”内核(就是先一次性加载所有程序,然后顺序运行),ch3分支。
问题概述:假设每个程序是2MB,一共两个程序。那么它们在链接时会在0x8020_0000上面一点,但是运行前会分别被拷贝到[0x8040_0000,0x8060_0000)和[0x8060_0000,0x8080_0000)。然后修改第二个用户程序,只需要改成println!("{}",1),然后在fs.rs里打印缓冲区起始地址,会发现它并不在[0x8060_0000,0x8080_0000)之间,而是0x8020_0000上一点(即链接的位置)。
WX20220320-223258@2x
image
image

The asm! has been stable since 1.59.0

The rust-toolchain is set to be 1.57.0 nightly. So the unstable feature asm can be used and the macro asm! is bring to the crate scope

But after the feature became stable, the usage #![feature(asm)] can not bring the macro asm! to the crate scope. I used rust 1.63 nightly to complie the source code. It seems that the only way to refer the macro asm is core::arch::asm!

But if you keep the rust complier version in 1.57.0, the compilation of dependency riscv will fail due to unreference of #![feature(asm)]

Encountered some weird problems in Ch 2

Hi, I'm learning through the rCore-Tutorial-Book-v3 (it's HOT and thank you guys so much for making this tutorial!), but get into trouble today when testing Chapter 2 code. My code: https://github.com/itewqq/rCore-dev/tree/ch2

1. Usermode app runtime error

The first werid thing came out when I was trying to test the usermode code with qemu-riscv64, which under cargo 1.57.0-nightly (d56b42c54 2021-09-27) and qemu-riscv64 version 5.0.0.

App 0 and 1 was OK but for app2 (02power) it will print 3^10000=Segmentation fault (core dumped) and exit. And if I change the QEMU to version 6.1.0 it will run just like expected in the tutorial, see the figure below:

image

I have tried gdb-debugging and it shows that in QEMU 5.0.0 the program will crash at a load instruction and complain about no access for the address

image

However in QEMU 6.1.0 everything looks fine, the binary file I user here are exactly same:

image

I have no idea about this, do not know if you have any insights?

2. Unsupported trap Interrupt(VirtualSupervisorSoft), stval = 0x0! in testing the batch execution

The second problem appeared when I finished and tested the code of the os module. After the app 00hello_world printed the "Hello, World!" line, it paniced with the message "Unsupported trap Interrupt(VirtualSupervisorSoft), stval = 0x0!". I have to change the trap_handler function code in os/src/trap/mod.rs to keep going after this unsupported trap Interrupt.

I have searched for a while but only found this https://codechina.csdn.net/qq_21726851/rcore-rust-rhonin#day12 . The output is identical to mine but I use the same RustSBI here, so still no solution for this.

The complete output is shown below. I would be very grateful if you could give some help 😢 .
Thanks again for your contributions.

    Finished release [optimized] target(s) in 7.66s
[rustsbi] RustSBI version 0.2.0-alpha.1
.______       __    __      _______.___________.  _______..______   __
|   _  \     |  |  |  |    /       |           | /       ||   _  \ |  |
|  |_)  |    |  |  |  |   |   (----`---|  |----`|   (----`|  |_)  ||  |
|      /     |  |  |  |    \   \       |  |      \   \    |   _  < |  |
|  |\  \----.|  `--'  |.----)   |      |  |  .----)   |   |  |_)  ||  |
| _| `._____| \______/ |_______/       |__|  |_______/    |______/ |__|

[rustsbi] Platform: QEMU (Version 0.2.0)
[rustsbi] misa: RV64ACDFIMSU
[rustsbi] mideleg: 0x222
[rustsbi] medeleg: 0xb1ab
[rustsbi-dtb] Hart count: cluster0 with 1 cores
[rustsbi] Kernel entry: 0x80200000
[kernel] Hello, world!
Number of app is 3
[kernel] app 0 starts at 0x8020b028, ends at 0x8020c030
[kernel] app 1 starts at 0x8020c030, ends at 0x8020d0c8
[kernel] app 2 starts at 0x8020d0c8, ends at 0x8020e278
[kernel] Loading app0 ...
Hello, world!
Unsupported trap Interrupt(VirtualSupervisorSoft), stval = 0x0!
[kernel] Loading app1 ...
Into Test store_fault, we will insert an invalid store operation...
Kernel should kill this application!
[kernel] PageFault in application, core dumped.
[kernel] Loading app2 ...
3^10000=5079
3^20000=8202
3^30000=8824
3^40000=5750
3^50000=3824
3^60000=8516
3^70000=2510
3^80000=9379
3^90000=2621
3^100000=2749
Test power OK!
[kernel] Application exited with code 0
Panicked at src/batch.rs:72 All applications completed!
itemqq@ubuntu:~/rCore-dev/os$ cargo --version
cargo 1.57.0-nightly (d56b42c54 2021-09-27)
itemqq@ubuntu:~/rCore-dev/os$ qemu-riscv64 --version
qemu-riscv64 version 5.0.0
Copyright (c) 2003-2020 Fabrice Bellard and the QEMU Project developers

error[E0557]: feature has been removed

平台:WSL2
操作系统: Ubuntu18.04/Ubuntu20.04
Rust版本:rustc 1.49.0

在每次rCore-Tutorial-v3 os中进行make run时,都会提示:
error[E0557]: feature has been removed
--> src/main.rs:6:12
|
6 | #![feature(const_in_array_repeat_expressions)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ feature has been removed
|
= note: removed due to causing promotable bugs

error: aborting due to previous error

For more information about this error, try rustc --explain E0557.
error: could not compile os

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.