feat(riscv): riscv下能够运行hello world用户程序 (#770)

* feat(riscv): riscv下能够运行hello world用户程序
This commit is contained in:
LoGin
2024-04-26 11:59:47 +08:00
committed by GitHub
parent 40348dd8d5
commit 471d65cf15
33 changed files with 402 additions and 97 deletions

View File

@ -21,7 +21,7 @@ pub struct PhysPageFrame {
impl PhysPageFrame {
pub fn new(paddr: PhysAddr) -> Self {
return Self {
number: paddr.data() / MMArch::PAGE_SIZE,
number: paddr.data() >> MMArch::PAGE_SHIFT,
};
}

View File

@ -113,7 +113,6 @@ impl KernelMapper {
let count = PageFrameCount::new(page_align_up(size) / MMArch::PAGE_SIZE);
// kdebug!("kernel mapper: map_phys: vaddr: {vaddr:?}, paddr: {paddr:?}, count: {count:?}, flags: {flags:?}");
for _ in 0..count.data() {
let flusher = self.mapper.map_phys(vaddr, paddr, flags).unwrap();

View File

@ -352,6 +352,11 @@ impl MemBlockManager {
return self.set_or_clear_flags(base, size, true, MemoryAreaAttr::NOMAP);
}
/// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/mm/memblock.c?fi=memblock_mark_mirror#940
pub fn mark_mirror(&self, base: PhysAddr, size: usize) -> Result<(), SystemError> {
return self.set_or_clear_flags(base, size, true, MemoryAreaAttr::MIRROR);
}
fn set_or_clear_flags(
&self,
mut base: PhysAddr,

View File

@ -447,6 +447,8 @@ pub trait MemoryManagementArch: Clone + Copy + Debug {
const ENTRY_FLAG_PRESENT: usize;
/// 页表项为read only时的值
const ENTRY_FLAG_READONLY: usize;
/// 页表项的write bit
const ENTRY_FLAG_WRITEABLE: usize;
/// 页表项为可读写状态的值
const ENTRY_FLAG_READWRITE: usize;
/// 页面项标记页面为user page的值

View File

@ -530,9 +530,18 @@ impl<Arch: MemoryManagementArch> PageFlags<Arch> {
Self::from_data(Arch::ENTRY_FLAG_DEFAULT_TABLE)
}
};
if user {
r.set_user(true)
} else {
#[cfg(target_arch = "x86_64")]
{
if user {
r.set_user(true)
} else {
r
}
}
#[cfg(target_arch = "riscv64")]
{
r
}
};
@ -607,7 +616,9 @@ impl<Arch: MemoryManagementArch> PageFlags<Arch> {
if value {
return self.update_flags(Arch::ENTRY_FLAG_READWRITE, true);
} else {
return self.update_flags(Arch::ENTRY_FLAG_READONLY, true);
return self
.update_flags(Arch::ENTRY_FLAG_READONLY, true)
.update_flags(Arch::ENTRY_FLAG_WRITEABLE, false);
}
}
}
@ -724,13 +735,25 @@ impl<Arch: MemoryManagementArch> PageFlags<Arch> {
/// MMIO内存的页表项标志
#[inline(always)]
pub fn mmio_flags() -> Self {
return Self::new()
.set_user(false)
.set_write(true)
.set_execute(true)
.set_page_cache_disable(true)
.set_page_write_through(true)
.set_page_global(true);
#[cfg(target_arch = "x86_64")]
{
Self::new()
.set_user(false)
.set_write(true)
.set_execute(true)
.set_page_cache_disable(true)
.set_page_write_through(true)
.set_page_global(true)
}
#[cfg(target_arch = "riscv64")]
{
Self::new()
.set_user(false)
.set_write(true)
.set_execute(true)
.set_page_global(true)
}
}
}
@ -873,6 +896,7 @@ impl<Arch: MemoryManagementArch, F: FrameAllocator> PageMapper<Arch, F> {
let mut table = self.table();
loop {
let i = table.index_of(virt)?;
assert!(i < Arch::PAGE_ENTRY_NUM);
if table.level() == 0 {
compiler_fence(Ordering::SeqCst);
@ -891,13 +915,10 @@ impl<Arch: MemoryManagementArch, F: FrameAllocator> PageMapper<Arch, F> {
// 清空这个页帧
MMArch::write_bytes(MMArch::phys_2_virt(frame).unwrap(), 0, MMArch::PAGE_SIZE);
// 设置页表项的flags
let flags: PageFlags<Arch> =
PageFlags::new_page_table(virt.kind() == PageTableKind::User);
// kdebug!("Flags: {:?}", flags);
// 把新分配的页表映射到当前页表
table.set_entry(i, PageEntry::new(frame, flags));