diff options
author | Marvin Borner | 2020-04-18 17:45:30 +0200 |
---|---|---|
committer | Marvin Borner | 2020-04-18 17:45:30 +0200 |
commit | 54d848127e2026b710463508b1e6ca89c2b4b068 (patch) | |
tree | 73929602c8824bc6fa06236840b6cac664448241 /src/kernel | |
parent | 8d78616a2b80c7625c1aa9ca4733e48a8bf8bf22 (diff) |
I don't know HOW I did it, but it works!
I finally fixed the acpi tables with some memory mapping magic and
paging allocations, which seems to do the trick. YAY.
Diffstat (limited to 'src/kernel')
-rw-r--r-- | src/kernel/acpi/acpi.c | 45 | ||||
-rw-r--r-- | src/kernel/acpi/acpi.h | 3 | ||||
-rw-r--r-- | src/kernel/cmos/rtc.c | 10 | ||||
-rw-r--r-- | src/kernel/kernel.c | 4 | ||||
-rw-r--r-- | src/kernel/lib/lib.h | 2 | ||||
-rw-r--r-- | src/kernel/lib/memory.c | 32 | ||||
-rw-r--r-- | src/kernel/memory/paging.c | 10 | ||||
-rw-r--r-- | src/kernel/memory/paging.h | 4 | ||||
-rw-r--r-- | src/kernel/multiboot.c | 8 |
9 files changed, 82 insertions, 36 deletions
diff --git a/src/kernel/acpi/acpi.c b/src/kernel/acpi/acpi.c index b348613..d58e017 100644 --- a/src/kernel/acpi/acpi.c +++ b/src/kernel/acpi/acpi.c @@ -10,35 +10,62 @@ #include <kernel/lib/stdio.h> #include <kernel/acpi/acpi.h> #include <kernel/memory/paging.h> +#include <kernel/memory/alloc.h> struct rsdt *rsdt; struct fadt *fadt; struct hpet *hpet; -struct apic *apic; +struct madt *madt; + +int check_sum(struct sdt_header *header) +{ + uint8_t sum = 0; + + for (uint32_t i = 0; i < header->length; i++) + sum += ((char *)header)[i]; + + return sum == 0; +} void acpi_init(struct rsdp *rsdp) { - // TODO: Fix usage of ACPI tables after paging! + struct sdt_header *header = (struct sdt_header *)kmalloc(sizeof(struct sdt_header)); + rsdt = (struct rsdt *)kmalloc(sizeof(struct rsdt)); + fadt = (struct fadt *)kmalloc(sizeof(struct fadt)); + hpet = (struct hpet *)kmalloc(sizeof(struct hpet)); + madt = (struct madt *)kmalloc(sizeof(struct madt)); + if (strncmp(rsdp->signature, "RSD PTR ", 8) == 0) { - rsdt = (struct rsdt *)rsdp->rsdt_address; - int entries = (rsdt->header.length - sizeof(rsdt->header)) / 4; + memcpy(rsdt, rsdp->rsdt_address, sizeof(struct rsdt) + 32); + + uint32_t *pointer = (uint32_t *)(rsdt + 1); + uint32_t *end = (uint32_t *)((uint8_t *)rsdt + rsdt->header.length); + + while (pointer < end) { + uint32_t address = *pointer++; + memcpy(header, (void *)address, sizeof(struct sdt_header)); - for (int i = 0; i < entries; i++) { - struct sdt_header *header = (struct sdt_header *)rsdt->sdt_pointer[i]; if (strncmp(header->signature, "FACP", 4) == 0) { info("Found FADT"); - fadt = (struct fadt *)header; + memcpy(fadt, (void *)address, sizeof(struct fadt)); + if (!check_sum((struct sdt_header *)fadt)) + warn("Corrupted FADT!"); } else if (strncmp(header->signature, "HPET", 4) == 0) { info("Found HPET"); - hpet = (struct hpet *)header; + memcpy(hpet, (void *)address, sizeof(struct hpet)); + if (!check_sum((struct sdt_header *)hpet)) + warn("Corrupted HPET!"); } else if (strncmp(header->signature, "APIC", 4) == 0) { info("Found MADT"); - apic = (struct apic *)header; + memcpy(madt, (void *)address, sizeof(struct madt)); + if (!check_sum((struct sdt_header *)madt)) + warn("Corrupted MADT!"); // This is currently okay } } } else { warn("Wrong RSD signature!"); } + kfree(header); } void acpi_old_init(struct multiboot_tag_old_acpi *tag) diff --git a/src/kernel/acpi/acpi.h b/src/kernel/acpi/acpi.h index 886dc6c..c9df040 100644 --- a/src/kernel/acpi/acpi.h +++ b/src/kernel/acpi/acpi.h @@ -50,12 +50,11 @@ struct sdt_header { struct rsdt { struct sdt_header header; - uint32_t sdt_pointer[0]; }; struct xsdt { struct sdt_header header; - uint32_t sdt_pointer[0]; + uint32_t *sdt_pointer; }; struct fadt { diff --git a/src/kernel/cmos/rtc.c b/src/kernel/cmos/rtc.c index 6108a1e..c995be2 100644 --- a/src/kernel/cmos/rtc.c +++ b/src/kernel/cmos/rtc.c @@ -24,7 +24,6 @@ uint8_t get_rtc_register(int reg) void read_rtc() { - halt_loop(); unsigned int century = 20; // ... uint8_t last_second; uint8_t last_minute; @@ -37,15 +36,13 @@ void read_rtc() while (get_update_in_progress_flag()) { }; - halt_loop(); second = get_rtc_register(0x00); minute = get_rtc_register(0x02); hour = get_rtc_register(0x04); day = get_rtc_register(0x07); month = get_rtc_register(0x08); year = get_rtc_register(0x09); - halt_loop(); - // century = get_rtc_register(fadt->century); // TODO: Fix fadt table (page fault!) + century = get_rtc_register(fadt->century); // Try until the values are the same (fix for RTC updates) do { @@ -65,7 +62,7 @@ void read_rtc() day = get_rtc_register(0x07); month = get_rtc_register(0x08); year = get_rtc_register(0x09); - // century = get_rtc_register(fadt->century); + century = get_rtc_register(fadt->century); } while ((last_second != second) || (last_minute != minute) || (last_hour != hour) || (last_day != day) || (last_month != month) || (last_year != year) || (last_century != century)); @@ -79,7 +76,7 @@ void read_rtc() day = (uint8_t)((day & 0x0F) + ((day / 16) * 10)); month = (uint8_t)((month & 0x0F) + ((month / 16) * 10)); year = (year & 0x0F) + ((year / 16) * 10); - // century = (century & 0x0F) + ((century / 16) * 10); + century = (century & 0x0F) + ((century / 16) * 10); } year += century * 100; @@ -92,7 +89,6 @@ void read_rtc() void rtc_print() { - log("%d", fadt->century); read_rtc(); info("Current time: %d:%d:%d %d/%d/%d", hour, minute, second, month, day, year); } diff --git a/src/kernel/kernel.c b/src/kernel/kernel.c index 40d11b9..d3806fa 100644 --- a/src/kernel/kernel.c +++ b/src/kernel/kernel.c @@ -41,8 +41,8 @@ void kernel_main(uint32_t magic, uint32_t multiboot_address) isrs_install(); irq_install(); + paging_install(multiboot_address); multiboot_parse(multiboot_address); - paging_install(); // Install drivers cli(); @@ -54,7 +54,7 @@ void kernel_main(uint32_t magic, uint32_t multiboot_address) sti(); memory_print(); - //rtc_print(); // TODO: Fix ACPI memory mapping! + rtc_print(); vfs_init(); ata_init(); diff --git a/src/kernel/lib/lib.h b/src/kernel/lib/lib.h index e107da6..986e522 100644 --- a/src/kernel/lib/lib.h +++ b/src/kernel/lib/lib.h @@ -36,6 +36,8 @@ void memory_info_init(struct multiboot_tag_basic_meminfo *tag); void memory_mmap_init(struct multiboot_tag_mmap *tag); +int memory_init(uint32_t multiboot_address); + void memory_print(); uint32_t memory_get_all(); diff --git a/src/kernel/lib/memory.c b/src/kernel/lib/memory.c index b571b83..3901c39 100644 --- a/src/kernel/lib/memory.c +++ b/src/kernel/lib/memory.c @@ -80,12 +80,40 @@ void memory_mmap_init(struct multiboot_tag_mmap *tag) mmap = (multiboot_memory_map_t *)((uint32_t)mmap + ((struct multiboot_tag_mmap *)tag)->entry_size)) { if (mmap->type == MULTIBOOT_MEMORY_AVAILABLE) { + log("Found free memory"); + paging_set_present(mmap->addr, mmap->len >> 12); sum += mmap->len; + } else if (mmap->type == MULTIBOOT_MEMORY_RESERVED) { + log("Found reserved memory"); + paging_set_present(mmap->addr, mmap->len >> 12); + paging_set_used(mmap->addr, mmap->len >> 12); } else if (mmap->type == MULTIBOOT_MEMORY_ACPI_RECLAIMABLE) { - log("ACPI reclaimable memory"); + log("Found ACPI reclaimable memory"); + } else if (mmap->type == MULTIBOOT_MEMORY_NVS) { + log("Found NVS memory"); } else if (mmap->type == MULTIBOOT_MEMORY_BADRAM) { - warn("Bad memory!"); + warn("Found bad memory!"); } } total = sum >> 10; // I want kb } + +int memory_init(uint32_t multiboot_address) +{ + int ret = 0; + struct multiboot_tag *tag; + + for (tag = (struct multiboot_tag *)(multiboot_address + 8); + tag->type != MULTIBOOT_TAG_TYPE_END; + tag = (struct multiboot_tag *)((multiboot_uint8_t *)tag + ((tag->size + 7) & ~7))) { + if (tag->type == MULTIBOOT_TAG_TYPE_BASIC_MEMINFO) { + info("Got memory info"); + memory_info_init((struct multiboot_tag_basic_meminfo *)tag); + } else if (tag->type == MULTIBOOT_TAG_TYPE_MMAP) { + info("Got memory map"); + memory_mmap_init((struct multiboot_tag_mmap *)tag); + ret = 1; + } + } + return ret; +} diff --git a/src/kernel/memory/paging.c b/src/kernel/memory/paging.c index 4b87540..38ed4a7 100644 --- a/src/kernel/memory/paging.c +++ b/src/kernel/memory/paging.c @@ -25,11 +25,9 @@ void paging_init() for (uint32_t i = 0; i < 1024; i++) { current_page_directory[i] = ((uint32_t)current_page_tables[i]) | PD_RW | PD_PRESENT; } - - paging_set_present(0, memory_get_all() >> 3); // /4 } -void paging_install() +void paging_install(uint32_t multiboot_address) { // User paging //paging_switch_directory(1); @@ -39,10 +37,14 @@ void paging_install() // Kernel paging paging_switch_directory(0); paging_init(); + + // if mmap approach didn't work + if (!memory_init(multiboot_address)) + paging_set_present(0, memory_get_all() >> 3); // /4 paging_set_used(0, ((uint32_t)ASM_KERNEL_END >> 12) + 1); // /4096 paging_enable(); - vga_log("Installed paging"); + log("Installed paging"); } void paging_disable() diff --git a/src/kernel/memory/paging.h b/src/kernel/memory/paging.h index 5836430..1578e2a 100644 --- a/src/kernel/memory/paging.h +++ b/src/kernel/memory/paging.h @@ -25,7 +25,7 @@ int paging_enabled; uint32_t *current_page_directory; -void paging_install(); +void paging_install(uint32_t multiboot_address); void paging_enable(); @@ -61,4 +61,4 @@ uint32_t paging_alloc_pages(uint32_t count); uint32_t paging_get_used_pages(); -#endif
\ No newline at end of file +#endif diff --git a/src/kernel/multiboot.c b/src/kernel/multiboot.c index 01a2f66..8f20662 100644 --- a/src/kernel/multiboot.c +++ b/src/kernel/multiboot.c @@ -24,17 +24,9 @@ void multiboot_parse(uint32_t multiboot_address) case MULTIBOOT_TAG_TYPE_MODULE: info("Got modules"); break; - case MULTIBOOT_TAG_TYPE_BASIC_MEMINFO: - info("Got memory info"); - memory_info_init((struct multiboot_tag_basic_meminfo *)tag); - break; case MULTIBOOT_TAG_TYPE_BOOTDEV: info("Got boot device"); break; - case MULTIBOOT_TAG_TYPE_MMAP: - info("Got memory map"); - memory_mmap_init((struct multiboot_tag_mmap *)tag); - break; case MULTIBOOT_TAG_TYPE_VBE: info("Got VBE info"); break; |