From 4ac1efd433034b3b6d710ca8cca24d93138f550f Mon Sep 17 00:00:00 2001 From: rami Date: Sun, 28 Jul 2024 10:11:15 -0400 Subject: [PATCH] r/w syscalls and elf init program --- .gdb_history | 256 ----------------------- .gitignore | 1 + Makefile | 18 +- bochsrc | 2 +- boot/initrd | Bin 432 -> 964 bytes include/kernel/ps2.h | 114 +++++++++++ include/kernel/task.h | 4 + kernel/init.asm | 16 +- kernel/kernel.c | 54 +++-- kernel/pic.c | 4 +- kernel/ps2.c | 394 ++++++++++++++++++++++++++++++++++++ kernel/task.c | 37 +++- peda-session-kernel.bin.txt | 2 +- user/Makefile | 34 ++++ user/shell.c | 39 ++++ user/userinit.asm | 7 - 16 files changed, 685 insertions(+), 297 deletions(-) delete mode 100644 .gdb_history mode change 100644 => 100755 boot/initrd create mode 100644 include/kernel/ps2.h create mode 100644 kernel/ps2.c create mode 100644 user/Makefile create mode 100644 user/shell.c delete mode 100644 user/userinit.asm diff --git a/.gdb_history b/.gdb_history deleted file mode 100644 index b2641ca..0000000 --- a/.gdb_history +++ /dev/null @@ -1,256 +0,0 @@ -ni -ni -c -ni -ni -ni -ni -ni -ni -ni -ni -ni -ni -ni -c -ni -ni -ni -ni -ni -ni -ni -ni -ni -ni -target remote localhost:1234 -target remote localhost:1234 -ni -ni -c -ni -ni -ni -ni -ni -ni -ni -ni -ni -ni -ni -ni -c -ni -ni -ni -ni -ni -ni -ni -ni -ni -ni -ni -c -ni -ni -ni -ni -ni -ni -ni -ni -ni -ni -ni -ni -ni -ni -ni -ni -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -ni -ni -ni -ni -ni -ni -ni -ni -ni -ni -ni -ni -ni -ni -ni -ni -ni -b pit_isr -c -target remote localhost:1234 -c -ni -ni -ni -ni -ni -c -target remote localhost:1234 -target remote localhost:1234 -c -ni -ni -ni -ni -ni -ni -ni -ni -ni -ni diff --git a/.gitignore b/.gitignore index f0888e2..edf51d9 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ *.iso *.bin .cache +.gdb_history diff --git a/Makefile b/Makefile index f46ee64..c2eb474 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -CC = i686-elf-gcc +CC = /home/rami/crossdev/bin/i686-elf-gcc AS = nasm BUILDDIR := build @@ -12,17 +12,14 @@ KIMG := kernel.bin LSRC := $(wildcard lib/*.c) LOBJ := $(addprefix $(BUILDDIR)/, \ - $(notdir \ - $(patsubst %.c,%.o, $(LSRC)))) + $(notdir \ + $(patsubst %.c,%.o, $(LSRC)))) ISO := Hazel.iso CFLAGS := -ffreestanding -Wall -Wextra -Werror -I $(INCLUDEDIR) -I lib LDFLAGS := -ffreestanding -nostdlib -lgcc -T kernel/kernel.ld -QEMUFLAGS := -cdrom $(BUILDDIR)/$(ISO) \ - -s -d int \ - -m 512M \ - -serial stdio +QEMUFLAGS := -cdrom $(BUILDDIR)/$(ISO) -s -m 512M -serial stdio $(BUILDDIR)/$(KIMG): $(KOBJ) $(LOBJ) $(CC) $^ -o $@ $(LDFLAGS) @@ -34,13 +31,16 @@ $(BUILDDIR)/%.o: */%.c kernel: $(BUILDDIR)/$(KIMG) $(BUILDDIR)/$(ISO): kernel - rm -f $(BUILDDIR)/$(ISO) boot/initrd - nasm -felf32 user/userinit.asm -o boot/initrd + make -C user cp $(BUILDDIR)/$(KIMG) boot/$(KIMG) + rm -f $(BUILDDIR)/$(ISO) grub-mkrescue -o $(BUILDDIR)/$(ISO) . iso: $(BUILDDIR)/$(ISO) +all: iso + qemu: iso qemu-system-i386 $(QEMUFLAGS) clean: + make clean -C user rm -f build/* boot/*.bin boot/initrd diff --git a/bochsrc b/bochsrc index f5de00b..387e109 100644 --- a/bochsrc +++ b/bochsrc @@ -2,4 +2,4 @@ ata0-slave: type=cdrom, path=./build/Hazel.iso, status=inserted magic_break: enabled=1 boot: cdrom -display_library: sdl2 +display_library: x diff --git a/boot/initrd b/boot/initrd old mode 100644 new mode 100755 index c533958aa6e51947f3667e8089dd6284858af24c..ddd825f659c771e63c1459263740b438bdbc4389 GIT binary patch literal 964 zcma)5O=uHQ5T2y5T_u=UFM}#S8LC&cC%yG11nNb+O4o08_dz@e4$OY@%{TMjzQ1Rgo3oKfgp@^T zgqVF^jcIA%n`oeIgPeik(Z-$n!b5l$wF^6l>jS}UVPTA6sHlhG1ATIj|sLt@)t!pl59|oek+rqD8Y@tX51Rt3q0)m^W6;vZ%YJ zBV5ZYmnV+VWkCx!ve&ZLvs9|q1bf4D*&){LM|SmzEigvKuuI6y&CE=T$+_G4l$c8E zQ~Cv7^WVnXq%1~1y`vzTIGfYJajfnXkk522@geV3rJN0PGTx?lvmYSO!Wb zKubl^d@4zIs(!W38)4cKGyb3Pnt4A);kOV literal 432 zcmb<-^>JflWMqH=Mh0dE1doBi0V-hvrZpH?8JJ*7Nuoh!f-oCYmjIB%hh%~Pl+6yL znUTa5fa(;H_#iVtKoE$LT@nD4Z~%(205M2Ehz6M{3FQMRFqi;TCk5jGX_$F1p`Gvd zt-ZGcBzm^t^* #include #include +#include #include kernel_ctx_t ctx = {0}; @@ -16,6 +17,7 @@ tss_t tss = {0}; extern uint32_t isr_stub_table[32]; extern void pit_isr(void); +extern void ps2_isr(void); extern void jmp_user_mode(uint32_t esp, uint32_t eip); extern void flush_tss(uint32_t segment_selector); extern void task_switch(task_t *task); @@ -25,8 +27,35 @@ extern gdt_t gdt[6]; extern uint32_t boot_page_dir[1024]; extern uint32_t boot_page_tab[1024]; +#define FD_STDIN 0 +#define FD_STDOUT 1 void syscall_write(stack_frame_t r) { - LOG("SYSCALL %08X\n", r.eax); + uint32_t fd = r.edi; + uint8_t *buf = (uint8_t *)r.esi; + if (fd == FD_STDOUT) { + LOG("%s", buf); + } +} + +void syscall_read(stack_frame_t r) { + uint32_t fd = r.edi; + uint8_t *buf = (uint8_t *)r.esi; + uint32_t len = r.edx; + if (fd == FD_STDOUT) { + // Not yet + } else if (fd == FD_STDIN) { + asm volatile ("sti" ::); + while (ctx.current_task->stdin[ctx.current_task->stdin_len - 1] != '\n') cpu_relax; + if (ctx.current_task->stdin_len > 0) ctx.current_task->stdin[--ctx.current_task->stdin_len] = 0; + memcpy(buf, ctx.current_task->stdin, len); + for (int i = 0; i < 0x1000; i++) ctx.current_task->stdin[i] = 0; + ctx.current_task->stdin_len = 0; + } +} + +void syscall_uptime(stack_frame_t r) { + uint64_t *buf = (uint64_t *)r.esi; + *buf = ctx.ticks; } void exception_handler(int_stack_frame_t r) { @@ -47,8 +76,9 @@ void idt_init(void) { for (int i = 0; i < 32; i++) { idt_encode_entry(idt, i, isr_stub_table[i], GDT_SEGMENT_SELECTOR(GDT_KERNEL_CODE, RING0), TRAP_GATE_32 | INT_RING0 | INT_PRESENT); } - idt_encode_entry(idt, 32, (uint32_t)pit_isr, GDT_SEGMENT_SELECTOR(GDT_KERNEL_CODE, RING0), INT_GATE_32 | INT_RING0 | INT_PRESENT); - idt_encode_entry(idt, 0x80, (uint32_t)syscall_isr, GDT_SEGMENT_SELECTOR(GDT_USER_CODE, RING3), INT_GATE_32 | INT_RING3 | INT_PRESENT); + idt_encode_entry(idt, 32, (uint32_t)pit_isr, GDT_SEGMENT_SELECTOR(GDT_KERNEL_CODE, RING0), TRAP_GATE_32 | INT_RING0 | INT_PRESENT); + idt_encode_entry(idt, 0x21, (uint32_t)ps2_isr, GDT_SEGMENT_SELECTOR(GDT_KERNEL_CODE, RING0), TRAP_GATE_32 | INT_RING0 | INT_PRESENT); + idt_encode_entry(idt, 0x80, (uint32_t)syscall_isr, GDT_SEGMENT_SELECTOR(GDT_USER_CODE, RING3), TRAP_GATE_32 | INT_RING3 | INT_PRESENT); idtr.size = (sizeof(struct idt_entry) * 256) - 1; idtr.base = (uint32_t) idt; @@ -56,16 +86,10 @@ void idt_init(void) { asm volatile ("lidt %0" :: "m"(idtr)); } -void test(void) { - for (;;) { - LOG("B"); - } -} - void kernel(multiboot_info_t *info) { if (!CHECK_FLAG(info->flags, 3)) goto halt; // Modules - if (!CHECK_FLAG(info->flags, 6)) goto halt; // Memory map - if (!CHECK_FLAG(info->flags, 12)) goto halt; // VBE data + if (!CHECK_FLAG(info->flags, 6)) goto halt; // Memory map + if (!CHECK_FLAG(info->flags, 12)) goto halt; // VBE data if (serial_port_init(COM1)) ctx.log_method = LOG_COM1; LOG("Kernel log being sent to COM1\n"); @@ -78,6 +102,7 @@ void kernel(multiboot_info_t *info) { idt_init(); pic_remap(PIC_1_START, PIC_2_START); + ps2_init(); asm volatile ("sti" ::); ctx.ticks = 0; pit_init(); @@ -95,6 +120,7 @@ void kernel(multiboot_info_t *info) { tss.ss0 = GDT_SEGMENT_SELECTOR(GDT_KERNEL_DATA, RING0); uint32_t esp0 = 0; asm volatile ("mov %%esp, %0" : "=r" (esp0)); + // Questionable tss.esp0 = esp0; tss.cs = GDT_SEGMENT_SELECTOR(GDT_USER_CODE, RING3); tss.ss = tss.ds = tss.es = tss.fs = tss.gs = GDT_SEGMENT_SELECTOR(GDT_USER_DATA, RING3); @@ -156,9 +182,9 @@ void kernel(multiboot_info_t *info) { ); // Set the ring0 syscall entry 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) + "movl $0x176, %%ecx \n\t" + "movl %0, %%eax \n\t" + "xor %%edx, %%edx \n\t" "wrmsr" : : "r"(syscall) diff --git a/kernel/pic.c b/kernel/pic.c index c49ef35..a74cd11 100644 --- a/kernel/pic.c +++ b/kernel/pic.c @@ -26,6 +26,6 @@ void pic_remap(int pic1_start, int pic2_start) { outb(PIC_2_DATA, 0x01); // Unmask - outb(PIC_1_DATA, 0b11111110); - outb(PIC_2_DATA, 0b11111110); + outb(PIC_1_DATA, 0b11111101); + outb(PIC_2_DATA, 0b11111101); } diff --git a/kernel/ps2.c b/kernel/ps2.c new file mode 100644 index 0000000..c9e9dec --- /dev/null +++ b/kernel/ps2.c @@ -0,0 +1,394 @@ +#include +#include +#include +#include + +extern kernel_ctx_t ctx; +char shell_buffer[512] = {0}; +int shell_index = 0; + +// TODO: Support dual ports +void ps2_init() { + // disable ps/2 ports so nothing gets messed up + outb(PS2_8042_COMMAND, 0xAD); + outb(PS2_8042_COMMAND, 0xA7); + + // flush output buffer + inb(PS2_8042_DATA); + + // get config byte + outb(PS2_8042_COMMAND, 0x20); + uint8_t config = inb(0x60); + // disable IRQs and translation, also make sure 0 vals are 0 + config &= 0b00110100; + // write our config byte back + outb(PS2_8042_COMMAND, 0x60); + while (inb(PS2_8042_STATUS) & 0x2) cpu_relax; + outb(PS2_8042_DATA, config); + + // perform self test + outb(PS2_8042_COMMAND, 0xAA); + while (!(inb(PS2_8042_STATUS) & 0x1)) cpu_relax; + uint8_t result = inb(PS2_8042_DATA); + if (result == 0x55) LOG("Passed PS/2 self test\n") + else LOG("Failed!\n") + + // perform test + outb(PS2_8042_COMMAND, 0xAB); + while (!(inb(PS2_8042_STATUS) & 0x1)) cpu_relax; + result = inb(PS2_8042_DATA); + if (!result) LOG("Passed PS/2 port 1 test\n") + else LOG("Failed!\n") + + // enable ps/2 + outb(PS2_8042_COMMAND, 0xAE); + + // enable IRQ 1 + config = 0b01100101; + outb(PS2_8042_COMMAND, 0x60); + while (inb(PS2_8042_STATUS) & 0x2) cpu_relax; + outb(PS2_8042_DATA, config); +} + +void push_stdin(const char c) { + ctx.current_task->stdin[ctx.current_task->stdin_len++] = c; + _putchar(c); +} + +void ps2_handler() { + uint8_t scancode = inb(0x60); + + if (scancode > 0x80) goto eoi; + + switch(scancode) { + case KBD_ESC: + break; + case KBD_1: + push_stdin('1'); + break; + case KBD_2: + push_stdin('2'); + break; + case KBD_3: + push_stdin('3'); + break; + case KBD_4: + push_stdin('4'); + break; + case KBD_5: + push_stdin('5'); + break; + case KBD_6: + push_stdin('6'); + break; + case KBD_7: + push_stdin('7'); + break; + case KBD_8: + push_stdin('8'); + break; + case KBD_9: + push_stdin('9'); + break; + case KBD_0: + push_stdin('0'); + break; + case KBD_MINUS: + push_stdin('-'); + break; + case KBD_EQUALS: + push_stdin('='); + break; + case KBD_BACKSPACE: + /* + if (shell_index > 0) { + //popchar(); + shell_buffer[--shell_index] = 0; + }*/ + break; + case KBD_TAB: + break; + case KBD_Q: + push_stdin('Q'); + break; + case KBD_W: + push_stdin('W'); + break; + case KBD_E: + push_stdin('E'); + break; + case KBD_R: + push_stdin('R'); + break; + case KBD_T: + push_stdin('T'); + break; + case KBD_Y: + push_stdin('Y'); + break; + case KBD_U: + push_stdin('U'); + break; + case KBD_I: + push_stdin('I'); + break; + case KBD_O: + push_stdin('O'); + break; + case KBD_P: + push_stdin('P'); + break; + case KBD_LBRACKET: + push_stdin('['); + break; + case KBD_RBRACKET: + push_stdin(']'); + break; + case KBD_ENTER: + /* + if (strcmp(shell_buffer, "PINGAS") == 0) { + printf("andew pingas detected"); + } else if (strcmp(shell_buffer, "HELLO") == 0) { + printf("hi"); + } else if (strcmp(shell_buffer, "READ") == 0) { + uint8_t sector[512] = {0}; + ata_read_sector(ATA_PRIMARY, ATA_MASTER, 0, sector); + for (int i = 0; i < 512; i++) { + push_stdin(sector[i]); + } + } else { + printf("unknown command '%s' idiot", shell_buffer); + } + for (int i = 0; i < 512; i++) { + shell_buffer[i] = 0; + } + shell_index = 0; + */ + push_stdin('\n'); + break; + case KBD_LCTRL: + // Handle left control key + break; + case KBD_A: + push_stdin('A'); + break; + case KBD_S: + push_stdin('S'); + break; + case KBD_D: + push_stdin('D'); + break; + case KBD_F: + push_stdin('F'); + break; + case KBD_G: + push_stdin('G'); + break; + case KBD_H: + push_stdin('H'); + break; + case KBD_J: + push_stdin('J'); + break; + case KBD_K: + push_stdin('K'); + break; + case KBD_L: + push_stdin('L'); + break; + case KBD_SEMICOLON: + push_stdin(';'); + break; + case KBD_APOSTROPHE: + push_stdin('\''); + break; + case KBD_GRAVE: + push_stdin('`'); + break; + case KBD_LSHIFT: + // Handle left shift key + break; + case KBD_BACKSLASH: + push_stdin('\\'); + break; + case KBD_Z: + push_stdin('Z'); + break; + case KBD_X: + push_stdin('X'); + break; + case KBD_C: + push_stdin('C'); + break; + case KBD_V: + push_stdin('V'); + break; + case KBD_B: + push_stdin('B'); + break; + case KBD_N: + push_stdin('N'); + break; + case KBD_M: + push_stdin('M'); + break; + case KBD_COMMA: + push_stdin(','); + break; + case KBD_PERIOD: + push_stdin('.'); + break; + case KBD_SLASH: + push_stdin('/'); + break; + case KBD_RSHIFT: + // Handle right shift key + break; + case KBD_PRINTSCREEN: + // Handle print screen key + break; + case KBD_LALT: + // Handle left alt key + break; + case KBD_SPACE: + push_stdin(' '); + break; + case KBD_CAPSLOCK: + // Handle caps lock key + break; + case KBD_F1: + // Handle F1 key + break; + case KBD_F2: + // Handle F2 key + break; + case KBD_F3: + // Handle F3 key + break; + case KBD_F4: + // Handle F4 key + break; + case KBD_F5: + // Handle F5 key + break; + case KBD_F6: + // Handle F6 key + break; + case KBD_F7: + // Handle F7 key + break; + case KBD_F8: + // Handle F8 key + break; + case KBD_F9: + // Handle F9 key + break; + case KBD_F10: + // Handle F10 key + break; + case KBD_NUMLOCK: + // Handle num lock key + break; + case KBD_SCROLLLOCK: + // Handle scroll lock key + break; + case KBD_HOME: + // Handle home key + break; + case KBD_UP: + // Handle up arrow key + break; + case KBD_PAGEUP: + // Handle page up key + break; + case KBD_KP_MINUS: + // Handle keypad minus key + break; + case KBD_LEFT: + // Handle left arrow key + break; + case KBD_KP_5: + // Handle keypad 5 key + break; + case KBD_RIGHT: + // Handle right arrow key + break; + case KBD_KP_PLUS: + // Handle keypad plus key + break; + case KBD_END: + // Handle end key + break; + case KBD_DOWN: + // Handle down arrow key + break; + case KBD_PAGEDOWN: + // Handle page down key + break; + case KBD_INSERT: + // Handle insert key + break; + case KBD_DELETE: + // Handle delete key + break; + case KBD_SYSRQ: + // Handle system request key + break; + case KBD_F11: + // Handle F11 key + break; + case KBD_F12: + // Handle F12 key + break; + case KBD_KP_ENTER: + break; + case KBD_RCTRL: + // Handle right control key + break; + case KBD_KP_DIVIDE: + // Handle keypad divide key + break; + case KBD_PRINTSCREEN2: + // Handle print screen key (alternate) + break; + case KBD_RALT: + // Handle right alt key + break; + case KBD_HOME2: + // Handle home key (alternate) + break; + case KBD_UP2: + // Handle up arrow key (alternate) + break; + case KBD_PAGEUP2: + // Handle page up key (alternate) + break; + case KBD_LEFT2: + // Handle left arrow key (alternate) + break; + case KBD_RIGHT2: + // Handle right arrow key (alternate) + break; + case KBD_END2: + // Handle end key (alternate) + break; + case KBD_DOWN2: + // Handle down arrow key (alternate) + break; + case KBD_PAGEDOWN2: + // Handle page down key (alternate) + break; + case KBD_INSERT2: + // Handle insert key (alternate) + break; + case KBD_DELETE2: + // Handle delete key (alternate) + break; + default: + // Handle unknown scan codes + LOG("Unknown scan code\n"); + break; + } +eoi: + pic_send_eoi(1); +} diff --git a/kernel/task.c b/kernel/task.c index a46528e..b82f2b9 100644 --- a/kernel/task.c +++ b/kernel/task.c @@ -1,15 +1,39 @@ +#include "kernel/kernel.h" #include #include extern uint32_t boot_page_tab[1024]; extern kernel_ctx_t ctx; +//int task_init(task_t *task, uint32_t *img) { int task_init(task_t *task, elf_t *elf) { - section_t *text = elf_find_section(elf, ".text"); - if (!text) return 0; - task->eip = elf->e_entry + text->sh_offset; + + if (!elf) return 0; + uint8_t *s = (uint8_t *)mmap_find_first_free_block(); + /* + memset(s, 0, 0x1000); + int idx = 0; + // Loop section header to find ALLOC sections then allocate them + for (int i = 0; i < elf->e_shnum; i++) { + section_t *sec = (section_t *)((uint32_t)elf + elf->e_shoff + i*elf->e_shentsize); + if (!(sec->sh_flags & 0x2)) continue; + if (!sec->sh_addr) continue; + idx += sec->sh_offset; + memcpy(s + idx, (void *)((uint32_t)elf + sec->sh_offset), sec->sh_offset); + LOG("%d\n", sec->sh_offset); + } + */ + memcpy(s, elf, 0x1000); + + //section_t *text = elf_find_section(elf, ".text"); + //if (!text) return 0; + task->eip = elf->e_entry; // Allocate a page for a stack task->esp = (uint32_t)mmap_find_first_free_block() + 0x1000; + // Allocate a page for stdin + // LATER: Allow for allocating more on demand + task->stdin = (uint8_t *)mmap_find_first_free_block(); + task->stdin_len = 0; uint32_t *page_dir = mmap_find_first_free_block(); task->cr3 = (uint32_t)page_dir - KERNEL_VMA; @@ -24,11 +48,16 @@ int task_init(task_t *task, elf_t *elf) { } // Map the ELF image to its specified entry // This will cause problems if the ELF image is larger than 4 MiB so I need to fix this + //page_dir[PAGE_DIR_INDEX(elf->e_entry)] = ((uint32_t)page_tab - KERNEL_VMA) | 7; page_dir[PAGE_DIR_INDEX(elf->e_entry)] = ((uint32_t)page_tab - KERNEL_VMA) | 7; - uint32_t elf_phys = (uint32_t)elf - KERNEL_VMA; + + /* + uint32_t elf_phys = (uint32_t)s - KERNEL_VMA; for (int i = 0; i < 1024; i++) { page_tab[i] = (elf_phys + 0x1000*i) | 7; } + */ + page_tab[PAGE_TAB_INDEX(elf->e_entry)] = ((uint32_t)s - KERNEL_VMA) | 7; return 1; } diff --git a/peda-session-kernel.bin.txt b/peda-session-kernel.bin.txt index c6611c0..415bf53 100644 --- a/peda-session-kernel.bin.txt +++ b/peda-session-kernel.bin.txt @@ -1,2 +1,2 @@ -break pit_isr +break *(0x08048060) diff --git a/user/Makefile b/user/Makefile new file mode 100644 index 0000000..567cd97 --- /dev/null +++ b/user/Makefile @@ -0,0 +1,34 @@ +CC = i686-elf-gcc +ASM = nasm + +# Flags +CFLAGS = -ffreestanding -nostdlib -Wall -Wextra +ASMFLAGS = -f elf32 + +# Source files +C_SOURCES = $(wildcard *.c) +ASM_SOURCES = $(wildcard *.asm) + +# Object files +C_OBJECTS = $(C_SOURCES:.c=.o) +ASM_OBJECTS = $(ASM_SOURCES:.asm=.o) +OBJECTS = $(C_OBJECTS) $(ASM_OBJECTS) + +# Output binary +OUTPUT = ../boot/initrd + +.PHONY: all clean + +all: $(OUTPUT) + +$(OUTPUT): $(OBJECTS) + $(CC) -ffreestanding -nostdlib $(OBJECTS) -o $(OUTPUT) + +%.o: %.c + $(CC) $(CFLAGS) -c -o $@ $< + +%.o: %.asm + $(ASM) $(ASMFLAGS) -o $@ $< + +clean: + rm -f $(OBJECTS) $(OUTPUT) diff --git a/user/shell.c b/user/shell.c new file mode 100644 index 0000000..36aa38f --- /dev/null +++ b/user/shell.c @@ -0,0 +1,39 @@ +#include "../lib/strcmp.h" + +void puts(const char *str) { + asm volatile ( + "movl $1, %%eax\n\t" + "movl $1, %%edi\n\t" + "movl %0, %%esi\n\t" + "int $0x80" + : + : "r"(str) + : "%eax", "%edi", "%esi" + ); +} + +void read(int fd, void *buf, int size) { + asm volatile ( + "movl $0, %%eax\n\t" + "int $0x80" + : + : "D"(fd), "d"(size), "S"(buf) + : "eax" + ); +} + +extern char *buf; + +void _start() { + char buf1[256] = {0}; + puts("Welcome to the Hazel user shell!\n"); + while (1) { + puts("> "); + read(0, buf1, 256); + if (!strcmp(buf1, "SKIBIDI")) { + puts("dop dop yes yes!\n"); + } else { + puts("unknown command!\n"); + } + } +} diff --git a/user/userinit.asm b/user/userinit.asm deleted file mode 100644 index f7f0ae9..0000000 --- a/user/userinit.asm +++ /dev/null @@ -1,7 +0,0 @@ -[bits 32] -global _start -_start: - mov ecx, 0xDEADBEEF - mov eax, 1 - int 0x80 - jmp $