forked from metaverse/kernel-dev
Compare commits
3 Commits
0613dadeaf
...
2aaa592636
Author | SHA1 | Date |
---|---|---|
pointer-to-bios | 2aaa592636 | |
pointer-to-bios | aedcb8749e | |
pointer-to-bios | c52d9f4960 |
|
@ -11,3 +11,10 @@
|
|||
* 等待审核代码
|
||||
|
||||
若你的代码通过审核,将会把你的PR合并到主分支中。
|
||||
|
||||
## 需要注意的还未解决的问题
|
||||
|
||||
* rust中所有有关字符串格式化的宏中,出现超过一个不止是`{}`的格式化占位符时内核必然崩溃。
|
||||
* rust中所有有关字符串格式化的宏中,出现需要调用自定义的`Debug trait`的类型时内核必然崩溃,推荐定义`ToString trait`并调用`.to_string()`后传入宏参数。
|
||||
* 鉴于以上两条原因,不建议在复杂的字符串格式化任务中使用`format!()`宏。推荐通过使用`::kernel::tty::tty::MessageBuilder`构造`kernel::tty::tty::Message`对象,或使用
|
||||
`message`宏,并调用此对象的`.to_string()`方法实现格式化字符串。
|
||||
|
|
|
@ -7,9 +7,9 @@
|
|||
/**
|
||||
* @name MEMM_PAGE_SIZE
|
||||
* @addindex 平台定制宏
|
||||
*
|
||||
*
|
||||
* 最小的页大小。
|
||||
*
|
||||
*
|
||||
* @if arch == x86_64 then
|
||||
* 4096
|
||||
* @endif
|
||||
|
@ -28,7 +28,7 @@ extern u64 PML4[512];
|
|||
/**
|
||||
* @name MEMM_PAGE_TABLE_FLAGS_MASK
|
||||
* @addindex 平台依赖宏 x86_64
|
||||
*
|
||||
*
|
||||
* 页表项中属性标志位使用的最低12位的掩码`0xfff`。
|
||||
*/
|
||||
#define MEMM_PAGE_TABLE_FLAGS_MASK ((u64)0xfff)
|
||||
|
@ -36,7 +36,7 @@ extern u64 PML4[512];
|
|||
/**
|
||||
* @name MEMM_xx_ALIGN_MASK
|
||||
* @addindex 平台依赖宏 x86_64
|
||||
*
|
||||
*
|
||||
* 页对齐掩码。
|
||||
* `xx`为`x86_64`架构的页的三种大小,分别为`4K`、`2M`和`1G`。这些页一定是以它们自己的大小对齐,因此会出现低n位总为0的情况。
|
||||
* `4K`对应`0xfff`;`2M`对应`0x1fffff`;`1G`对应`0x3fffffff`。
|
||||
|
@ -48,9 +48,9 @@ extern u64 PML4[512];
|
|||
/**
|
||||
* @name MEMM_ENTRY_FLAG_xx
|
||||
* @addindex 平台依赖宏 x86_64
|
||||
*
|
||||
*
|
||||
* 页表项属性标志位。定义如下:
|
||||
*
|
||||
*
|
||||
* ```c
|
||||
* #define MEMM_ENTRY_FLAG_PRESENT ((u64)1)
|
||||
* #define MEMM_ENTRY_FLAG_WRITE ((u64)1 << 1)
|
||||
|
@ -65,7 +65,7 @@ extern u64 PML4[512];
|
|||
* #define MEMM_PTE_ENTRY_FLAG_PAT ((u64)1 << 7)
|
||||
* #define MEMM_ENTRY_FLAG_XD ((u64)1 << 63)
|
||||
* ```
|
||||
*
|
||||
*
|
||||
* 其中`MEMM_PTE_ENTRY_FLAG_PAT`的`pte`表示此属性标志位只存在与`pte`页表项中。
|
||||
*/
|
||||
#define MEMM_ENTRY_FLAG_PRESENT ((u64)1)
|
||||
|
@ -84,9 +84,9 @@ extern u64 PML4[512];
|
|||
/**
|
||||
* @name memm_entry_flag_get(entry, flag)
|
||||
* @addindex 平台依赖宏 x86_64
|
||||
*
|
||||
*
|
||||
* 获取页表项中某个属性标志位,得到布尔值。
|
||||
*
|
||||
*
|
||||
* 其中`flag`是`MEMM_ENTRY_FLAG_xx`。
|
||||
*/
|
||||
#define memm_entry_flag_get(entry, flag) \
|
||||
|
@ -95,13 +95,13 @@ extern u64 PML4[512];
|
|||
/**
|
||||
* @name MEMM_ENTRY_ADDRESS_MASK, MEMM_BP_ENTRY_ADDRESS_MASK
|
||||
* @addindex 平台依赖宏 x86_64
|
||||
*
|
||||
*
|
||||
* 页表项地址域掩码。将页表项与掩码作与运算可得到页表项指向的**下一级页表的起始地址**或**页框的起始地址**。
|
||||
*
|
||||
*
|
||||
* 含`BP`的为大型页页表项的地址域掩码。
|
||||
*
|
||||
*
|
||||
* 定义如下:
|
||||
*
|
||||
*
|
||||
* ```c
|
||||
* #define MEMM_ENTRY_ADDRESS_MASK ((u64)0x000ffffffffff000)
|
||||
* #define MEMM_BP_ENTRY_ADDRESS_MASK ((u64)0x000fffffffffe000)
|
||||
|
@ -113,7 +113,7 @@ extern u64 PML4[512];
|
|||
/**
|
||||
* @name memm_entry_get_address(entry)
|
||||
* @addindex 平台依赖宏 x86_64
|
||||
*
|
||||
*
|
||||
* 获取页表项指向的地址。
|
||||
*/
|
||||
#define memm_entry_get_address(entry) \
|
||||
|
@ -138,7 +138,7 @@ extern u64 PML4[512];
|
|||
/**
|
||||
* @name MEMM_LA_xxxxI
|
||||
* @addindex 平台依赖宏 x86_64
|
||||
*
|
||||
*
|
||||
* 在4级分页中,线性地址的四个页表项索引宏。其中`xxxx`分别为`PML4E`、`PDPTE`、`PDE`和`PE`。
|
||||
*/
|
||||
#define MEMM_LA_PML4EI
|
||||
|
@ -149,9 +149,9 @@ extern u64 PML4[512];
|
|||
/**
|
||||
* @name memm_la_get_entry_index(addr, entry)
|
||||
* @addindex 平台依赖宏 x86_64
|
||||
*
|
||||
*
|
||||
* 获取线性地址`addr`中的`entry`页表项索引。
|
||||
*
|
||||
*
|
||||
* 其中`entry`应为宏`MEMM_LA_xxxxI`。
|
||||
*/
|
||||
#define memm_la_get_entry_index(addr, entry) \
|
||||
|
@ -160,7 +160,7 @@ extern u64 PML4[512];
|
|||
/**
|
||||
* @name MEMM_LA_xxx_PAGE_OFFSET
|
||||
* @addindex 平台依赖宏 x86_64
|
||||
*
|
||||
*
|
||||
* 线性地址的页内偏移宏。其中`xxx`为三种页容量`4KB`、`2MB`、`1GB`。
|
||||
*/
|
||||
#define MEMM_LA_1GB_PAGE_OFFSET
|
||||
|
@ -170,9 +170,9 @@ extern u64 PML4[512];
|
|||
/**
|
||||
* @name memm_la_get_offset(addr, page_type)
|
||||
* @addindex 平台依赖宏 x86_64
|
||||
*
|
||||
*
|
||||
* 获取线性地址的页内偏移部分。
|
||||
*
|
||||
*
|
||||
* 其中`page_type`应为宏`MEMM_LA_xxx_PAGE_OFFSET`。
|
||||
*/
|
||||
#define memm_la_get_offset(addr, page_type) \
|
||||
|
@ -180,20 +180,20 @@ extern u64 PML4[512];
|
|||
|
||||
/**
|
||||
* @name memm_map_pageframes_to
|
||||
*
|
||||
*
|
||||
* ```c
|
||||
* bool memm_map_pageframes_to(
|
||||
* u64 target, u64 physical,
|
||||
* usize size,
|
||||
* bool user, bool write);
|
||||
* ```
|
||||
*
|
||||
*
|
||||
* 仅支持**canonical**型地址
|
||||
*
|
||||
*
|
||||
* `target`与`physical`保证至少都是以MEMM_PAGE_SIZE对齐的。
|
||||
*
|
||||
*
|
||||
* 没有MEMM_PAGE_SIZE对齐的,和非canonical型地址都会返回false
|
||||
*
|
||||
*
|
||||
* 当剩余长度超过1GB的一半且地址1GB对齐,则会映射一个1GB页;
|
||||
* 当剩余长度超过2MB的一半且地址2MB对齐,则会映射一个2MB页;
|
||||
* 否则映射4KB页。
|
||||
|
@ -206,7 +206,7 @@ bool memm_map_pageframes_to(
|
|||
/**
|
||||
* @name reload_pml4
|
||||
* @addindex 平台依赖宏 x86_64
|
||||
*
|
||||
*
|
||||
* ```c
|
||||
* void reload_pml4();
|
||||
* ```
|
||||
|
@ -216,9 +216,9 @@ extern void reload_pml4();
|
|||
/**
|
||||
* @name is_user_address(addr)
|
||||
* @addindex 平台定制宏
|
||||
*
|
||||
*
|
||||
* 判断`addr`是否是一个用户空间地址,得到一个布尔值。
|
||||
*
|
||||
*
|
||||
* @if arch == x86_64
|
||||
* `canonical`型地址的高地址为用户空间,低地址为内核空间。
|
||||
* @endif
|
||||
|
@ -229,7 +229,7 @@ extern void reload_pml4();
|
|||
/**
|
||||
* @name is_cannonical(addr)
|
||||
* @addindex 平台依赖宏 x86_64
|
||||
*
|
||||
*
|
||||
* 判断`addr`是否是一个cannonical型地址。
|
||||
*/
|
||||
#define is_cannonical(addr) \
|
||||
|
@ -238,9 +238,9 @@ extern void reload_pml4();
|
|||
/**
|
||||
* @name memm_get_page_align(addr)
|
||||
* @addindex 平台依赖宏 x86_64
|
||||
*
|
||||
*
|
||||
* 获取地址`addr`的页对齐大小,得到一个`memm_page_size`类型值。
|
||||
*
|
||||
*
|
||||
* 当地址`addr`是*4KB对齐*或*没有4KB对齐时*,都得到`MEMM_PAGE_SIZE_4K`。
|
||||
*/
|
||||
#define memm_get_page_align(addr) \
|
||||
|
@ -250,4 +250,21 @@ extern void reload_pml4();
|
|||
? MEMM_PAGE_SIZE_2M \
|
||||
: MEMM_PAGE_SIZE_4K))
|
||||
|
||||
/**
|
||||
* @name memm_page_counter
|
||||
* @addindex 平台定制结构
|
||||
*
|
||||
* 页计数器
|
||||
*
|
||||
* @if arch == x86_64
|
||||
* 使用三个成员分别记录`4KB`、`2MB`、`1GB`页的大小。
|
||||
* @endif
|
||||
*/
|
||||
typedef struct __memm_page_counter
|
||||
{
|
||||
usize mapped_4k_page;
|
||||
usize mapped_2m_page;
|
||||
usize mapped_1g_page;
|
||||
} memm_page_counter;
|
||||
|
||||
#endif
|
||||
|
|
|
@ -35,9 +35,9 @@
|
|||
*
|
||||
* 分配器的一对`分配`、`释放`函数指针。内核中可以根据情况使用多种不同的分配器来分配内存,`allocator`中提供一对此类型的变量,用于
|
||||
* 动态绑定不同的分配器。
|
||||
*
|
||||
*
|
||||
* 分配器在`kernel/memm/allocator/`中定义。
|
||||
*
|
||||
*
|
||||
* 分配器**必须**实现的行为:
|
||||
*
|
||||
* **`memm_allocate_t`**:
|
||||
|
@ -78,7 +78,11 @@ typedef void (*memm_free_t)(void *allocator, void *mem);
|
|||
* 在**内核镜像结尾**至`MEMM_ALLOC_ONLY_MEMORY`空间中,包含一个分配器`内核大分配器`。
|
||||
*
|
||||
* 分配器指针**必须**使用内核地址。
|
||||
*
|
||||
*
|
||||
* @internal magic
|
||||
*
|
||||
* 分配器有效性由此检验,不为`MEMM_ALLOCATOR_MAGIC_NUM`说明获得了一个错误的分配器地址。
|
||||
*
|
||||
* @internal full
|
||||
*
|
||||
* 调用分配器的`allocate`方法后,在返回`nullptr`时会设为`true`。
|
||||
|
@ -88,6 +92,10 @@ typedef void (*memm_free_t)(void *allocator, void *mem);
|
|||
*
|
||||
* 进程标志服,表示此分配器所属的进程,为0代表属于内核。
|
||||
*
|
||||
* @internal userspace
|
||||
*
|
||||
* 若分配器不属于内核,此成员储存此分配器的用户空间地址。
|
||||
*
|
||||
* @internal type
|
||||
*
|
||||
* 分配器类型。在目录`include/kernel/memm/allocator`中对每个分配器分别定义一个唯一值。
|
||||
|
@ -107,17 +115,21 @@ typedef void (*memm_free_t)(void *allocator, void *mem);
|
|||
*/
|
||||
typedef struct __allocator_t
|
||||
{
|
||||
#define MEMM_ALLOCATOR_MAGIC_NUM 0x271fe441
|
||||
#ifndef MEMM_ALLOCATOR_MAGIC
|
||||
#define MEMM_ALLOCATOR_MAGIC 0x271fe441
|
||||
#endif
|
||||
// 分配器有效性由此检验,不为`MEMM_ALLOCATOR_MAGIC_NUM`说明获得了一个错误的分配器地址。
|
||||
// 此值在编译时通过各种方式确定,若
|
||||
u32 magic;
|
||||
|
||||
bool initialized;
|
||||
|
||||
// 调用分配器的`allocate`方法后,在返回`nullptr`时会设为`true`。
|
||||
// 调用分配器的`free`方法时设为`false`。
|
||||
bool full;
|
||||
|
||||
// 进程标志服,表示此分配器所属的进程,为0代表属于内核。
|
||||
usize pid;
|
||||
// 若分配器不属于内核,此成员储存此分配器的用户空间地址。
|
||||
void *userspace;
|
||||
// 分配器类型。在目录`include/kernel/memm/allocator`中对每个分配器分别定义一个唯一值。
|
||||
usize type;
|
||||
usize size;
|
||||
|
@ -186,11 +198,7 @@ typedef struct __mem_manager_t
|
|||
|
||||
// 已经映射的页数量。若不是最小的页会被视作多个最小页计数。
|
||||
usize mapped_page_amount;
|
||||
#ifdef __x86_64__
|
||||
usize mapped_4k_page;
|
||||
usize mapped_2m_page;
|
||||
usize mapped_1g_page;
|
||||
#endif
|
||||
memm_page_counter platformed_page_counter;
|
||||
|
||||
// 页地图。每个bit都表示这个页是否被映射。
|
||||
u8 *page_map;
|
||||
|
@ -294,18 +302,18 @@ void *memm_user_allocate(usize size, usize pid);
|
|||
|
||||
/**
|
||||
* @name memm_free
|
||||
*
|
||||
*
|
||||
* ```c
|
||||
* void memm_free(void *mem);
|
||||
* ```
|
||||
*
|
||||
*
|
||||
* 释放内存。
|
||||
*/
|
||||
void memm_free(void *mem);
|
||||
|
||||
/**
|
||||
* @name find_fitable_pages
|
||||
*
|
||||
*
|
||||
* ```c
|
||||
* usize find_fitable_pages(usize page_count);
|
||||
* ```
|
||||
|
|
|
@ -126,11 +126,11 @@ bool memm_map_pageframes_to(
|
|||
switch (align)
|
||||
{
|
||||
case MEMM_PAGE_SIZE_4K:
|
||||
mm->mapped_4k_page++;
|
||||
mm->platformed_page_counter.mapped_4k_page++;
|
||||
case MEMM_PAGE_SIZE_2M:
|
||||
mm->mapped_2m_page++;
|
||||
mm->platformed_page_counter.mapped_2m_page++;
|
||||
case MEMM_PAGE_SIZE_1G:
|
||||
mm->mapped_1g_page++;
|
||||
mm->platformed_page_counter.mapped_1g_page++;
|
||||
}
|
||||
for (usize i = physical / MEMM_PAGE_SIZE; i < physical / MEMM_PAGE_SIZE + align; i++)
|
||||
{
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
use alloc::string::ToString;
|
||||
use alloc::vec;
|
||||
use alloc::vec::Vec;
|
||||
|
||||
|
@ -181,7 +180,7 @@ impl<'a> Iterator for LogIterator<'a> {
|
|||
let res = if let Some((time, msg)) = self.logs.first() {
|
||||
Some(
|
||||
MessageBuilder::new()
|
||||
.message(&time.to_string())
|
||||
.message(time)
|
||||
.append(MessageBuilder::from_message(msg.clone()))
|
||||
.build(),
|
||||
)
|
||||
|
|
|
@ -77,8 +77,7 @@ memory_manager_t *memm_get_manager()
|
|||
allocator_t *memm_allocator_new(void *start, usize length, usize type, usize pid)
|
||||
{
|
||||
allocator_t *allocator = start;
|
||||
allocator->magic = MEMM_ALLOCATOR_MAGIC_NUM;
|
||||
allocator->initialized = true;
|
||||
allocator->magic = MEMM_ALLOCATOR_MAGIC;
|
||||
allocator->full = false;
|
||||
allocator->pid = 0;
|
||||
allocator->size = length;
|
||||
|
@ -91,14 +90,14 @@ allocator_t *memm_allocator_new(void *start, usize length, usize type, usize pid
|
|||
allocator->free = (memm_free_t)raw_allocator_free;
|
||||
break;
|
||||
default:
|
||||
allocator->initialized = false;
|
||||
allocator->magic = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void memm_allocator_destruct(allocator_t *allocator)
|
||||
{
|
||||
allocator->initialized = false;
|
||||
allocator->magic = 0;
|
||||
// TODO 从分配器树中删除这个分配器
|
||||
KERNEL_TODO();
|
||||
}
|
||||
|
@ -226,7 +225,7 @@ void *memm_user_allocate(usize size, usize pid)
|
|||
void memm_free(void *mem)
|
||||
{
|
||||
allocator_t *allocator = memm_addr_get_allocator(mem);
|
||||
if (allocator->magic != MEMM_ALLOCATOR_MAGIC_NUM)
|
||||
if (allocator->magic != MEMM_ALLOCATOR_MAGIC)
|
||||
return;
|
||||
if (is_user_address((u64)mem))
|
||||
{ // TODO 对于用户空间的地址需要先转换到内核地址后释放
|
||||
|
|
|
@ -181,6 +181,16 @@ pub struct MessageSection {
|
|||
#[derive(Clone)]
|
||||
pub struct Message(Vec<MessageSection>);
|
||||
|
||||
impl ToString for Message {
|
||||
fn to_string(&self) -> String {
|
||||
let mut res = String::new();
|
||||
for MessageSection { msg, .. } in self.0.iter() {
|
||||
res += msg;
|
||||
}
|
||||
res
|
||||
}
|
||||
}
|
||||
|
||||
/// ## MessageBuilder
|
||||
///
|
||||
/// 使用链式调用模式构造一个消息.
|
||||
|
@ -226,7 +236,7 @@ impl MessageBuilder {
|
|||
Self { msg }
|
||||
}
|
||||
|
||||
pub fn message(mut self, msg: &str) -> Self {
|
||||
pub fn message<T: ToString + ?Sized>(mut self, msg: &T) -> Self {
|
||||
self.msg.0.push(MessageSection {
|
||||
msg: msg.to_string(),
|
||||
fgcolor: Color(0xee, 0xee, 0xee),
|
||||
|
@ -235,7 +245,7 @@ impl MessageBuilder {
|
|||
self
|
||||
}
|
||||
|
||||
pub fn message_mut(&mut self, msg: &str) {
|
||||
pub fn message_mut<T: ToString + ?Sized>(&mut self, msg: &T) {
|
||||
self.msg.0.push(MessageSection {
|
||||
msg: msg.to_string(),
|
||||
fgcolor: Color(0xee, 0xee, 0xee),
|
||||
|
|
Loading…
Reference in New Issue