mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-09 11:16:47 +00:00
parent
d8e29bffee
commit
c75ef4e212
@ -42,7 +42,7 @@ pub(super) struct MMDebugLogManager;
|
|||||||
|
|
||||||
impl MMDebugLogManager {
|
impl MMDebugLogManager {
|
||||||
/// 最大的内存分配器日志数量
|
/// 最大的内存分配器日志数量
|
||||||
pub const MAX_ALLOC_LOG_NUM: usize = 100000;
|
pub const MAX_ALLOC_LOG_NUM: usize = 10000;
|
||||||
|
|
||||||
/// 记录内存分配器的日志
|
/// 记录内存分配器的日志
|
||||||
///
|
///
|
||||||
|
@ -38,6 +38,7 @@ use crate::{
|
|||||||
},
|
},
|
||||||
include::bindings::bindings::{
|
include::bindings::bindings::{
|
||||||
multiboot2_get_Framebuffer_info, multiboot2_iter, multiboot_tag_framebuffer_info_t,
|
multiboot2_get_Framebuffer_info, multiboot2_iter, multiboot_tag_framebuffer_info_t,
|
||||||
|
FRAME_BUFFER_MAPPING_OFFSET,
|
||||||
},
|
},
|
||||||
init::{boot_params, initcall::INITCALL_DEVICE},
|
init::{boot_params, initcall::INITCALL_DEVICE},
|
||||||
libs::{
|
libs::{
|
||||||
@ -650,7 +651,11 @@ pub fn vesafb_early_init() -> Result<VirtAddr, SystemError> {
|
|||||||
boottime_screen_info.lfb_size =
|
boottime_screen_info.lfb_size =
|
||||||
(width * height * ((fb_info.framebuffer_bpp as u32 + 7) / 8)) as usize;
|
(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);
|
boottime_screen_info.lfb_virt_base = Some(buf_vaddr);
|
||||||
|
|
||||||
let init_text = "Video driver to map.\n\0";
|
let init_text = "Video driver to map.\n\0";
|
||||||
|
@ -3,9 +3,6 @@ use core::sync::atomic::{AtomicBool, Ordering};
|
|||||||
use crate::{
|
use crate::{
|
||||||
arch::MMArch,
|
arch::MMArch,
|
||||||
driver::tty::serial::serial8250::send_to_default_serial8250_port,
|
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,
|
init::boot_params,
|
||||||
kinfo,
|
kinfo,
|
||||||
libs::{
|
libs::{
|
||||||
@ -16,7 +13,7 @@ use crate::{
|
|||||||
},
|
},
|
||||||
mm::{
|
mm::{
|
||||||
allocator::page_frame::PageFrameCount, kernel_mapper::KernelMapper, page::PageFlags,
|
allocator::page_frame::PageFrameCount, kernel_mapper::KernelMapper, page::PageFlags,
|
||||||
MemoryManagementArch, VirtAddr,
|
MemoryManagementArch,
|
||||||
},
|
},
|
||||||
time::timer::{Timer, TimerFunction},
|
time::timer::{Timer, TimerFunction},
|
||||||
};
|
};
|
||||||
@ -86,10 +83,11 @@ impl VideoRefreshManager {
|
|||||||
*/
|
*/
|
||||||
fn init_frame_buffer(&self) {
|
fn init_frame_buffer(&self) {
|
||||||
kinfo!("Re-mapping VBE frame buffer...");
|
kinfo!("Re-mapping VBE frame buffer...");
|
||||||
let buf_vaddr = VirtAddr::new(
|
let buf_vaddr = boot_params()
|
||||||
SPECIAL_MEMOEY_MAPPING_VIRT_ADDR_BASE as usize + FRAME_BUFFER_MAPPING_OFFSET as usize,
|
.read_irqsave()
|
||||||
);
|
.screen_info
|
||||||
boot_params().write_irqsave().screen_info.lfb_virt_base = Some(buf_vaddr);
|
.lfb_virt_base
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
let mut frame_buffer_info_guard = self.device_buffer.write();
|
let mut frame_buffer_info_guard = self.device_buffer.write();
|
||||||
if let ScmBuffer::DeviceBuffer(vaddr) = &mut (frame_buffer_info_guard).buf {
|
if let ScmBuffer::DeviceBuffer(vaddr) = &mut (frame_buffer_info_guard).buf {
|
||||||
|
@ -1,15 +1,20 @@
|
|||||||
//! 该文件用于系统启动早期,内存管理器初始化之前,提供一些简单的内存映射功能
|
//! 该文件用于系统启动早期,内存管理器初始化之前,提供一些简单的内存映射功能
|
||||||
//!
|
//!
|
||||||
//! 这里假设在内核引导文件中,已经填写了前100M的页表,其中,前50M是真实映射到内存的,后面的仅仅创建了页表,表项全部为0。
|
|
||||||
//! 因此这里映射内存不需要任何动态分配。
|
|
||||||
//!
|
|
||||||
//! 映射关系为:
|
//! 映射关系为:
|
||||||
//!
|
//!
|
||||||
//! 虚拟地址 0-100M与虚拟地址 0x8000_0000_0000 - 0x8000_0640_0000 之间具有重映射关系。
|
//! 虚拟地址 0-100M与虚拟地址 0x8000_0000_0000 - 0x8000_0640_0000 之间具有重映射关系。
|
||||||
//! 也就是说,他们的第二级页表在最顶级页表中,占用了第0和第256个页表项。
|
//! 也就是说,他们的第二级页表在最顶级页表中,占用了第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 core::marker::PhantomData;
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
@ -18,6 +23,74 @@ use super::{
|
|||||||
PageTableKind, VirtAddr,
|
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> {
|
struct PseudoAllocator<MMA> {
|
||||||
phantom: PhantomData<MMA>,
|
phantom: PhantomData<MMA>,
|
||||||
@ -33,17 +106,26 @@ impl<MMA: MemoryManagementArch> PseudoAllocator<MMA> {
|
|||||||
|
|
||||||
/// 为NoInitAllocator实现FrameAllocator
|
/// 为NoInitAllocator实现FrameAllocator
|
||||||
impl<MMA: MemoryManagementArch> FrameAllocator for PseudoAllocator<MMA> {
|
impl<MMA: MemoryManagementArch> FrameAllocator for PseudoAllocator<MMA> {
|
||||||
unsafe fn allocate(&mut self, _count: PageFrameCount) -> Option<(PhysAddr, PageFrameCount)> {
|
unsafe fn allocate(&mut self, count: PageFrameCount) -> Option<(PhysAddr, PageFrameCount)> {
|
||||||
panic!("NoInitAllocator can't allocate page frame");
|
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) {
|
unsafe fn free(&mut self, address: PhysAddr, count: PageFrameCount) {
|
||||||
panic!("NoInitAllocator can't free page frame");
|
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: 获取内存区域页帧的使用情况
|
/// @brief: 获取内存区域页帧的使用情况
|
||||||
/// @param self
|
/// @param self
|
||||||
/// @return 页帧的使用情况
|
/// @return 页帧的使用情况
|
||||||
unsafe fn usage(&self) -> PageFrameUsage {
|
unsafe fn usage(&self) -> PageFrameUsage {
|
||||||
|
// 暂时不支持
|
||||||
panic!("NoInitAllocator can't get page frame usage");
|
panic!("NoInitAllocator can't get page frame usage");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user