Compare commits
3 Commits
edcfd676bf
...
306f430cc2
Author | SHA1 | Date | |
---|---|---|---|
306f430cc2 | |||
6dd79e6303 | |||
8851f7ec91 |
|
@ -133,7 +133,4 @@ 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
|
||||||
|
|
|
@ -49,6 +49,4 @@ 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
|
||||||
|
|
|
@ -108,7 +108,8 @@
|
||||||
#define KBD_INSERT2 0xD2
|
#define KBD_INSERT2 0xD2
|
||||||
#define KBD_DELETE2 0xD3
|
#define KBD_DELETE2 0xD3
|
||||||
|
|
||||||
void ps2_init();
|
void initialize_8042ps2();
|
||||||
|
extern void ps2_isr();
|
||||||
void ps2_handler();
|
void ps2_handler();
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
60
src/acpi.c
60
src/acpi.c
|
@ -1,8 +1,5 @@
|
||||||
#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;
|
||||||
|
@ -58,60 +55,3 @@ 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;
|
|
||||||
}
|
|
||||||
|
|
23
src/idt.c
23
src/idt.c
|
@ -1,8 +1,6 @@
|
||||||
#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);
|
||||||
|
@ -12,27 +10,6 @@ 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();
|
||||||
|
|
||||||
|
|
155
src/kmain.c
155
src/kmain.c
|
@ -19,10 +19,16 @@
|
||||||
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 {
|
||||||
|
@ -31,13 +37,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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -77,9 +83,123 @@ void switch_to_user_mode(void *user_stack, void *user_entry) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void user_init() {
|
void kmain(struct multiboot_info *info) {
|
||||||
// Setup syscalls
|
clear_screen();
|
||||||
uint32_t eip = (uint32_t)&syscall;
|
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
|
||||||
uint32_t esp;
|
uint32_t esp;
|
||||||
|
|
||||||
// Get the current value of ESP
|
// Get the current value of ESP
|
||||||
|
@ -92,7 +212,7 @@ void user_init() {
|
||||||
"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"(GDT_SEGMENT_SELECTOR(GDT_KERNEL_CODE, RING0))
|
: "r"((uint32_t)cs_selector)
|
||||||
: "eax", "ecx", "edx"
|
: "eax", "ecx", "edx"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -118,10 +238,7 @@ void user_init() {
|
||||||
: "eax", "ecx", "edx"
|
: "eax", "ecx", "edx"
|
||||||
);
|
);
|
||||||
|
|
||||||
// Switch
|
void *page = mmap_find_first_free_block(&ctx);
|
||||||
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");
|
||||||
|
@ -129,24 +246,8 @@ void user_init() {
|
||||||
// 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 (;;) {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@ char shell_buffer[512];
|
||||||
int shell_index;
|
int shell_index;
|
||||||
|
|
||||||
// TODO: Support dual ports
|
// TODO: Support dual ports
|
||||||
void ps2_init() {
|
void initialize_8042ps2() {
|
||||||
// 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);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user