修复内存分配器返回地址错误的问题,修复内核获取的内存大小与实际内存不能对应的问题
This commit is contained in:
parent
ed30e09f01
commit
325e0a01bd
|
@ -4,3 +4,4 @@
|
||||||
*.map
|
*.map
|
||||||
*.elf
|
*.elf
|
||||||
metaverse_kernel
|
metaverse_kernel
|
||||||
|
kerndisass.txt
|
||||||
|
|
|
@ -134,7 +134,7 @@ typedef struct __bootinfo_elf_symbols_t
|
||||||
* will increment this field. Future version are guranteed to be backward compatible with
|
* will increment this field. Future version are guranteed to be backward compatible with
|
||||||
* older format. Each entry has the following structure: bootinfo_memory_map_entry.
|
* older format. Each entry has the following structure: bootinfo_memory_map_entry.
|
||||||
*
|
*
|
||||||
* ‘size’ contains the size of current entry including this field itself. It may be bigger
|
* 'size' contains the size of current entry including this field itself. It may be bigger
|
||||||
* than 24 bytes in future versions but is guaranteed to be ‘base_addr’ is the starting
|
* than 24 bytes in future versions but is guaranteed to be ‘base_addr’ is the starting
|
||||||
* physical address.
|
* physical address.
|
||||||
* ‘length’ is the size of the memory region in bytes.
|
* ‘length’ is the size of the memory region in bytes.
|
||||||
|
@ -158,7 +158,7 @@ typedef struct __bootinfo_memory_map_t
|
||||||
u32 size;
|
u32 size;
|
||||||
u32 entry_size;
|
u32 entry_size;
|
||||||
u32 entry_version;
|
u32 entry_version;
|
||||||
struct bootinfo_memory_map_entry_t
|
struct __bootinfo_memory_map_entry_t
|
||||||
{
|
{
|
||||||
u64 base_addr;
|
u64 base_addr;
|
||||||
u64 length;
|
u64 length;
|
||||||
|
@ -167,7 +167,9 @@ typedef struct __bootinfo_memory_map_t
|
||||||
} DISALIGNED entries[0];
|
} DISALIGNED entries[0];
|
||||||
} DISALIGNED bootinfo_memory_map_t;
|
} DISALIGNED bootinfo_memory_map_t;
|
||||||
#define bootinfo_memory_map(addr) (bootinfo_memory_map_t *)((usize)(addr) - sizeof(u32))
|
#define bootinfo_memory_map(addr) (bootinfo_memory_map_t *)((usize)(addr) - sizeof(u32))
|
||||||
|
#define bootinfo_memory_map_end(addr) ((void *)(addr) + (addr)->size - sizeof(u32))
|
||||||
#define BOOTINFO_MEMORY_MAP_TYPE 6
|
#define BOOTINFO_MEMORY_MAP_TYPE 6
|
||||||
|
typedef struct __bootinfo_memory_map_entry_t bootinfo_memory_map_entry_t;
|
||||||
|
|
||||||
/** Boot loader name
|
/** Boot loader name
|
||||||
* ‘string’ contains the name of a boot loader booting the kernel. The name is a normal
|
* ‘string’ contains the name of a boot loader booting the kernel. The name is a normal
|
||||||
|
|
|
@ -21,7 +21,7 @@ multiboot2_header:
|
||||||
bootinfo_request_tag:
|
bootinfo_request_tag:
|
||||||
dd 1
|
dd 1
|
||||||
dd bootinfo_request_tag_end - bootinfo_request_tag
|
dd bootinfo_request_tag_end - bootinfo_request_tag
|
||||||
dd 4 ; basic mamory info
|
dd 6 ; memory map
|
||||||
dd 1 ; boot command line
|
dd 1 ; boot command line
|
||||||
dd 8 ; framebuffer info
|
dd 8 ; framebuffer info
|
||||||
dd 12 ; efi64 system table pointer
|
dd 12 ; efi64 system table pointer
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#include <kernel/memm.h>
|
#include <kernel/memm.h>
|
||||||
|
|
||||||
#include <libk/multiboot2.h>
|
#include <libk/multiboot2.h>
|
||||||
|
#include <libk/math.h>
|
||||||
|
|
||||||
// 通过bootinfo获取临时的帧缓冲区信息
|
// 通过bootinfo获取临时的帧缓冲区信息
|
||||||
void get_frame_buffer_with_bootinfo(framebuffer *fb, bootinfo_t *bootinfo);
|
void get_frame_buffer_with_bootinfo(framebuffer *fb, bootinfo_t *bootinfo);
|
||||||
|
@ -16,12 +17,20 @@ void kmain(void *mb2_bootinfo)
|
||||||
// 获取内存信息
|
// 获取内存信息
|
||||||
void **tags;
|
void **tags;
|
||||||
usize tags_amount;
|
usize tags_amount;
|
||||||
if ((tags_amount = bootinfo_get_tag(&bootinfo, BOOTINFO_BASIC_MEMORY_INFO_TYPE, &tags)) == 0)
|
if ((tags_amount = bootinfo_get_tag(&bootinfo, BOOTINFO_MEMORY_MAP_TYPE, &tags)) == 0)
|
||||||
{
|
{
|
||||||
KERNEL_TODO();
|
KERNEL_TODO();
|
||||||
}
|
}
|
||||||
bootinfo_basic_memory_info_t *meminfo = bootinfo_basic_memory_info(tags[0]);
|
bootinfo_memory_map_t *meminfo = bootinfo_memory_map(tags[0]);
|
||||||
usize mem_size = 1024 * 1024 + meminfo->mem_upper * 1024;
|
usize mem_size = 0;
|
||||||
|
for (
|
||||||
|
bootinfo_memory_map_entry_t *it = meminfo->entries;
|
||||||
|
(void *)it < bootinfo_memory_map_end(meminfo);
|
||||||
|
it++)
|
||||||
|
{
|
||||||
|
if (it->type == 1 || it->type == 3 || it->type == 4 || it->type == 5)
|
||||||
|
mem_size += it->length;
|
||||||
|
}
|
||||||
|
|
||||||
// 初始化内存管理模块
|
// 初始化内存管理模块
|
||||||
mem_manager_t *memm = memm_new(mem_size);
|
mem_manager_t *memm = memm_new(mem_size);
|
||||||
|
@ -31,10 +40,11 @@ void kmain(void *mb2_bootinfo)
|
||||||
|
|
||||||
framebuffer fb;
|
framebuffer fb;
|
||||||
get_frame_buffer_with_bootinfo(&fb, &bootinfo);
|
get_frame_buffer_with_bootinfo(&fb, &bootinfo);
|
||||||
|
KERNEL_TODO();
|
||||||
tty *tty0 = tty_new(tty_type_raw_framebuffer, tty_mode_text);
|
tty *tty0 = tty_new(tty_type_raw_framebuffer, tty_mode_text);
|
||||||
tty_set_framebuffer(&tty0, &fb);
|
tty_set_framebuffer(tty0, &fb);
|
||||||
|
|
||||||
tty_text_print(&tty0, "Hello Metaverse!\n", gen_color(0xee, 0xee, 0xee), gen_color(0, 0, 0));
|
tty_text_print(tty0, "Hello Metaverse!\n", gen_color(0xee, 0xee, 0xee), gen_color(0, 0, 0));
|
||||||
|
|
||||||
// 初始化内核日志模块
|
// 初始化内核日志模块
|
||||||
|
|
||||||
|
@ -56,9 +66,9 @@ void get_frame_buffer_with_bootinfo(framebuffer *fb, bootinfo_t *bootinfo)
|
||||||
fb->width = fbinfo->framebuffer_width;
|
fb->width = fbinfo->framebuffer_width;
|
||||||
fb->height = fbinfo->framebuffer_height;
|
fb->height = fbinfo->framebuffer_height;
|
||||||
fb->pixsize = fbinfo->framebuffer_bpp / 8;
|
fb->pixsize = fbinfo->framebuffer_bpp / 8;
|
||||||
memm_map_pageframes_to(
|
memm_map_pageframes_to( // TODO 总共需要映射8MB空间,但是它只映射了2MB
|
||||||
(u64)fb->pointer, (u64)fb->pointer,
|
(u64)fb->pointer, (u64)fb->pointer,
|
||||||
fb->width * fb->height * fb->pixsize,
|
fb->width * fb->height * fb->pixsize,
|
||||||
false, true);
|
false, true);
|
||||||
// TODO fb->type需要确定
|
KERNEL_TODO();
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,45 +13,36 @@ void raw_allocator_new(raw_allocator_t *allocator, usize size)
|
||||||
|
|
||||||
void *raw_allocator_allocate(raw_allocator_t *allocator, usize size, usize align)
|
void *raw_allocator_allocate(raw_allocator_t *allocator, usize size, usize align)
|
||||||
{
|
{
|
||||||
// 搜索
|
usize rsize = size;
|
||||||
|
align_to(rsize, 16);
|
||||||
raw_allocator_cell *cell = allocator->cells;
|
raw_allocator_cell *cell = allocator->cells;
|
||||||
while ((void *)cell < (void *)allocator + allocator->size &&
|
while ((void *)cell + cell->capacity + sizeof(raw_allocator_cell) < (void *)allocator + allocator->size)
|
||||||
cell->length != 0 && cell->capacity >= size)
|
|
||||||
{
|
{
|
||||||
cell = (void *)cell + sizeof(raw_allocator_cell) + cell->capacity;
|
while (
|
||||||
|
(void *)cell + cell->capacity + sizeof(raw_allocator_cell) < (void *)allocator + allocator->size &&
|
||||||
|
cell->length != 0)
|
||||||
|
{
|
||||||
|
cell = (void *)cell + cell->capacity + sizeof(raw_allocator_cell);
|
||||||
|
}
|
||||||
|
if (rsize <= cell->capacity)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
if ((void *)cell >= (void *)allocator + allocator->size)
|
if ((void *)cell < (void *)allocator + allocator->size)
|
||||||
|
goto fitable_cell_finded;
|
||||||
|
else
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
// 合并
|
fitable_cell_finded:
|
||||||
raw_allocator_cell *next_cell = (void *)cell + sizeof(raw_allocator_cell) + cell->capacity;
|
|
||||||
while ((void *)next_cell < (void *)allocator + allocator->size &&
|
|
||||||
next_cell->length == 0)
|
|
||||||
{
|
|
||||||
cell->capacity += sizeof(raw_allocator_cell) + next_cell->capacity;
|
|
||||||
next_cell = (void *)next_cell + sizeof(raw_allocator_cell) + next_cell->capacity;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 分割
|
|
||||||
usize allsize = sizeof(raw_allocator_cell) + size;
|
|
||||||
align_to(allsize, 16);
|
|
||||||
next_cell = (void *)cell + allsize;
|
|
||||||
if (allsize + sizeof(raw_allocator_cell) < sizeof(raw_allocator_cell) + cell->capacity)
|
|
||||||
{
|
|
||||||
usize nextsize = sizeof(raw_allocator_cell) + cell->capacity - allsize;
|
|
||||||
next_cell->capacity = nextsize - sizeof(raw_allocator_cell);
|
|
||||||
next_cell->length = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
allsize += 16;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 分配
|
|
||||||
cell->capacity = allsize - sizeof(raw_allocator_cell);
|
|
||||||
cell->length = size;
|
cell->length = size;
|
||||||
|
if (rsize < cell->capacity)
|
||||||
return &cell->content;
|
{
|
||||||
|
usize cap = cell->capacity;
|
||||||
|
cell->capacity = rsize;
|
||||||
|
raw_allocator_cell *ncell = (void *)cell + cell->capacity + sizeof(raw_allocator_cell);
|
||||||
|
ncell->capacity = cap - rsize - sizeof(raw_allocator_cell);
|
||||||
|
ncell->length = 0;
|
||||||
|
}
|
||||||
|
return cell->content;
|
||||||
}
|
}
|
||||||
|
|
||||||
void raw_allocator_free(raw_allocator_t *allocator, void *mem)
|
void raw_allocator_free(raw_allocator_t *allocator, void *mem)
|
||||||
|
|
|
@ -12,10 +12,10 @@ mem_manager_t *memm_new(usize mem_size)
|
||||||
memset(&memory_manager, 0, sizeof(memory_manager));
|
memset(&memory_manager, 0, sizeof(memory_manager));
|
||||||
memory_manager.memory_size = mem_size;
|
memory_manager.memory_size = mem_size;
|
||||||
memory_manager.page_amount = mem_size / MEMM_PAGE_SIZE;
|
memory_manager.page_amount = mem_size / MEMM_PAGE_SIZE;
|
||||||
|
memory_manager.alloc_only_memory = MEMM_ALLOC_ONLY_MEMORY;
|
||||||
|
|
||||||
usize kernel_initial_size = (usize)&kend;
|
usize kernel_initial_size = (usize)&kend;
|
||||||
align_to(kernel_initial_size, MEMM_PAGE_SIZE);
|
align_to(kernel_initial_size, MEMM_PAGE_SIZE);
|
||||||
memory_manager.alloc_only_memory = MEMM_ALLOC_ONLY_MEMORY;
|
|
||||||
|
|
||||||
// 配置分配器树
|
// 配置分配器树
|
||||||
allocator_t *allocator0 = memm_allocator_new(
|
allocator_t *allocator0 = memm_allocator_new(
|
||||||
|
@ -29,6 +29,7 @@ mem_manager_t *memm_new(usize mem_size)
|
||||||
alcatr_ind->allocator = allocator0;
|
alcatr_ind->allocator = allocator0;
|
||||||
alcatr_ind->left = nullptr;
|
alcatr_ind->left = nullptr;
|
||||||
alcatr_ind->right = nullptr;
|
alcatr_ind->right = nullptr;
|
||||||
|
alcatr_ind->owned_allocator = allocator0;
|
||||||
|
|
||||||
memory_manager.allocators = alcatr_ind;
|
memory_manager.allocators = alcatr_ind;
|
||||||
|
|
||||||
|
@ -81,8 +82,8 @@ allocator_t *memm_allocator_new(void *start, usize length, usize type, usize pid
|
||||||
{
|
{
|
||||||
case MEMM_RAW_ALLOCATOR:
|
case MEMM_RAW_ALLOCATOR:
|
||||||
raw_allocator_new((void *)allocator->allocator_instance, length - sizeof(allocator_t));
|
raw_allocator_new((void *)allocator->allocator_instance, length - sizeof(allocator_t));
|
||||||
allocator->allocate = &raw_allocator_allocate;
|
allocator->allocate = raw_allocator_allocate;
|
||||||
allocator->free = &raw_allocator_free;
|
allocator->free = raw_allocator_free;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
allocator->initialized = false;
|
allocator->initialized = false;
|
||||||
|
@ -171,16 +172,17 @@ void *memm_allocate(usize size, usize pid, allocator_t **allocator)
|
||||||
align_to(size, MEMM_PAGE_SIZE);
|
align_to(size, MEMM_PAGE_SIZE);
|
||||||
size /= MEMM_PAGE_SIZE;
|
size /= MEMM_PAGE_SIZE;
|
||||||
usize allocator_start = find_fitable_pages(size);
|
usize allocator_start = find_fitable_pages(size);
|
||||||
|
if (allocator_start == 0)
|
||||||
|
return nullptr; // 内存中已经没有可分配的页了
|
||||||
for (usize i = allocator_start; i < allocator_start + size; i++)
|
for (usize i = allocator_start; i < allocator_start + size; i++)
|
||||||
{
|
{
|
||||||
bitmap_set(memory_manager.map_with_allocator, i);
|
bitmap_set(memory_manager.map_with_allocator, i);
|
||||||
}
|
}
|
||||||
if (allocator_start == 0)
|
memm_map_pageframes_to(
|
||||||
return nullptr; // 内存中已经没有可分配的页了
|
allocator_start * MEMM_PAGE_SIZE, allocator_start * MEMM_PAGE_SIZE,
|
||||||
memm_map_pageframes_to(allocator_start * MEMM_PAGE_SIZE, allocator_start * MEMM_PAGE_SIZE,
|
size * MEMM_PAGE_SIZE,
|
||||||
size * MEMM_PAGE_SIZE,
|
false, // 用户空间标志
|
||||||
false, // 用户空间标志
|
true // 写权限
|
||||||
true // 写权限
|
|
||||||
);
|
);
|
||||||
|
|
||||||
// 在新映射的页中创建一个分配器
|
// 在新映射的页中创建一个分配器
|
||||||
|
|
|
@ -48,7 +48,7 @@ void bootinfo_new(bootinfo_t *bootinfo, void *bootinfo_addr)
|
||||||
{
|
{
|
||||||
bootinfo->map_counts[res.type] = true;
|
bootinfo->map_counts[res.type] = true;
|
||||||
}
|
}
|
||||||
else if (res.addr && bootinfo->map_counts[res.type] < 16)
|
else if (res.addr != nullptr && bootinfo->map_counts[res.type] < 16)
|
||||||
{ // 同类型tag数量只能16个以内
|
{ // 同类型tag数量只能16个以内
|
||||||
bootinfo->map[res.type][bootinfo->map_counts[res.type]++] = res.addr;
|
bootinfo->map[res.type][bootinfo->map_counts[res.type]++] = res.addr;
|
||||||
}
|
}
|
||||||
|
|
Reference in New Issue