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

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 *.map
*.elf *.elf
metaverse_kernel 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 * 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

View File

@ -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

View File

@ -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();
} }

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) 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 ((void *)cell >= (void *)allocator + allocator->size) if (rsize <= cell->capacity)
break;
}
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)

View File

@ -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,13 +172,14 @@ 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 // 写权限

View File

@ -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;
} }