Skip to content
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
2 changes: 1 addition & 1 deletion kernel/src/debug/klog/mm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ pub(super) struct MMDebugLogManager;

impl MMDebugLogManager {
/// 最大的内存分配器日志数量
pub const MAX_ALLOC_LOG_NUM: usize = 100000;
pub const MAX_ALLOC_LOG_NUM: usize = 10000;

/// 记录内存分配器的日志
///
Expand Down
7 changes: 6 additions & 1 deletion kernel/src/driver/video/fbdev/vesafb.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ use crate::{
},
include::bindings::bindings::{
multiboot2_get_Framebuffer_info, multiboot2_iter, multiboot_tag_framebuffer_info_t,
FRAME_BUFFER_MAPPING_OFFSET,
},
init::{boot_params, initcall::INITCALL_DEVICE},
libs::{
Expand Down Expand Up @@ -650,7 +651,11 @@ pub fn vesafb_early_init() -> Result<VirtAddr, SystemError> {
boottime_screen_info.lfb_size =
(width * height * ((fb_info.framebuffer_bpp as u32 + 7) / 8)) as usize;

let buf_vaddr = VirtAddr::new(0xffff800003200000);
// let buf_vaddr = VirtAddr::new(0xffff800003200000);
let buf_vaddr = VirtAddr::new(
crate::include::bindings::bindings::SPECIAL_MEMOEY_MAPPING_VIRT_ADDR_BASE as usize
+ FRAME_BUFFER_MAPPING_OFFSET as usize,
);
boottime_screen_info.lfb_virt_base = Some(buf_vaddr);

let init_text = "Video driver to map.\n\0";
Expand Down
14 changes: 6 additions & 8 deletions kernel/src/driver/video/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,6 @@ use core::sync::atomic::{AtomicBool, Ordering};
use crate::{
arch::MMArch,
driver::tty::serial::serial8250::send_to_default_serial8250_port,
include::bindings::bindings::{
FRAME_BUFFER_MAPPING_OFFSET, SPECIAL_MEMOEY_MAPPING_VIRT_ADDR_BASE,
},
init::boot_params,
kinfo,
libs::{
Expand All @@ -16,7 +13,7 @@ use crate::{
},
mm::{
allocator::page_frame::PageFrameCount, kernel_mapper::KernelMapper, page::PageFlags,
MemoryManagementArch, VirtAddr,
MemoryManagementArch,
},
time::timer::{Timer, TimerFunction},
};
Expand Down Expand Up @@ -86,10 +83,11 @@ impl VideoRefreshManager {
*/
fn init_frame_buffer(&self) {
kinfo!("Re-mapping VBE frame buffer...");
let buf_vaddr = VirtAddr::new(
SPECIAL_MEMOEY_MAPPING_VIRT_ADDR_BASE as usize + FRAME_BUFFER_MAPPING_OFFSET as usize,
);
boot_params().write_irqsave().screen_info.lfb_virt_base = Some(buf_vaddr);
let buf_vaddr = boot_params()
.read_irqsave()
.screen_info
.lfb_virt_base
.unwrap();

let mut frame_buffer_info_guard = self.device_buffer.write();
if let ScmBuffer::DeviceBuffer(vaddr) = &mut (frame_buffer_info_guard).buf {
Expand Down
98 changes: 90 additions & 8 deletions kernel/src/mm/no_init.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,20 @@
//! 该文件用于系统启动早期,内存管理器初始化之前,提供一些简单的内存映射功能
//!
//! 这里假设在内核引导文件中,已经填写了前100M的页表,其中,前50M是真实映射到内存的,后面的仅仅创建了页表,表项全部为0。
//! 因此这里映射内存不需要任何动态分配。
//!
//! 映射关系为:
//!
//! 虚拟地址 0-100M与虚拟地址 0x8000_0000_0000 - 0x8000_0640_0000 之间具有重映射关系。
//! 也就是说,他们的第二级页表在最顶级页表中,占用了第0和第256个页表项。
//!
//! 对于x86:
//! 这里假设在内核引导文件中,已经填写了前100M的页表,其中,前50M是真实映射到内存的,后面的仅仅创建了页表,表项全部为0。

use bitmap::{traits::BitMapOps, StaticBitmap};

use crate::{
libs::spinlock::SpinLock,
mm::{MMArch, MemoryManagementArch, PhysAddr},
};

use crate::mm::{MMArch, MemoryManagementArch, PhysAddr};
use core::marker::PhantomData;

use super::{
Expand All @@ -18,6 +23,74 @@ use super::{
PageTableKind, VirtAddr,
};

/// 用于存储重映射页表的位图和页面
static EARLY_IOREMAP_PAGES: SpinLock<EarlyIoRemapPages> = SpinLock::new(EarlyIoRemapPages::new());

/// 早期重映射使用的页表
#[repr(C)]
#[repr(align(4096))]
#[derive(Clone, Copy)]
struct EarlyRemapPage {
data: [u64; MMArch::PAGE_SIZE],
}

impl EarlyRemapPage {
/// 清空数据
fn zero(&mut self) {
self.data.fill(0);
}
}

#[repr(C)]
struct EarlyIoRemapPages {
pages: [EarlyRemapPage; Self::EARLY_REMAP_PAGES_NUM],
bmp: StaticBitmap<{ Self::EARLY_REMAP_PAGES_NUM }>,
}

impl EarlyIoRemapPages {
/// 预留的用于在内存管理初始化之前,映射内存所使用的页表数量
pub const EARLY_REMAP_PAGES_NUM: usize = 256;
pub const fn new() -> Self {
Self {
pages: [EarlyRemapPage {
data: [0; MMArch::PAGE_SIZE],
}; Self::EARLY_REMAP_PAGES_NUM],
bmp: StaticBitmap::new(),
}
}

/// 分配一个页面
///
/// 如果成功,返回虚拟地址
///
/// 如果失败,返回None
pub fn allocate_page(&mut self) -> Option<VirtAddr> {
if let Some(index) = self.bmp.first_false_index() {
self.bmp.set(index, true);
// 清空数据
self.pages[index].zero();

let p = &self.pages[index] as *const EarlyRemapPage as usize;
let vaddr = VirtAddr::new(p);
assert!(vaddr.check_aligned(MMArch::PAGE_SIZE));
return Some(vaddr);
} else {
return None;
}
}

pub fn free_page(&mut self, addr: VirtAddr) {
// 判断地址是否合法
let start_vaddr = &self.pages[0] as *const EarlyRemapPage as usize;
let offset = addr.data() - start_vaddr;
let index = offset / MMArch::PAGE_SIZE;
if index < Self::EARLY_REMAP_PAGES_NUM {
assert_eq!(self.bmp.get(index).unwrap(), true);
self.bmp.set(index, false);
}
}
}

/// 伪分配器
struct PseudoAllocator<MMA> {
phantom: PhantomData<MMA>,
Expand All @@ -33,17 +106,26 @@ impl<MMA: MemoryManagementArch> PseudoAllocator<MMA> {

/// 为NoInitAllocator实现FrameAllocator
impl<MMA: MemoryManagementArch> FrameAllocator for PseudoAllocator<MMA> {
unsafe fn allocate(&mut self, _count: PageFrameCount) -> Option<(PhysAddr, PageFrameCount)> {
panic!("NoInitAllocator can't allocate page frame");
unsafe fn allocate(&mut self, count: PageFrameCount) -> Option<(PhysAddr, PageFrameCount)> {
assert!(count.data() == 1);
let vaddr = EARLY_IOREMAP_PAGES.lock_irqsave().allocate_page()?;
let paddr = MMA::virt_2_phys(vaddr)?;
return Some((paddr, count));
}

unsafe fn free(&mut self, _address: PhysAddr, _count: PageFrameCount) {
panic!("NoInitAllocator can't free page frame");
unsafe fn free(&mut self, address: PhysAddr, count: PageFrameCount) {
assert_eq!(count.data(), 1);
assert!(address.check_aligned(MMA::PAGE_SIZE));
let vaddr = MMA::phys_2_virt(address);
if let Some(vaddr) = vaddr {
EARLY_IOREMAP_PAGES.lock_irqsave().free_page(vaddr);
}
}
/// @brief: 获取内存区域页帧的使用情况
/// @param self
/// @return 页帧的使用情况
unsafe fn usage(&self) -> PageFrameUsage {
// 暂时不支持
panic!("NoInitAllocator can't get page frame usage");
}
}
Expand Down