修复内存分配器返回地址错误的问题,修复内核获取的内存大小与实际内存不能对应的问题

This commit is contained in:
pointer-to-bios 2024-01-06 18:12:00 +08:00
parent ed30e09f01
commit 325e0a01bd
7 changed files with 59 additions and 53 deletions

1
.gitignore vendored
View File

@ -4,3 +4,4 @@
*.map
*.elf
metaverse_kernel
kerndisass.txt

View File

@ -134,7 +134,7 @@ typedef struct __bootinfo_elf_symbols_t
* 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.
*
* 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
* physical address.
* length is the size of the memory region in bytes.
@ -158,7 +158,7 @@ typedef struct __bootinfo_memory_map_t
u32 size;
u32 entry_size;
u32 entry_version;
struct bootinfo_memory_map_entry_t
struct __bootinfo_memory_map_entry_t
{
u64 base_addr;
u64 length;
@ -167,7 +167,9 @@ typedef struct __bootinfo_memory_map_t
} DISALIGNED entries[0];
} DISALIGNED bootinfo_memory_map_t;
#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
typedef struct __bootinfo_memory_map_entry_t bootinfo_memory_map_entry_t;
/** Boot loader name
* string contains the name of a boot loader booting the kernel. The name is a normal

View File

@ -21,7 +21,7 @@ multiboot2_header:
bootinfo_request_tag:
dd 1
dd bootinfo_request_tag_end - bootinfo_request_tag
dd 4 ; basic mamory info
dd 6 ; memory map
dd 1 ; boot command line
dd 8 ; framebuffer info
dd 12 ; efi64 system table pointer

View File

@ -3,6 +3,7 @@
#include <kernel/memm.h>
#include <libk/multiboot2.h>
#include <libk/math.h>
// 通过bootinfo获取临时的帧缓冲区信息
void get_frame_buffer_with_bootinfo(framebuffer *fb, bootinfo_t *bootinfo);
@ -16,12 +17,20 @@ void kmain(void *mb2_bootinfo)
// 获取内存信息
void **tags;
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();
}
bootinfo_basic_memory_info_t *meminfo = bootinfo_basic_memory_info(tags[0]);
usize mem_size = 1024 * 1024 + meminfo->mem_upper * 1024;
bootinfo_memory_map_t *meminfo = bootinfo_memory_map(tags[0]);
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);
@ -31,10 +40,11 @@ void kmain(void *mb2_bootinfo)
framebuffer fb;
get_frame_buffer_with_bootinfo(&fb, &bootinfo);
KERNEL_TODO();
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->height = fbinfo->framebuffer_height;
fb->pixsize = fbinfo->framebuffer_bpp / 8;
memm_map_pageframes_to(
memm_map_pageframes_to( // TODO 总共需要映射8MB空间但是它只映射了2MB
(u64)fb->pointer, (u64)fb->pointer,
fb->width * fb->height * fb->pixsize,
false, true);
// TODO fb->type需要确定
KERNEL_TODO();
}

View File

@ -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)
{
// 搜索
usize rsize = size;
align_to(rsize, 16);
raw_allocator_cell *cell = allocator->cells;
while ((void *)cell < (void *)allocator + allocator->size &&
cell->length != 0 && cell->capacity >= size)
while ((void *)cell + cell->capacity + sizeof(raw_allocator_cell) < (void *)allocator + allocator->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;
// 合并
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);
fitable_cell_finded:
cell->length = size;
return &cell->content;
if (rsize < cell->capacity)
{
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)

View File

@ -12,10 +12,10 @@ mem_manager_t *memm_new(usize mem_size)
memset(&memory_manager, 0, sizeof(memory_manager));
memory_manager.memory_size = mem_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;
align_to(kernel_initial_size, MEMM_PAGE_SIZE);
memory_manager.alloc_only_memory = MEMM_ALLOC_ONLY_MEMORY;
// 配置分配器树
allocator_t *allocator0 = memm_allocator_new(
@ -29,6 +29,7 @@ mem_manager_t *memm_new(usize mem_size)
alcatr_ind->allocator = allocator0;
alcatr_ind->left = nullptr;
alcatr_ind->right = nullptr;
alcatr_ind->owned_allocator = allocator0;
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:
raw_allocator_new((void *)allocator->allocator_instance, length - sizeof(allocator_t));
allocator->allocate = &raw_allocator_allocate;
allocator->free = &raw_allocator_free;
allocator->allocate = raw_allocator_allocate;
allocator->free = raw_allocator_free;
break;
default:
allocator->initialized = false;
@ -171,16 +172,17 @@ void *memm_allocate(usize size, usize pid, allocator_t **allocator)
align_to(size, MEMM_PAGE_SIZE);
size /= MEMM_PAGE_SIZE;
usize allocator_start = find_fitable_pages(size);
if (allocator_start == 0)
return nullptr; // 内存中已经没有可分配的页了
for (usize i = allocator_start; i < allocator_start + size; i++)
{
bitmap_set(memory_manager.map_with_allocator, i);
}
if (allocator_start == 0)
return nullptr; // 内存中已经没有可分配的页了
memm_map_pageframes_to(allocator_start * MEMM_PAGE_SIZE, allocator_start * MEMM_PAGE_SIZE,
size * MEMM_PAGE_SIZE,
false, // 用户空间标志
true // 写权限
memm_map_pageframes_to(
allocator_start * MEMM_PAGE_SIZE, allocator_start * MEMM_PAGE_SIZE,
size * MEMM_PAGE_SIZE,
false, // 用户空间标志
true // 写权限
);
// 在新映射的页中创建一个分配器

View File

@ -48,7 +48,7 @@ void bootinfo_new(bootinfo_t *bootinfo, void *bootinfo_addr)
{
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个以内
bootinfo->map[res.type][bootinfo->map_counts[res.type]++] = res.addr;
}