From edcfd676bfbdac187dbd872b7527d485d41ff1ae Mon Sep 17 00:00:00 2001 From: rami Date: Mon, 27 May 2024 14:18:37 -0400 Subject: [PATCH] cleanup 2 --- include/kernel/acpi.h | 3 + include/kernel/idt.h | 2 + include/kernel/ps2.h | 3 +- src/acpi.c | 60 ++++++++++++++++ src/idt.c | 23 +++++++ src/kmain.c | 155 ++++++++---------------------------------- src/ps2.c | 2 +- 7 files changed, 117 insertions(+), 131 deletions(-) diff --git a/include/kernel/acpi.h b/include/kernel/acpi.h index 015c6e2..4fcc764 100644 --- a/include/kernel/acpi.h +++ b/include/kernel/acpi.h @@ -133,4 +133,7 @@ int acpi_validate_sdt_checksum(struct ACPISDTHeader *s); struct ACPISDTHeader *acpi_find_table(struct rsdt *root, const char *signature); void *acpi_locate_sdt(struct rsdt *rsdt, const char sig[4]); +struct kernel_context; +int acpi_init(struct kernel_context *ctx); + #endif diff --git a/include/kernel/idt.h b/include/kernel/idt.h index ab00b62..08d4f1c 100644 --- a/include/kernel/idt.h +++ b/include/kernel/idt.h @@ -49,4 +49,6 @@ void encode_idt_entry(struct idt_entry idt[], int i, uint32_t offset, uint16_t s void flush_idt(uint32_t idt_pointer); void exception_handler(struct registers regs); +void interrupts_init(struct idt_entry idt[], struct idtr idtr); + #endif diff --git a/include/kernel/ps2.h b/include/kernel/ps2.h index bea23a4..799bf8d 100644 --- a/include/kernel/ps2.h +++ b/include/kernel/ps2.h @@ -108,8 +108,7 @@ #define KBD_INSERT2 0xD2 #define KBD_DELETE2 0xD3 -void initialize_8042ps2(); -extern void ps2_isr(); +void ps2_init(); void ps2_handler(); #endif diff --git a/src/acpi.c b/src/acpi.c index 7141150..f071834 100644 --- a/src/acpi.c +++ b/src/acpi.c @@ -1,5 +1,8 @@ #include #include +#include +#include +#include struct rsdp *acpi_locate_rsdp() { char *ptr = (char *)BIOS_START; @@ -55,3 +58,60 @@ void *acpi_locate_sdt(struct rsdt *rsdt, const char sig[4]) { return 0; } + +int acpi_init(struct kernel_context *ctx) { + struct rsdp *found_rsdp = acpi_locate_rsdp(); + if (!found_rsdp) { + set_color(VGA_COLOR_RED); + printf("Failed to find RSDP signature\n"); + return 0; + } + + if (found_rsdp->Revision == ACPI_VER_1) { + if (!acpi_validate_rsdp_checksum(found_rsdp)) { + set_color(VGA_COLOR_RED); + printf("RSDP has an invalid checksum\n"); + return 0; + } + ctx->rsdp = found_rsdp; + ctx->xsdp = 0; + + if (!acpi_validate_sdt_checksum((struct ACPISDTHeader *)found_rsdp->RsdtAddress)) { + set_color(VGA_COLOR_RED); + printf("RSDT has an invalid checksum\n"); + return 0; + } + + ctx->rsdt = (struct rsdt*)found_rsdp->RsdtAddress; + + } else if (found_rsdp->Revision == ACPI_VER_OTHER) { + set_color(VGA_COLOR_RED); + printf("ACPI versions higher than 1.0 are not yet supported because I'm lazy\n"); + return 0; + } else { + set_color(VGA_COLOR_RED); + printf("Invalid RSDP\n"); + return 0; + } + + printf("[KERNEL] Using ACPI v1.0\n"); + + struct fadt *fadt = acpi_locate_sdt(ctx->rsdt, "FACP"); + if (!fadt) { + set_color(VGA_COLOR_RED); + printf("Failed to find FADT\n"); + return 0; + } + printf("[KERNEL] Found FADT at 0x%x\n", fadt); + if (fadt->Flags & 1) + printf("[KERNEL] Legacy devices are supported\n"); + else { + /* + set_color(VGA_COLOR_RED); + printf("Legacy devices are not supported. I'm too lazy to support modern devices, bye bye.\n"); + goto halt; + */ + } + + return 1; +} diff --git a/src/idt.c b/src/idt.c index a16fb8e..9badcbb 100644 --- a/src/idt.c +++ b/src/idt.c @@ -1,6 +1,8 @@ #include #include #include +#include +#include void encode_idt_entry(struct idt_entry idt[], int i, uint32_t offset, uint16_t segment_selector, uint8_t attributes) { idt[i].offset_lo = (uint16_t)(offset & 0xFFFF); @@ -10,6 +12,27 @@ void encode_idt_entry(struct idt_entry idt[], int i, uint32_t offset, uint16_t s idt[i].offset_hi = (uint16_t)(offset >> 16); } +extern uint32_t isr_stub_table[32]; +extern void ps2_isr(); +extern void syscall_isr(); +void interrupts_init(struct idt_entry idt[], struct idtr idtr) { + for (int i = 0; i < 32; i++) { + encode_idt_entry(idt, i, isr_stub_table[i], GDT_SEGMENT_SELECTOR(GDT_KERNEL_CODE, 0x00), TRAP_GATE_32 | INT_RING0 | INT_PRESENT); + } + + encode_idt_entry(idt, 0x21, (uint32_t)&ps2_isr, GDT_SEGMENT_SELECTOR(GDT_KERNEL_CODE, RING0), INT_GATE_32 | INT_RING0 | INT_PRESENT); + encode_idt_entry(idt, 0x80, (uint32_t)&syscall_isr, GDT_SEGMENT_SELECTOR(GDT_USER_CODE, RING3), INT_GATE_32 | INT_RING3 | INT_PRESENT); + + idtr.size = (sizeof(struct idt_entry) * 256) - 1; + idtr.base = (uint32_t) idt; + + asm volatile ("lidt %0" :: "m"(idtr)); + + pic_remap(PIC_1_START, PIC_2_START); + + asm volatile ("sti" ::); +} + void exception_handler(struct registers regs) { clear_screen(); diff --git a/src/kmain.c b/src/kmain.c index cf7024a..cd67f6e 100644 --- a/src/kmain.c +++ b/src/kmain.c @@ -19,16 +19,10 @@ struct kernel_context ctx = {0}; struct idt_entry g_idt[256] = {0}; struct idtr g_idtr = {0}; -extern uint32_t isr_stub_table[32]; -extern void ps2_isr(); extern struct gdt_entry gdt[6]; -extern void syscall_isr(); extern void syscall(); extern void test(); -linked_mem_t stdout = {0}; -linked_mem_t stdin = {0}; - struct tss_entry tss; struct stack_frame { @@ -37,13 +31,13 @@ struct stack_frame { void syscall_read(struct stack_frame regs) { uint32_t fd = regs.edi; - char *buf = (char *)regs.esi; + // char *buf = (char *)regs.esi; uint32_t count = regs.edx; if (fd == FD_STDOUT) { int pages = count / BLOCK_SIZE; if (pages == 0) { - memcpy(buf, stdout.data, count); +// memcpy(buf, stdout.data, count); } } } @@ -83,123 +77,9 @@ void switch_to_user_mode(void *user_stack, void *user_entry) { ); } -void kmain(struct multiboot_info *info) { - clear_screen(); - set_color(VGA_COLOR_CYAN); -// Check if the bootloader gave us the upper and lower memory - if (!(info->flags & 0x1)) goto halt; - - ctx.multi_mmap = (struct multiboot_mmap_entry *)info->memMapAddress; - ctx.multi_mmap_size = info->memMapLength / sizeof(struct multiboot_mmap_entry); - - if (!mmap_init(&ctx)) { - set_color(VGA_COLOR_RED); - printf("Failed to create memory map\n"); - goto halt; - } - - printf("[KERNEL] Detected %d bytes of memory\n", ctx.available_bytes); - -// Create and load an IDT - for (int i = 0; i < 32; i++) { - encode_idt_entry(g_idt, i, isr_stub_table[i], GDT_SEGMENT_SELECTOR(GDT_KERNEL_CODE, 0x00), TRAP_GATE_32 | INT_RING0 | INT_PRESENT); - } - - g_idtr.size = (sizeof(struct idt_entry) * 256) - 1; - g_idtr.base = (uint32_t) &g_idt; - - asm volatile ("lidt %0" :: "m"(g_idtr)); - - struct rsdp *found_rsdp = acpi_locate_rsdp(); - if (!found_rsdp) { - set_color(VGA_COLOR_RED); - printf("Failed to find RSDP signature\n"); - goto halt; - } - - if (found_rsdp->Revision == ACPI_VER_1) { - if (!acpi_validate_rsdp_checksum(found_rsdp)) { - set_color(VGA_COLOR_RED); - printf("RSDP has an invalid checksum\n"); - goto halt; - } - ctx.rsdp = found_rsdp; - ctx.xsdp = 0; - - if (!acpi_validate_sdt_checksum((struct ACPISDTHeader *)found_rsdp->RsdtAddress)) { - set_color(VGA_COLOR_RED); - printf("RSDT has an invalid checksum\n"); - goto halt; - } - - ctx.rsdt = (struct rsdt*)found_rsdp->RsdtAddress; - - } else if (found_rsdp->Revision == ACPI_VER_OTHER) { - set_color(VGA_COLOR_RED); - printf("ACPI versions higher than 1.0 are not yet supported because I'm lazy\n"); - goto halt; - } else { - set_color(VGA_COLOR_RED); - printf("Invalid RSDP\n"); - goto halt; - } - - printf("[KERNEL] Using ACPI v1.0\n"); - - struct fadt *fadt = acpi_locate_sdt(ctx.rsdt, "FACP"); - if (!fadt) { - set_color(VGA_COLOR_RED); - printf("Failed to find FADT\n"); - goto halt; - } - printf("[KERNEL] Found FADT at 0x%x\n", fadt); - if (fadt->Flags & 1) - printf("[KERNEL] Legacy devices are supported\n"); - else { - /* - set_color(VGA_COLOR_RED); - printf("Legacy devices are not supported. I'm too lazy to support modern devices, bye bye.\n"); - goto halt; - */ - } - pic_remap(PIC_1_START, PIC_2_START); -// ACPI version 1.0 is so old that we assume that our PC supports the 8042 ps/2 controller - - // Allocate 4KiB for stdout - stdout.data = mmap_find_first_free_block(&ctx); - stdout.next = NULL; - // Allocate 4KiB for stdin - stdin.data = mmap_find_first_free_block(&ctx); - stdin.next = NULL; - - initialize_8042ps2(); - encode_idt_entry(g_idt, 0x21, (uint32_t)&ps2_isr, GDT_SEGMENT_SELECTOR(GDT_KERNEL_CODE, RING0), INT_GATE_32 | INT_RING0 | INT_PRESENT); - asm volatile ("sti" ::); -/* - struct mcfg *mcfg = acpi_locate_sdt(ctx.rsdt, "MCFG"); - if (!mcfg) { - set_color(VGA_COLOR_RED); - printf("Failed to find MCFG\n"); - } else { - - printf("Looks like you are using PCIe- Found MCFG at 0x%x\n", mcfg); - - struct pci_config_space *ide = pcie_find_device(mcfg, MASS_STORAGE_CONTROLLER, IDE_INTERFACE); - if (ide) { - printf("IDE controller detected. Program Interface: %X\n", ide->program_interface); - - uint16_t ide_buf[256] = {0}; - ide_identify(ATA_PRIMARY, ATA_MASTER, ide_buf); - } - } -*/ - - write_tss(&tss, gdt, 5, 0x10, 0x0); - tss_flush(0x2B); - encode_idt_entry(g_idt, 0x80, (uint32_t)&syscall_isr, GDT_SEGMENT_SELECTOR(GDT_USER_CODE, RING3), INT_GATE_32 | INT_RING3 | INT_PRESENT); - - uint16_t cs_selector = 0x10; // Example code segment selector - uint32_t eip = (uint32_t)&syscall; // Example entry point address +void user_init() { +// Setup syscalls + uint32_t eip = (uint32_t)&syscall; uint32_t esp; // Get the current value of ESP @@ -212,7 +92,7 @@ void kmain(struct multiboot_info *info) { "xor %%edx, %%edx \n\t" // Upper 32 bits (zero for 32-bit value) "wrmsr" : - : "r"((uint32_t)cs_selector) + : "r"(GDT_SEGMENT_SELECTOR(GDT_KERNEL_CODE, RING0)) : "eax", "ecx", "edx" ); @@ -238,7 +118,10 @@ void kmain(struct multiboot_info *info) { : "eax", "ecx", "edx" ); - void *page = mmap_find_first_free_block(&ctx); +// Switch + write_tss(&tss, gdt, 5, 0x10, 0x0); + tss_flush(0x2B); + void *page = (uint32_t *)0x6000; ata_read_sector(ATA_PRIMARY, ATA_MASTER, 0, page); printf("[KERNEL] Init program loaded to 0x%08X\n", page); printf("[KERNEL] Transferring control... goodbye\n"); @@ -246,8 +129,24 @@ void kmain(struct multiboot_info *info) { // 4 KiB for stack void *stack_bottom = mmap_find_first_free_block(&ctx); void *stack_top = stack_bottom + 0x1000; - MAGIC_BREAKPOINT switch_to_user_mode(stack_top, page); +} + +void kmain(struct multiboot_info *info) { + clear_screen(); + set_color(VGA_COLOR_CYAN); +// Check if the bootloader gave us the upper and lower memory + if (!(info->flags & 0x1)) goto halt; + + ctx.multi_mmap = (struct multiboot_mmap_entry *)info->memMapAddress; + ctx.multi_mmap_size = info->memMapLength / sizeof(struct multiboot_mmap_entry); + + mmap_init(&ctx); + acpi_init(&ctx); + ps2_init(); + interrupts_init(g_idt, g_idtr); + user_init(); + halt: for (;;) {} } diff --git a/src/ps2.c b/src/ps2.c index 87480ac..2b1b172 100644 --- a/src/ps2.c +++ b/src/ps2.c @@ -13,7 +13,7 @@ char shell_buffer[512]; int shell_index; // TODO: Support dual ports -void initialize_8042ps2() { +void ps2_init() { // disable ps/2 ports so nothing gets messed up outportb(PS2_8042_COMMAND, 0xAD); outportb(PS2_8042_COMMAND, 0xA7);