diff options
author | Freya Murphy <freya@freyacat.org> | 2024-01-31 12:49:06 -0500 |
---|---|---|
committer | Freya Murphy <freya@freyacat.org> | 2024-01-31 12:49:06 -0500 |
commit | 50fee8495e9329081067e9eb91f7e0ad9adc4025 (patch) | |
tree | 351790da66d5a795462618e768f077e071e4d444 /src/arch/amd64 | |
parent | disable wip code (diff) | |
download | corn-50fee8495e9329081067e9eb91f7e0ad9adc4025.tar.gz corn-50fee8495e9329081067e9eb91f7e0ad9adc4025.tar.bz2 corn-50fee8495e9329081067e9eb91f7e0ad9adc4025.zip |
better mboot and kalloc
Diffstat (limited to 'src/arch/amd64')
-rw-r--r-- | src/arch/amd64/acpi.c | 27 | ||||
-rw-r--r-- | src/arch/amd64/linker.ld | 13 | ||||
-rw-r--r-- | src/arch/amd64/mboot.c | 246 | ||||
-rw-r--r-- | src/arch/amd64/paging.c | 6 |
4 files changed, 242 insertions, 50 deletions
diff --git a/src/arch/amd64/acpi.c b/src/arch/amd64/acpi.c index 61083f4..732add7 100644 --- a/src/arch/amd64/acpi.c +++ b/src/arch/amd64/acpi.c @@ -5,6 +5,7 @@ #include <stddef.h> #include "bindings.h" +#include "memory.h" #include "serial.h" /* global state, idk a better way rn */ @@ -51,7 +52,7 @@ struct xsdp { // ACPI 1.0 struct rsdt { struct acpi_header h; - uint64_t sdt_pointers[]; + uint32_t sdt_pointers[]; }; // eXtended system descriptor table @@ -140,6 +141,11 @@ struct fadt { }; struct acpi_state { + union { + struct xsdt *xsdt; + struct rsdt *rsdt; + } dst; + uint8_t version; struct fadt fadt; uint16_t SLP_TYPa; uint16_t SLP_TYPb; @@ -196,10 +202,15 @@ static int read_s5_addr(struct acpi_state *state) { } static void *acpi_find_table_rsdt(struct rsdt *rsdt, const char *identifier, int ident_len) { - int entries = (rsdt->h.length - sizeof(rsdt->h)) / 8; + int entries = (rsdt->h.length - sizeof(rsdt->h)) / 4; for (int i = 0; i < entries; i++) { struct acpi_header *h = (struct acpi_header *) (uintptr_t) rsdt->sdt_pointers[i]; + char buf[6]; + memcpy(buf, h->signature, 4); + buf[4] = '\n'; + buf[5] = '\0'; + serial_out_str(buf); if (!strncmp(h->signature, identifier, ident_len)) return (void *)h; } @@ -222,6 +233,11 @@ static void *acpi_find_table_xsdt(struct xsdt *xsdt, const char *identifier, int } int acpi_init_rsdt(struct rsdt *rsdt) { + rsdt = mmap(rsdt, sizeof(struct rsdt)); + + state.dst.rsdt = rsdt; + state.version = 0; + if (!checksum((uint8_t *) &rsdt->h, rsdt->h.length)) return -1; @@ -238,6 +254,11 @@ int acpi_init_rsdt(struct rsdt *rsdt) { } int acpi_init_xsdt(struct xsdt *xsdt) { + + xsdt = mmap(xsdt, sizeof(struct xsdt)); + state.dst.xsdt = xsdt; + state.version = 2; + if (!checksum((uint8_t *) &xsdt->h, xsdt->h.length)) return -1; @@ -256,7 +277,7 @@ int acpi_init_xsdt(struct xsdt *xsdt) { int acpi_init(void *rootsdp) { struct rsdp *rsdp = (struct rsdp *) rootsdp; - if (!checksum((uint8_t *)rsdp, sizeof(struct xsdp))) + if (!checksum((uint8_t *)rsdp, sizeof(struct rsdp))) return -1; int res; diff --git a/src/arch/amd64/linker.ld b/src/arch/amd64/linker.ld index 3dd90ff..a9484d4 100644 --- a/src/arch/amd64/linker.ld +++ b/src/arch/amd64/linker.ld @@ -1,8 +1,12 @@ ENTRY(start) +PHDRS { + loadable PT_LOAD FLAGS(7) ; +} + SECTIONS { . = 1M; - + kernel_start = .; .boot BLOCK(4K) : ALIGN(4K) @@ -24,6 +28,11 @@ SECTIONS { { *(.bss) } - + + .symtab : { + symtab = .; + *(.symtab) + } :loadable + kernel_end = .; } diff --git a/src/arch/amd64/mboot.c b/src/arch/amd64/mboot.c index 89fb431..7fd3f62 100644 --- a/src/arch/amd64/mboot.c +++ b/src/arch/amd64/mboot.c @@ -1,71 +1,227 @@ #include "mboot.h" +#include "serial.h" #include "shim.h" #include <lib.h> +#include <stdint.h> + +extern char symtab; +#define kaddr(addr) ((uintptr_t)(&addr)) + +typedef unsigned char mboot_uint8_t; +typedef unsigned short mboot_uint16_t; +typedef unsigned int mboot_uint32_t; +typedef unsigned long long mboot_uint64_t; + +struct mboot_info { + mboot_uint32_t total_size; + mboot_uint32_t reserved; + char tags[]; +}; + +struct mboot_tag { + mboot_uint32_t type; + mboot_uint32_t size; + char data[]; +}; enum mboot_tag_type { MBOOT_CMDLINE = 0, MBOOT_MEMORYMAP = 6, MBOOT_SYMBOLS = 9, - MBOOT_XSDP = 14 + MBOOT_RSDP = 14, + MBOOT_XSDP = 15, }; -static void read_cmdline(struct boot_info *shim_info, char *data, uint8_t len) { - if (len >= CMDLINE_MAX) - len = CMDLINE_MAX; // truncate :( - memcpy(shim_info->cmdline, data, len); - shim_info->cmdline[len] = '\0'; -} +struct mboot_elf_header_layout { + mboot_uint32_t type; + mboot_uint32_t size; + mboot_uint32_t num; + mboot_uint32_t entsize; + mboot_uint32_t shndx; + char elf_section_headers[]; +}; -static void read_memorymap(struct boot_info *shim_info, uint64_t size, uint32_t *data) { - shim_info->map = (struct memory_map *) data; - shim_info->map->size = size; -} +struct mboot_elf_section_header { + mboot_uint32_t sh_name; + mboot_uint32_t sh_type; + mboot_uint64_t sh_flags; + mboot_uint64_t sh_addr; + mboot_uint64_t sh_offset; + mboot_uint64_t sh_size; + mboot_uint32_t sh_link; + mboot_uint32_t sh_info; + mboot_uint64_t sh_addralign; + mboot_uint64_t sh_entsize; +}; -static void read_xsdp(struct boot_info *shim_info, char *data) { - shim_info->acpi_table = (void *) data; -} +struct mboot_memory_segment { + mboot_uint64_t addr; + mboot_uint64_t len; + mboot_uint32_t type; + mboot_uint32_t reserved; +}; -static uint32_t *read_tag(uint32_t *data, struct boot_info *shim_info) { +struct mboot_memory_map { + mboot_uint32_t tag; + mboot_uint32_t size; + mboot_uint32_t entry_size; + mboot_uint32_t entry_version; + struct memory_segment entries[]; +}; + +struct mboot_rsdp { + mboot_uint32_t tag; + mboot_uint32_t size; + mboot_uint8_t rsdp[]; +}; - uint16_t type = *((uint16_t *)data); - uint32_t size = data[1]; +struct mboot_xsdp { + mboot_uint32_t tag; + mboot_uint32_t size; + mboot_uint8_t xsdp[]; +}; - uint8_t data_len = size - 2 * sizeof(uint32_t); +struct mboot_cmdline { + mboot_uint32_t tag; + mboot_uint32_t size; + char cmdline[]; +}; - switch (type) { - case MBOOT_CMDLINE: - read_cmdline(shim_info, (char *)(data + 2), data_len); - break; - case MBOOT_MEMORYMAP: - read_memorymap(shim_info, size, data + 2); - break; - case MBOOT_SYMBOLS: - shim_info->symbol_table = (void *) (data + 2); - break; - case MBOOT_XSDP: - read_xsdp(shim_info, (char *) (data + 2)); - break; - default: - break; - } +static void read_symbols( + struct boot_info *shim_info, + struct mboot_elf_header_layout *layout +) { - if(size % 8 != 0) { - size += 8 - (size % 8); - } + shim_info->symbol_table = layout->elf_section_headers; - return data + size / sizeof(uint32_t); +// struct mboot_elf_section_header *section = +// (struct mboot_elf_section_header *) (layout->elf_section_headers); +// +// for (mboot_uint32_t i = 0; i < layout->num; i++) { +// char buf[20]; +// +// ultoa(i, buf, 10); +// serial_out_str("["); +// serial_out_str(buf); +// serial_out_str("]\t"); +// +// serial_out_str((char *)(kaddr(symtab) + section->sh_name)); +// serial_out('\t'); +// +// ultoa(section->sh_type, buf, 16); +// serial_out_str("type: 0x"); +// serial_out_str(buf); +// serial_out('\t'); +// +// ultoa(section->sh_addr, buf, 16); +// serial_out_str("addr: 0x"); +// serial_out_str(buf); +// serial_out('\t'); +// +// ultoa(section->sh_offset, buf, 16); +// serial_out_str("offset: 0x"); +// serial_out_str(buf); +// serial_out('\n'); +// +// section++; +// } +} + +static void read_cmdline( + struct boot_info *shim_info, + struct mboot_cmdline *cmdline +) { + mboot_uint32_t size = cmdline->size - 8; + if (size >= CMDLINE_MAX) + size = CMDLINE_MAX; // truncate :( + memcpy(shim_info->cmdline, cmdline->cmdline, size); + shim_info->cmdline[size] = '\0'; +} + +static void read_memorymap( + struct boot_info *shim_info, + struct mboot_memory_map *map +) { + int size = map->size - sizeof(mboot_uint32_t) * 4; + int count = size / map->entry_size; + + shim_info->map.entry_count = count; + shim_info->map.entry_length = map->entry_size; + shim_info->map.entries = map->entries; +} + +static void read_rsdp( + struct boot_info *shim_info, + struct mboot_rsdp *rsdp +) { + if (shim_info->acpi_table != NULL) + return; // xsdp is newer and has been loaded + shim_info->acpi_table = rsdp->rsdp; +} + +static void read_xsdp( + struct boot_info *shim_info, + struct mboot_xsdp *xsdp +) { + shim_info->acpi_table = xsdp->xsdp; } void mboot_load_info( - const void *mboot_info, + const void *mboot_data_ptr, struct boot_info *shim_info ) { - uint32_t* data = (uint32_t*) mboot_info; - uint32_t total_size = *data++; - data++; //reserved - while((uint8_t*) data < (uint8_t*) mboot_info + total_size) { - data = read_tag(data, shim_info); - } + memset(shim_info, 0, sizeof(struct boot_info)); + + struct mboot_info *mboot_info = (struct mboot_info *) mboot_data_ptr; + const char *mboot_end = ((char *) mboot_info) + mboot_info->total_size; + + char *tag_ptr = mboot_info->tags; + + while (tag_ptr < mboot_end) { + struct mboot_tag *tag = (struct mboot_tag *) tag_ptr; + + switch (tag->type) { + case MBOOT_CMDLINE: + read_cmdline( + shim_info, + (struct mboot_cmdline *) tag + ); + break; + case MBOOT_MEMORYMAP: + read_memorymap( + shim_info, + (struct mboot_memory_map *) tag + ); + break; + case MBOOT_SYMBOLS: + read_symbols( + shim_info, + (struct mboot_elf_header_layout *) tag + ); + break; + case MBOOT_RSDP: + read_rsdp( + shim_info, + (struct mboot_rsdp *) tag + ); + break; + case MBOOT_XSDP: + read_xsdp( + shim_info, + (struct mboot_xsdp *) tag + ); + break; + default: + break; + } + + int size = tag->size; + if (size % 8 != 0) { + size += 8 - (size % 8); + } + + tag_ptr += size; + } } diff --git a/src/arch/amd64/paging.c b/src/arch/amd64/paging.c index 453af9d..3ea79f1 100644 --- a/src/arch/amd64/paging.c +++ b/src/arch/amd64/paging.c @@ -1,3 +1,4 @@ +#include <panic.h> #include <cpuid.h> #include <stdint.h> #include <lib.h> @@ -568,6 +569,11 @@ void *alloc_pages(int count) { } void free_page(void *virt) { + (void) virt; + panic("free_page is not yet implemented"); +} + +void free_pages(void *virt) { long pages = virtaddr_free(virt); if (pages < 1) return; |