cleanup 2

This commit is contained in:
rami 2024-05-27 14:18:37 -04:00
parent 99ed9c37db
commit edcfd676bf
7 changed files with 117 additions and 131 deletions

View File

@ -133,4 +133,7 @@ int acpi_validate_sdt_checksum(struct ACPISDTHeader *s);
struct ACPISDTHeader *acpi_find_table(struct rsdt *root, const char *signature); struct ACPISDTHeader *acpi_find_table(struct rsdt *root, const char *signature);
void *acpi_locate_sdt(struct rsdt *rsdt, const char sig[4]); void *acpi_locate_sdt(struct rsdt *rsdt, const char sig[4]);
struct kernel_context;
int acpi_init(struct kernel_context *ctx);
#endif #endif

View File

@ -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 flush_idt(uint32_t idt_pointer);
void exception_handler(struct registers regs); void exception_handler(struct registers regs);
void interrupts_init(struct idt_entry idt[], struct idtr idtr);
#endif #endif

View File

@ -108,8 +108,7 @@
#define KBD_INSERT2 0xD2 #define KBD_INSERT2 0xD2
#define KBD_DELETE2 0xD3 #define KBD_DELETE2 0xD3
void initialize_8042ps2(); void ps2_init();
extern void ps2_isr();
void ps2_handler(); void ps2_handler();
#endif #endif

View File

@ -1,5 +1,8 @@
#include <kernel/acpi.h> #include <kernel/acpi.h>
#include <kernel/strcmp.h> #include <kernel/strcmp.h>
#include <kernel/vga.h>
#include <kernel/printf.h>
#include <kernel/kernel.h>
struct rsdp *acpi_locate_rsdp() { struct rsdp *acpi_locate_rsdp() {
char *ptr = (char *)BIOS_START; char *ptr = (char *)BIOS_START;
@ -55,3 +58,60 @@ void *acpi_locate_sdt(struct rsdt *rsdt, const char sig[4]) {
return 0; 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;
}

View File

@ -1,6 +1,8 @@
#include <kernel/idt.h> #include <kernel/idt.h>
#include <kernel/vga.h> #include <kernel/vga.h>
#include <kernel/printf.h> #include <kernel/printf.h>
#include <kernel/gdt.h>
#include <kernel/pic8259.h>
void encode_idt_entry(struct idt_entry idt[], int i, uint32_t offset, uint16_t segment_selector, uint8_t attributes) { 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); 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); 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) { void exception_handler(struct registers regs) {
clear_screen(); clear_screen();

View File

@ -19,16 +19,10 @@
struct kernel_context ctx = {0}; struct kernel_context ctx = {0};
struct idt_entry g_idt[256] = {0}; struct idt_entry g_idt[256] = {0};
struct idtr g_idtr = {0}; struct idtr g_idtr = {0};
extern uint32_t isr_stub_table[32];
extern void ps2_isr();
extern struct gdt_entry gdt[6]; extern struct gdt_entry gdt[6];
extern void syscall_isr();
extern void syscall(); extern void syscall();
extern void test(); extern void test();
linked_mem_t stdout = {0};
linked_mem_t stdin = {0};
struct tss_entry tss; struct tss_entry tss;
struct stack_frame { struct stack_frame {
@ -37,13 +31,13 @@ struct stack_frame {
void syscall_read(struct stack_frame regs) { void syscall_read(struct stack_frame regs) {
uint32_t fd = regs.edi; uint32_t fd = regs.edi;
char *buf = (char *)regs.esi; // char *buf = (char *)regs.esi;
uint32_t count = regs.edx; uint32_t count = regs.edx;
if (fd == FD_STDOUT) { if (fd == FD_STDOUT) {
int pages = count / BLOCK_SIZE; int pages = count / BLOCK_SIZE;
if (pages == 0) { 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) { void user_init() {
clear_screen(); // Setup syscalls
set_color(VGA_COLOR_CYAN); uint32_t eip = (uint32_t)&syscall;
// 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
uint32_t esp; uint32_t esp;
// Get the current value of 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) "xor %%edx, %%edx \n\t" // Upper 32 bits (zero for 32-bit value)
"wrmsr" "wrmsr"
: :
: "r"((uint32_t)cs_selector) : "r"(GDT_SEGMENT_SELECTOR(GDT_KERNEL_CODE, RING0))
: "eax", "ecx", "edx" : "eax", "ecx", "edx"
); );
@ -238,7 +118,10 @@ void kmain(struct multiboot_info *info) {
: "eax", "ecx", "edx" : "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); ata_read_sector(ATA_PRIMARY, ATA_MASTER, 0, page);
printf("[KERNEL] Init program loaded to 0x%08X\n", page); printf("[KERNEL] Init program loaded to 0x%08X\n", page);
printf("[KERNEL] Transferring control... goodbye\n"); printf("[KERNEL] Transferring control... goodbye\n");
@ -246,8 +129,24 @@ void kmain(struct multiboot_info *info) {
// 4 KiB for stack // 4 KiB for stack
void *stack_bottom = mmap_find_first_free_block(&ctx); void *stack_bottom = mmap_find_first_free_block(&ctx);
void *stack_top = stack_bottom + 0x1000; void *stack_top = stack_bottom + 0x1000;
MAGIC_BREAKPOINT
switch_to_user_mode(stack_top, page); 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: halt:
for (;;) {} for (;;) {}
} }

View File

@ -13,7 +13,7 @@ char shell_buffer[512];
int shell_index; int shell_index;
// TODO: Support dual ports // TODO: Support dual ports
void initialize_8042ps2() { void ps2_init() {
// disable ps/2 ports so nothing gets messed up // disable ps/2 ports so nothing gets messed up
outportb(PS2_8042_COMMAND, 0xAD); outportb(PS2_8042_COMMAND, 0xAD);
outportb(PS2_8042_COMMAND, 0xA7); outportb(PS2_8042_COMMAND, 0xA7);