Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ch4 #5

Open
wants to merge 20 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added .DS_Store
Binary file not shown.
1 change: 1 addition & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
*/*
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ os/Cargo.lock
user/target/*
user/.idea/*
user/Cargo.lock
tools/
40 changes: 40 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
FROM ubuntu:18.04
LABEL maintainer="dinghao188" \
version="1.1" \
description="ubuntu 18.04 with tools for tsinghua's rCore-Tutorial-V3"

#install some deps
RUN set -x \
&& apt-get update \
&& apt-get install -y curl wget autoconf automake autotools-dev curl libmpc-dev libmpfr-dev libgmp-dev \
gawk build-essential bison flex texinfo gperf libtool patchutils bc xz-utils \
zlib1g-dev libexpat-dev pkg-config libglib2.0-dev libpixman-1-dev git tmux python3

#install rust and qemu
RUN set -x; \
RUSTUP='/root/rustup.sh' \
&& cd $HOME \
#install rust
&& curl https://sh.rustup.rs -sSf > $RUSTUP && chmod +x $RUSTUP \
&& $RUSTUP -y --default-toolchain nightly --profile minimal \

#compile qemu
&& wget https://ftp.osuosl.org/pub/blfs/conglomeration/qemu/qemu-5.0.0.tar.xz \
&& tar xvJf qemu-5.0.0.tar.xz \
&& cd qemu-5.0.0 \
&& ./configure --target-list=riscv64-softmmu,riscv64-linux-user \
&& make -j$(nproc) install \
&& cd $HOME && rm -rf qemu-5.0.0 qemu-5.0.0.tar.xz

#for chinese network
RUN set -x; \
APT_CONF='/etc/apt/sources.list'; \
CARGO_CONF='/root/.cargo/config'; \
BASHRC='/root/.bashrc' \
&& echo 'export RUSTUP_DIST_SERVER=https://mirrors.ustc.edu.cn/rust-static' >> $BASHRC \
&& echo 'export RUSTUP_UPDATE_ROOT=https://mirrors.ustc.edu.cn/rust-static/rustup' >> $BASHRC \
&& touch $CARGO_CONF \
&& echo '[source.crates-io]' > $CARGO_CONF \
&& echo "replace-with = 'ustc'" >> $CARGO_CONF \
&& echo '[source.ustc]' >> $CARGO_CONF \
&& echo 'registry = "git://mirrors.ustc.edu.cn/crates.io-index"' >> $CARGO_CONF
8 changes: 8 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
DOCKER_NAME ?= dinghao188/rcore-tutorial
.PHONY: docker build_docker

docker:
docker run --rm -it --mount type=bind,source=$(shell pwd),destination=/mnt ${DOCKER_NAME}

build_docker:
docker build -t ${DOCKER_NAME} .
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
# rCore-Tutorial-v3
rCore-Tutorial version 3.
rCore-Tutorial version 3.
Binary file modified bootloader/rustsbi-k210.bin
Binary file not shown.
Binary file modified bootloader/rustsbi-qemu.bin
Binary file not shown.
37 changes: 28 additions & 9 deletions os/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,24 @@ TARGET := riscv64gc-unknown-none-elf
MODE := release
KERNEL_ELF := target/$(TARGET)/$(MODE)/os
KERNEL_BIN := $(KERNEL_ELF).bin
KERNEL_ENTRY_PA := 0x80020000
DISASM_TMP := target/$(TARGET)/$(MODE)/asm

# BOARD
BOARD ?= qemu
SBI ?= rustsbi
BOOTLOADER := ../bootloader/$(SBI)-$(BOARD).bin
BOARD ?= qemu
SBI ?= rustsbi
BOOTLOADER := ../bootloader/$(SBI)-$(BOARD).bin
K210_BOOTLOADER_SIZE := 131072

# KERNEL ENTRY
ifeq ($(BOARD), qemu)
KERNEL_ENTRY_PA := 0x80200000
else ifeq ($(BOARD), k210)
KERNEL_ENTRY_PA := 0x80020000
endif

# Run K210
K210-SERIALPORT = /dev/ttyUSB0
K210-BURNER = ../tools/kflash.py
K210-BURNER = ../tools/kflash.py

# Binutils
OBJDUMP := rust-objdump --arch-name=riscv64
Expand All @@ -22,14 +29,23 @@ OBJCOPY := rust-objcopy --binary-architecture=riscv64
# Disassembly
DISASM ?= -x

build: $(KERNEL_BIN)
build: env $(KERNEL_BIN)

env:
(rustup target list | grep "riscv64gc-unknown-none-elf (installed)") || rustup target add $(TARGET)
cargo install cargo-binutils --vers ~0.2
rustup component add rust-src
rustup component add llvm-tools-preview

$(KERNEL_BIN): kernel
@$(OBJCOPY) $(KERNEL_ELF) --strip-all -O binary $@

kernel:
@cd ../user && make build
@echo Platform: $(BOARD)
@cp src/linker-$(BOARD).ld src/linker.ld
@cargo build --release --features "board_$(BOARD)"
@rm src/linker.ld

clean:
@cargo clean
Expand All @@ -44,6 +60,8 @@ disasm-vim: kernel

run: run-inner



run-inner: build
ifeq ($(BOARD),qemu)
@qemu-system-riscv64 \
Expand All @@ -52,12 +70,13 @@ ifeq ($(BOARD),qemu)
-bios $(BOOTLOADER) \
-device loader,file=$(KERNEL_BIN),addr=$(KERNEL_ENTRY_PA)
else
(which $(K210-BURNER)) || (cd .. && git clone https://github.com/sipeed/kflash.py.git && mv kflash.py tools)
@cp $(BOOTLOADER) $(BOOTLOADER).copy
@dd if=$(KERNEL_BIN) of=$(BOOTLOADER).copy bs=128K seek=1
@dd if=$(KERNEL_BIN) of=$(BOOTLOADER).copy bs=$(K210_BOOTLOADER_SIZE) seek=1
@mv $(BOOTLOADER).copy $(KERNEL_BIN)
@sudo chmod 777 $(K210-SERIALPORT)
python3 $(K210-BURNER) -p $(K210-SERIALPORT) -b 1500000 $(KERNEL_BIN)
miniterm --eol LF --dtr 0 --rts 0 --filter direct $(K210-SERIALPORT) 115200
python3 -m serial.tools.miniterm --eol LF --dtr 0 --rts 0 --filter direct $(K210-SERIALPORT) 115200
endif

debug: build
Expand All @@ -66,4 +85,4 @@ debug: build
tmux split-window -h "riscv64-unknown-elf-gdb -ex 'file $(KERNEL_ELF)' -ex 'set arch riscv:rv64' -ex 'target remote localhost:1234'" && \
tmux -2 attach-session -d

.PHONY: build kernel clean disasm disasm-vim run-inner
.PHONY: build env kernel clean disasm disasm-vim run-inner
3 changes: 2 additions & 1 deletion os/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ fn insert_app_data() -> Result<()> {
apps.sort();

writeln!(f, r#"
.align 4
.align 3
.section .data
.global _num_app
_num_app:
Expand All @@ -40,6 +40,7 @@ _num_app:
.section .data
.global app_{0}_start
.global app_{0}_end
.align 3
app_{0}_start:
.incbin "{2}{1}"
app_{0}_end:"#, idx, app, TARGET_PATH)?;
Expand Down
4 changes: 2 additions & 2 deletions os/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ pub fn kernel_stack_position(app_id: usize) -> (usize, usize) {
}

#[cfg(feature = "board_k210")]
pub const CPU_FREQ: usize = 10000000;
pub const CLOCK_FREQ: usize = 403000000 / 62;

#[cfg(feature = "board_qemu")]
pub const CPU_FREQ: usize = 12500000;
pub const CLOCK_FREQ: usize = 12500000;
3 changes: 3 additions & 0 deletions os/src/linker.ld → os/src/linker-k210.ld
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,15 @@ SECTIONS
srodata = .;
.rodata : {
*(.rodata .rodata.*)
*(.srodata .srodata.*)
}

. = ALIGN(4K);
erodata = .;
sdata = .;
.data : {
*(.data .data.*)
*(.sdata .sdata.*)
}

. = ALIGN(4K);
Expand All @@ -38,6 +40,7 @@ SECTIONS
*(.bss.stack)
sbss = .;
*(.bss .bss.*)
*(.sbss .sbss.*)
}

. = ALIGN(4K);
Expand Down
53 changes: 53 additions & 0 deletions os/src/linker-qemu.ld
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
OUTPUT_ARCH(riscv)
ENTRY(_start)
BASE_ADDRESS = 0x80200000;

SECTIONS
{
. = BASE_ADDRESS;
skernel = .;

stext = .;
.text : {
*(.text.entry)
. = ALIGN(4K);
strampoline = .;
*(.text.trampoline);
. = ALIGN(4K);
*(.text .text.*)
}

. = ALIGN(4K);
etext = .;
srodata = .;
.rodata : {
*(.rodata .rodata.*)
*(.srodata .srodata.*)
}

. = ALIGN(4K);
erodata = .;
sdata = .;
.data : {
*(.data .data.*)
*(.sdata .sdata.*)
}

. = ALIGN(4K);
edata = .;
sbss_with_stack = .;
.bss : {
*(.bss.stack)
sbss = .;
*(.bss .bss.*)
*(.sbss .sbss.*)
}

. = ALIGN(4K);
ebss = .;
ekernel = .;

/DISCARD/ : {
*(.eh_frame)
}
}
2 changes: 1 addition & 1 deletion os/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ pub fn rust_main() -> ! {
println!("[kernel] back to world!");
mm::remap_test();
trap::init();
//trap::enable_interrupt();
// trap::enable_interrupt();
trap::enable_timer_interrupt();
timer::set_next_trigger();
task::run_first_task();
Expand Down
4 changes: 2 additions & 2 deletions os/src/mm/address.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ impl From<VirtPageNum> for usize {

impl VirtAddr {
pub fn floor(&self) -> VirtPageNum { VirtPageNum(self.0 / PAGE_SIZE) }
pub fn ceil(&self) -> VirtPageNum { VirtPageNum((self.0 + PAGE_SIZE - 1) / PAGE_SIZE) }
pub fn ceil(&self) -> VirtPageNum { VirtPageNum((self.0 - 1 + PAGE_SIZE) / PAGE_SIZE) }
pub fn page_offset(&self) -> usize { self.0 & (PAGE_SIZE - 1) }
pub fn aligned(&self) -> bool { self.page_offset() == 0 }
}
Expand All @@ -84,7 +84,7 @@ impl From<VirtPageNum> for VirtAddr {
}
impl PhysAddr {
pub fn floor(&self) -> PhysPageNum { PhysPageNum(self.0 / PAGE_SIZE) }
pub fn ceil(&self) -> PhysPageNum { PhysPageNum((self.0 + PAGE_SIZE - 1) / PAGE_SIZE) }
pub fn ceil(&self) -> PhysPageNum { PhysPageNum((self.0 - 1 + PAGE_SIZE) / PAGE_SIZE) }
pub fn page_offset(&self) -> usize { self.0 & (PAGE_SIZE - 1) }
pub fn aligned(&self) -> bool { self.page_offset() == 0 }
}
Expand Down
13 changes: 13 additions & 0 deletions os/src/mm/memory_set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@ impl MemorySet {
map_perm,
);
max_end_vpn = map_area.vpn_range.get_end();
// println!("{:#X} ~ {:#X}", start_va.0 , end_va.0);
memory_set.push(
map_area,
Some(&elf.input[ph.offset() as usize..(ph.offset() + ph.file_size()) as usize])
Expand All @@ -169,13 +170,15 @@ impl MemorySet {
MapType::Framed,
MapPermission::R | MapPermission::W | MapPermission::U,
), None);
// println!("{:#X} ~ {:#X}", user_stack_bottom, user_stack_top);
// map TrapContext
memory_set.push(MapArea::new(
TRAP_CONTEXT.into(),
TRAMPOLINE.into(),
MapType::Framed,
MapPermission::R | MapPermission::W,
), None);
// println!("{:#X} ~ {:#X}", TRAP_CONTEXT , TRAMPOLINE);
(memory_set, user_stack_top, elf.header.pt2.entry_point() as usize)
}
pub fn activate(&self) {
Expand All @@ -188,6 +191,16 @@ impl MemorySet {
pub fn translate(&self, vpn: VirtPageNum) -> Option<PageTableEntry> {
self.page_table.translate(vpn)
}
pub fn find_vpn(&self, vpn: VirtPageNum) -> bool {
self.page_table.find_vpn(vpn)
}
pub fn munmap(&mut self, vpn: VirtPageNum){
//为了简单,参数错误时不考虑内存的恢复和回收。
// for i in 0..(self.areas.len()) {
// self.areas[i].unmap_one(&mut self.page_table, vpn);
// }
self.areas[0].unmap_one(&mut self.page_table, vpn);
}
}

pub struct MapArea {
Expand Down
2 changes: 1 addition & 1 deletion os/src/mm/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,5 @@ pub use memory_set::remap_test;
pub fn init() {
heap_allocator::init_heap();
frame_allocator::init_frame_allocator();
KERNEL_SPACE.clone().lock().activate();
KERNEL_SPACE.lock().activate();
}
18 changes: 16 additions & 2 deletions os/src/mm/page_table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,9 @@ impl PageTable {
}
}
fn find_pte_create(&mut self, vpn: VirtPageNum) -> Option<&mut PageTableEntry> {
// if vpn.0 == 65537 as usize {
// println!("Create!!!");
// }
let idxs = vpn.indexes();
let mut ppn = self.root_ppn;
let mut result: Option<&mut PageTableEntry> = None;
Expand Down Expand Up @@ -112,6 +115,7 @@ impl PageTable {
}
#[allow(unused)]
pub fn map(&mut self, vpn: VirtPageNum, ppn: PhysPageNum, flags: PTEFlags) {
// println!("map_pte {}", vpn.0);
let pte = self.find_pte_create(vpn).unwrap();
assert!(!pte.is_valid(), "vpn {:?} is mapped before mapping", vpn);
*pte = PageTableEntry::new(ppn, flags | PTEFlags::V);
Expand All @@ -126,12 +130,18 @@ impl PageTable {
self.find_pte(vpn)
.map(|pte| {pte.clone()})
}
pub fn find_vpn(&self, vpn: VirtPageNum) -> bool {
match self.find_pte(vpn) {
None => false,
Some(x) => x.is_valid(),
}
}
pub fn token(&self) -> usize {
8usize << 60 | self.root_ppn.0
}
}

pub fn translated_byte_buffer(token: usize, ptr: *const u8, len: usize) -> Vec<&'static [u8]> {
pub fn translated_byte_buffer(token: usize, ptr: *const u8, len: usize) -> Vec<&'static mut [u8]> {
let page_table = PageTable::from_token(token);
let mut start = ptr as usize;
let end = start + len;
Expand All @@ -146,7 +156,11 @@ pub fn translated_byte_buffer(token: usize, ptr: *const u8, len: usize) -> Vec<&
vpn.step();
let mut end_va: VirtAddr = vpn.into();
end_va = end_va.min(VirtAddr::from(end));
v.push(&ppn.get_bytes_array()[start_va.page_offset()..end_va.page_offset()]);
if end_va.page_offset() == 0 {
v.push(&mut ppn.get_bytes_array()[start_va.page_offset()..]);
} else {
v.push(&mut ppn.get_bytes_array()[start_va.page_offset()..end_va.page_offset()]);
}
start = end_va.into();
}
v
Expand Down
Loading