From 7830b92f87933753a3bf7c919f6951c7415ef42c Mon Sep 17 00:00:00 2001 From: rami Date: Sun, 26 May 2024 01:24:40 -0500 Subject: [PATCH] added syscalls & fixed bug in mem manager --- .../clangd/index/kmain.c.9B04FE5F8A3537CE.idx | Bin 5038 -> 5244 bytes gdt.c | 28 +++ image.img | Bin 0 -> 42 bytes include/fat12.h | 34 ---- include/gdt.h | 10 + include/mem.h | 8 +- kmain.c | 171 +++++++++++------- mem.c | 10 +- multiboot.asm | 41 ++++- ps2.c | 3 + test.a | 15 ++ 11 files changed, 214 insertions(+), 106 deletions(-) create mode 100644 gdt.c create mode 100644 image.img delete mode 100644 include/fat12.h create mode 100644 test.a diff --git a/.cache/clangd/index/kmain.c.9B04FE5F8A3537CE.idx b/.cache/clangd/index/kmain.c.9B04FE5F8A3537CE.idx index 5da2d05d91c22a741659cdf67de55aa0ae65fbfd..b460e5495671529cec617f7790333bbeb210abb6 100644 GIT binary patch literal 5244 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 + +void write_tss(struct tss_entry *tss, struct gdt_entry *gdt, int num, uint16_t ss0, uint32_t esp0) { + uint32_t base = (uint32_t)tss; + uint32_t limit = base + sizeof(struct tss_entry); + + gdt[num].base_low = base & 0xFFFF; + gdt[num].base_middle = (base >> 16) & 0xFF; + gdt[num].base_high = (base >> 24) & 0xFF; + gdt[num].limit_low = limit & 0xFFFF; + gdt[num].granularity = (limit >> 16) & 0x0F; + gdt[num].granularity |= 0x40; + gdt[num].access = 0x89; + + memset(&tss, 0, sizeof(struct tss_entry)); + tss->ss0 = ss0; + tss->esp0 = esp0; + tss->cs = 0x0b; + tss->ss = tss->ds = tss->es = tss->fs = tss->gs = 0x13; +} + +void tss_flush(uint16_t tss_selector) { + asm volatile ( + "ltr %0" + : // no output + : "r" (tss_selector) + ); +} diff --git a/image.img b/image.img new file mode 100644 index 0000000000000000000000000000000000000000..c4b85c4db49aaa60cccdc0e7492cf331fe99caa8 GIT binary patch literal 42 wcmWITe7b{?fq`K^5Hsu(OJHC)+wl6IV_r&Xxk7PvW>RKKrb0n}ZeAt>05ru8*8l(j literal 0 HcmV?d00001 diff --git a/include/fat12.h b/include/fat12.h deleted file mode 100644 index ff71f10..0000000 --- a/include/fat12.h +++ /dev/null @@ -1,34 +0,0 @@ -#ifndef RK_FAT12_H_ -#define RK_FAT12_H_ - -#include - -struct fat12_boot_sector { - uint8_t jump_boot[3]; // Jump instruction to boot code - uint8_t oem_name[8]; // OEM name and version - uint16_t bytes_per_sector; // Bytes per sector - uint8_t sectors_per_cluster; // Sectors per cluster - uint16_t reserved_sectors; // Reserved sectors - uint8_t num_fats; // Number of FATs - uint16_t root_entry_count; // Number of root directory entries - uint16_t total_sectors_16; // Total sectors (16-bit) - uint8_t media; // Media descriptor - uint16_t fat_size_16; // Sectors per FAT (16-bit) - uint16_t sectors_per_track; // Sectors per track (for BIOS) - uint16_t num_heads; // Number of heads (for BIOS) - uint32_t hidden_sectors; // Hidden sectors - uint32_t total_sectors_32; // Total sectors (32-bit) - - // Extended Boot Record (EBR) fields - uint8_t drive_number; // Drive number - uint8_t reserved1; // Reserved - uint8_t boot_signature; // Extended boot signature - uint32_t volume_id; // Volume ID (serial number) - uint8_t volume_label[11]; // Volume label - uint8_t file_system_type[8]; // File system type (e.g., "FAT12 ") - - uint8_t boot_code[448]; // Boot code - uint16_t boot_sector_signature; // Boot sector signature (0xAA55) -} __attribute__((packed)); - -#endif diff --git a/include/gdt.h b/include/gdt.h index e6241e9..d0d3477 100644 --- a/include/gdt.h +++ b/include/gdt.h @@ -2,10 +2,17 @@ #define RK_GDT_H_ #include +#include #define GDT_NULL 0 #define GDT_KERNEL_CODE 1 #define GDT_KERNEL_DATA 2 +#define GDT_USER_CODE 3 +#define GDT_USER_DATA 4 + +#define RING0 0 +#define RING3 3 + #define GDT_SEGMENT_SELECTOR(i, p) ((i << 3) | p) struct gdt_entry { @@ -47,4 +54,7 @@ struct tss_entry { uint16_t iomap_base; } __attribute__((packed)); +void write_tss(struct tss_entry *tss, struct gdt_entry *gdt, int num, uint16_t ss0, uint32_t esp0); +void tss_flush(uint16_t tss_selector); + #endif diff --git a/include/mem.h b/include/mem.h index c628ae7..1e7e296 100644 --- a/include/mem.h +++ b/include/mem.h @@ -15,6 +15,12 @@ void mmap_free_block(struct kernel_context *ctx, int block); void *mmap_find_first_free_block(struct kernel_context *ctx); void *mmap_block_to_physical(struct kernel_context *ctx, int block); -void *memset(void *s, int c, uint32_t len); +void memset(void *s, int c, uint32_t len); +void memcpy(void *dest, void *src, int n); + +typedef struct { + void *data; + void *next; +} linked_mem_t; #endif diff --git a/kmain.c b/kmain.c index 952d712..c436ea5 100644 --- a/kmain.c +++ b/kmain.c @@ -11,35 +11,51 @@ #include #include #include -#include - -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(); #define MAGIC_BREAKPOINT __asm__ volatile("xchgw %bx, %bx"); +#define FD_STDOUT 0 +#define FD_STDIN 1 -#define USER_DS 0x23 // User data segment selector -#define USER_CS 0x1B // User code segment selector - +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; -void tss_flush(uint16_t tss_selector) { - asm volatile ( - "ltr %0" - : // no output - : "r" (tss_selector) - ); +struct stack_frame { + uint32_t edi, esi, ebp, esp, ebx, edx, ecx, eax; +}; + +void syscall_read(struct stack_frame regs) { + uint32_t fd = regs.edi; + 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); + } + } } -void test() { - printf("\n\nHello from user mode!\n"); - for (;;) {} +void syscall_write(struct stack_frame regs) { + uint32_t fd = regs.edi; + char *buf = (char *)regs.esi; + //uint32_t count = regs.edx; + + if (fd == FD_STDOUT) { + printf("%s", buf); + } } void switch_to_user_mode(void *user_stack, void *user_entry) { @@ -67,25 +83,6 @@ void switch_to_user_mode(void *user_stack, void *user_entry) { ); } -void write_tss(int num, uint16_t ss0, uint32_t esp0) { - uint32_t base = (uint32_t)&tss; - uint32_t limit = base + sizeof(tss); - - gdt[num].base_low = base & 0xFFFF; - gdt[num].base_middle = (base >> 16) & 0xFF; - gdt[num].base_high = (base >> 24) & 0xFF; - gdt[num].limit_low = limit & 0xFFFF; - gdt[num].granularity = (limit >> 16) & 0x0F; - gdt[num].granularity |= 0x40; - gdt[num].access = 0x89; - - memset(&tss, 0, sizeof(tss)); - tss.ss0 = ss0; - tss.esp0 = esp0; - tss.cs = 0x0b; - tss.ss = tss.ds = tss.es = tss.fs = tss.gs = 0x13; -} - void kmain(struct multiboot_info *info) { clear_screen(); set_color(VGA_COLOR_CYAN); @@ -95,22 +92,13 @@ void kmain(struct multiboot_info *info) { ctx.multi_mmap = (struct multiboot_mmap_entry *)info->memMapAddress; ctx.multi_mmap_size = info->memMapLength / sizeof(struct multiboot_mmap_entry); - for (uint32_t i = 0; i < ctx.multi_mmap_size; i++) { - struct multiboot_mmap_entry entry = ctx.multi_mmap[i]; - if (entry.type != MULTIBOOT_MEMORY_AVAILABLE) continue; - - uint32_t len = (uint32_t)(entry.len_low | entry.len_high); - uint32_t addr = (uint32_t)(entry.addr_low | entry.addr_high); - printf("Region #%d: 0x%08X-0x%08X\n", i, addr, addr+len); - } - if (!mmap_init(&ctx)) { set_color(VGA_COLOR_RED); printf("Failed to create memory map\n"); goto halt; } - printf("Detected %d bytes of memory\n", ctx.available_bytes); + printf("[KERNEL] Detected %d bytes of memory\n", ctx.available_bytes); // Create and load an IDT for (int i = 0; i < 32; i++) { @@ -156,7 +144,7 @@ void kmain(struct multiboot_info *info) { goto halt; } - printf("Using ACPI v1.0\n"); + printf("[KERNEL] Using ACPI v1.0\n"); struct fadt *fadt = acpi_locate_sdt(ctx.rsdt, "FACP"); if (!fadt) { @@ -164,9 +152,9 @@ void kmain(struct multiboot_info *info) { printf("Failed to find FADT\n"); goto halt; } - printf("Found FADT at 0x%x\n", fadt); + printf("[KERNEL] Found FADT at 0x%x\n", fadt); if (fadt->Flags & 1) - printf("Legacy devices are supported\n"); + printf("[KERNEL] Legacy devices are supported\n"); else { /* set_color(VGA_COLOR_RED); @@ -176,10 +164,18 @@ void kmain(struct multiboot_info *info) { } 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 - initialize_8042ps2(); - encode_idt_entry(g_idt, 0x21, (uint32_t)&ps2_isr, GDT_SEGMENT_SELECTOR(GDT_KERNEL_CODE, 0x00), INT_GATE_32 | INT_RING0 | INT_PRESENT); - asm volatile ("sti" ::); + // 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); @@ -196,19 +192,62 @@ void kmain(struct multiboot_info *info) { ide_identify(ATA_PRIMARY, ATA_MASTER, ide_buf); } } +*/ - set_color(VGA_COLOR_WHITE); - - void *buf = mmap_find_first_free_block(&ctx); - ata_read_sector(ATA_PRIMARY, ATA_MASTER, 0, (uint8_t *)buf); -// struct fat12_boot_sector *boot_sect = (struct fat12_boot_sector *)buf; -// int fat_size = boot_sect->total_sectors_16 * boot_sect->bytes_per_sector; - - write_tss(5, 0x10, 0x0); + 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; + + // Get the current value of ESP + __asm__ volatile ("mov %%esp, %0" : "=r"(esp)); + + // Write to MSR_SYSENTER_CS (0x174) + __asm__ volatile ( + "movl $0x174, %%ecx \n\t" // MSR address + "movl %0, %%eax \n\t" // Lower 32 bits (cs_selector) + "xor %%edx, %%edx \n\t" // Upper 32 bits (zero for 32-bit value) + "wrmsr" + : + : "r"((uint32_t)cs_selector) + : "eax", "ecx", "edx" + ); + + // Write to MSR_SYSENTER_ESP (0x175) + __asm__ volatile ( + "movl $0x175, %%ecx \n\t" // MSR address + "movl %0, %%eax \n\t" // Lower 32 bits (esp) + "xor %%edx, %%edx \n\t" // Upper 32 bits (zero for 32-bit value) + "wrmsr" + : + : "r"(esp) + : "eax", "ecx", "edx" + ); + + // Write to MSR_SYSENTER_EIP (0x176) + __asm__ volatile ( + "movl $0x176, %%ecx \n\t" // MSR address + "movl %0, %%eax \n\t" // Lower 32 bits (eip) + "xor %%edx, %%edx \n\t" // Upper 32 bits (zero for 32-bit value) + "wrmsr" + : + : "r"(eip) + : "eax", "ecx", "edx" + ); + + void *page = mmap_find_first_free_block(&ctx); + 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"); + set_color(VGA_COLOR_WHITE); + // 4 KiB for stack void *stack_bottom = mmap_find_first_free_block(&ctx); - void *stack_top = stack_bottom + 4096; - switch_to_user_mode(stack_top, buf); + void *stack_top = stack_bottom + 0x1000; + MAGIC_BREAKPOINT + switch_to_user_mode(stack_top, page); halt: for (;;) {} } diff --git a/mem.c b/mem.c index bd445a2..20e6924 100644 --- a/mem.c +++ b/mem.c @@ -19,14 +19,18 @@ void *mmap_block_to_physical(struct kernel_context *ctx, int block) { return 0; } -void *memset(void *s, int c, uint32_t len) { +void memset(void *s, int c, uint32_t len) { unsigned char *dst = s; while (len > 0) { *dst = (unsigned char) c; dst++; len--; } - return s; +} + +void memcpy(void *dest, void *src, int n) { + for (int i=0; immap_size = ctx->available_bytes / BLOCK_SIZE / 8; - printf("Memory map size: %d bytes\n", ctx->mmap_size); // Loop again to find the first region with enough space to hold the memory map int index = -1; @@ -113,6 +116,7 @@ void *mmap_find_first_free_block(struct kernel_context *ctx) { uint32_t dword = ctx->mmap[index]; if (!(dword & mask)) { + mmap_set_block(ctx, i); return mmap_block_to_physical(ctx, i); } } diff --git a/multiboot.asm b/multiboot.asm index c5d9240..26cbf49 100644 --- a/multiboot.asm +++ b/multiboot.asm @@ -116,15 +116,45 @@ isr_stub_table: global ps2_isr ps2_isr: - cli extern ps2_handler pushad cld - and esp, 0xFFFFFFF0 call ps2_handler popad iret +global test +test: + push ebp + mov ebp, esp + + mov eax, 1 + mov edi, 0 + mov esi, buf + int 0x80 + jmp $ +buf: db "Hello from stdout!", 0 + +global syscall_isr +syscall_isr: + xchg bx, bx + pushad + mov ecx, esp + sysenter +after_syscall: + popad + iret + +global syscall +syscall: + imul eax, eax, 4 + add eax, syscall_table + pushad + call [eax] + popad + mov edx, after_syscall + sysexit + ; GDT for a flat memory layout ; We get access to all memory and can utilize paging global gdt @@ -167,6 +197,13 @@ gdtp: dw gdt_end - gdt - 1 dd gdt +global syscall_table +syscall_table: + extern syscall_read + dd syscall_read + + extern syscall_write + dd syscall_write ; Reserve 16KiB of kernel stack space section .bss diff --git a/ps2.c b/ps2.c index 2f0b990..0f67b43 100644 --- a/ps2.c +++ b/ps2.c @@ -5,6 +5,7 @@ #include #include #include +#include #define cpu_relax asm volatile ("pause" ::); @@ -54,6 +55,8 @@ void initialize_8042ps2() { outportb(PS2_8042_DATA, config); } +extern linked_mem_t stdin; + void ps2_handler() { uint8_t scancode = inportb(0x60); diff --git a/test.a b/test.a new file mode 100644 index 0000000..a0c3005 --- /dev/null +++ b/test.a @@ -0,0 +1,15 @@ +[org 0x6000] +[bits 32] +_start: + push ebp + mov ebp, esp + ; Syscall #1 = write + mov eax, 1 + ; File descriptor = stdout + mov edi, 0 + ; ESI = buffer + mov esi, buf + int 0x80 + jmp $ + +buf: db "Andew skibidi pomni", 0