修复内存分配器返回地址错误的问题,修复内核获取的内存大小与实际内存不能对应的问题
This commit is contained in:
parent
ed30e09f01
commit
325e0a01bd
|
@ -4,3 +4,4 @@
|
|||
*.map
|
||||
*.elf
|
||||
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
|
||||
* 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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 // 写权限
|
||||
);
|
||||
|
||||
// 在新映射的页中创建一个分配器
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Reference in New Issue