mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-09 15:26:47 +00:00
🆕 完成了初始化内存管理单元的代码
This commit is contained in:
parent
134692fa85
commit
8131264e3f
@ -114,8 +114,9 @@ static inline int strlen(char *s)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
inline void *memset(void *dst, unsigned char C, ul Count)
|
void *memset(void *dst, unsigned char C, ul Count)
|
||||||
{
|
{
|
||||||
|
|
||||||
int d0, d1;
|
int d0, d1;
|
||||||
unsigned long tmp = C * 0x0101010101010101UL;
|
unsigned long tmp = C * 0x0101010101010101UL;
|
||||||
__asm__ __volatile__("cld \n\t"
|
__asm__ __volatile__("cld \n\t"
|
||||||
@ -136,3 +137,10 @@ inline void *memset(void *dst, unsigned char C, ul Count)
|
|||||||
: "memory");
|
: "memory");
|
||||||
return dst;
|
return dst;
|
||||||
}
|
}
|
||||||
|
void *memset_c(void *dst, unsigned char c, ul n)
|
||||||
|
{
|
||||||
|
unsigned char *s = (unsigned char *)dst;
|
||||||
|
for(int i=0;i<n;++i)
|
||||||
|
s[i] = c;
|
||||||
|
return dst;
|
||||||
|
}
|
@ -9,7 +9,9 @@
|
|||||||
#include "mm/mm.h"
|
#include "mm/mm.h"
|
||||||
|
|
||||||
int *FR_address = (int *)0xffff800000a00000; //帧缓存区的地址
|
int *FR_address = (int *)0xffff800000a00000; //帧缓存区的地址
|
||||||
char fxsave_region[512] __attribute__((aligned(16)));
|
//char fxsave_region[512] __attribute__((aligned(16)));
|
||||||
|
|
||||||
|
struct memory_desc memory_management_struct = {{0}, 0};
|
||||||
|
|
||||||
void show_welcome()
|
void show_welcome()
|
||||||
{
|
{
|
||||||
@ -75,7 +77,7 @@ void init()
|
|||||||
init_sys_vector();
|
init_sys_vector();
|
||||||
|
|
||||||
|
|
||||||
asm volatile(" fxsave %0 " ::"m"(fxsave_region));
|
//asm volatile(" fxsave %0 " ::"m"(fxsave_region));
|
||||||
// 初始化内存管理单元
|
// 初始化内存管理单元
|
||||||
printk("[ DragonOS ] Initializing memory manage unit...\n");
|
printk("[ DragonOS ] Initializing memory manage unit...\n");
|
||||||
mm_init();
|
mm_init();
|
||||||
|
225
kernel/mm/mm.c
225
kernel/mm/mm.c
@ -2,28 +2,237 @@
|
|||||||
#include "../common/printk.h"
|
#include "../common/printk.h"
|
||||||
|
|
||||||
ul Total_Memory = 0;
|
ul Total_Memory = 0;
|
||||||
|
ul total_2M_pages = 0;
|
||||||
|
|
||||||
void mm_init()
|
void mm_init()
|
||||||
{
|
{
|
||||||
|
printk("[ INFO ] Initializing memory management unit...\n");
|
||||||
// 实模式下获取到的信息的起始地址,转换为ARDS指针
|
// 实模式下获取到的信息的起始地址,转换为ARDS指针
|
||||||
struct ARDS *ards_ptr = (struct ARDS *)0xffff800000007e00;
|
struct ARDS *ards_ptr = (struct ARDS *)0xffff800000007e00;
|
||||||
|
|
||||||
for (int i = 0; i < 32; ++i)
|
for (int i = 0; i < 32; ++i)
|
||||||
{
|
{
|
||||||
printk("Addr = %#10lx,%8lx\tLength = %#10lx,%8lx\tType = %#10lx\n",
|
//printk("Addr = %#18lx\tLength = %#18lx\tType = %#10lx\n",
|
||||||
ards_ptr->BaseAddrH, ards_ptr->BaseAddrL, ards_ptr->LengthH, ards_ptr->LengthL, ards_ptr->type);
|
// ards_ptr->BaseAddr, ards_ptr->Length, ards_ptr->type);
|
||||||
|
|
||||||
//可用的内存
|
//可用的内存
|
||||||
if (ards_ptr->type == 1)
|
if (ards_ptr->type == 1)
|
||||||
{
|
Total_Memory += ards_ptr->Length;
|
||||||
Total_Memory += ards_ptr->LengthL;
|
|
||||||
Total_Memory += ((ul)(ards_ptr->LengthH)) << 32;
|
// 保存信息到mms
|
||||||
}
|
memory_management_struct.e820[i].BaseAddr = ards_ptr->BaseAddr;
|
||||||
|
memory_management_struct.e820[i].Length = ards_ptr->Length;
|
||||||
|
memory_management_struct.e820[i].type = ards_ptr->type;
|
||||||
|
memory_management_struct.len_e820 = i;
|
||||||
|
|
||||||
++ards_ptr;
|
++ards_ptr;
|
||||||
|
|
||||||
// 脏数据
|
// 脏数据
|
||||||
if (ards_ptr->type > 4)
|
if (ards_ptr->type > 4 || ards_ptr->Length == 0 || ards_ptr->type < 1)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
printk_color(ORANGE, BLACK, "Total amount of RAM DragonOS can use: %ld bytes\n", Total_Memory);
|
printk("[ INFO ] Total amounts of RAM : %ld bytes\n", Total_Memory);
|
||||||
|
|
||||||
|
// 计算有效内存页数
|
||||||
|
|
||||||
|
for (int i = 0; i < memory_management_struct.len_e820; ++i)
|
||||||
|
{
|
||||||
|
if (memory_management_struct.e820[i].type != 1)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// 将内存段的起始物理地址按照2M进行对齐
|
||||||
|
ul addr_start = PAGE_2M_ALIGN(memory_management_struct.e820[i].BaseAddr);
|
||||||
|
// 将内存段的终止物理地址的低2M区域清空,以实现对齐
|
||||||
|
ul addr_end = ((memory_management_struct.e820[i].BaseAddr + memory_management_struct.e820[i].Length) & PAGE_2M_MASK);
|
||||||
|
|
||||||
|
// 内存段不可用
|
||||||
|
if (addr_end <= addr_start)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
total_2M_pages += ((addr_end - addr_start) >> PAGE_2M_SHIFT);
|
||||||
|
}
|
||||||
|
printk("[ INFO ] Total amounts of 2M pages : %ld.\n", total_2M_pages);
|
||||||
|
|
||||||
|
// 设置内核程序不同部分的起止地址
|
||||||
|
memory_management_struct.kernel_code_start = (ul)&_text;
|
||||||
|
memory_management_struct.kernel_code_end = (ul)&_etext;
|
||||||
|
memory_management_struct.kernel_data_end = (ul)&_edata;
|
||||||
|
memory_management_struct.kernel_end = (ul)&_end;
|
||||||
|
|
||||||
|
// 物理地址空间的最大地址(包含了物理内存、内存空洞、ROM等)
|
||||||
|
ul max_addr = memory_management_struct.e820[memory_management_struct.len_e820].BaseAddr + memory_management_struct.e820[memory_management_struct.len_e820].Length;
|
||||||
|
// 初始化mms的bitmap
|
||||||
|
// bmp的指针指向截止位置的4k对齐的上边界(防止修改了别的数据)
|
||||||
|
memory_management_struct.bmp = (unsigned long *)((memory_management_struct.kernel_end + PAGE_4K_SIZE - 1) & PAGE_4K_MASK);
|
||||||
|
memory_management_struct.bits_size = max_addr >> PAGE_2M_SHIFT; // 物理地址空间的最大页面数
|
||||||
|
memory_management_struct.bmp_len = ((unsigned long)((max_addr >> PAGE_2M_SHIFT) + sizeof(unsigned long) * 8 - 1) / 8) & (~(sizeof(unsigned long) - 1)); // bmp由多少个unsigned long变量组成
|
||||||
|
|
||||||
|
|
||||||
|
// 初始化bitmap, 先将整个bmp空间全部置位。稍后再将可用物理内存页复位。
|
||||||
|
memset(memory_management_struct.bmp, 0xff, memory_management_struct.bmp_len);
|
||||||
|
|
||||||
|
// 初始化内存页结构
|
||||||
|
// 将页结构映射于bmp之后
|
||||||
|
|
||||||
|
memory_management_struct.pages_struct = (struct Page *)(((unsigned long)memory_management_struct.bmp + memory_management_struct.bmp_len + PAGE_4K_SIZE - 1) & PAGE_4K_MASK);
|
||||||
|
|
||||||
|
memory_management_struct.count_pages = max_addr >> PAGE_2M_SHIFT;
|
||||||
|
memory_management_struct.pages_struct_len = ((max_addr >> PAGE_2M_SHIFT) * sizeof(struct Page) + sizeof(long) - 1) & (~(sizeof(long) - 1));
|
||||||
|
// 将pages_struct全部清空,以备后续初始化
|
||||||
|
memset(memory_management_struct.pages_struct, 0x00, memory_management_struct.pages_struct_len); //init pages memory
|
||||||
|
|
||||||
|
// 初始化内存区域
|
||||||
|
memory_management_struct.zones_struct = (struct Zone *)(((ul)memory_management_struct.pages_struct + memory_management_struct.pages_struct_len + PAGE_4K_SIZE - 1) & PAGE_4K_MASK);
|
||||||
|
// 由于暂时无法计算zone结构体的数量,因此先将其设为0
|
||||||
|
memory_management_struct.count_zones = 0;
|
||||||
|
// zones-struct 成员变量暂时按照5个来计算
|
||||||
|
memory_management_struct.zones_struct_len = (5 * sizeof(struct Zone) + sizeof(ul) - 1) & (~(sizeof(ul) - 1));
|
||||||
|
memset(memory_management_struct.zones_struct, 0x00, memory_management_struct.zones_struct_len);
|
||||||
|
|
||||||
|
// ==== 遍历e820数组,完成成员变量初始化工作 ===
|
||||||
|
|
||||||
|
for (int i = 0; i < memory_management_struct.len_e820; ++i)
|
||||||
|
{
|
||||||
|
if (memory_management_struct.e820[i].type != 1) // 不是操作系统可以使用的物理内存
|
||||||
|
continue;
|
||||||
|
ul addr_start = PAGE_2M_ALIGN(memory_management_struct.e820[i].BaseAddr);
|
||||||
|
ul addr_end = (memory_management_struct.e820[i].BaseAddr + memory_management_struct.e820[i].Length) & PAGE_2M_MASK;
|
||||||
|
|
||||||
|
if (addr_end <= addr_start)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// zone init
|
||||||
|
struct Zone *z = memory_management_struct.zones_struct + memory_management_struct.count_zones;
|
||||||
|
++memory_management_struct.count_zones;
|
||||||
|
|
||||||
|
z->zone_addr_start = addr_start;
|
||||||
|
z->zone_addr_end = addr_end;
|
||||||
|
z->zone_length = addr_end - addr_start;
|
||||||
|
|
||||||
|
z->count_pages_using = 0;
|
||||||
|
z->count_pages_free = (addr_end - addr_start) >> PAGE_2M_SHIFT;
|
||||||
|
z->total_pages_link = 0;
|
||||||
|
|
||||||
|
z->attr = 0;
|
||||||
|
z->gmd_struct = &memory_management_struct;
|
||||||
|
|
||||||
|
z->count_pages = (addr_end - addr_start) >> PAGE_2M_SHIFT;
|
||||||
|
z->pages_group = (struct Page *)(memory_management_struct.pages_struct + (addr_start >> PAGE_2M_SHIFT));
|
||||||
|
|
||||||
|
// 初始化页
|
||||||
|
struct Page *p = z->pages_group;
|
||||||
|
|
||||||
|
for (int j = 0; j < z->count_pages; ++j, ++p)
|
||||||
|
{
|
||||||
|
p->zone = z;
|
||||||
|
p->addr_phys = addr_start + PAGE_2M_SIZE * j;
|
||||||
|
p->attr = 0;
|
||||||
|
|
||||||
|
p->ref_counts = 0;
|
||||||
|
p->age = 0;
|
||||||
|
|
||||||
|
// 将bmp中对应的位 复位
|
||||||
|
*(memory_management_struct.bmp + ((p->addr_phys >> PAGE_2M_SHIFT) >> 6)) ^= (1UL << ((p->addr_phys >> PAGE_2M_SHIFT) % 64));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 初始化0~2MB的物理页
|
||||||
|
// 由于这个区间的内存由多个内存段组成,因此不会被以上代码初始化,需要我们手动配置page[0]。
|
||||||
|
|
||||||
|
memory_management_struct.pages_struct->zone = memory_management_struct.zones_struct;
|
||||||
|
memory_management_struct.pages_struct->addr_phys = 0UL;
|
||||||
|
memory_management_struct.pages_struct->attr = 0;
|
||||||
|
memory_management_struct.pages_struct->ref_counts = 0;
|
||||||
|
memory_management_struct.pages_struct->age = 0;
|
||||||
|
|
||||||
|
// 计算zone结构体的总长度(按照64位对齐)
|
||||||
|
memory_management_struct.zones_struct_len = (memory_management_struct.count_zones * sizeof(struct Zone) + sizeof(ul) - 1) & (~(sizeof(ul) - 1));
|
||||||
|
|
||||||
|
printk_color(ORANGE, BLACK, "bmp:%#18lx, bmp_len:%#18lx, bits_size:%#18lx\n", memory_management_struct.bmp, memory_management_struct.bmp_len, memory_management_struct.bits_size);
|
||||||
|
|
||||||
|
printk_color(ORANGE, BLACK, "pages_struct:%#18lx, count_pages:%#18lx, pages_struct_len:%#18lx\n", memory_management_struct.pages_struct, memory_management_struct.count_pages, memory_management_struct.pages_struct_len);
|
||||||
|
|
||||||
|
printk_color(ORANGE, BLACK, "zones_struct:%#18lx, count_zones:%#18lx, zones_struct_len:%#18lx\n", memory_management_struct.zones_struct, memory_management_struct.count_zones, memory_management_struct.zones_struct_len);
|
||||||
|
|
||||||
|
ZONE_DMA_INDEX = 0; //need rewrite in the future
|
||||||
|
ZONE_NORMAL_INDEX = 0; //need rewrite in the future
|
||||||
|
|
||||||
|
for (int i = 0; i < memory_management_struct.count_zones; ++i) //need rewrite in the future
|
||||||
|
{
|
||||||
|
struct Zone *z = memory_management_struct.zones_struct + i;
|
||||||
|
printk_color(ORANGE, BLACK, "zone_addr_start:%#18lx, zone_addr_end:%#18lx, zone_length:%#18lx, pages_group:%#18lx, count_pages:%#18lx\n",
|
||||||
|
z->zone_addr_start, z->zone_addr_end, z->zone_length, z->pages_group, z->count_pages);
|
||||||
|
|
||||||
|
// 1GB以上的内存空间不做映射
|
||||||
|
if (z->zone_addr_start == 0x100000000)
|
||||||
|
ZONE_UNMAPED_INDEX = i;
|
||||||
|
}
|
||||||
|
// 设置内存页管理结构的地址,预留了一段空间,防止内存越界。
|
||||||
|
memory_management_struct.end_of_struct = (ul)((ul)memory_management_struct.zones_struct + memory_management_struct.zones_struct_len + sizeof(long) * 32) & (~(sizeof(long) - 1));
|
||||||
|
|
||||||
|
printk_color(ORANGE, BLACK, "code_start:%#18lx, code_end:%#18lx, data_end:%#18lx, kernel_end:%#18lx, end_of_struct:%#18lx\n",
|
||||||
|
memory_management_struct.kernel_code_start, memory_management_struct.kernel_code_end, memory_management_struct.kernel_data_end, memory_management_struct.kernel_end, memory_management_struct.end_of_struct);
|
||||||
|
|
||||||
|
// 初始化内存管理单元结构所占的物理页的结构体
|
||||||
|
|
||||||
|
ul mms_max_page = (virt_2_phys(memory_management_struct.end_of_struct) >> PAGE_2M_SHIFT); // 内存管理单元所占据的序号最大的物理页
|
||||||
|
|
||||||
|
for (ul j = 0; j <= mms_max_page; ++j)
|
||||||
|
{
|
||||||
|
page_init(memory_management_struct.pages_struct+j, PAGE_PGT_MAPPED|PAGE_KERNEL|PAGE_KERNEL_INIT|PAGE_ACTIVE);
|
||||||
|
}
|
||||||
|
|
||||||
|
ul* cr3 = get_CR3();
|
||||||
|
|
||||||
|
printk_color(INDIGO, BLACK, "cr3:\t%#018lx\n", cr3);
|
||||||
|
printk_color(INDIGO, BLACK, "*cr3:\t%#018lx\n", *(phys_2_virt(cr3))&(~0xff));
|
||||||
|
printk_color(INDIGO, BLACK, "**cr3:\t%#018lx\n", *phys_2_virt(*(phys_2_virt(cr3))&(~0xff))&(~0xff));
|
||||||
|
|
||||||
|
// 消除一致性页表映射,将页目录(PML4E)的前10项清空
|
||||||
|
for(int i=0;i<10;++i)
|
||||||
|
*(phys_2_virt(cr3)+i) = 0UL;
|
||||||
|
|
||||||
|
flush_tlb();
|
||||||
|
|
||||||
|
printk("[ INFO ] Memory management unit initialized.\n");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 初始化内存页
|
||||||
|
*
|
||||||
|
* @param page 内存页结构体
|
||||||
|
* @param flags 标志位
|
||||||
|
* 对于新页面: 初始化struct page
|
||||||
|
* 对于当前页面属性/flags中含有引用属性或共享属性时,则只增加struct page和struct zone的被引用计数。否则就只是添加页表属性,并置位bmp的相应位。
|
||||||
|
* @return unsigned long
|
||||||
|
*/
|
||||||
|
unsigned long page_init(struct Page *page, ul flags)
|
||||||
|
{
|
||||||
|
// 全新的页面
|
||||||
|
if (!page->attr)
|
||||||
|
{
|
||||||
|
// 将bmp对应的标志位置位
|
||||||
|
*(memory_management_struct.bmp + ((page->addr_phys >> PAGE_2M_SHIFT) >> 6)) |= (1UL << ((page->addr_phys >> PAGE_2M_SHIFT) % 64));
|
||||||
|
|
||||||
|
page->attr = flags;
|
||||||
|
++(page->ref_counts);
|
||||||
|
++(page->zone->count_pages_using);
|
||||||
|
--(page->zone->count_pages_free);
|
||||||
|
++(page->zone->total_pages_link);
|
||||||
|
}
|
||||||
|
// 不是全新的页面,而是含有引用属性/共享属性
|
||||||
|
else if ((page->attr & PAGE_REFERENCED) || (page->attr & PAGE_K_SHARE_TO_U) || (flags & PAGE_REFERENCED) || (flags & PAGE_K_SHARE_TO_U))
|
||||||
|
{
|
||||||
|
page->attr |= flags;
|
||||||
|
++(page->ref_counts);
|
||||||
|
++(page->zone->total_pages_link);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// 将bmp对应的标志位置位
|
||||||
|
*(memory_management_struct.bmp + ((page->addr_phys >> PAGE_2M_SHIFT) >> 6)) |= (1UL << ((page->addr_phys >> PAGE_2M_SHIFT) % 64));
|
||||||
|
page->attr |= flags;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
182
kernel/mm/mm.h
182
kernel/mm/mm.h
@ -1,21 +1,183 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include"../common/glib.h"
|
#include "../common/glib.h"
|
||||||
|
|
||||||
|
// 每个页表的项数
|
||||||
|
// 64位下,每个页表4k,每条页表项8B,故一个页表有512条
|
||||||
|
#define PTRS_PER_PGT 512
|
||||||
|
|
||||||
|
// 内核层的起始地址
|
||||||
|
#define KERNEL_BASE_ADDR 0xffff800000000000
|
||||||
|
|
||||||
|
#define PAGE_4K_SHIFT 12
|
||||||
|
#define PAGE_2M_SHIFT 21
|
||||||
|
#define PAGE_1G_SHIFT 30
|
||||||
|
|
||||||
|
// 不同大小的页的容量
|
||||||
|
#define PAGE_4K_SIZE (1UL << PAGE_4K_SHIFT)
|
||||||
|
#define PAGE_2M_SIZE (1UL << PAGE_2M_SHIFT)
|
||||||
|
#define PAGE_1G_SIZE (1UL << PAGE_1G_SHIFT)
|
||||||
|
|
||||||
|
// 屏蔽低于x的数值
|
||||||
|
#define PAGE_4K_MASK (~(PAGE_4K_SIZE - 1))
|
||||||
|
#define PAGE_2M_MASK (~(PAGE_2M_SIZE - 1))
|
||||||
|
|
||||||
|
// 将addr按照x的上边界对齐
|
||||||
|
#define PAGE_4K_ALIGN(addr) (((unsigned long)(addr) + PAGE_4K_SIZE - 1) & PAGE_4K_MASK)
|
||||||
|
#define PAGE_2M_ALIGN(addr) (((unsigned long)(addr) + PAGE_2M_SIZE - 1) & PAGE_2M_MASK)
|
||||||
|
|
||||||
|
// 虚拟地址与物理地址转换
|
||||||
|
#define virt_2_phys(addr) ((unsigned long)(addr)-KERNEL_BASE_ADDR)
|
||||||
|
#define phys_2_virt(addr) ((unsigned long *)((unsigned long)(addr) + KERNEL_BASE_ADDR))
|
||||||
|
|
||||||
|
// ===== 页面属性 =====
|
||||||
|
// 页面在页表中已被映射
|
||||||
|
#define PAGE_PGT_MAPPED (1 << 0)
|
||||||
|
// 内核初始化程序的页
|
||||||
|
#define PAGE_KERNEL_INIT (1 << 1)
|
||||||
|
// 引用的页
|
||||||
|
#define PAGE_REFERENCED (1 << 2)
|
||||||
|
// 脏页
|
||||||
|
#define PAGE_DIRTY (1 << 3)
|
||||||
|
// 使用中的页
|
||||||
|
#define PAGE_ACTIVE (1 << 4)
|
||||||
|
// 过时的页
|
||||||
|
#define PAGE_UP_TO_DATE (1 << 5)
|
||||||
|
// 设备对应的页
|
||||||
|
#define PAGE_DEVICE (1 << 6)
|
||||||
|
// 内核层页
|
||||||
|
#define PAGE_KERNEL (1 << 7)
|
||||||
|
// 内核共享给用户态程序的页面
|
||||||
|
#define PAGE_K_SHARE_TO_U (1 << 8)
|
||||||
|
// slab内存分配器的页
|
||||||
|
#define PAGE_SLAB (1 << 9)
|
||||||
|
|
||||||
// Address Range Descriptor Structure 地址范围描述符
|
// Address Range Descriptor Structure 地址范围描述符
|
||||||
struct ARDS
|
struct ARDS
|
||||||
{
|
{
|
||||||
unsigned int BaseAddrL; // 基地址低32位
|
ul BaseAddr; // 基地址
|
||||||
unsigned int BaseAddrH; // 基地址高32位
|
ul Length; // 内存长度 以字节为单位
|
||||||
unsigned int LengthL; // 内存长度低32位 以字节为单位
|
unsigned int type; // 本段内存的类型
|
||||||
unsigned int LengthH; // 内存长度高32位
|
// type=1 表示可以被操作系统使用
|
||||||
unsigned int type; // 本段内存的类型
|
// type=2 ARR - 内存使用中或被保留,操作系统不能使用
|
||||||
// type=1 表示可以被操作系统使用
|
// 其他 未定义,操作系统需要将其视为ARR
|
||||||
// type=2 ARR - 内存使用中或被保留,操作系统不能使用
|
} __attribute__((packed)); // 修饰该结构体不会生成对齐空间,改用紧凑格式
|
||||||
// 其他 未定义,操作系统需要将其视为ARR
|
|
||||||
|
struct memory_desc
|
||||||
|
{
|
||||||
|
|
||||||
|
struct ARDS e820[32]; // 物理内存段结构数组
|
||||||
|
ul len_e820; // 物理内存段长度
|
||||||
|
|
||||||
|
ul *bmp; // 物理空间页映射位图
|
||||||
|
ul bmp_len; // bmp的长度
|
||||||
|
ul bits_size; // 物理地址空间页数量
|
||||||
|
|
||||||
|
struct Page *pages_struct;
|
||||||
|
ul count_pages; // struct page结构体的总数
|
||||||
|
ul pages_struct_len; // pages_struct链表的长度
|
||||||
|
|
||||||
|
struct Zone *zones_struct;
|
||||||
|
ul count_zones; // zone结构体的数量
|
||||||
|
ul zones_struct_len; // zones_struct列表的长度
|
||||||
|
|
||||||
|
ul kernel_code_start, kernel_code_end; // 内核程序代码段起始地址、结束地址
|
||||||
|
ul kernel_data_end, kernel_end; // 内核程序数据段结束地址、 内核程序结束地址
|
||||||
|
|
||||||
|
ul end_of_struct; // 内存页管理结构的结束地址
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct Zone
|
||||||
|
{
|
||||||
|
// 指向内存页的指针
|
||||||
|
struct Page *pages_group;
|
||||||
|
ul count_pages; // 本区域的struct page结构体总数
|
||||||
|
|
||||||
|
// 本内存区域的起始、结束的页对齐地址
|
||||||
|
ul zone_addr_start;
|
||||||
|
ul zone_addr_end;
|
||||||
|
ul zone_length; // 区域长度
|
||||||
|
|
||||||
|
// 本区域空间的属性
|
||||||
|
ul attr;
|
||||||
|
|
||||||
void mm_init();
|
struct memory_desc *gmd_struct;
|
||||||
|
|
||||||
|
// 本区域正在使用中和空闲中的物理页面数量
|
||||||
|
ul count_pages_using;
|
||||||
|
ul count_pages_free;
|
||||||
|
|
||||||
|
// 物理页被引用次数
|
||||||
|
ul total_pages_link;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Page
|
||||||
|
{
|
||||||
|
// 本页所属的内存域结构体
|
||||||
|
struct Zone *zone;
|
||||||
|
// 本页对应的物理地址
|
||||||
|
ul addr_phys;
|
||||||
|
// 页面属性
|
||||||
|
ul attr;
|
||||||
|
// 页面被引用的次数
|
||||||
|
ul ref_counts;
|
||||||
|
// 本页的创建时间
|
||||||
|
ul age;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern struct memory_desc memory_management_struct;
|
||||||
|
|
||||||
|
// 导出内核程序的几个段的起止地址
|
||||||
|
extern char _text;
|
||||||
|
extern char _etext;
|
||||||
|
extern char _edata;
|
||||||
|
extern char _end;
|
||||||
|
|
||||||
|
// 每个区域的索引
|
||||||
|
|
||||||
|
int ZONE_DMA_INDEX = 0;
|
||||||
|
int ZONE_NORMAL_INDEX = 0; //low 1GB RAM ,was mapped in pagetable
|
||||||
|
int ZONE_UNMAPED_INDEX = 0; //above 1GB RAM,unmapped in pagetable
|
||||||
|
|
||||||
|
// 初始化内存管理单元
|
||||||
|
void mm_init();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 初始化内存页
|
||||||
|
*
|
||||||
|
* @param page 内存页结构体
|
||||||
|
* @param flags 标志位
|
||||||
|
* 对于新页面: 初始化struct page
|
||||||
|
* 对于当前页面属性/flags中含有引用属性或共享属性时,则只增加struct page和struct zone的被引用计数。否则就只是添加页表属性,并置位bmp的相应位。
|
||||||
|
* @return unsigned long
|
||||||
|
*/
|
||||||
|
unsigned long page_init(struct Page *page, ul flags);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 读取CR3寄存器的值(存储了页目录的基地址)
|
||||||
|
*
|
||||||
|
* @return unsigned* cr3的值的指针
|
||||||
|
*/
|
||||||
|
unsigned long *get_CR3()
|
||||||
|
{
|
||||||
|
ul *tmp;
|
||||||
|
__asm__ __volatile__(
|
||||||
|
"movq %%cr3, %0\n\t"
|
||||||
|
: "=r"(tmp)::"memory");
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 刷新TLB的宏定义
|
||||||
|
* 由于任何写入cr3的操作都会刷新TLB,因此这个宏定义可以刷新TLB
|
||||||
|
*/
|
||||||
|
#define flush_tlb() \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
ul tmp; \
|
||||||
|
__asm__ __volatile__( \
|
||||||
|
"movq %%cr3, %0\n\t" \
|
||||||
|
"movq %0, %%cr3\n\t" \
|
||||||
|
: "=r"(tmp)::"memory"); \
|
||||||
|
\
|
||||||
|
} while (0);
|
||||||
|
@ -8,7 +8,7 @@ fi
|
|||||||
# 第一个参数如果是--notbuild 那就不构建,直接运行
|
# 第一个参数如果是--notbuild 那就不构建,直接运行
|
||||||
if [ ! "$1" == "--nobuild" ]; then
|
if [ ! "$1" == "--nobuild" ]; then
|
||||||
echo "开始构建..."
|
echo "开始构建..."
|
||||||
make all
|
make all -j 16
|
||||||
make clean
|
make clean
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user