Skip to content
This repository was archived by the owner on Aug 12, 2026. It is now read-only.
Merged
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
8 changes: 8 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 0 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ resolver = "2"
members = [
"kernel",
"user_lib",
]
exclude = [
"framework",
]

Expand Down
1 change: 1 addition & 0 deletions framework/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ version.workspace = true
edition.workspace = true

[dependencies]
buddy_system_allocator.workspace = true

[lints]
workspace = true
43 changes: 43 additions & 0 deletions framework/src/boot.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
unsafe extern "C" {
fn skernel();
fn stext();
fn etext();
fn srodata();
fn erodata();
fn sdata();
fn edata();
fn sbss();
fn ebss();
fn sbss_with_stack();
fn ekernel();
fn strampoline();
}

pub fn clear_bss() {
for addr in sbss_addr()..ebss_addr() {
unsafe {
(addr as *mut u8).write_volatile(0);
}
}
}

macro_rules! define_addr_getter {
($name:ident, $sym:ident) => {
pub fn $name() -> usize {
$sym as *const () as usize
}
};
}

define_addr_getter!(skernel_addr, skernel);
define_addr_getter!(stext_addr, stext);
define_addr_getter!(etext_addr, etext);
define_addr_getter!(srodata_addr, srodata);
define_addr_getter!(erodata_addr, erodata);
define_addr_getter!(sdata_addr, sdata);
define_addr_getter!(edata_addr, edata);
define_addr_getter!(sbss_addr, sbss);
define_addr_getter!(ebss_addr, ebss);
define_addr_getter!(sbss_with_stack_addr, sbss_with_stack);
define_addr_getter!(ekernel_addr, ekernel);
define_addr_getter!(strampoline_addr, strampoline);
12 changes: 12 additions & 0 deletions framework/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#![no_std]
mod boot;
mod memory;

pub use boot::{
clear_bss, ebss_addr, edata_addr, ekernel_addr, erodata_addr, etext_addr, sbss_addr,
sbss_with_stack_addr, sdata_addr, skernel_addr, srodata_addr, stext_addr, strampoline_addr,
};
pub use memory::{
KERNEL_HEAP_SIZE, heap_region, init_heap_allocator, phys_to_byte_slice, phys_to_ref,
phys_to_slice, sfence_vma, write_satp,
};
3 changes: 0 additions & 3 deletions framework/src/main.rs

This file was deleted.

43 changes: 43 additions & 0 deletions framework/src/memory.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
use buddy_system_allocator::LockedHeap;
use core::arch::asm;

pub const KERNEL_HEAP_SIZE: usize = 0x30_0000;

static mut HEAP_SPACE: [u8; KERNEL_HEAP_SIZE] = [0; KERNEL_HEAP_SIZE];

pub fn heap_region() -> &'static mut [u8] {
unsafe { &mut *core::ptr::addr_of_mut!(HEAP_SPACE) }
}

pub fn init_heap_allocator(allocator: &LockedHeap) {
let heap = heap_region();
unsafe {
allocator
.lock()
.init(heap.as_mut_ptr() as usize, KERNEL_HEAP_SIZE);
}
}

pub fn phys_to_byte_slice(phys_addr: usize, len: usize) -> &'static mut [u8] {
unsafe { core::slice::from_raw_parts_mut(phys_addr as *mut u8, len) }
}

pub fn phys_to_slice<T>(phys_addr: usize, count: usize) -> &'static mut [T] {
unsafe { core::slice::from_raw_parts_mut(phys_addr as *mut T, count) }
}

pub fn phys_to_ref<T>(phys_addr: usize) -> &'static mut T {
unsafe { (phys_addr as *mut T).as_mut().unwrap() }
}

pub fn write_satp(val: usize) {
unsafe {
asm!("csrw satp, {}", in(reg) val);
}
}

pub fn sfence_vma() {
unsafe {
asm!("sfence.vma");
}
}
1 change: 1 addition & 0 deletions kernel/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ xmas-elf.workspace = true
sbi-rt.workspace = true
buddy_system_allocator.workspace = true
bitflags.workspace = true
framework = { path = "../framework" }

[lints]
workspace = true
2 changes: 0 additions & 2 deletions kernel/src/boards/qemu.rs → kernel/src/boards.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
//! Constants used in rCore for qemu

// Board-level configuration for the QEMU virt machine
pub const CLOCK_FREQ: usize = 1250_0000;
pub const MEMORY_END: usize = 0x8800_0000;

// MMIO regions: (start_addr, size)
pub const MMIO: &[(usize, usize)] = &[
(0x0010_0000, 0x00_2000), // VIRT_TEST/RTC in virt-machine
];
2 changes: 0 additions & 2 deletions kernel/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ pub const APP_BASE_ADDRESS: usize = 0x80400000;
pub const APP_SIZE_LIMIT: usize = 0x20000;
pub const USER_STACK_SIZE: usize = 4096 * 2;
pub const KERNEL_STACK_SIZE: usize = 4096 * 2;
pub const KERNEL_HEAP_SIZE: usize = 0x30_0000;
/// Current page size (typical value 0x1000: 4KB)
pub const PAGE_SIZE: usize = 0x1000;
/// Number of bits used for page offset (with 0x1000 page size,
Expand All @@ -23,4 +22,3 @@ pub fn kernel_stack_position(app_id: usize) -> (usize, usize) {
let bottom = top - KERNEL_STACK_SIZE;
(bottom, top)
}

5 changes: 3 additions & 2 deletions kernel/src/loader.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use core::arch::asm;

use crate::config::*;
use crate::trap::TrapContext;
use core::arch::asm;

#[repr(align(4096))]
#[derive(Clone, Copy)]
Expand All @@ -27,7 +28,7 @@ impl KernelStack {
self.data.as_ptr() as usize + KERNEL_STACK_SIZE
}
pub fn push_context(&self, trap_cx: TrapContext) -> usize {
let trap_cx_ptr = (self.get_sp() - core::mem::size_of::<TrapContext>()) as *mut TrapContext;
let trap_cx_ptr = (self.get_sp() - size_of::<TrapContext>()) as *mut TrapContext;
unsafe {
*trap_cx_ptr = trap_cx;
}
Expand Down
69 changes: 12 additions & 57 deletions kernel/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,57 +2,38 @@
#![no_main]
#![feature(alloc_error_handler)]

#[path = "boards/qemu.rs"]
mod boards;

//add my MODs
extern crate bitflags;
extern crate alloc;

#[macro_use]
mod console;

mod boards;
mod config;
mod lang_items;
mod loader;
mod logging;
mod mm;
mod sbi;
mod sync;
mod timer;

pub mod syscall;
pub mod task;
mod timer;
pub mod trap;
extern crate alloc;

use core::arch::global_asm;
use framework::clear_bss;
use log::*;

use crate::mm::{frame_allocator_test, init_frame_allocator, init_heap};
global_asm!(include_str!("entry.asm"));
global_asm!(include_str!("link_app.S"));

/// clear BSS segment
fn clear_bss() {
unsafe extern "C" {
safe fn sbss();
safe fn ebss();
}
for item in sbss as unsafe extern "C" fn() as usize..ebss as unsafe extern "C" fn() as usize {
unsafe {
(item as *mut u8).write_volatile(0);
}
}
}

#[allow(unused)]
fn heap_test() {
info!("[kernel test02] heap init test ...");
use alloc::boxed::Box;
use alloc::vec::Vec;
unsafe extern "C" {
safe fn sbss();
safe fn ebss();
}
let bss_range = sbss as *const () as usize..ebss as *const () as usize;

let bss_range = framework::sbss_addr()..framework::ebss_addr();
let a = Box::new(5);
assert_eq!(*a, 5);
assert!(bss_range.contains(&(a.as_ref() as *const _ as *const () as usize)));
Expand All @@ -69,42 +50,16 @@ fn heap_test() {
info!("[kernel test02] heap init test passed!");
}

/// the rust entry-point of OS
#[unsafe(no_mangle)]
pub fn rust_main() -> ! {
// Referrence
// clear_bss();
// logging::init();
// info!("[kernel] Hello, world!");
//
// // Initialize the kernel heap and run a heap memory test
// init_heap();
// heap_test();
//
// // Initialize the physical frame allocator
// init_frame_allocator();
// frame_allocator_test();
//
// // Run user applications
// trap::init();
// loader::load_apps();
// trap::enable_timer_interrupt();
// timer::set_next_trigger();
// task::run_first_task();
//
// panic!("Unreachable in rust_main");
clear_bss(); // test ok!
clear_bss();
logging::init();
// TODO:
// 7.19,20;继续排除问题重构代码让上面这两个函数的调用链正常,遇到必要时,重构代码和写测试代码
// 重构代码,参考framework kernel,分离safe rust和unsafe rust;
// 分享想法(重构framework kernel后,录制演示视频)
// 直接录制演示视频,写一个架构介绍去咨询意见
mm::init();
trap::init(); // setup the kernel trap
// NOTE: finished removed (only necessary unsafe in framework) all the unsafe in the "mm::init"
// TODO: 7.22 remove necessary(minimal) unsafe to framework in trap::init();
trap::init();
trap::enable_timer_interrupt();
timer::set_next_trigger();
task::run_first_task();
panic!("Unreachable in rust_main!");
// NOTE: 7.14决定完全重构,刚检查完主函数,后续继续重构
}
7 changes: 2 additions & 5 deletions kernel/src/mm/mod.rs → kernel/src/mm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,9 @@ use crate::heap_test;

/// initiate the heap allocator, frame allocator and kernel space
pub fn init() {
heap_allocator::init_heap();
init_heap();
heap_test();
frame_allocator::init_frame_allocator();
init_frame_allocator();
frame_allocator_test();
// NOTE: How the kernel page table is set up (TOPIC)
// Activate SV39 paging mode
// successfully established the KERNEL_SPACE
KERNEL_SPACE.exclusive_access().active();
}
8 changes: 4 additions & 4 deletions kernel/src/mm/address.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use core::fmt::{self, Debug, Formatter};

use crate::{
config::{PAGE_SIZE, PAGE_SIZE_BITS, PTES_PER_PAGE},
config::{PAGE_SIZE, PAGE_SIZE_BITS},
mm::page_table::PageTableEntry,
};

Expand Down Expand Up @@ -146,15 +146,15 @@ impl PhysPageNum {
/// the entire page like a normal array.
pub fn get_bytes_array(&self) -> &'static mut [u8] {
let pa: PhysAddr = self.clone().into();
unsafe { core::slice::from_raw_parts_mut(pa.0 as *mut u8, PAGE_SIZE) }
framework::phys_to_byte_slice(pa.0, PAGE_SIZE)
}
pub fn get_pte_array(&self) -> &'static mut [PageTableEntry] {
let pa: PhysAddr = self.clone().into();
unsafe { core::slice::from_raw_parts_mut(pa.0 as *mut PageTableEntry, PTES_PER_PAGE) }
framework::phys_to_slice(pa.0, crate::config::PTES_PER_PAGE)
}
pub fn get_mut<T>(&self) -> &'static mut T {
let pa: PhysAddr = self.clone().into();
unsafe { (pa.0 as *mut T).as_mut().unwrap() }
framework::phys_to_ref(pa.0)
}
}
impl VirtPageNum {
Expand Down
5 changes: 1 addition & 4 deletions kernel/src/mm/frame_allocator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,11 +106,8 @@ lazy_static! {
// operation on the allocator, we must call FRAME_ALLOCATOR.exclusive_access()
// to obtain a mutable reference.
pub fn init_frame_allocator() {
unsafe extern "C" {
safe fn ekernel();
}
FRAME_ALLOCATOR.exclusive_access().init(
PhysAddr::from(ekernel as *const u8 as usize).ceil(),
PhysAddr::from(framework::ekernel_addr()).ceil(),
PhysAddr::from(MEMORY_END).floor(),
);
}
Expand Down
11 changes: 1 addition & 10 deletions kernel/src/mm/heap_allocator.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,11 @@
use core::ptr::addr_of_mut;

use crate::config::KERNEL_HEAP_SIZE;
use buddy_system_allocator::LockedHeap;

//follow the rules to provide ABIs for allocator
#[global_allocator]
static HEAP_ALLOCATOR: LockedHeap = LockedHeap::empty();

static mut HEAP_SPACE: [u8; KERNEL_HEAP_SIZE] = [0; KERNEL_HEAP_SIZE];

pub fn init_heap() {
unsafe {
HEAP_ALLOCATOR
.lock()
.init(addr_of_mut!(HEAP_SPACE) as usize, KERNEL_HEAP_SIZE);
}
framework::init_heap_allocator(&HEAP_ALLOCATOR);
}

#[alloc_error_handler]
Expand Down
Loading
Loading