kernel-dev/include/kernel/memm.h

235 lines
6.2 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#ifndef MEMM_H
#define MEMM_H 1
#ifdef __x86_64__
#include <kernel/arch/x86_64/memm.h>
#endif
#include <libk/lst.h>
/**
* @name MEMM_MAX_SUPPORTED_MEMORY
*
* 支持的最大物理内存,为固定值`1TB`。
*/
#define MEMM_MAX_SUPPORTED_MEMORY (1024 * (1024 * (1024 * (usize)1024)))
/**
* @name MEMM_MAX_SUPPORTED_PAGES
*
* 支持的最大页数量,通过宏`MEMM_MAX_SUPPORTED_MEMORY`与宏`MEMM_PAGE_SIZE`相除得到。
*/
#define MEMM_MAX_SUPPORTED_PAGES (MEMM_MAX_SUPPORTED_MEMORY / MEMM_PAGE_SIZE)
/**
* @name MEMM_ALLOC_ONLY_MEMORY
*
* 只分配不映射空间,暂时为固定值`64MB`。物理地址`0`\~`MEMM_ALLOC_ONLY_MEMORY`的空间在进入内核前已经映射至内核空间。
*
* 这段内存空间包含**1MB以内低地址**、**内核镜像**以及未分配空间,未分配空间被一个分配器独占。
*/
#define MEMM_ALLOC_ONLY_MEMORY (64 * 1024 * 1024)
#define MEMM_PAGE_TABLE_AREA_MAX (4 * 1024 * 1024)
/**
* @name memm_allocate_t, memm_free_t
*
* 分配器的一对`分配`、`释放`函数指针。内核中可以根据情况使用多种不同的分配器来分配内存,`allocator`中提供一对此类型的变量,用于
* 动态绑定不同的分配器。
*
* 分配器在`kernel/memm/allocator/`中定义。
*
* 分配器**必须**实现的行为:
*
* **`memm_allocate_t`**
*
* ```c
* typedef void *(*memm_allocate_t)(void *allocator, usize size);
* ```
*
* 从分配器`allocator`中分配`size`字节的内存。
*
* 无法分配空间时返回`nullptr`;当参数`size`为0时需要检查分配器占有的空间的可用性无可用空间时需要返回`nullptr`
* **返回的地址的16字节前**必须保留8字节空间用于存放内存所在分配器的内核空间地址。
*
* **`memm_free_t`**
*
* ```c
* typedef void (*memm_free_t)(void *allocator, void *mem);
* ```
*
* 释放分配器`allocator`中的内存`mem`。
*
* 由于此函数只由内核调用,因此对参数作出保证,保证地址`mem`属于这个`allocator`。
*/
typedef void *(*memm_allocate_t)(void *allocator, usize size);
typedef void (*memm_free_t)(void *allocator, void *mem);
/**
* @name allocator_t
*
* ```c
* typedef struct { } allocator_t;
* ```
*
* 内存分配器。
*
* 内存分配器用于为`memm_allocate`函数提供管理数据以及分配空间。
*
* 在**内核镜像结尾**至`MEMM_ALLOC_ONLY_MEMORY`空间中,包含一个分配器`内核大分配器`。
*
* 分配器指针**必须**使用内核地址。
*
* @internal magic
*
* 分配器有效性由此检验,不为`MEMM_ALLOCATOR_MAGIC_NUM`说明获得了一个错误的分配器地址。
*
* @internal full
*
* 调用分配器的`allocate`方法后,在返回`nullptr`时会设为`true`。
* 调用分配器的`free`方法时设为`false`。
*
* @internal pid
*
* 进程标志服表示此分配器所属的进程为0代表属于内核。
*
* @internal userspace
*
* 若分配器不属于内核,此成员储存此分配器的用户空间地址。
*
* @internal type
*
* 分配器类型。在目录`include/kernel/memm/allocator`中对每个分配器分别定义一个唯一值。
*
* @internal allocate
*
* 分配器实例的allocate函数。当无法分配空间时返回nullptr。在size参数为0时保证不可以分配空间
* 但是如果空间已满依然返回nullptr。
*
* @internal free
*
* 分配器实例的free函数。若不是allocate得到的地址则什么都不做。
*
* @internal allocator_instance
*
* 分配器实例。
*/
typedef struct __allocator_t
{
#ifndef MEMM_ALLOCATOR_MAGIC
#define MEMM_ALLOCATOR_MAGIC ((u32)0x271fe441)
#endif
// 分配器有效性由此检验,不为`MEMM_ALLOCATOR_MAGIC_NUM`说明获得了一个错误的分配器地址。
// 此值在编译时通过各种方式确定,若
u32 magic;
// 调用分配器的`allocate`方法后,在返回`nullptr`时会设为`true`。
// 调用分配器的`free`方法时设为`false`。
bool full;
// 分配器类型。在目录`include/kernel/memm/allocator`中对每个分配器分别定义一个唯一值。
usize type;
usize size;
// 分配器实例的allocate函数。当无法分配空间时返回nullptr。在size参数为0时
// 保证不可以分配空间但是如果空间已满依然返回nullptr。
memm_allocate_t allocate;
// 分配器实例的free函数。若不是allocate得到的地址则什么都不做。
memm_free_t free;
// 分配器实例。
u64 allocator_instance[0];
} allocator_t;
/**
* @name 内存管理器
*
* @internal alloc_only_memory
*
* 在进入内核主程序之前,有些不在内核中的虚拟内存空间已经被页表映射,这部分内存不可以再映射到物理页框。
*/
typedef struct __mem_manager_t
{
usize memory_size;
usize page_amount;
usize alloc_only_memory;
allocator_t *kernel_base_allocator;
usize page_table_area;
} memory_manager_t;
/**
* @name memm_new
*
* ```c
* memory_manager_t *memm_new(usize mem_size);
* ```
*
* 初始化内存管理结构。
*/
memory_manager_t *memm_new(usize mem_size);
/**
* @name memm_get_manager
*
* ```c
* memory_manager_t *memm_get_manager();
* ```
*
* 在其它源代码文件中,获取内存管理结构的方式。
*/
memory_manager_t *memm_get_manager();
/**
* @name memm_allocator_new
*
* ```c
* allocator_t *memm_allocator_new(void *start, usize length, usize type, usize pid);
* ```
*
* 在`start`处创建一个长度为`length`的内存分配器,当`pid`为0时表示这个分配器只给内核使用。
*/
allocator_t *memm_allocator_new(void *start, usize length, usize type, usize pid);
/**
* @name memm_allocator_destruct
*
* ```c
* void memm_allocator_destruct(allocator_t *allocator);
* ```
*
* 释放分配器对象。
*
* 只能被**内存回收模块**调用。
*/
void memm_allocator_destruct(allocator_t *allocator);
/**
* @name memm_kernel_allocate
*
* ```c
* void *memm_kernel_allocate(usize size);
* ```
*
* 为内核空间申请内存。
*/
void *memm_kernel_allocate(usize size);
/**
* @name memm_free
*
* ```c
* void memm_free(void *mem);
* ```
*
* 释放内存。
*/
void memm_free(void *mem);
void *memm_allcate_pagetable();
#endif