load multiboot memory map, heap is done!!!

This commit is contained in:
Murphy 2025-04-03 22:19:32 -04:00
parent 16b7b4c2c0
commit 876970bcfd
Signed by: freya
GPG key ID: 9FBC6FFD6D2DBF17
8 changed files with 236 additions and 15 deletions

View file

@ -32,6 +32,8 @@ const kernel_src = &[_][]const u8{
"kernel/cpu/pic.c", "kernel/cpu/pic.c",
"kernel/io/io.c", "kernel/io/io.c",
"kernel/io/panic.c", "kernel/io/panic.c",
"kernel/mboot/mboot.c",
"kernel/mboot/mmap.c",
"kernel/memory/memory.c", "kernel/memory/memory.c",
"kernel/memory/paging.c", "kernel/memory/paging.c",
"kernel/memory/physalloc.c", "kernel/memory/physalloc.c",

View file

@ -0,0 +1,16 @@
/**
* @file mboot.h
*
* @author Freya Murphy <freya@freyacat.org>
*
* Multiboot functions
*/
#ifndef MBOOT_H_
#define MBOOT_H_
#include <comus/memory.h>
void mboot_load_mmap(volatile void *mboot, struct memory_map *map);
#endif /* mboot.h */

View file

@ -1,12 +1,29 @@
#include <comus/cpu.h> #include <comus/cpu.h>
#include <comus/memory.h> #include <comus/memory.h>
#include <comus/mboot.h>
#include <lib.h> #include <lib.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h>
void main(void) struct memory_map mmap;
void main(long magic, volatile void *mboot)
{ {
(void) magic; // TODO: check multiboot magic
// initalize idt and pic
// WARNING: must be done before anything else
cpu_init(); cpu_init();
memory_init(NULL);
// load memory map
mboot_load_mmap(mboot, &mmap);
// initalize memory
memory_init(&mmap);
char *a = malloc(3);
*a = 3;
// halt
printf("halting...\n"); printf("halting...\n");
while(1);
} }

View file

@ -6,33 +6,30 @@ SECTIONS
kernel_start = .; kernel_start = .;
.boot : { . = ALIGN(0x1000);
.text : {
*(.multiboot) *(.multiboot)
*(.text)
} }
. = ALIGN(0x1000); . = ALIGN(0x1000);
.rodata : { .rodata : {
*(.rodata .rodata.* .gnu.linkonce.r.*) *(.rodata)
} }
. = ALIGN(0x1000); . = ALIGN(0x1000);
.text : { .data : {
*(.text .stub .text.* .gnu.linkonce.t.*) *(.data)
} }
. = ALIGN(0x1000); . = ALIGN(0x1000);
.bss : { .bss : {
*(COMMON) *(COMMON)
*(.bss .bss.*) *(.bss)
}
/DISCARD/ : {
*(.stab .stab_info .stabstr)
*(.eh_frame .eh_frame_hdr)
*(.note.GNU-stack .note.gnu.property .comment)
} }
kernel_end = .; kernel_end = .;

26
kernel/mboot/mboot.c Normal file
View file

@ -0,0 +1,26 @@
#include "mboot.h"
void *locate_mboot_table(volatile void *mboot, uint32_t type)
{
struct mboot_info *info = (struct mboot_info *) mboot;
const char *mboot_end = ((char *) info) + info->total_size;
char *tag_ptr = info->tags;
while (tag_ptr < mboot_end) {
struct mboot_tag *tag = (struct mboot_tag *) tag_ptr;
if (tag->type == type)
return tag;
// goto next
int size = tag->size;
if (size % 8 != 0) {
size += 8 - (size % 8);
}
tag_ptr += size;
}
return NULL;
}

106
kernel/mboot/mboot.h Normal file
View file

@ -0,0 +1,106 @@
/**
* @file mboot.h
*
* @author Freya Murphy <freya@freyacat.org>
*
* Internal multiboot structures
*/
#ifndef __MBOOT_H_
#define __MBOOT_H_
#include <lib.h>
#define MBOOT_HEADER_MAGIC 0x36D76289
#define MBOOT_CMDLINE 1
#define MBOOT_MEMORY_MAP 6
#define MBOOT_FRAMEBUFFER 8
#define MBOOT_ELF_SYMBOLS 9
#define MBOOT_OLD_RSDP 14
#define MBOOT_NEW_RSDP 15
struct mboot_info {
uint32_t total_size;
uint32_t reserved;
char tags[];
};
struct mboot_tag {
uint32_t type;
uint32_t size;
char data[];
};
struct mboot_tag_elf_sections {
uint32_t type;
uint32_t size;
uint16_t num;
uint16_t entsize;
uint16_t shndx;
uint16_t reserved;
char sections[];
};
struct mboot_tag_elf_sections_entry {
uint32_t sh_name;
uint32_t sh_type;
uint64_t sh_flags;
uint64_t sh_addr;
uint64_t sh_offset;
uint64_t sh_size;
uint32_t sh_link;
uint32_t sh_info;
uint64_t sh_addralign;
uint64_t sh_entsize;
};
struct mboot_mmap_entry {
uint64_t addr;
uint64_t len;
uint32_t type;
uint32_t zero;
};
struct mboot_tag_mmap {
uint32_t type;
uint32_t size;
uint32_t entry_size;
uint32_t entry_version;
struct mboot_mmap_entry entries[];
};
struct mboot_tag_old_rsdp {
uint32_t type;
uint32_t size;
char rsdp[];
};
struct mboot_tag_new_rsdp {
uint32_t type;
uint32_t size;
char rsdp[];
};
struct mboot_tag_cmdline {
uint32_t type;
uint32_t size;
uint8_t cmdline[];
};
struct mboot_tag_framebuffer {
uint32_t type;
uint32_t size;
uint64_t framebuffer_addr;
uint32_t framebuffer_pitch;
uint32_t framebuffer_width;
uint32_t framebuffer_height;
uint8_t framebuffer_bpp;
uint8_t framebuffer_type;
uint16_t reserved;
};
void *locate_mboot_table(volatile void *mboot, uint32_t type);
#endif /* mboot.h */

49
kernel/mboot/mmap.c Normal file
View file

@ -0,0 +1,49 @@
#include <lib.h>
#include <comus/mboot.h>
#include "mboot.h"
#include <stdint.h>
#include <stdio.h>
static const char *segment_type[] = {
"Reserved",
"Free",
"Reserved",
"ACPI Reserved",
"Hibernation",
"Defective",
"Unknown"
};
void mboot_load_mmap(volatile void *mboot, struct memory_map *res)
{
void *tag = locate_mboot_table(mboot, MBOOT_MEMORY_MAP);
struct mboot_tag_mmap *mmap = (struct mboot_tag_mmap *) tag;
int idx = 0;
uintptr_t i = (uintptr_t)mmap->entries;
printf("MEMORY MAP\n");
char buf[20];
for (;
i < (uintptr_t)mmap->entries + mmap->size;
i += mmap->entry_size, idx++
) {
struct mboot_mmap_entry *seg = (struct mboot_mmap_entry *) i;
const char *type = NULL;
if (seg->type > 6)
type = segment_type[6];
else
type = segment_type[seg->type];
printf("ADDR: %16p LEN: %4s TYPE: %s (%d)\n",
(void *)seg->addr,
btoa(seg->len, buf),
type,
seg->type
);
if (seg->type != 1 || seg->len < 1)
continue;
res->entries[idx].addr = seg->addr;
res->entries[idx].len = seg->len;
}
res->entry_count = idx;
}

View file

@ -1,3 +1,4 @@
#include <stddef.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdbool.h> #include <stdbool.h>
@ -389,7 +390,7 @@ static void do_printf(context_t *ctx, va_list args)
char c; char c;
while (c = *fmt++, c != '\0') { while (c = *fmt++, c != '\0') {
// save start of fmt for current iteration // save start of fmt for current iteration
const char *start = fmt; const char *start = fmt - 1;
// ignore if not % // ignore if not %
if (c != '%') { if (c != '%') {
@ -422,6 +423,12 @@ static void do_printf(context_t *ctx, va_list args)
// read data from args // read data from args
data_t data; data_t data;
switch (spec) { switch (spec) {
case 'p':
opts.len = PRINTF_LEN_SIZE_T;
opts.width_set = true;
opts.radix = 16;
opts.hash = true;
opts.zero = true;
case 'd': case 'd':
case 'i': case 'i':
case 'u': case 'u':
@ -470,6 +477,7 @@ static void do_printf(context_t *ctx, va_list args)
handle_int_specifier(ctx, &opts, true, data); handle_int_specifier(ctx, &opts, true, data);
break; break;
// unsigned int // unsigned int
case 'p':
case 'u': case 'u':
case 'o': case 'o':
case 'x': case 'x':