aboutsummaryrefslogtreecommitdiff
path: root/src/kernel
diff options
context:
space:
mode:
authorMarvin Borner2020-04-18 17:45:30 +0200
committerMarvin Borner2020-04-18 17:45:30 +0200
commit54d848127e2026b710463508b1e6ca89c2b4b068 (patch)
tree73929602c8824bc6fa06236840b6cac664448241 /src/kernel
parent8d78616a2b80c7625c1aa9ca4733e48a8bf8bf22 (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.c45
-rw-r--r--src/kernel/acpi/acpi.h3
-rw-r--r--src/kernel/cmos/rtc.c10
-rw-r--r--src/kernel/kernel.c4
-rw-r--r--src/kernel/lib/lib.h2
-rw-r--r--src/kernel/lib/memory.c32
-rw-r--r--src/kernel/memory/paging.c10
-rw-r--r--src/kernel/memory/paging.h4
-rw-r--r--src/kernel/multiboot.c8
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;