From 95cd78840f0891e60f5ebecc8a8eb4fbaf3c2ebf Mon Sep 17 00:00:00 2001 From: Danny Holman Date: Sun, 12 Jan 2025 01:17:36 -0600 Subject: PROJECT RESTRUCTURING Move the entire kernel into its own directory. Create new directories for system commands, libraries and other required essentials for a complete Unix-like operating system. Signed-off-by: Danny Holman --- .gitignore | 41 ++++++-- Makefile | 116 ++++----------------- arch/i386/boot/boot.s | 149 --------------------------- arch/i386/boot/crti.s | 15 --- arch/i386/boot/crtn.s | 7 -- arch/i386/include/kernel/asm.h | 158 ----------------------------- arch/i386/include/kernel/gdt.h | 53 ---------- arch/i386/include/kernel/idt.h | 31 ------ arch/i386/include/kernel/multiboot.h | 102 ------------------- arch/i386/include/kernel/paging.h | 46 --------- arch/i386/include/kernel/pic.h | 44 -------- arch/i386/include/kernel/pmem.h | 17 ---- arch/i386/include/kernel/syscall.h | 34 ------- arch/i386/include/kernel/timer.h | 9 -- arch/i386/include/kernel/vmem.h | 17 ---- arch/i386/kernel/gdt.c | 58 ----------- arch/i386/kernel/idt.c | 149 --------------------------- arch/i386/kernel/isr.s | 129 ------------------------ arch/i386/kernel/jump_userspace.s | 21 ---- arch/i386/kernel/kmalloc.c | 68 ------------- arch/i386/kernel/multiboot.c | 49 --------- arch/i386/kernel/paging.c | 130 ------------------------ arch/i386/kernel/pic.c | 79 --------------- arch/i386/kernel/pmem.c | 45 --------- arch/i386/kernel/serial.c | 42 -------- arch/i386/kernel/spinlock.s | 30 ------ arch/i386/kernel/stack_trace.s | 31 ------ arch/i386/kernel/switch_thread.s | 28 ------ arch/i386/kernel/syscall.c | 25 ----- arch/i386/kernel/timer.c | 24 ----- arch/i386/linker.ld | 30 ------ arch/i386/make.config | 20 ---- bin/Makefile | 18 ++++ drivers/input/keyboard.c | 142 -------------------------- drivers/video/framebuffer.c | 109 -------------------- etc/fstab | 4 + etc/group | 18 ++++ etc/passwd | 4 + etc/shadow | 4 + etc/shells | 4 + include/kernel/input/keyboard.h | 32 ------ include/kernel/interrupt.h | 13 --- include/kernel/panic.h | 10 -- include/kernel/sched.h | 20 ---- include/kernel/serial.h | 21 ---- include/kernel/video/framebuffer.h | 23 ----- include/kernel/video/vga.h | 33 ------ include/libk/container_of.h | 10 -- include/libk/data/list.h | 32 ------ include/libk/data/ringbuf.h | 50 --------- include/libk/io.h | 10 -- include/libk/kmalloc.h | 19 ---- include/libk/string.h | 19 ---- kernel/arch/x86/include/kernel/asm.h | 167 +++++++++++++++++++++++++++++++ kernel/arch/x86/include/kernel/gdt.h | 53 ++++++++++ kernel/arch/x86/include/kernel/idt.h | 31 ++++++ kernel/arch/x86/include/kernel/paging.h | 45 +++++++++ kernel/arch/x86/include/kernel/pic.h | 44 ++++++++ kernel/arch/x86/include/kernel/pmem.h | 19 ++++ kernel/arch/x86/include/kernel/syscall.h | 34 +++++++ kernel/arch/x86/include/kernel/timer.h | 9 ++ kernel/arch/x86/include/kernel/vmem.h | 17 ++++ kernel/arch/x86/kernel/gdt.c | 54 ++++++++++ kernel/arch/x86/kernel/idt.c | 149 +++++++++++++++++++++++++++ kernel/arch/x86/kernel/kmalloc.c | 70 +++++++++++++ kernel/arch/x86/kernel/multiboot.c | 49 +++++++++ kernel/arch/x86/kernel/paging.c | 130 ++++++++++++++++++++++++ kernel/arch/x86/kernel/pic.c | 79 +++++++++++++++ kernel/arch/x86/kernel/pmem.c | 66 ++++++++++++ kernel/arch/x86/kernel/serial.c | 42 ++++++++ kernel/arch/x86/kernel/syscall.c | 25 +++++ kernel/arch/x86/kernel/timer.c | 25 +++++ kernel/core/interrupt.c | 21 ++++ kernel/core/panic.c | 31 ++++++ kernel/core/sched.c | 74 ++++++++++++++ kernel/drivers/input/keyboard.c | 142 ++++++++++++++++++++++++++ kernel/drivers/video/framebuffer.c | 109 ++++++++++++++++++++ kernel/init.c | 35 ------- kernel/interrupt.c | 20 ---- kernel/libk/io.c | 78 +++++++++++++++ kernel/libk/string.c | 133 ++++++++++++++++++++++++ kernel/panic.c | 26 ----- kernel/sched.c | 74 -------------- lib/Makefile | 16 +++ libk/io.c | 78 --------------- libk/stack_protector.c | 9 -- libk/string.c | 133 ------------------------ sbin/Makefile | 17 ++++ usr.bin/Makefile | 17 ++++ usr.sbin/Makefile | 17 ++++ 90 files changed, 1866 insertions(+), 2664 deletions(-) delete mode 100644 arch/i386/boot/boot.s delete mode 100644 arch/i386/boot/crti.s delete mode 100644 arch/i386/boot/crtn.s delete mode 100644 arch/i386/include/kernel/asm.h delete mode 100644 arch/i386/include/kernel/gdt.h delete mode 100644 arch/i386/include/kernel/idt.h delete mode 100644 arch/i386/include/kernel/multiboot.h delete mode 100644 arch/i386/include/kernel/paging.h delete mode 100644 arch/i386/include/kernel/pic.h delete mode 100644 arch/i386/include/kernel/pmem.h delete mode 100644 arch/i386/include/kernel/syscall.h delete mode 100644 arch/i386/include/kernel/timer.h delete mode 100644 arch/i386/include/kernel/vmem.h delete mode 100644 arch/i386/kernel/gdt.c delete mode 100644 arch/i386/kernel/idt.c delete mode 100644 arch/i386/kernel/isr.s delete mode 100644 arch/i386/kernel/jump_userspace.s delete mode 100644 arch/i386/kernel/kmalloc.c delete mode 100644 arch/i386/kernel/multiboot.c delete mode 100644 arch/i386/kernel/paging.c delete mode 100644 arch/i386/kernel/pic.c delete mode 100644 arch/i386/kernel/pmem.c delete mode 100644 arch/i386/kernel/serial.c delete mode 100644 arch/i386/kernel/spinlock.s delete mode 100644 arch/i386/kernel/stack_trace.s delete mode 100644 arch/i386/kernel/switch_thread.s delete mode 100644 arch/i386/kernel/syscall.c delete mode 100644 arch/i386/kernel/timer.c delete mode 100644 arch/i386/linker.ld delete mode 100644 arch/i386/make.config create mode 100644 bin/Makefile delete mode 100644 drivers/input/keyboard.c delete mode 100644 drivers/video/framebuffer.c create mode 100644 etc/fstab create mode 100644 etc/group create mode 100644 etc/passwd create mode 100644 etc/shadow create mode 100644 etc/shells delete mode 100644 include/kernel/input/keyboard.h delete mode 100644 include/kernel/interrupt.h delete mode 100644 include/kernel/panic.h delete mode 100644 include/kernel/sched.h delete mode 100644 include/kernel/serial.h delete mode 100644 include/kernel/video/framebuffer.h delete mode 100644 include/kernel/video/vga.h delete mode 100644 include/libk/container_of.h delete mode 100644 include/libk/data/list.h delete mode 100644 include/libk/data/ringbuf.h delete mode 100644 include/libk/io.h delete mode 100644 include/libk/kmalloc.h delete mode 100644 include/libk/string.h create mode 100644 kernel/arch/x86/include/kernel/asm.h create mode 100644 kernel/arch/x86/include/kernel/gdt.h create mode 100644 kernel/arch/x86/include/kernel/idt.h create mode 100644 kernel/arch/x86/include/kernel/paging.h create mode 100644 kernel/arch/x86/include/kernel/pic.h create mode 100644 kernel/arch/x86/include/kernel/pmem.h create mode 100644 kernel/arch/x86/include/kernel/syscall.h create mode 100644 kernel/arch/x86/include/kernel/timer.h create mode 100644 kernel/arch/x86/include/kernel/vmem.h create mode 100644 kernel/arch/x86/kernel/gdt.c create mode 100644 kernel/arch/x86/kernel/idt.c create mode 100644 kernel/arch/x86/kernel/kmalloc.c create mode 100644 kernel/arch/x86/kernel/multiboot.c create mode 100644 kernel/arch/x86/kernel/paging.c create mode 100644 kernel/arch/x86/kernel/pic.c create mode 100644 kernel/arch/x86/kernel/pmem.c create mode 100644 kernel/arch/x86/kernel/serial.c create mode 100644 kernel/arch/x86/kernel/syscall.c create mode 100644 kernel/arch/x86/kernel/timer.c create mode 100644 kernel/core/interrupt.c create mode 100644 kernel/core/panic.c create mode 100644 kernel/core/sched.c create mode 100644 kernel/drivers/input/keyboard.c create mode 100644 kernel/drivers/video/framebuffer.c delete mode 100644 kernel/init.c delete mode 100644 kernel/interrupt.c create mode 100644 kernel/libk/io.c create mode 100644 kernel/libk/string.c delete mode 100644 kernel/panic.c delete mode 100644 kernel/sched.c create mode 100644 lib/Makefile delete mode 100644 libk/io.c delete mode 100644 libk/stack_protector.c delete mode 100644 libk/string.c create mode 100644 sbin/Makefile create mode 100644 usr.bin/Makefile create mode 100644 usr.sbin/Makefile diff --git a/.gitignore b/.gitignore index a9a564b..dbc549a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,6 @@ # Normal rules .* *.a -*.bin *.bz2 *.c.* *.d @@ -21,14 +20,40 @@ *.xz *.zst -# Top-level files -/vmbox -/a.img -/bochsrc -/debug.log +# Built exec's +bin/cat/cat +bin/chmod/chmod +bin/chown/chown +bin/cp/cp +bin/date/date +bin/echo/echo +bin/kill/kill +bin/login/login +bin/ls/ls +bin/man/man +bin/mv/mv +bin/ps/ps +bin/pwd/pwd +bin/sh/sh +bin/su/su +bin/touch/touch +kernel/vmbox +sbin/init/init +sbin/mknod/mknod +sbin/mount/mount +sbin/nologin/nologin +sbin/shutdown/shutdown +sbin/umount/umount +usr.sbin/bxpkg/bxpkg +usr.sbin/cron/cron +usr.sbin/gfdisk/gfdisk +usr.sbin/mkfs.fat/mkfs.fat +usr.sbin/useradd/useradd +usr.sbin/usermod/usermod -# Image generation files -/img/ +# Built libs +lib/libc/libc.so +lib/libm/libm.so # Don't ignore these! !.gitattributes diff --git a/Makefile b/Makefile index 5525936..50d1fc5 100644 --- a/Makefile +++ b/Makefile @@ -1,110 +1,30 @@ -INCLUDE?=-Iinclude -CFLAGS?=-O0 -ffreestanding -std=gnu11 -LDFLAGS?=-nostdlib -LIBS?=-lgcc -ARCH?=i386 +ARCH?=x86 +DESTDIR?=base-system +PREFIX?=/usr # -- Do not edit below this line -- -CC:=i686-elf-gcc VERSION:="$(shell git describe --abbrev=4 --dirty --always --tags)" -INCLUDE:=$(INCLUDE) -CFLAGS:=$(CFLAGS) -Wall -Wextra -DVERSION=\"$(VERSION)\" -ggdb -fstack-protector-all -LDFLAGS:=$(LDFLAGS) -LIBS:=$(LIBS) ARCH:=$(ARCH) +DESTDIR:=base-system/ +PREFIX:=/usr/ +export ARCH VERSION PREFIX -ARCHDIR=arch/$(ARCH) +SUBDIRS:=kernel \ + bin \ + lib \ + sbin \ + usr.sbin \ -include $(ARCHDIR)/make.config +.PHONY: all clean install install-headers $(SUBDIRS) -CFLAGS:=$(CFLAGS) $(KERNEL_ARCH_CFLAGS) -LDFLAGS:=$(LDFLAGS) $(KERNEL_ARCH_LDFLAGS) -LIBS:=$(LIBS) $(KERNEL_ARCH_LIBS) +all: $(SUBDIRS) -KERNEL=vmbox +subdirs: $(SUBDIRS) -LIBK_OBJS=libk/string.o \ - libk/io.o \ - libk/stack_protector.o \ - libk/ubsan.o \ +$(SUBDIRS): + $(MAKE) $(MAKECMDGOALS) -C $@ -KERNEL_OBJS=$(KERNEL_ARCH_OBJS) \ - kernel/init.o \ - kernel/panic.o \ - kernel/vfs.o \ - kernel/sched.o \ - kernel/kthread.o \ +clean: $(SUBDIRS) -DRIVER_OBJS=drivers/video/framebuffer.o \ - drivers/input/keyboard.o \ - drivers/pci/pci.o \ - drivers/pci/ide.o \ - drivers/tty/tty_vga.o \ - -OBJS=$(ARCHDIR)/boot/crti.o \ - $(ARCHDIR)/crtbegin.o \ - $(KERNEL_OBJS) \ - $(DRIVER_OBJS) \ - $(LIBK_OBJS) \ - $(ARCHDIR)/crtend.o \ - $(ARCHDIR)/boot/crtn.o \ - -LINK_LIST=$(LDFLAGS) \ - $(KERNEL_OBJS) \ - $(DRIVER_OBJS) \ - $(LIBK_OBJS) \ - $(LIBS) \ - -.PHONY: all clean install install-headers install-kernel -.SUFFIXES: .o .c .s - -all: $(KERNEL) - -$(KERNEL): $(OBJS) $(ARCHDIR)/linker.ld - @$(CC) -T $(ARCHDIR)/linker.ld -o $@ $(LINK_LIST) - @echo [LD] $@ - -$(ARCHDIR)/crtbegin.o $(ARCHDIR)/crtend.o: - @OBJ=`$(CC) $(CFLAGS) $(LDFLAGS) -print-file-name=$(@F)` && cp "$$OBJ" $@ - -.c.o: - @$(CC) -MD -c $< -o $@ $(CFLAGS) $(INCLUDE) - @echo [CC] $@ - -.s.o: - @$(CC) -MD -c $< -o $@ $(CFLAGS) $(INCLUDE) - @echo [AS] $@ - -clean: - $(RM) $(KERNEL) - $(RM) $(OBJS) *.o */*.o */*/*.o - $(RM) $(OBJS:.o=.d) *.d */*.d */*/*.d - -install: install-headers install-kernel - -install-headers: - mkdir -p $(DESTDIR)$(INCLUDEDIR) - cp -R --preserve-timestamps include/. $(DESTDIR)$(INCLUDEDIR)/. - -install-kernel: $(KERNEL) - mkdir -p $(DESTDIR)$(BOOTDIR) - cp $(KERNEL) $(DESTDIR)$(BOOTDIR) - -install-disk: $(KERNEL) - rm a.img - bximage -q -func=create -fd=1.44M a.img - mkdosfs a.img - syslinux -i a.img - mcopy -i a.img img/libcom32.c32 ::libcom32.c32 - mcopy -i a.img img/mboot.c32 ::mboot.c32 - mcopy -i a.img img/syslinux.cfg ::syslinux.cfg - mcopy -i a.img vmbox ::vmbox - -run: $(KERNEL) - qemu-system-i386 -kernel $(KERNEL) -serial stdio -m 1G -drive file=a.img,format=raw -append "root=/dev/sda init=/bin/sh" - -debug: $(KERNEL) - qemu-system-i386 -kernel $(KERNEL) -s -S -m 1G -drive file=a.img,format=raw -append "root=/dev/sda init=/bin/sh" & - --include $(OBJS:.o=.d) +install: $(SUBDIRS) diff --git a/arch/i386/boot/boot.s b/arch/i386/boot/boot.s deleted file mode 100644 index 5357910..0000000 --- a/arch/i386/boot/boot.s +++ /dev/null @@ -1,149 +0,0 @@ -.set ALIGN, 1<<0 -.set MEMINFO, 1<<1 -.set FLAGS, ALIGN | MEMINFO -.set MAGIC, 0x1BADB002 -.set CHECKSUM, -(MAGIC + FLAGS) - -.section .multiboot.data, "aw" -.align 4 -.long MAGIC -.long FLAGS -.long CHECKSUM - -.section .bootstrap_stack, "aw", @nobits -stack_bottom: -.skip 16384 -stack_top: - -.section .bss, "aw", @nobits - .align 4096 -boot_page_directory: - .skip 4096 -boot_page_table0: - .skip 4096 -boot_page_table1: - .skip 4096 - -.section .multiboot.text, "a" -.global _start -.type _start, @function -_start: - movl $(boot_page_table0 - 0xC0000000), %edi - movl $0, %esi - movl $1023, %ecx - -1: cmpl $_kernel_start, %esi - jl 2f - cmpl $(_kernel_end - 0xC0000000), %esi - jge 3f - - movl %esi, %edx - orl $0x003, %edx - movl %edx, (%edi) - -2: addl $4096, %esi - addl $4, %edi - loop 1b - - -3: movl $boot_page_directory, %ecx - subl $0xC0000000, %ecx - orl $0x003, %ecx - movl %ecx, boot_page_directory - 0xC0000000 + 1023 * 4 - - movl $boot_page_table0, %ecx - subl $0xC0000000, %ecx - orl $0x003, %ecx - movl %ecx, boot_page_directory - 0xC0000000 - movl %ecx, boot_page_directory - 0xC0000000 + 768 * 4 - - movl $boot_page_table1, %ecx - subl $0xC0000000, %ecx - orl $0x003, %ecx - movl %ecx, boot_page_directory - 0xC0000000 + 1022 * 4 - - movl $boot_page_directory, %ecx - subl $0xC0000000, %ecx - movl %ecx, %cr3 - - movl %cr0, %ecx - orl $0x80000000, %ecx - movl %ecx, %cr0 - - lea 4f, %ecx - jmp *%ecx - -.section .text - -4: movl $stack_top, %esp - and $-16, %esp - - call setup_stack_guard - - xorl %ebp, %ebp - pushl %ebx - pushl %eax - call i386_entry - - cli -1: hlt - jmp 1b - -.global setup_stack_guard -.type setup_stack_guard, @function -setup_stack_guard: - pushl %eax - pushl %ebx - pushl %ecx - - movl $1, %eax - movl $0, %ecx - cpuid - shrl $30, %ecx - andl $1, %ecx - jnz start_loop - jmp fail -start_loop: - rdrand %eax - jc done - loop start_loop -fail: - movl $-1, %eax -done: - movl %eax, __stack_chk_guard - popl %ecx - popl %ebx - popl %eax - ret - -.global enable_paging -.type enable_paging, @function -enable_paging: - pushl %ebp - movl %esp, %ebp - - movl 8(%esp), %eax - movl %eax, %cr3 - - movl %cr0, %eax - orl $0x80000001, %eax - movl %eax, %cr0 - - movl $0, %eax - popl %ebp - ret - -.global flush_gdt -.type flush_gdt, @function -flush_gdt: - cli - lgdt (gp) - movw $0x10, %ax - movw %ax, %ds - movw %ax, %es - movw %ax, %fs - movw %ax, %gs - movw %ax, %ss - jmp $0x08, $.flush -.flush: - ret diff --git a/arch/i386/boot/crti.s b/arch/i386/boot/crti.s deleted file mode 100644 index 8386b77..0000000 --- a/arch/i386/boot/crti.s +++ /dev/null @@ -1,15 +0,0 @@ -.section .init - -.global _init -.type _init, @function -_init: - pushl %ebp - movl %esp, %ebp - -.section .fini - -.global _fini -.type _fini, @function -_fini: - pushl %ebp - movl %esp, %ebp diff --git a/arch/i386/boot/crtn.s b/arch/i386/boot/crtn.s deleted file mode 100644 index 447afb1..0000000 --- a/arch/i386/boot/crtn.s +++ /dev/null @@ -1,7 +0,0 @@ -.section .init - popl %ebp - ret - -.section .fini - popl %ebp - ret diff --git a/arch/i386/include/kernel/asm.h b/arch/i386/include/kernel/asm.h deleted file mode 100644 index cc570c5..0000000 --- a/arch/i386/include/kernel/asm.h +++ /dev/null @@ -1,158 +0,0 @@ -#ifndef I386_ASM_H -#define I386_ASM_H - -#include -#include - -#define PCI_CONFIG_ADDR 0xCF8 -#define PCI_CONFIG_DATA 0xCFC - -#define COM_PORT 0x3F8 - -#define MAX_ISR 256 - -struct regs { - uint32_t eax; - uint32_t ebx; - uint32_t ecx; - uint32_t edx; - uint32_t esi; - uint32_t edi; - uint32_t ebp; - uint32_t esp; - - uint32_t cr0; - uint32_t cr2; - uint32_t cr3; - uint32_t cr4; -}; - -struct isr_frame { - uint32_t cr4; - uint32_t cr3; - uint32_t cr2; - uint32_t cr0; - - uint32_t edi; - uint32_t esi; - uint32_t edx; - uint32_t ecx; - uint32_t ebx; - uint32_t eax; - - uint32_t isr_vector; - uint32_t isr_err; - uint32_t eip; - uint32_t cs; - uint32_t eflags; -} __attribute__((packed)); - -void isr_stub_0(void); -void isr_stub_1(void); -void isr_stub_2(void); -void isr_stub_3(void); -void isr_stub_4(void); -void isr_stub_5(void); -void isr_stub_6(void); -void isr_stub_7(void); -void isr_stub_8(void); -void isr_stub_9(void); -void isr_stub_10(void); -void isr_stub_11(void); -void isr_stub_12(void); -void isr_stub_13(void); -void isr_stub_14(void); -void isr_stub_15(void); -void isr_stub_16(void); -void isr_stub_17(void); -void isr_stub_18(void); -void isr_stub_19(void); -void isr_stub_20(void); -void isr_stub_21(void); -void isr_stub_22(void); -void isr_stub_23(void); -void isr_stub_24(void); -void isr_stub_25(void); -void isr_stub_26(void); -void isr_stub_27(void); -void isr_stub_28(void); -void isr_stub_29(void); -void isr_stub_30(void); -void isr_stub_31(void); - -void irq_stub_0(void); -void irq_stub_1(void); -void irq_stub_2(void); -void irq_stub_3(void); -void irq_stub_4(void); -void irq_stub_5(void); -void irq_stub_6(void); -void irq_stub_7(void); -void irq_stub_8(void); -void irq_stub_9(void); -void irq_stub_10(void); -void irq_stub_11(void); -void irq_stub_12(void); -void irq_stub_13(void); -void irq_stub_14(void); -void irq_stub_15(void); - -void isr_stub_128(void); - -void aquire_lock(int *lock); -void release_lock(int *lock); - -void enable_paging(uint32_t new_cr3); -void flush_gdt(void); - -static inline void outb(uint16_t port, uint8_t value) { - __asm__ volatile("outb %0, %1" : : "a"(value), "Nd"(port)); -} - -static inline void outw(uint16_t port, uint16_t value) { - __asm__ volatile("outw %0, %1" : : "a"(value), "Nd"(port)); -} - -static inline void outl(uint16_t port, uint32_t value) { - __asm__ volatile("outl %0, %1" : : "a"(value), "Nd"(port)); -} - -static inline uint8_t inb(uint16_t port) { - uint8_t ret; - __asm__ volatile("inb %1, %0" : "=a"(ret) : "Nd"(port)); - return ret; -} - -static inline uint16_t inw(uint16_t port) { - uint16_t ret; - __asm__ volatile("inw %1, %0" : "=a"(ret) : "Nd"(port)); - return ret; -} - -static inline uint32_t inl(uint16_t port) { - uint32_t ret; - __asm__ volatile("inl %1, %0" : "=a"(ret) : "Nd"(port)); - return ret; -} - -static inline void enable_ints(void) { - __asm__ volatile("sti"); -} - -static inline void disable_ints(void) { - __asm__ volatile("cli"); -} - -static inline void flush_tss(void) { - __asm__ volatile("movw $0x28, %ax; ltr %ax"); -} - -static inline void flush_tlb(void) { - __asm__ volatile("movl %cr3, %eax; movl %eax, %cr3"); -} - -static inline void invlpg(void *addr) { - __asm__ volatile("invlpg (%0)" : : "b"(addr) : "memory"); -} - -#endif diff --git a/arch/i386/include/kernel/gdt.h b/arch/i386/include/kernel/gdt.h deleted file mode 100644 index ec02719..0000000 --- a/arch/i386/include/kernel/gdt.h +++ /dev/null @@ -1,53 +0,0 @@ -#ifndef I386_GDT_H -#define I386_GDT_H - -#include - -struct gdt_entry { - uint16_t limit_low; - uint16_t base_low; - uint8_t base_middle; - uint8_t access; - uint8_t gran; - uint8_t base_high; -} __attribute__((packed)); - -struct gdt_ptr { - uint16_t limit; - uint32_t base; -} __attribute__((packed)); - -struct tss_entry { - uint32_t link; - uint32_t esp0; - uint32_t ss0; - uint32_t esp1; - uint32_t ss2; - uint32_t cr3; - uint32_t eip; - uint32_t eflags; - uint32_t eax; - uint32_t ecx; - uint32_t edx; - uint32_t ebx; - uint32_t esp; - uint32_t ebp; - uint32_t esi; - uint32_t edi; - uint32_t es; - uint32_t cs; - uint32_t ss; - uint32_t ds; - uint32_t fs; - uint32_t gs; - uint32_t ldtr; - uint16_t trap; - uint16_t iomap_base; -} __attribute__((packed)); - -void gdt_set_gate(int num, uint32_t base, uint32_t limit, uint8_t access, uint8_t gran); -void write_tss(int num, uint32_t ss0, uint32_t esp0); -void set_kernel_esp(uint32_t esp); -void gdt_install(void); - -#endif diff --git a/arch/i386/include/kernel/idt.h b/arch/i386/include/kernel/idt.h deleted file mode 100644 index 29ec39f..0000000 --- a/arch/i386/include/kernel/idt.h +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef I386_IDT_H -#define I386_IDT_H - -#include - -#define SEGMENT_PRESENT 0x80 -#define SEGMENT_RING0 0x00 -#define SEGMENT_RING3 0x60 -#define SEGMENT_STORAGE 0x00 -#define SEGMENT_INTERRUPT 0x0E -#define IDT_EXCEPTION (SEGMENT_PRESENT | SEGMENT_INTERRUPT) -#define IDT_INTERRUPT (SEGMENT_PRESENT | SEGMENT_INTERRUPT) - -#define IDT_MAX_DESCRIPTORS 256 - -struct idt_entry { - uint16_t isr_low; - uint16_t kernel_cs; - uint8_t reserved; - uint8_t flags; - uint16_t isr_high; -} __attribute__((packed)); - -struct idt_ptr { - uint16_t limit; - uint32_t base; -} __attribute__((packed)); - -void idt_install(void); - -#endif diff --git a/arch/i386/include/kernel/multiboot.h b/arch/i386/include/kernel/multiboot.h deleted file mode 100644 index abbd8a9..0000000 --- a/arch/i386/include/kernel/multiboot.h +++ /dev/null @@ -1,102 +0,0 @@ -#ifndef I386_MULTIBOOT_H -#define I386_MULTIBOOT_H - -#include - -#define MBOOT_HEADER_MAGIC 0x1BADB002 -#define MBOOT_LOADER_MAGIC 0x2BADB002 - -// Multiboot flags -#define MBOOT_INFO_MMAP 0x00000001 -#define MBOOT_INFO_BOOTDEV 0x00000002 -#define MBOOT_INFO_CMDLINE 0x00000004 -#define MBOOT_INFO_MODS 0x00000008 -#define MBOOT_INFO_AOUT_SYMS 0x00000010 -#define MBOOT_INFO_ELF_HEADER 0x00000020 -#define MBOOT_INFO_MEM_MAP 0x00000040 -#define MBOOT_INFO_DRIVE_INFO 0x00000080 -#define MBOOT_INFO_CONFIG_TBL 0x00000100 -#define MBOOT_INFO_BL_NAME 0x00000200 -#define MBOOT_INFO_APM_TBL 0x00000400 -#define MBOOT_INFO_VBE 0x00000800 -#define MBOOT_INFO_FRAMEBUFFER 0x00001000 - -// Memory types -#define MBOOT_MEM_AVAILABLE 1 -#define MBOOT_MEM_RESERVED 2 -#define MBOOT_MEM_ACPI_REC 3 -#define MBOOT_MEM_NVS 4 -#define MBOOT_MEM_BADRAM 5 - -struct aout_symbol_table { - uint32_t tabsize; - uint32_t strsize; - uint32_t addr; - uint32_t reserved; -}; - -struct elf_section_header { - uint32_t num; - uint32_t size; - uint32_t addr; - uint32_t shndx; -}; - -struct mboot_header { - uint32_t magic; - uint32_t flags; - uint32_t checksum; - uint32_t header_addr; - uint32_t load_addr; - uint32_t load_end_addr; - uint32_t bss_end_addr; - uint32_t entry_addr; - uint32_t mode_type; - uint32_t width; - uint32_t height; - uint32_t depth; -}; - -struct mboot_info { - uint32_t flags; - uint32_t mem_lower; - uint32_t mem_upper; - uint32_t boot_device; - uint32_t cmdline; - uint32_t mods_count; - uint32_t mods_addr; - union { - struct aout_symbol_table aout_sym; - struct elf_section_header elf_sec; - } u; - uint32_t mmap_length; - uint32_t mmap_addr; - uint32_t drives_length; - uint32_t drives_addr; - uint32_t config_table; - uint32_t boot_loader_name; - uint32_t apm_table; - uint32_t vbe_control_info; - uint32_t vbe_mode_info; - uint16_t vbe_mode; - uint16_t vbe_interface_seg; - uint16_t vbe_interface_off; - uint16_t vbe_interface_len; - uint64_t framebuffer_addr; - uint32_t framebuffer_pitch; - uint32_t framebuffer_width; - uint32_t framebuffer_height; - uint8_t framebuffer_bpp; - uint8_t framebuffer_type; -}; - -struct mboot_mmap_entry { - uint32_t size; - uint32_t addr_low; - uint32_t addr_high; - uint32_t len_low; - uint32_t len_high; - uint32_t type; -} __attribute__((packed)); - -#endif diff --git a/arch/i386/include/kernel/paging.h b/arch/i386/include/kernel/paging.h deleted file mode 100644 index d8bb8f3..0000000 --- a/arch/i386/include/kernel/paging.h +++ /dev/null @@ -1,46 +0,0 @@ -#ifndef I386_PAGING_H -#define I386_PAGING_H - -#include -#include -#include - -#define PAGE_SIZE 4096 - -#define PD_PRES 0x0001 -#define PD_RW 0x0002 -#define PD_USR 0x0004 -#define PD_PWT 0x0008 -#define PD_PCD 0x0010 -#define PD_ACC 0x0020 -#define PD_DIRTY 0x0040 -#define PD_PS 0x0080 -#define PD_GLOB 0x0100 -#define PD_PAT 0x1000 - -#define ERR_PRESENT 0x1 -#define ERR_RW 0x2 -#define ERR_USER 0x4 -#define ERR_RESERVED 0x8 -#define ERR_INST 0x10 - -#define PGROUNDUP(size) (((size)+PAGE_SIZE-1) & ~(PAGE_SIZE-1)) -#define PGROUNDDN(size) (((size)) & ~(PAGE_SIZE-1)) - -#define GET_PADDR(x) (((uint32_t)(x)) - 0xC0000000) -#define GET_VADDR(x) (((uint32_t)(x)) + 0xC0000000) - -#define GET_PDX(x) ((uintptr_t)(x) >> 22) -#define GET_PTX(x) (((uintptr_t)(x) >> 12) & 0x03FF) - -uintptr_t get_physaddr(void *vaddr); - -void paging_init(void); - -uintptr_t init_page_directory(void); -void map_page(uintptr_t paddr, uintptr_t vaddr, uint32_t flags); -void unmap_page(uintptr_t vaddr); - -void page_fault_handler(struct isr_frame *frame); - -#endif diff --git a/arch/i386/include/kernel/pic.h b/arch/i386/include/kernel/pic.h deleted file mode 100644 index 187d553..0000000 --- a/arch/i386/include/kernel/pic.h +++ /dev/null @@ -1,44 +0,0 @@ -#ifndef I386_PIC_H -#define I386_PIC_H - -#include -#include - -#define PIC1 0x20 -#define PIC2 0x28 -#define PIC1_COMMAND PIC1 -#define PIC1_DATA (PIC1+1) -#define PIC2_COMMAND PIC2 -#define PIC2_DATA (PIC2+1) - -#define ICW1_ICW4 0x01 -#define ICW1_SINGLE 0x02 -#define ICW1_INTERVAL4 0x04 -#define ICW1_LEVEL 0x08 -#define ICW1_INIT 0x10 - -#define ICW4_8086 0x01 -#define ICW4_AUTO 0x02 -#define ICW4_BUF_SLAVE 0x08 -#define ICW4_BUF_MASTER 0x0C -#define ICW4_SFNM 0x10 - -#define PIC_READ_IRR 0x0A -#define PIC_READ_ISR 0x0B - -static inline void io_wait(void) { - outb(0x80, 0); -} - -void pic_eoi(uint8_t irq); -void pic_remap(void); -uint16_t pic_get_irr(void); -uint16_t pic_get_isr(void); - -void register_irq_handler(uint8_t irq, void (*handler)(struct isr_frame *frame)); -void irq_dispatch(struct isr_frame *frame); - -void irq_set_mask(uint8_t irq); -void irq_clear_mask(uint8_t irq); - -#endif diff --git a/arch/i386/include/kernel/pmem.h b/arch/i386/include/kernel/pmem.h deleted file mode 100644 index e6e4f57..0000000 --- a/arch/i386/include/kernel/pmem.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef I386_PMEM_H -#define I386_PMEM_H - -#include -#include -#include - -struct pfa_page { - struct pfa_page *next; -}; - -void pfa_init(struct mboot_info *header); - -void pfa_free_dma(uintptr_t paddr, size_t num_pages); -void pfa_free(uintptr_t paddr, size_t num_pages); - -#endif diff --git a/arch/i386/include/kernel/syscall.h b/arch/i386/include/kernel/syscall.h deleted file mode 100644 index a657527..0000000 --- a/arch/i386/include/kernel/syscall.h +++ /dev/null @@ -1,34 +0,0 @@ -#ifndef I386_SYSCALL_H -#define I386_SYSCALL_H - -#include -#include -#include - -// Unix standard calls -#define SYS_FORK 1 -#define SYS_EXIT 2 -#define SYS_WAIT 3 -#define SYS_PIPE 4 -#define SYS_READ 5 -#define SYS_WRITE 6 -#define SYS_KILL 7 -#define SYS_FSTAT 8 -#define SYS_CHDIR 9 -#define SYS_DUP 10 -#define SYS_GETPID 11 -#define SYS_SLEEP 12 -#define SYS_OPEN 13 -#define SYS_MKNOD 14 -#define SYS_UNLINK 15 -#define SYS_LINK 16 -#define SYS_MKDIR 17 -#define SYS_CLOSE 18 -#define SYS_EXEC 19 - -#define SYS_HALT 87 -#define SYS_REBOOT 88 - -void handle_syscall(struct isr_frame *frame); - -#endif diff --git a/arch/i386/include/kernel/timer.h b/arch/i386/include/kernel/timer.h deleted file mode 100644 index c0b3a73..0000000 --- a/arch/i386/include/kernel/timer.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef I386_TIMER_H -#define I386_TIMER_H - -#include - -void timer_handler(struct isr_frame *frame); -void timer_init(void); - -#endif diff --git a/arch/i386/include/kernel/vmem.h b/arch/i386/include/kernel/vmem.h deleted file mode 100644 index 94aa32d..0000000 --- a/arch/i386/include/kernel/vmem.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef I386_VMEM_H -#define I386_VMEM_H - -extern uintptr_t _kernel_start; -extern uintptr_t _kernel_end; - -#define KSTART ((uintptr_t)&_kernel_start) -#define KEND ((uintptr_t)&_kernel_end - 0xC0000000) - -#define KHEAP_START (GET_VADDR(KEND) + 0x2000) -#define KHEAP_STOP 0xFF7FF000 - -#define PAGE_DIR_MAP 0xFFFFF000 -#define PAGE_TAB_MAP 0xFFC00000 -#define PAGE_TMP_MAP 0xFFBFF000 - -#endif diff --git a/arch/i386/kernel/gdt.c b/arch/i386/kernel/gdt.c deleted file mode 100644 index 0d9e1d2..0000000 --- a/arch/i386/kernel/gdt.c +++ /dev/null @@ -1,58 +0,0 @@ -#include -#include -#include - -struct gdt_entry desc[6]; -struct gdt_ptr gp; -struct tss_entry tss_entry; - -void gdt_set_gate(int num, uint32_t base, uint32_t limit, uint8_t access, uint8_t gran) { - desc[num].base_low = (base & 0xFFFF); - desc[num].base_middle = (base >> 16) & 0xFF; - desc[num].base_high = (base >> 24) & 0xFF; - - desc[num].limit_low = (limit & 0xFFFF); - desc[num].gran = (limit >> 16) & 0x0F; - desc[num].gran |= (gran & 0xF0); - desc[num].access = access; -} - -void write_tss(int num, uint32_t ss0, uint32_t esp0) { - uint32_t base = (uint32_t)&tss_entry; - uint32_t limit = base + sizeof(struct tss_entry); - - gdt_set_gate(num, base, limit, 0x89, 0x00); - memset(&tss_entry, 0x0, sizeof(tss_entry)); - - tss_entry.ss0 = ss0; - tss_entry.esp0 = esp0; - tss_entry.cs = 0x0B; - tss_entry.ss = 0x13; - tss_entry.ds = 0x13; - tss_entry.es = 0x13; - tss_entry.fs = 0x13; - tss_entry.gs = 0x13; - tss_entry.iomap_base = sizeof(tss_entry); -} - -void set_kernel_esp(uint32_t esp) { - tss_entry.esp0 = esp; -} - -void gdt_install(void) { - gp.limit = (sizeof(struct gdt_entry) * 6) - 1; - gp.base = (uint32_t)&desc; - - gdt_set_gate(0, 0, 0, 0, 0); - gdt_set_gate(1, 0, 0xFFFFF, 0x9A, 0xCF); - gdt_set_gate(2, 0, 0xFFFFF, 0x92, 0xCF); - gdt_set_gate(3, 0, 0xFFFFF, 0xFA, 0xCF); - gdt_set_gate(4, 0, 0xFFFFF, 0xF2, 0xCF); - - uint32_t esp; - __asm__ volatile("movl %%esp, %0" : "=r"(esp)); - write_tss(5, 0x10, esp); - - flush_gdt(); - flush_tss(); -} diff --git a/arch/i386/kernel/idt.c b/arch/i386/kernel/idt.c deleted file mode 100644 index a178801..0000000 --- a/arch/i386/kernel/idt.c +++ /dev/null @@ -1,149 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -__attribute__((aligned(0x10))) -struct idt_entry idt[256]; -struct idt_ptr idtr; - -const char* exceptions[] = { - "Division by zero", - "Debug", - "Non-maskable interrupt", - "Breakpoint", - "Overflow", - "Out-of-bounds", - "Invalid opcode", - "FPU not available", - "Double fault", - "RESERVED", - "Invalid TSS", - "Segment not present", - "Stack fault", - "General protection fault", - "Page fault", - "RESERVED", - "FPU exception", - "Alignment check", - "Machine check", - "FPU-SIMD exception", - "Virtualization exception", - "Control protection" - "RESERVED", - "Hypervisor injection", - "VMM exception", - "Security exception", - "RESERVED", - "Triple fault", - "RESERVED" -}; - -void exception_handler(struct isr_frame *frame) { - switch (frame->isr_vector) { - case 0x00: - panic("Division by zero in kernel address space"); - break; - case 0x06: - panic("Invalid opcode in kernel address space"); - break; - case 0x08: - panic("Double fault in interrupt handler"); - break; - case 0x0D: - panic("Protection fault in kernel address space"); - break; - case 0x0E: - page_fault_handler(frame); - break; - default: - panic("Unhandled exception"); - } -} - -void generic_handler(struct isr_frame *frame) { - kprintf("No handler registered for IRQ %d\n", frame->isr_vector); - if (frame->isr_vector > 32 && frame->isr_vector < 48) - pic_eoi(frame->isr_vector-32); -} - -void idt_set_gate(uint8_t num, void (*handler)(void), uint16_t cs, uint8_t flags) { - struct idt_entry *desc = &idt[num]; - desc->isr_low = (uint16_t)(((uint32_t)handler >> 0) & 0xFFFF); - desc->isr_high = (uint16_t)(((uint32_t)handler >> 16) & 0xFFFF); - desc->reserved = 0; - desc->kernel_cs = cs; - desc->flags = flags; -} - -void idt_install(void) { - idtr.limit = (uint16_t)sizeof(struct idt_entry) * 256 - 1; - idtr.base = (uint32_t)idt; - - for (int i = 0; i < 32; i++) - register_isr_handler(i, exception_handler); - for (int i = 32; i < 224; i++) - register_isr_handler(i, generic_handler); - register_isr_handler(0x80, handle_syscall); - - idt_set_gate(0x0, isr_stub_0, 0x08, IDT_EXCEPTION); - idt_set_gate(0x1, isr_stub_1, 0x08, IDT_EXCEPTION); - idt_set_gate(0x2, isr_stub_2, 0x08, IDT_EXCEPTION); - idt_set_gate(0x3, isr_stub_3, 0x08, IDT_EXCEPTION); - idt_set_gate(0x4, isr_stub_4, 0x08, IDT_EXCEPTION); - idt_set_gate(0x5, isr_stub_5, 0x08, IDT_EXCEPTION); - idt_set_gate(0x6, isr_stub_6, 0x08, IDT_EXCEPTION); - idt_set_gate(0x7, isr_stub_7, 0x08, IDT_EXCEPTION); - idt_set_gate(0x8, isr_stub_8, 0x08, IDT_EXCEPTION); - idt_set_gate(0x9, isr_stub_9, 0x08, IDT_EXCEPTION); - idt_set_gate(0xA, isr_stub_10, 0x08, IDT_EXCEPTION); - idt_set_gate(0xB, isr_stub_11, 0x08, IDT_EXCEPTION); - idt_set_gate(0xC, isr_stub_12, 0x08, IDT_EXCEPTION); - idt_set_gate(0xD, isr_stub_13, 0x08, IDT_EXCEPTION); - idt_set_gate(0xE, isr_stub_14, 0x08, IDT_EXCEPTION); - idt_set_gate(0xF, isr_stub_15, 0x08, IDT_EXCEPTION); - idt_set_gate(0x10, isr_stub_16, 0x08, IDT_EXCEPTION); - idt_set_gate(0x11, isr_stub_17, 0x08, IDT_EXCEPTION); - idt_set_gate(0x12, isr_stub_18, 0x08, IDT_EXCEPTION); - idt_set_gate(0x13, isr_stub_19, 0x08, IDT_EXCEPTION); - idt_set_gate(0x14, isr_stub_20, 0x08, IDT_EXCEPTION); - idt_set_gate(0x15, isr_stub_21, 0x08, IDT_EXCEPTION); - idt_set_gate(0x16, isr_stub_22, 0x08, IDT_EXCEPTION); - idt_set_gate(0x17, isr_stub_23, 0x08, IDT_EXCEPTION); - idt_set_gate(0x18, isr_stub_24, 0x08, IDT_EXCEPTION); - idt_set_gate(0x19, isr_stub_25, 0x08, IDT_EXCEPTION); - idt_set_gate(0x1A, isr_stub_26, 0x08, IDT_EXCEPTION); - idt_set_gate(0x1B, isr_stub_27, 0x08, IDT_EXCEPTION); - idt_set_gate(0x1C, isr_stub_28, 0x08, IDT_EXCEPTION); - idt_set_gate(0x1D, isr_stub_29, 0x08, IDT_EXCEPTION); - idt_set_gate(0x1E, isr_stub_30, 0x08, IDT_EXCEPTION); - idt_set_gate(0x1F, isr_stub_31, 0x08, IDT_EXCEPTION); - - idt_set_gate(0x20, irq_stub_0, 0x08, IDT_INTERRUPT); - idt_set_gate(0x21, irq_stub_1, 0x08, IDT_INTERRUPT); - idt_set_gate(0x22, irq_stub_2, 0x08, IDT_INTERRUPT); - idt_set_gate(0x23, irq_stub_3, 0x08, IDT_INTERRUPT); - idt_set_gate(0x24, irq_stub_4, 0x08, IDT_INTERRUPT); - idt_set_gate(0x25, irq_stub_5, 0x08, IDT_INTERRUPT); - idt_set_gate(0x26, irq_stub_6, 0x08, IDT_INTERRUPT); - idt_set_gate(0x27, irq_stub_7, 0x08, IDT_INTERRUPT); - idt_set_gate(0x28, irq_stub_8, 0x08, IDT_INTERRUPT); - idt_set_gate(0x29, irq_stub_9, 0x08, IDT_INTERRUPT); - idt_set_gate(0x2A, irq_stub_10, 0x08, IDT_INTERRUPT); - idt_set_gate(0x2B, irq_stub_11, 0x08, IDT_INTERRUPT); - idt_set_gate(0x2C, irq_stub_12, 0x08, IDT_INTERRUPT); - idt_set_gate(0x2D, irq_stub_13, 0x08, IDT_INTERRUPT); - idt_set_gate(0x2E, irq_stub_14, 0x08, IDT_INTERRUPT); - idt_set_gate(0x2F, irq_stub_15, 0x08, IDT_INTERRUPT); - - idt_set_gate(0x80, isr_stub_128, 0x08, IDT_INTERRUPT); - - __asm__ volatile("lidt %0" : : "memory"(idtr)); -} diff --git a/arch/i386/kernel/isr.s b/arch/i386/kernel/isr.s deleted file mode 100644 index 55db35e..0000000 --- a/arch/i386/kernel/isr.s +++ /dev/null @@ -1,129 +0,0 @@ -.section .text - -.macro isr_err_stub num -.global isr_stub_\num -.type isr_stub_\num, @function -isr_stub_\num: - cli - pushl $\num - jmp isr_frame_asm -.endm -.macro isr_no_err_stub num -.global isr_stub_\num -.type isr_stub_\num, @function -isr_stub_\num: - cli - pushl $0 - pushl $\num - jmp isr_frame_asm -.endm - -.macro irq_stub num -.global irq_stub_\num -.type irq_stub_\num, @function -irq_stub_\num: - cli - pushl $0 - pushl $\num+32 - jmp isr_frame_asm -.endm - -.global syscall_stub -syscall_stub: - cli - pushl $0 - pushl $0x80 - jmp isr_frame_asm - -isr_frame_asm: - pushl %eax - pushl %ebx - pushl %ecx - pushl %edx - pushl %esi - pushl %edi - - movl %cr0, %eax - pushl %eax - movl %cr2, %eax - pushl %eax - movl %cr3, %eax - pushl %eax - movl %cr4, %eax - pushl %eax - - pushl %esp - call set_kernel_esp - addl $4, %esp - - cld - call interrupt_handler - - popl %eax - movl %eax, %cr4 - popl %eax - movl %eax, %cr3 - popl %eax - movl %eax, %cr2 - popl %eax - movl %eax, %cr0 - - popl %edi - popl %esi - popl %edx - popl %ecx - popl %ebx - popl %eax - addl $8, %esp - - iret - -isr_no_err_stub 0 -isr_no_err_stub 1 -isr_no_err_stub 2 -isr_no_err_stub 3 -isr_no_err_stub 4 -isr_no_err_stub 5 -isr_no_err_stub 6 -isr_no_err_stub 7 -isr_err_stub 8 -isr_no_err_stub 9 -isr_err_stub 10 -isr_err_stub 11 -isr_err_stub 12 -isr_err_stub 13 -isr_err_stub 14 -isr_no_err_stub 15 -isr_no_err_stub 16 -isr_err_stub 17 -isr_no_err_stub 18 -isr_no_err_stub 19 -isr_no_err_stub 20 -isr_err_stub 21 -isr_no_err_stub 22 -isr_no_err_stub 23 -isr_no_err_stub 24 -isr_no_err_stub 25 -isr_no_err_stub 26 -isr_no_err_stub 27 -isr_no_err_stub 28 -isr_err_stub 29 -isr_err_stub 30 -isr_no_err_stub 31 - -irq_stub 0 -irq_stub 1 -irq_stub 2 -irq_stub 3 -irq_stub 4 -irq_stub 5 -irq_stub 6 -irq_stub 7 -irq_stub 8 -irq_stub 9 -irq_stub 10 -irq_stub 11 -irq_stub 12 -irq_stub 13 -irq_stub 14 -irq_stub 15 diff --git a/arch/i386/kernel/jump_userspace.s b/arch/i386/kernel/jump_userspace.s deleted file mode 100644 index add144a..0000000 --- a/arch/i386/kernel/jump_userspace.s +++ /dev/null @@ -1,21 +0,0 @@ -.global jump_userspace -.type jump_userspace, @function -jump_userspace: - movw $0x23, %ax - movw %ax, %ds - movw %ax, %es - movw %ax, %fs - movw %ax, %gs - - movl %esp, %eax - pushl $0x23 - pushl %eax - pushf - push $0x1B - pushl $start_init - - pushl %esp - call set_kernel_esp - addl $4, %esp - - iret diff --git a/arch/i386/kernel/kmalloc.c b/arch/i386/kernel/kmalloc.c deleted file mode 100644 index ea77428..0000000 --- a/arch/i386/kernel/kmalloc.c +++ /dev/null @@ -1,68 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -static uintptr_t heap_start = KEND + 0xC0001000; -static uintptr_t heap_end = 0xFFBFF000; - -static void *kbrk = NULL; -static struct mem_block *first = NULL; - -void _request_page(void) { - uintptr_t paddr = pfa_alloc(1); - uintptr_t vaddr = PGROUNDDN((uintptr_t)kbrk + PAGE_SIZE); - kbrk += PAGE_SIZE; - map_page(paddr, vaddr, PD_PRES | PD_RW); -} - -void kmalloc_init(void) { - kbrk = PGROUNDDN(heap_start); - _request_page(); - first = (struct mem_block*)kbrk; - first->start = (uintptr_t)kbrk + sizeof(struct mem_block); - first->size = 0; - first->alloc = 1; - first->next = NULL; -} - -void* kmalloc(size_t sz) { - if (kbrk == NULL) - panic("Attmpted to malloc before initialization"); - if ((uintptr_t)kbrk >= heap_end) - return NULL; - - struct mem_block *temp = first; - while (temp->next != NULL) { - if (temp->next->size <= sz && temp->next->alloc == 0) { - temp->next->alloc = 1; - return (void*)temp->next->start; - } - temp = temp->next; - } - - temp->next = (struct mem_block*)((uintptr_t)temp + sizeof(struct mem_block) + temp->size); - if (temp->next > kbrk) - _request_page(); - temp->next->prev = temp; - temp->next->start = (uintptr_t)(temp->next + sizeof(struct mem_block)); - temp->next->size = sz; - temp->next->alloc = 1; - temp->next->next = NULL; - return (void*)temp->start; -} - -void kfree(void *ptr) { - struct mem_block *temp = first; - while (temp != NULL) { - if (temp->start == (uintptr_t)ptr) { - temp->alloc = 0; - return; - } - temp = temp->next; - } - panic("Attempted to free memory not alloc'd"); -} diff --git a/arch/i386/kernel/multiboot.c b/arch/i386/kernel/multiboot.c deleted file mode 100644 index dedf163..0000000 --- a/arch/i386/kernel/multiboot.c +++ /dev/null @@ -1,49 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -void kernel_main(char *cmdline); - -void i386_entry(uint32_t mboot_magic, struct mboot_info *header) { - map_page(0xB8000, (uintptr_t)VGA_MEMORY, PD_RW); - fb_init(); - - if (mboot_magic != MBOOT_LOADER_MAGIC) { - disable_ints(); - panic("Not booted with multiboot bootloader"); - } - - map_page(0x9000, 0x9000, PD_RW); - if (!(header->flags >> 6 & 0x1)) { - disable_ints(); - panic("Physical memory map not provided by bootloader"); - } - - char cmdline[4096]; - map_page(header->cmdline, PAGE_TMP_MAP, 0); - memcpy(cmdline, (char*)PAGE_TMP_MAP, strlen((char*)PAGE_TMP_MAP)); - unmap_page(PAGE_TMP_MAP); - pfa_init(header); - gdt_install(); - idt_install(); - paging_init(); - map_page(0xB8000, (uintptr_t)VGA_MEMORY, PD_RW); - pic_remap(); - timer_init(); - - enable_ints(); - kernel_main(cmdline); - - while (1); -} diff --git a/arch/i386/kernel/paging.c b/arch/i386/kernel/paging.c deleted file mode 100644 index a0bbb92..0000000 --- a/arch/i386/kernel/paging.c +++ /dev/null @@ -1,130 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include - -static int paging_enabled = 0; - -void paging_init(void) { - if (paging_enabled == 1) - return; - - uintptr_t phys_pt = pfa_alloc(1); - map_page(phys_pt, PAGE_TMP_MAP, PD_PRES | PD_RW); - uintptr_t *pt = (uintptr_t*)PAGE_TMP_MAP; - for (uintptr_t i = KSTART; i < KEND; i += PAGE_SIZE) - pt[GET_PTX(GET_VADDR(i))] = i | PD_PRES; - unmap_page(PAGE_TMP_MAP); - - uintptr_t temp_pt = pfa_alloc(1); - - uintptr_t phys_pd = pfa_alloc(1); - map_page(phys_pd, PAGE_TMP_MAP, PD_PRES | PD_RW); - uintptr_t *pd = (uintptr_t*)PAGE_TMP_MAP; - pd[GET_PDX(GET_VADDR(KSTART))] = phys_pt | PD_PRES | PD_RW; - pd[GET_PDX(PAGE_TMP_MAP)] = temp_pt | PD_PRES | PD_RW; - pd[1023] = phys_pd | PD_PRES | PD_RW; - unmap_page(PAGE_TMP_MAP); - - enable_paging(phys_pd); - paging_enabled = 1; - return; -} - -void init_page_table(int pdindex, uint32_t flags) { - uintptr_t *pd = (uintptr_t*)PAGE_DIR_MAP; - if ((pd[pdindex] & PD_PRES) != 0) - return; - - uintptr_t paddr = pfa_alloc(1); - pd[pdindex] = paddr | PD_PRES | PD_RW | flags; - - uintptr_t *pt = ((uintptr_t*)PAGE_TAB_MAP) + (pdindex << 12); - pd[GET_PDX(pt)] = paddr | PD_PRES | PD_RW; -} - -uintptr_t init_page_directory(void) { - uintptr_t ret = pfa_alloc(1); - map_page(ret, PAGE_TMP_MAP, PD_RW); - - uintptr_t *new_pd = (uintptr_t*)PAGE_TMP_MAP; - uintptr_t *cur_pd = (uintptr_t*)PAGE_DIR_MAP; - int kernel_pdx = GET_PDX(GET_VADDR(KSTART)); - new_pd[kernel_pdx] = cur_pd[kernel_pdx]; - - unmap_page(PAGE_TMP_MAP); - return ret; -} - -void map_page(uintptr_t paddr, uintptr_t vaddr, uint32_t flags) { - paddr = PGROUNDDN(paddr); - vaddr = PGROUNDDN(vaddr); - - int pdindex = GET_PDX(vaddr); - int ptindex = GET_PTX(vaddr); - - uintptr_t *pd = (uintptr_t*)PAGE_DIR_MAP; - if ((pd[pdindex] & PD_PRES) == 0) - init_page_table(pdindex, 0); - - uintptr_t *pt = (uintptr_t*)(PAGE_TAB_MAP + (pdindex << 12)); - pt[ptindex] = paddr | PD_PRES | flags; - invlpg((void*)vaddr); -} - -void unmap_page(uintptr_t vaddr) { - uintptr_t pdindex = GET_PDX(vaddr); - uintptr_t ptindex = GET_PTX(vaddr); - - uintptr_t *pd = (uintptr_t*)PAGE_DIR_MAP; - if ((pd[pdindex] & PD_PRES) == 0) - return; - - uintptr_t *pt = (uintptr_t*)(PAGE_TAB_MAP + (pdindex << 12)); - pt[ptindex] = 0; - invlpg((void*)vaddr); -} - -void page_fault_handler(struct isr_frame *frame) { - uintptr_t fault_addr; - __asm__ volatile("movl %%cr2, %0" : "=r"(fault_addr)); - - kprintf("Faulting address: %x\n", fault_addr); - panic("Page fault not operational"); - switch (frame->isr_err) { - case 0: - //map_page((uintptr_t*)GET_VADDR(frame->cr3), pfa_alloc(), fault_addr, PD_PRES); - break; - case 1: - panic("Kernel process caused protection fault on read\n"); - break; - case 2: - //map_page((uintptr_t*)GET_VADDR(frame->cr3), pfa_alloc(), fault_addr, PD_PRES | PD_RW); - break; - case 3: - panic("Kernel process caused protection fault on write\n"); - break; - case 4: - //map_page((uintptr_t*)GET_VADDR(frame->cr3), pfa_alloc(), fault_addr, PD_PRES | PD_USR); - break; - case 5: - // TODO: instead of panicking, kill process - panic("User process caused protection fault on read\n"); - break; - case 6: - //map_page((uintptr_t*)GET_VADDR(frame->cr3), pfa_alloc(), fault_addr, PD_PRES | PD_RW | PD_USR); - break; - case 7: - // TODO: see case 101 - panic("USER process caused protection fault on write\n"); - break; - default: - kprintf("Unknown paging error occured on address %x\n", fault_addr); - panic("Paging error"); - break; - } -} diff --git a/arch/i386/kernel/pic.c b/arch/i386/kernel/pic.c deleted file mode 100644 index 0d29473..0000000 --- a/arch/i386/kernel/pic.c +++ /dev/null @@ -1,79 +0,0 @@ -#include - -static void (*irq_handlers[16])(struct isr_frame *frame); - -void pic_eoi(uint8_t irq) { - if (irq >= 8) - outb(PIC2_COMMAND, 0x20); - outb(PIC1_COMMAND, 0x20); -} - -void pic_remap(void) { - unsigned char a1 = inb(PIC1_DATA); - unsigned char a2 = inb(PIC2_DATA); - - outb(PIC1_COMMAND, ICW1_INIT | ICW1_ICW4); - outb(PIC2_COMMAND, ICW1_INIT | ICW1_ICW4); - outb(PIC1_DATA, PIC1); - outb(PIC2_DATA, PIC2); - outb(PIC1_DATA, 4); - outb(PIC2_DATA, 2); - outb(PIC1_DATA, ICW4_8086); - outb(PIC2_DATA, ICW4_8086); - outb(PIC1_DATA, a1); - outb(PIC2_DATA, a2); -} - -static uint16_t _pic_get_irq_reg(int ocw3) { - outb(PIC1_COMMAND, ocw3); - outb(PIC2_COMMAND, ocw3); - return (inb(PIC2_COMMAND) << 8) | inb(PIC1_COMMAND); -} - -uint16_t pic_get_irr(void) { - return _pic_get_irq_reg(PIC_READ_IRR); -} - -uint16_t pic_get_isr(void) { - return _pic_get_irq_reg(PIC_READ_ISR); -} - -void register_irq_handler(uint8_t irq, void (*handler)(struct isr_frame *frame)) { - irq_handlers[irq] = handler; -} - -void irq_dispatch(struct isr_frame *frame) { - (*irq_handlers[frame->isr_vector-32])(frame); - pic_eoi(frame->isr_vector-32); - return; -} - -void irq_set_mask(uint8_t irq) { - uint16_t port; - uint8_t data; - - if (irq < 8) { - port = PIC1_DATA; - } else { - port = PIC2_DATA; - irq -= 8; - } - - data = inb(port) | (1 << irq); - outb(port, data); -} - -void irq_clear_mask(uint8_t irq) { - uint16_t port; - uint8_t data; - - if (irq < 8) { - port = PIC1_DATA; - } else { - port = PIC2_DATA; - irq -= 8; - } - - data = inb(port) & ~(1 << irq); - outb(port, data); -} diff --git a/arch/i386/kernel/pmem.c b/arch/i386/kernel/pmem.c deleted file mode 100644 index 40e3400..0000000 --- a/arch/i386/kernel/pmem.c +++ /dev/null @@ -1,45 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -static struct pfa_page freelist; - -void pfa_init(struct mboot_info *header) { - struct mboot_mmap_entry *mme; - for (uintptr_t i = 0; i < header->mmap_length; i += sizeof(struct mboot_mmap_entry)) { - mme = (struct mboot_mmap_entry*)(header->mmap_addr + i); - if (mme->type == MBOOT_MEM_AVAILABLE) - pfa_free(mme->addr_low, mme->len_low / PAGE_SIZE); - } -} - -uintptr_t pfa_alloc(size_t num_pages) { - struct pfa_page *temp = (struct pfa_page*)PAGE_TMP_MAP; - map_page(freelist.next, PAGE_TMP_MAP, PD_PRES | PD_RW); - uintptr_t ret = freelist.next; - freelist.next = temp->next; - memset(temp, 0, 32); - unmap_page(PAGE_TMP_MAP); - return ret; -} - -void pfa_free(uintptr_t paddr, size_t num_pages) { - uintptr_t addr; - struct pfa_page *temp = (struct pfa_page*)PAGE_TMP_MAP; - for (size_t i = 0; i < num_pages; i++) { - addr = (i * PAGE_SIZE + paddr); - if (addr >= KSTART && addr < KEND) - continue; - if (addr == 0) - continue; - map_page(addr, PAGE_TMP_MAP, PD_PRES | PD_RW); - memset(PAGE_TMP_MAP, 1, 32); - temp->next = freelist.next; - freelist.next = addr; - unmap_page(PAGE_TMP_MAP); - } -} diff --git a/arch/i386/kernel/serial.c b/arch/i386/kernel/serial.c deleted file mode 100644 index dc2a8bd..0000000 --- a/arch/i386/kernel/serial.c +++ /dev/null @@ -1,42 +0,0 @@ -#include -#include -#include -#include - -#define PORT 0x3f8 - -static inline int _serial_received(void) { - return inb(PORT + 5) & 1; -} - -static inline int _is_transmit_empty(void) { - return inb(PORT + 5) & 0x20; -} - -int serial_init(void) { - outb(PORT + 1, 0x00); - outb(PORT + 3, 0x80); - outb(PORT + 0, 0x03); - outb(PORT + 1, 0x00); - outb(PORT + 3, 0x03); - outb(PORT + 2, 0xC7); - outb(PORT + 4, 0x0B); - outb(PORT + 4, 0x1E); - outb(PORT + 0, 0xAE); - - if (inb(PORT + 0) != 0xAE) - return -1; - - outb(PORT + 4, 0x0F); - return 0; -} - -void serial_putchar(char c) { - while (_is_transmit_empty() == 0); - outb(PORT, c); -} - -char serial_getchar(void) { - while (_serial_received() == 0); - return inb(PORT); -} diff --git a/arch/i386/kernel/spinlock.s b/arch/i386/kernel/spinlock.s deleted file mode 100644 index c8235ca..0000000 --- a/arch/i386/kernel/spinlock.s +++ /dev/null @@ -1,30 +0,0 @@ -.section .text - -.global aquire_lock -.type aquire_lock, @function -aquire_lock: - pushl %ebp - movl %esp, %ebp -locked: - movl 8(%esp), %eax - lock incl (%eax) - jc spin_wait - - popl %ebp - ret -spin_wait: - test %eax, 1 - jnz spin_wait - jmp locked - -.global release_lock -.type release_lock, @function -release_lock: - pushl %ebp - movl %esp, %ebp - - movl 8(%ebp), %eax - lock decl (%eax) - - popl %ebp - ret diff --git a/arch/i386/kernel/stack_trace.s b/arch/i386/kernel/stack_trace.s deleted file mode 100644 index fbd77ed..0000000 --- a/arch/i386/kernel/stack_trace.s +++ /dev/null @@ -1,31 +0,0 @@ -.section .text - -.global walk_stack -.type walk_stack, @function -walk_stack: - pushl %ebp - movl %esp, %ebp - - pushl %edi - movl -4(%ebp), %edi - pushl %ebx - movl -8(%ebp), %ebx - - xorl %eax, %eax - movl 8(%esp), %ebx - movl 16(%esp), %edi - movl 20(%esp), %ecx -walk: - testl %ebx, %ebx - jz done - movl 4(%ebx), %edx - movl 0(%ebx), %ebx - movl %edx, (%edi) - addl $4, %edi - inc %eax - loop walk -done: - popl %ebx - popl %edi - popl %ebp - ret diff --git a/arch/i386/kernel/switch_thread.s b/arch/i386/kernel/switch_thread.s deleted file mode 100644 index f1168d5..0000000 --- a/arch/i386/kernel/switch_thread.s +++ /dev/null @@ -1,28 +0,0 @@ -.global switch_thread -.type switch_thread, @function -switch_thread: - pushl %ebp - movl %esp, %ebp - - pushl %ebx - pushl %esi - pushl %edi - pushl %ebp - - movl 8(%ebp), %esi - movl 12(%ebp), %edi - - movl %esp, (%edi); - movl %cr3, %ecx - movl %ecx, 4(%edi) - - movl (%esi), %esp - movl 4(%esi), %ecx - movl %ecx, %cr3 - - popl %ebp - popl %edi - popl %esi - popl %ebx - popl %ebp - ret diff --git a/arch/i386/kernel/syscall.c b/arch/i386/kernel/syscall.c deleted file mode 100644 index 200af4f..0000000 --- a/arch/i386/kernel/syscall.c +++ /dev/null @@ -1,25 +0,0 @@ -#include -#include -#include -#include -#include - -void sys_read(struct isr_frame *frame) { -} - -void sys_write(struct isr_frame *frame) { -} - -void handle_syscall(struct isr_frame *frame) { - switch (frame->eax) { - case SYS_READ: - sys_read(frame); - break; - case SYS_WRITE: - sys_write(frame); - break; - default: - panic("Invalid system call number"); - } - return 0; -} diff --git a/arch/i386/kernel/timer.c b/arch/i386/kernel/timer.c deleted file mode 100644 index a7d88dd..0000000 --- a/arch/i386/kernel/timer.c +++ /dev/null @@ -1,24 +0,0 @@ -#include -#include -#include - -static uint32_t num_ticks = 0; - -void timer_handler(struct isr_frame *frame) { - num_ticks++; - if (num_ticks == 3) { - num_ticks = 0; - schedule_next(); - } -} - -void timer_init(void) { - disable_ints(); - int divisor = 1193182 / 100; - outb(0x43, 0x34); - outb(0x40, divisor && 0xFF); - outb(0x40, divisor && 0xFF00 >> 8); - enable_ints(); - - register_irq_handler(0, timer_handler); -} diff --git a/arch/i386/linker.ld b/arch/i386/linker.ld deleted file mode 100644 index 734310f..0000000 --- a/arch/i386/linker.ld +++ /dev/null @@ -1,30 +0,0 @@ -ENTRY(_start) - -SECTIONS { - . = 0x00100000; - _kernel_start = .; - .multiboot.data : { - *(.multiboot.data) - } - .multiboot.text : { - *(.multiboot.text) - } - - . += 0xC0000000; - .text ALIGN(4K) : AT(ADDR(.text) - 0xC0000000) { - *(.text) - } - .rodata ALIGN(4K) : AT(ADDR(.rodata) - 0xC0000000) { - *(.rodata) - } - .data ALIGN(4K) : AT(ADDR(.data) - 0xC0000000) { - *(.data) - } - .bss ALIGN(4K) : AT(ADDR(.bss) - 0xC0000000) { - *(COMMON) - *(.bss) - *(.bootstrap_stack) - } - - _kernel_end = .; -} diff --git a/arch/i386/make.config b/arch/i386/make.config deleted file mode 100644 index 557f01a..0000000 --- a/arch/i386/make.config +++ /dev/null @@ -1,20 +0,0 @@ -KERNEL_ARCH_INCLUDE=$(ARCHDIR)/include -KERNEL_ARCH_CFLAGS=-I$(KERNEL_ARCH_INCLUDE) -KERNEL_ARCH_LDFLAGS= -KERNEL_ARCH_LIBS= - -KERNEL_ARCH_OBJS=$(ARCHDIR)/boot/boot.o \ - $(ARCHDIR)/kernel/idt.o \ - $(ARCHDIR)/kernel/gdt.o \ - $(ARCHDIR)/kernel/isr.o \ - $(ARCHDIR)/kernel/stack_trace.o \ - $(ARCHDIR)/kernel/multiboot.o \ - $(ARCHDIR)/kernel/serial.o \ - $(ARCHDIR)/kernel/pic.o \ - $(ARCHDIR)/kernel/timer.o \ - $(ARCHDIR)/kernel/spinlock.o \ - $(ARCHDIR)/kernel/syscall.o \ - $(ARCHDIR)/kernel/paging.o \ - $(ARCHDIR)/kernel/pmem.o \ - $(ARCHDIR)/kernel/kmalloc.o \ - $(ARCHDIR)/kernel/switch_thread.o \ diff --git a/bin/Makefile b/bin/Makefile new file mode 100644 index 0000000..e23bd68 --- /dev/null +++ b/bin/Makefile @@ -0,0 +1,18 @@ +SUBDIRS:=cat \ + echo \ + login \ + +export ARCH VERSION PREFIX + +.PHONY: all clean $(SUBDIRS) + +all: $(SUBDIRS) + +subdirs: $(SUBDIRS) + +$(SUBDIRS): + $(MAKE) $(MAKECMDGOALS) -C $@ + +clean: $(SUBDIRS) + +install: $(SUBDIRS) diff --git a/drivers/input/keyboard.c b/drivers/input/keyboard.c deleted file mode 100644 index f2a8eba..0000000 --- a/drivers/input/keyboard.c +++ /dev/null @@ -1,142 +0,0 @@ -#include -#include -#include -#include -#include -#include - -static uint8_t keymap_modifiers[256] = { - [0x1D] KB_CTL, - [0x2A] KB_SHIFT, - [0x36] KB_SHIFT, - [0x38] KB_ALT, - [0x9D] KB_CTL, - [0xB8] KB_ALT -}; - -static uint8_t keymap_toggles[256] = { - [0x3A] KB_CPSLK, - [0x45] KB_NUMLK, - [0x46] KB_SCLLK -}; - -static uint8_t keymap_normal[256] = { - 0, 0x1B, '1', '2', '3', '4', '5', '6', - '7', '8', '9', '0', '-', '=', '\b', '\t', - 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', - 'o', 'p', '[', ']', '\n', 0, 'a', 's', - 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', - '\'', '`', 0, '\\', 'z', 'x', 'c', 'v', - 'b', 'n', 'm', ',', '.', '/', 0, '*', - 0, ' ', 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, '7', - '8', '9', '-', '4', '5', '6', '+', '1', - '2', '3', '0', '.', 0, 0, 0, 0, - [0x9C] '\n', - [0xB5] '/', - [0xC8] KB_UP, - [0xD0] KB_DOWN, - [0xC9] KB_PGUP, - [0xD1] KB_PGDN, - [0xCB] KB_LEFT, - [0xCD] KB_RGHT, - [0x97] KB_HOME, - [0xCF] KB_END, - [0xD2] KB_INS, - [0xD3] KB_DEL -}; - -static uint8_t keymap_shifted[256] = { - 0, 0x33, '!', '@', '#', '$', '%', '^', - '&', '*', '(', ')', '_', '+', '\b', '\t', - 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', - 'O', 'P', '{', '}', '\n', 0, 'A', 'S', - 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', - '"', '~', 0, '|', 'Z', 'X', 'C', 'V', - 'B', 'N', 'M', '<', '>', '?', 0, '*', - 0, ' ', 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, '7', - '8', '9', '-', '4', '5', '6', '+', '1', - '2', '3', '0', '.', 0, 0, 0, 0, - [0x9C] '\n', - [0xB5] '/', - [0xC8] KB_UP, - [0xD0] KB_DOWN, - [0xC9] KB_PGUP, - [0xD1] KB_PGDN, - [0xCB] KB_LEFT, - [0xCD] KB_RGHT, - [0x97] KB_HOME, - [0xCF] KB_END, - [0xD2] KB_INS, - [0xD3] KB_DEL -}; - -static uint8_t keymap_control[256] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - C('Q'), C('W'), C('E'), C('R'), C('T'), C('Y'), C('U'), C('I'), - C('O'), C('P'), 0, 0, '\r', 0, C('A'), C('S'), - C('D'), C('F'), C('G'), C('H'), C('J'), C('K'), C('L'), 0, - 0, 0, 0, C('\\'), C('Z'), C('X'), C('C'), C('V'), - C('B'), C('N'), C('M'), 0, 0, C('/'), 0, 0, - [0x9C] '\r', - [0xB5] C('/'), - [0xC8] KB_UP, - [0xD0] KB_DOWN, - [0xC9] KB_PGUP, - [0xD1] KB_PGDN, - [0xCB] KB_LEFT, - [0xCD] KB_RGHT, - [0x97] KB_HOME, - [0xCF] KB_END, - [0xD2] KB_INS, - [0xD3] KB_DEL -}; - -static uint8_t* keymaps[4] = { - keymap_normal, - keymap_shifted, - keymap_control, - keymap_control, -}; - -char keyboard_getchar(void) { - static int shift = 0; - uint8_t st = inb(KB_STAT); - if ((st & KB_DIB) == 0) - return -1; - - uint8_t data = inb(KB_DATA); - - if (data == 0xE0) { - shift |= KB_E0ESC; - return -1; - } else if (data & 0x80) { - if (!(shift & KB_E0ESC)) - data &= 0x7F; - shift &= ~(keymap_modifiers[data] | KB_E0ESC); - return -1; - } else if (shift & KB_E0ESC) { - data |= 0x80; - shift &= ~KB_E0ESC; - } - - shift |= keymap_modifiers[data]; - shift ^= keymap_toggles[data]; - char c = keymaps[shift & (KB_CTL | KB_SHIFT)][data]; - if (shift & KB_CPSLK) { - if ('a' <= c && c <= 'z') - c += 'A' - 'a'; - else if ('A' <= c && c <= 'Z') - c += 'a' - 'A'; - } - return c; -} - -void keyboard_handler(struct isr_frame *frame) { - char c = keyboard_getchar(); - if (c != -1) - tty_getchar(c); - return; -} diff --git a/drivers/video/framebuffer.c b/drivers/video/framebuffer.c deleted file mode 100644 index 3df3df4..0000000 --- a/drivers/video/framebuffer.c +++ /dev/null @@ -1,109 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static size_t fb_row; -static size_t fb_column; -static uint8_t fb_color; -static uint16_t *framebuffer; - -void _enable_cursor(uint8_t cursor_start, uint8_t cursor_end) { - outb(0x3D4, 0x0A); - outb(0x3D5, (inb(0x3D5) & 0xC0) | cursor_start); - - outb(0x3D4, 0x0B); - outb(0x3D5, (inb(0x3D5) & 0xE0) | cursor_end); -} - -void _update_cursor(size_t x, size_t y) { - uint16_t pos = y * VGA_WIDTH + x; - - outb(0x3D4, 0x0F); - outb(0x3D5, (uint8_t)(pos & 0xFF)); - outb(0x3D4, 0x0E); - outb(0x3D5, (uint8_t)((pos >> 8) & 0xFF)); -} - -void _fb_putentryat(unsigned char c, uint8_t color, size_t x, size_t y) { - const size_t index = y * VGA_WIDTH + x; - framebuffer[index] = vga_entry(c, color); -} - -void _fb_scroll(void) { - for (size_t i = 0; i < VGA_HEIGHT-1; i++) { - for (size_t j = 0; j < VGA_WIDTH; j++) - framebuffer[i * VGA_WIDTH + j] = VGA_MEMORY[(i+1) * VGA_WIDTH + j]; - } -} - -void fb_init(void) { - fb_row = 0; - fb_column = 0; - fb_color = vga_entry_color(VGA_COLOR_LIGHT_GREY, VGA_COLOR_BLACK); - framebuffer = VGA_MEMORY; - for (size_t y = 0; y < VGA_HEIGHT; y++) { - for (size_t x = 0; x < VGA_WIDTH; x++) - _fb_putentryat(' ', fb_color, x, y); - } - _enable_cursor(0, 0); - _update_cursor(0, 0); -} - -void fb_setcolor(uint8_t color) { - fb_color = color; -} - -void fb_setpos(int x, int y) { - fb_row = y; - fb_column = x; - _update_cursor(fb_column, fb_row+1); -} - -void fb_offsetpos(int dx, int dy) { - fb_row += dy; - fb_column += dx; - _update_cursor(fb_column, fb_row+1); -} - -void fb_putchar(char c) { - unsigned char uc = c; - switch (uc) { - case '\r': - fb_column = 0; - break; - case '\n': - fb_column = 0; - if (++fb_row == VGA_HEIGHT) { - fb_row--; - _fb_scroll(); - } - break; - case '\t': - fb_column += 4; - if (++fb_column == VGA_WIDTH) { - fb_column = 4; - if (++fb_row == VGA_HEIGHT) { - fb_row--; - _fb_scroll(); - } - } - break; - default: - _fb_putentryat(uc, fb_color, fb_column, fb_row); - if (++fb_column == VGA_WIDTH) { - fb_column = 0; - if (++fb_row == VGA_HEIGHT) { - fb_row--; - _fb_scroll(); - } - } - break; - } - _update_cursor(fb_column, fb_row+1); -} diff --git a/etc/fstab b/etc/fstab new file mode 100644 index 0000000..5dc3ee1 --- /dev/null +++ b/etc/fstab @@ -0,0 +1,4 @@ +# Static information about the filesystems. +# See fstab(5) for details. + +# diff --git a/etc/group b/etc/group new file mode 100644 index 0000000..bb0d851 --- /dev/null +++ b/etc/group @@ -0,0 +1,18 @@ +root:x:0:root +bin:x:1:root,bin,daemon +daemon:x:2:root,bin,daemon +disk:x:3:root +adm:x:4:root,daemon +tty:x:5:root +mem:x:6: +kmem:x:7: +wheel:x:8:root +log:x:9:root +proc:x:10:root +audio:x:11: +video:x:11: +network:x:12: +power:x:13: +sudo:x:14:root +users:x:100: +nobody:x:65534: diff --git a/etc/passwd b/etc/passwd new file mode 100644 index 0000000..c814925 --- /dev/null +++ b/etc/passwd @@ -0,0 +1,4 @@ +root:x:0:0:Super User:/root:/bin/sh +bin:x:1:1::/:/sbin/nologin +daemon:x:2:2::/:/sbin/nologin +nobody:x:65534:99:Nobody:/:/sbin/nologin diff --git a/etc/shadow b/etc/shadow new file mode 100644 index 0000000..fd36873 --- /dev/null +++ b/etc/shadow @@ -0,0 +1,4 @@ +root::0::::::: +bin:!:0::::::: +daemon:!:0::::::: +nobody:!:0::::::: diff --git a/etc/shells b/etc/shells new file mode 100644 index 0000000..b357b99 --- /dev/null +++ b/etc/shells @@ -0,0 +1,4 @@ +# List of valid login shells +# See shells(5) for details. + +/bin/sh diff --git a/include/kernel/input/keyboard.h b/include/kernel/input/keyboard.h deleted file mode 100644 index a0d1470..0000000 --- a/include/kernel/input/keyboard.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef KERNEL_KEYBOARD_H -#define KERNEL_KEYBOARD_H - -#include - -#define KB_STAT 0x64 -#define KB_DATA 0x60 - -#define KB_DIB 0x01 -#define KB_SHIFT (1<<0) -#define KB_CTL (1<<1) -#define KB_ALT (1<<2) -#define KB_CPSLK (1<<3) -#define KB_NUMLK (1<<4) -#define KB_SCLLK (1<<5) -#define KB_E0ESC (1<<6) - -#define KB_HOME 0xE0 -#define KB_END 0xE1 -#define KB_UP 0xE2 -#define KB_DOWN 0xE3 -#define KB_LEFT 0xE4 -#define KB_RGHT 0xE5 -#define KB_PGUP 0xE6 -#define KB_PGDN 0xE7 -#define KB_INS 0xE8 -#define KB_DEL 0xE9 - -char keyboard_getchar(void); -void keyboard_handler(struct isr_frame *frame); - -#endif diff --git a/include/kernel/interrupt.h b/include/kernel/interrupt.h deleted file mode 100644 index b707fe7..0000000 --- a/include/kernel/interrupt.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef KERNEL_INTERRUPT_H -#define KERNEL_INTERRUPT_H - -#include -#include -#include - -void register_isr_handler(unsigned int isr, void (*handler)(struct isr_frame *frame)); -void clear_isr_handler(unsigned int isr); - -void isr_dispatch(struct isr_frame frame); - -#endif diff --git a/include/kernel/panic.h b/include/kernel/panic.h deleted file mode 100644 index adfcd71..0000000 --- a/include/kernel/panic.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef KERNEL_PANIC_H -#define KERNEL_PANIC_H - -#include -#include -#include - -void panic(const char *str); - -#endif diff --git a/include/kernel/sched.h b/include/kernel/sched.h deleted file mode 100644 index 00a5d95..0000000 --- a/include/kernel/sched.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef KERNEL_SCHED_H -#define KERNEL_SCHED_H - -#include -#include -#include - -void sched_init(void); -void schedule_next(void); -void schedule_thread(struct kthread *thread); - -void block_thread(struct kthread *thread); -void unblock_thread(struct kthread *thread); - -void sched_lock(void); -void sched_unlock(void); - -void switch_thread(struct kthread *old, struct kthread *new); - -#endif diff --git a/include/kernel/serial.h b/include/kernel/serial.h deleted file mode 100644 index 4767722..0000000 --- a/include/kernel/serial.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef KERNEL_SERIAL_H -#define KERNEL_SERIAL_H - -#include -#include - -int serial_init(void); -void serial_putchar(char c); -char serial_getchar(void); - -static inline void serial_write(const char *data, size_t size) { - for (size_t i = 0; i < size; i++) - serial_putchar(data[i]); -} - -static inline void serial_read(char *data, size_t size) { - for (size_t i = 0; i < size; i++) - data[i] = serial_getchar(); -} - -#endif diff --git a/include/kernel/video/framebuffer.h b/include/kernel/video/framebuffer.h deleted file mode 100644 index 500e71b..0000000 --- a/include/kernel/video/framebuffer.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef KERNEL_FRAMEBUFFER_H -#define KERNEL_FRAMEBUFFER_H - -#include -#include - -#define VGA_WIDTH 80 -#define VGA_HEIGHT 25 - -static uint16_t *const VGA_MEMORY = (uint16_t*)0xC03FF000; - -void fb_init(void); -void fb_setcolor(uint8_t color); -void fb_putchar(char c); -void fb_setpos(int x, int y); -void fb_offsetpos(int dx, int dy); - -static inline void fb_write(const char *data, size_t size) { - for (size_t i = 0; i < size; i++) - fb_putchar(data[i]); -} - -#endif diff --git a/include/kernel/video/vga.h b/include/kernel/video/vga.h deleted file mode 100644 index b639a3c..0000000 --- a/include/kernel/video/vga.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef KERNEL_VGA_H -#define KERNEL_VGA_H - -#include - -enum vga_color { - VGA_COLOR_BLACK = 0, - VGA_COLOR_BLUE = 1, - VGA_COLOR_GREEN = 2, - VGA_COLOR_CYAN = 3, - VGA_COLOR_RED = 4, - VGA_COLOR_MAGENTA = 5, - VGA_COLOR_BROWN = 6, - VGA_COLOR_LIGHT_GREY = 7, - VGA_COLOR_DARK_GREY = 8, - VGA_COLOR_LIGHT_BLUE = 9, - VGA_COLOR_LIGHT_GREEN = 10, - VGA_COLOR_LIGHT_CYAN = 11, - VGA_COLOR_LIGHT_RED = 12, - VGA_COLOR_LIGHT_MAGENTA = 13, - VGA_COLOR_LIGHT_BROWN = 14, - VGA_COLOR_LIGHT_WHITE = 15, -}; - -static inline uint8_t vga_entry_color(enum vga_color fg, enum vga_color bg) { - return fg | bg << 4; -} - -static inline uint16_t vga_entry(unsigned char uc, uint8_t color) { - return (uint16_t)uc | (uint16_t)color << 8; -} - -#endif diff --git a/include/libk/container_of.h b/include/libk/container_of.h deleted file mode 100644 index fdc400c..0000000 --- a/include/libk/container_of.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef LIBK_CONTAINER_OF_H -#define LIBK_CONTAINER_OF_H - -#ifndef container_of -#define container_of(ptr, type, member) ({ \ - const typeof(((type*)0)->member)*__mptr = (ptr); \ - (type*)((char*)__mptr - offsetof(type, member)); }) -#endif - -#endif diff --git a/include/libk/data/list.h b/include/libk/data/list.h deleted file mode 100644 index 69eee3a..0000000 --- a/include/libk/data/list.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef LIBK_LIST_H -#define LIBK_LIST_H - -#include - -struct list_head { - struct list_head *next; - struct list_head *prev; -}; - -static inline void list_add(struct list_head *new, struct list_head *head) { - struct list_head *temp = head; - while (temp->next != NULL) - temp = temp->next; - - temp->next = new; - new->prev = temp; - new->next = NULL; -} - -static inline void list_del(struct list_head *item) { - struct list_head *next = item->next; - struct list_head *prev = item->prev; - if (next != NULL) - next->prev = prev; - if (prev != NULL) - prev->next = next; - item->next = NULL; - item->prev = NULL; -} - -#endif diff --git a/include/libk/data/ringbuf.h b/include/libk/data/ringbuf.h deleted file mode 100644 index cc6d77b..0000000 --- a/include/libk/data/ringbuf.h +++ /dev/null @@ -1,50 +0,0 @@ -#ifndef LIBK_RINGBUF_H -#define LIBK_RINGBUF_H - -#include -#include -#include - -struct ringbuf { - void *buffer; - void *buf_end; - uint32_t capacity; - uint32_t count; - uint32_t size; - void *head; - void *tail; -}; - -static inline void rb_init(struct ringbuf *rb, uint32_t capacity, uint32_t size) { - rb->buffer = kmalloc(capacity * size); - rb->buf_end = (char*)rb->buffer + (capacity * size); - rb->capacity = capacity; - rb->size = size; - rb->head = rb->buffer; - rb->tail = rb->buffer; -} - -static inline int rb_push_back(struct ringbuf *rb, const void *item, size_t size) { - if (rb->count == rb->capacity) - return -1; - if (size > rb->size) - return -1; - - void *tmp = rb->tail + rb->size; - if (tmp > rb->head + rb->capacity * rb->size) - rb->tail = rb->head; - memcpy(rb->tail, item, size); - rb->tail += rb->size; - rb->count++; - return 0; -} - -static inline void rb_pop_front(struct ringbuf *rb, void *item) { - memcpy(item, rb->tail, rb->size); - rb->tail = (char*)rb->tail + rb->size; - if (rb->tail == rb->buf_end) - rb->tail = rb->buffer; - rb->count--; -} - -#endif diff --git a/include/libk/io.h b/include/libk/io.h deleted file mode 100644 index 72dc5d7..0000000 --- a/include/libk/io.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef LIBK_IO_H -#define LIBK_IO_H - -#include - -char* convert(unsigned int num, int base); -int vkprintf(const char *fmt, va_list args); -int kprintf(const char *fmt, ...); - -#endif diff --git a/include/libk/kmalloc.h b/include/libk/kmalloc.h deleted file mode 100644 index 6573d28..0000000 --- a/include/libk/kmalloc.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef LIBK_KMALLOC_H -#define LIBK_KMALLOC_H - -#include -#include - -struct mem_block { - void *start; - size_t size; - int alloc; - struct mem_block *next; - struct mem_block *prev; -}; - -void kmalloc_init(void); -void* kmalloc(size_t sz); -void kfree(void *ptr); - -#endif diff --git a/include/libk/string.h b/include/libk/string.h deleted file mode 100644 index 1fb4af1..0000000 --- a/include/libk/string.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef LIBK_STRING_H -#define LIBK_STRING_H - -#include - -int memcmp(const void *str1, const void *str2, size_t n); -void* memcpy(void* __restrict dest, const void* __restrict src, size_t n); -void* memmove(void* __restrict dest, const void* __restrict src, size_t n); -void* memset(void *str, int c, size_t n); -int strncmp(const char *str1, const char *str2, size_t n); -int strcmp(const char *str1, const char *str2); -size_t strlen(const char *str); -char* strncpy(char* __restrict dest, const char* __restrict src, size_t n); -char* strcpy(char* __restrict dest, const char* __restrict src); -char* strncat(char* __restrict dest, const char* __restrict src, size_t n); -char* strcat(char* __restrict dest, const char* __restrict src); -char* strtok(char* __restrict str, const char* __restrict delim); - -#endif diff --git a/kernel/arch/x86/include/kernel/asm.h b/kernel/arch/x86/include/kernel/asm.h new file mode 100644 index 0000000..18f53c4 --- /dev/null +++ b/kernel/arch/x86/include/kernel/asm.h @@ -0,0 +1,167 @@ +#ifndef I386_ASM_H +#define I386_ASM_H + +#include +#include +#include + +#define PCI_CONFIG_ADDR 0xCF8 +#define PCI_CONFIG_DATA 0xCFC + +#define COM_PORT 0x3F8 + +#define MAX_ISR 256 + +struct regs { + uint32_t eax; + uint32_t ebx; + uint32_t ecx; + uint32_t edx; + uint32_t esi; + uint32_t edi; + uint32_t ebp; + uint32_t esp; + + uint32_t cr0; + uint32_t cr2; + uint32_t cr3; + uint32_t cr4; +}; + +struct isr_frame { + uint32_t cr4; + uint32_t cr3; + uint32_t cr2; + uint32_t cr0; + + uint32_t edi; + uint32_t esi; + uint32_t edx; + uint32_t ecx; + uint32_t ebx; + uint32_t eax; + + uint32_t isr_vector; + uint32_t isr_err; + uint32_t eip; + uint32_t cs; + uint32_t eflags; +} __attribute__((packed)); + +struct cpuid_info { + char vendorID[12]; + uint32_t feat_ecx; + uint32_t feat_edx; +}; + +void isr_stub_0(void); +void isr_stub_1(void); +void isr_stub_2(void); +void isr_stub_3(void); +void isr_stub_4(void); +void isr_stub_5(void); +void isr_stub_6(void); +void isr_stub_7(void); +void isr_stub_8(void); +void isr_stub_9(void); +void isr_stub_10(void); +void isr_stub_11(void); +void isr_stub_12(void); +void isr_stub_13(void); +void isr_stub_14(void); +void isr_stub_15(void); +void isr_stub_16(void); +void isr_stub_17(void); +void isr_stub_18(void); +void isr_stub_19(void); +void isr_stub_20(void); +void isr_stub_21(void); +void isr_stub_22(void); +void isr_stub_23(void); +void isr_stub_24(void); +void isr_stub_25(void); +void isr_stub_26(void); +void isr_stub_27(void); +void isr_stub_28(void); +void isr_stub_29(void); +void isr_stub_30(void); +void isr_stub_31(void); + +void irq_stub_0(void); +void irq_stub_1(void); +void irq_stub_2(void); +void irq_stub_3(void); +void irq_stub_4(void); +void irq_stub_5(void); +void irq_stub_6(void); +void irq_stub_7(void); +void irq_stub_8(void); +void irq_stub_9(void); +void irq_stub_10(void); +void irq_stub_11(void); +void irq_stub_12(void); +void irq_stub_13(void); +void irq_stub_14(void); +void irq_stub_15(void); + +void isr_stub_128(void); + +void enable_paging(uint32_t new_cr3); +int cpuid_check(void); +void flush_gdt(void); + +static inline void cpuid(int code, uint32_t *ecx, uint32_t *ebx) { + __asm__ volatile("cpuid" : "=a"(*ecx), "=d"(*ebx) : "a"(code) : "ecx","ebx"); +} + +static inline void outb(uint16_t port, uint8_t value) { + __asm__ volatile("outb %0, %1" : : "a"(value), "Nd"(port)); +} + +static inline void outw(uint16_t port, uint16_t value) { + __asm__ volatile("outw %0, %1" : : "a"(value), "Nd"(port)); +} + +static inline void outl(uint16_t port, uint32_t value) { + __asm__ volatile("outl %0, %1" : : "a"(value), "Nd"(port)); +} + +static inline uint8_t inb(uint16_t port) { + uint8_t ret; + __asm__ volatile("inb %1, %0" : "=a"(ret) : "Nd"(port)); + return ret; +} + +static inline uint16_t inw(uint16_t port) { + uint16_t ret; + __asm__ volatile("inw %1, %0" : "=a"(ret) : "Nd"(port)); + return ret; +} + +static inline uint32_t inl(uint16_t port) { + uint32_t ret; + __asm__ volatile("inl %1, %0" : "=a"(ret) : "Nd"(port)); + return ret; +} + +static inline void enable_ints(void) { + __asm__ volatile("sti"); +} + +static inline void disable_ints(void) { + __asm__ volatile("cli"); +} + +static inline void flush_tss(void) { + __asm__ volatile("movw $0x28, %ax; ltr %ax"); +} + +static inline void flush_tlb(void) { + __asm__ volatile("movl %cr3, %eax; movl %eax, %cr3"); +} + +static inline void invlpg(void *addr) { + __asm__ volatile("invlpg (%0)" : : "b"(addr) : "memory"); +} + +#endif diff --git a/kernel/arch/x86/include/kernel/gdt.h b/kernel/arch/x86/include/kernel/gdt.h new file mode 100644 index 0000000..aa05408 --- /dev/null +++ b/kernel/arch/x86/include/kernel/gdt.h @@ -0,0 +1,53 @@ +#ifndef I386_GDT_H +#define I386_GDT_H + +#include + +struct gdt_entry { + uint16_t limit_low; + uint16_t base_low; + uint8_t base_middle; + uint8_t access; + uint8_t gran; + uint8_t base_high; +} __attribute__((packed)); + +struct gdt_ptr { + uint16_t limit; + uint64_t base; +} __attribute__((packed)); + +struct tss_entry { + uint32_t link; + uint32_t esp0; + uint32_t ss0; + uint32_t esp1; + uint32_t ss2; + uint32_t cr3; + uint32_t eip; + uint32_t eflags; + uint32_t eax; + uint32_t ecx; + uint32_t edx; + uint32_t ebx; + uint32_t esp; + uint32_t ebp; + uint32_t esi; + uint32_t edi; + uint32_t es; + uint32_t cs; + uint32_t ss; + uint32_t ds; + uint32_t fs; + uint32_t gs; + uint32_t ldtr; + uint16_t trap; + uint16_t iomap_base; +} __attribute__((packed)); + +void gdt_set_gate(int num, uint32_t base, uint32_t limit, uint8_t access, uint8_t gran); +void write_tss(int num, uint32_t ss0, uint32_t esp0); +void set_kernel_esp(uint32_t esp); +void gdt_install(void); + +#endif diff --git a/kernel/arch/x86/include/kernel/idt.h b/kernel/arch/x86/include/kernel/idt.h new file mode 100644 index 0000000..29ec39f --- /dev/null +++ b/kernel/arch/x86/include/kernel/idt.h @@ -0,0 +1,31 @@ +#ifndef I386_IDT_H +#define I386_IDT_H + +#include + +#define SEGMENT_PRESENT 0x80 +#define SEGMENT_RING0 0x00 +#define SEGMENT_RING3 0x60 +#define SEGMENT_STORAGE 0x00 +#define SEGMENT_INTERRUPT 0x0E +#define IDT_EXCEPTION (SEGMENT_PRESENT | SEGMENT_INTERRUPT) +#define IDT_INTERRUPT (SEGMENT_PRESENT | SEGMENT_INTERRUPT) + +#define IDT_MAX_DESCRIPTORS 256 + +struct idt_entry { + uint16_t isr_low; + uint16_t kernel_cs; + uint8_t reserved; + uint8_t flags; + uint16_t isr_high; +} __attribute__((packed)); + +struct idt_ptr { + uint16_t limit; + uint32_t base; +} __attribute__((packed)); + +void idt_install(void); + +#endif diff --git a/kernel/arch/x86/include/kernel/paging.h b/kernel/arch/x86/include/kernel/paging.h new file mode 100644 index 0000000..3a3c298 --- /dev/null +++ b/kernel/arch/x86/include/kernel/paging.h @@ -0,0 +1,45 @@ +#ifndef I386_PAGING_H +#define I386_PAGING_H + +#include +#include + +#define PAGE_SIZE 4096 + +#define PD_PRES 0x0001 +#define PD_RW 0x0002 +#define PD_USR 0x0004 +#define PD_PWT 0x0008 +#define PD_PCD 0x0010 +#define PD_ACC 0x0020 +#define PD_DIRTY 0x0040 +#define PD_PS 0x0080 +#define PD_GLOB 0x0100 +#define PD_PAT 0x1000 + +#define ERR_PRESENT 0x1 +#define ERR_RW 0x2 +#define ERR_USER 0x4 +#define ERR_RESERVED 0x8 +#define ERR_INST 0x10 + +#define PGROUNDUP(size) (((size)+PAGE_SIZE-1) & ~(PAGE_SIZE-1)) +#define PGROUNDDN(size) (((size)) & ~(PAGE_SIZE-1)) + +#define GET_PADDR(x) (((uint32_t)(x)) - 0xC0000000) +#define GET_VADDR(x) (((uint32_t)(x)) + 0xC0000000) + +#define GET_PDX(x) ((uintptr_t)(x) >> 22) +#define GET_PTX(x) (((uintptr_t)(x) >> 12) & 0x03FF) + +uintptr_t get_physaddr(void *vaddr); + +void paging_init(void); + +uintptr_t init_page_directory(void); +void map_page(uintptr_t paddr, uintptr_t vaddr, uint32_t flags); +void unmap_page(uintptr_t vaddr); + +void page_fault_handler(struct isr_frame *frame); + +#endif diff --git a/kernel/arch/x86/include/kernel/pic.h b/kernel/arch/x86/include/kernel/pic.h new file mode 100644 index 0000000..187d553 --- /dev/null +++ b/kernel/arch/x86/include/kernel/pic.h @@ -0,0 +1,44 @@ +#ifndef I386_PIC_H +#define I386_PIC_H + +#include +#include + +#define PIC1 0x20 +#define PIC2 0x28 +#define PIC1_COMMAND PIC1 +#define PIC1_DATA (PIC1+1) +#define PIC2_COMMAND PIC2 +#define PIC2_DATA (PIC2+1) + +#define ICW1_ICW4 0x01 +#define ICW1_SINGLE 0x02 +#define ICW1_INTERVAL4 0x04 +#define ICW1_LEVEL 0x08 +#define ICW1_INIT 0x10 + +#define ICW4_8086 0x01 +#define ICW4_AUTO 0x02 +#define ICW4_BUF_SLAVE 0x08 +#define ICW4_BUF_MASTER 0x0C +#define ICW4_SFNM 0x10 + +#define PIC_READ_IRR 0x0A +#define PIC_READ_ISR 0x0B + +static inline void io_wait(void) { + outb(0x80, 0); +} + +void pic_eoi(uint8_t irq); +void pic_remap(void); +uint16_t pic_get_irr(void); +uint16_t pic_get_isr(void); + +void register_irq_handler(uint8_t irq, void (*handler)(struct isr_frame *frame)); +void irq_dispatch(struct isr_frame *frame); + +void irq_set_mask(uint8_t irq); +void irq_clear_mask(uint8_t irq); + +#endif diff --git a/kernel/arch/x86/include/kernel/pmem.h b/kernel/arch/x86/include/kernel/pmem.h new file mode 100644 index 0000000..ea4fe29 --- /dev/null +++ b/kernel/arch/x86/include/kernel/pmem.h @@ -0,0 +1,19 @@ +#ifndef I386_PMEM_H +#define I386_PMEM_H + +#include +#include + +struct pfa_page { + struct pfa_page *next; +}; + +void pfa_init(struct mboot_info *header); + +uintptr_t pfa_alloc_dma(size_t num_pages); +uintptr_t pfa_alloc(size_t num_pages); + +void pfa_free_dma(uintptr_t paddr, size_t num_pages); +void pfa_free(uintptr_t paddr, size_t num_pages); + +#endif diff --git a/kernel/arch/x86/include/kernel/syscall.h b/kernel/arch/x86/include/kernel/syscall.h new file mode 100644 index 0000000..a657527 --- /dev/null +++ b/kernel/arch/x86/include/kernel/syscall.h @@ -0,0 +1,34 @@ +#ifndef I386_SYSCALL_H +#define I386_SYSCALL_H + +#include +#include +#include + +// Unix standard calls +#define SYS_FORK 1 +#define SYS_EXIT 2 +#define SYS_WAIT 3 +#define SYS_PIPE 4 +#define SYS_READ 5 +#define SYS_WRITE 6 +#define SYS_KILL 7 +#define SYS_FSTAT 8 +#define SYS_CHDIR 9 +#define SYS_DUP 10 +#define SYS_GETPID 11 +#define SYS_SLEEP 12 +#define SYS_OPEN 13 +#define SYS_MKNOD 14 +#define SYS_UNLINK 15 +#define SYS_LINK 16 +#define SYS_MKDIR 17 +#define SYS_CLOSE 18 +#define SYS_EXEC 19 + +#define SYS_HALT 87 +#define SYS_REBOOT 88 + +void handle_syscall(struct isr_frame *frame); + +#endif diff --git a/kernel/arch/x86/include/kernel/timer.h b/kernel/arch/x86/include/kernel/timer.h new file mode 100644 index 0000000..c0b3a73 --- /dev/null +++ b/kernel/arch/x86/include/kernel/timer.h @@ -0,0 +1,9 @@ +#ifndef I386_TIMER_H +#define I386_TIMER_H + +#include + +void timer_handler(struct isr_frame *frame); +void timer_init(void); + +#endif diff --git a/kernel/arch/x86/include/kernel/vmem.h b/kernel/arch/x86/include/kernel/vmem.h new file mode 100644 index 0000000..94aa32d --- /dev/null +++ b/kernel/arch/x86/include/kernel/vmem.h @@ -0,0 +1,17 @@ +#ifndef I386_VMEM_H +#define I386_VMEM_H + +extern uintptr_t _kernel_start; +extern uintptr_t _kernel_end; + +#define KSTART ((uintptr_t)&_kernel_start) +#define KEND ((uintptr_t)&_kernel_end - 0xC0000000) + +#define KHEAP_START (GET_VADDR(KEND) + 0x2000) +#define KHEAP_STOP 0xFF7FF000 + +#define PAGE_DIR_MAP 0xFFFFF000 +#define PAGE_TAB_MAP 0xFFC00000 +#define PAGE_TMP_MAP 0xFFBFF000 + +#endif diff --git a/kernel/arch/x86/kernel/gdt.c b/kernel/arch/x86/kernel/gdt.c new file mode 100644 index 0000000..57424aa --- /dev/null +++ b/kernel/arch/x86/kernel/gdt.c @@ -0,0 +1,54 @@ +#include +#include +#include + +struct gdt_entry desc[6]; +struct gdt_ptr gp; +struct tss_entry tss_entry; + +void gdt_set_gate(int num, uint32_t base, uint32_t limit, uint8_t access, uint8_t gran) { + desc[num].base_low = (base & 0xFFFF); + desc[num].base_middle = (base >> 16) & 0xFF; + desc[num].base_high = (base >> 24) & 0xFF; + + desc[num].limit_low = (limit & 0xFFFF); + desc[num].gran = (limit >> 16) & 0x0F; + desc[num].gran |= (gran & 0xF0); + desc[num].access = access; +} + +void write_tss(int num, uint32_t ss0, uint32_t esp0) { + uint64_t base = (uint64_t)&tss_entry; + uint32_t limit = base + sizeof(struct tss_entry); + + gdt_set_gate(num, base, limit, 0x89, 0x00); + memset(&tss_entry, 0x0, sizeof(tss_entry)); + + tss_entry.ss0 = ss0; + tss_entry.esp0 = esp0; + tss_entry.cs = 0x0B; + tss_entry.ss = 0x13; + tss_entry.ds = 0x13; + tss_entry.es = 0x13; + tss_entry.fs = 0x13; + tss_entry.gs = 0x13; + tss_entry.iomap_base = sizeof(tss_entry); +} + +void gdt_install(void) { + gp.limit = (sizeof(struct gdt_entry) * 6) - 1; + gp.base = (uint64_t)&desc; + + gdt_set_gate(0, 0, 0, 0, 0); + gdt_set_gate(1, 0, 0xFFFFF, 0x9A, 0xCF); + gdt_set_gate(2, 0, 0xFFFFF, 0x92, 0xCF); + gdt_set_gate(3, 0, 0xFFFFF, 0xFA, 0xCF); + gdt_set_gate(4, 0, 0xFFFFF, 0xF2, 0xCF); + + uint64_t rsp; + __asm__ volatile("movq %%rsp, %0" : "=r"(rsp)); + write_tss(5, 0x10, rsp); + + flush_gdt(); + flush_tss(); +} diff --git a/kernel/arch/x86/kernel/idt.c b/kernel/arch/x86/kernel/idt.c new file mode 100644 index 0000000..a178801 --- /dev/null +++ b/kernel/arch/x86/kernel/idt.c @@ -0,0 +1,149 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +__attribute__((aligned(0x10))) +struct idt_entry idt[256]; +struct idt_ptr idtr; + +const char* exceptions[] = { + "Division by zero", + "Debug", + "Non-maskable interrupt", + "Breakpoint", + "Overflow", + "Out-of-bounds", + "Invalid opcode", + "FPU not available", + "Double fault", + "RESERVED", + "Invalid TSS", + "Segment not present", + "Stack fault", + "General protection fault", + "Page fault", + "RESERVED", + "FPU exception", + "Alignment check", + "Machine check", + "FPU-SIMD exception", + "Virtualization exception", + "Control protection" + "RESERVED", + "Hypervisor injection", + "VMM exception", + "Security exception", + "RESERVED", + "Triple fault", + "RESERVED" +}; + +void exception_handler(struct isr_frame *frame) { + switch (frame->isr_vector) { + case 0x00: + panic("Division by zero in kernel address space"); + break; + case 0x06: + panic("Invalid opcode in kernel address space"); + break; + case 0x08: + panic("Double fault in interrupt handler"); + break; + case 0x0D: + panic("Protection fault in kernel address space"); + break; + case 0x0E: + page_fault_handler(frame); + break; + default: + panic("Unhandled exception"); + } +} + +void generic_handler(struct isr_frame *frame) { + kprintf("No handler registered for IRQ %d\n", frame->isr_vector); + if (frame->isr_vector > 32 && frame->isr_vector < 48) + pic_eoi(frame->isr_vector-32); +} + +void idt_set_gate(uint8_t num, void (*handler)(void), uint16_t cs, uint8_t flags) { + struct idt_entry *desc = &idt[num]; + desc->isr_low = (uint16_t)(((uint32_t)handler >> 0) & 0xFFFF); + desc->isr_high = (uint16_t)(((uint32_t)handler >> 16) & 0xFFFF); + desc->reserved = 0; + desc->kernel_cs = cs; + desc->flags = flags; +} + +void idt_install(void) { + idtr.limit = (uint16_t)sizeof(struct idt_entry) * 256 - 1; + idtr.base = (uint32_t)idt; + + for (int i = 0; i < 32; i++) + register_isr_handler(i, exception_handler); + for (int i = 32; i < 224; i++) + register_isr_handler(i, generic_handler); + register_isr_handler(0x80, handle_syscall); + + idt_set_gate(0x0, isr_stub_0, 0x08, IDT_EXCEPTION); + idt_set_gate(0x1, isr_stub_1, 0x08, IDT_EXCEPTION); + idt_set_gate(0x2, isr_stub_2, 0x08, IDT_EXCEPTION); + idt_set_gate(0x3, isr_stub_3, 0x08, IDT_EXCEPTION); + idt_set_gate(0x4, isr_stub_4, 0x08, IDT_EXCEPTION); + idt_set_gate(0x5, isr_stub_5, 0x08, IDT_EXCEPTION); + idt_set_gate(0x6, isr_stub_6, 0x08, IDT_EXCEPTION); + idt_set_gate(0x7, isr_stub_7, 0x08, IDT_EXCEPTION); + idt_set_gate(0x8, isr_stub_8, 0x08, IDT_EXCEPTION); + idt_set_gate(0x9, isr_stub_9, 0x08, IDT_EXCEPTION); + idt_set_gate(0xA, isr_stub_10, 0x08, IDT_EXCEPTION); + idt_set_gate(0xB, isr_stub_11, 0x08, IDT_EXCEPTION); + idt_set_gate(0xC, isr_stub_12, 0x08, IDT_EXCEPTION); + idt_set_gate(0xD, isr_stub_13, 0x08, IDT_EXCEPTION); + idt_set_gate(0xE, isr_stub_14, 0x08, IDT_EXCEPTION); + idt_set_gate(0xF, isr_stub_15, 0x08, IDT_EXCEPTION); + idt_set_gate(0x10, isr_stub_16, 0x08, IDT_EXCEPTION); + idt_set_gate(0x11, isr_stub_17, 0x08, IDT_EXCEPTION); + idt_set_gate(0x12, isr_stub_18, 0x08, IDT_EXCEPTION); + idt_set_gate(0x13, isr_stub_19, 0x08, IDT_EXCEPTION); + idt_set_gate(0x14, isr_stub_20, 0x08, IDT_EXCEPTION); + idt_set_gate(0x15, isr_stub_21, 0x08, IDT_EXCEPTION); + idt_set_gate(0x16, isr_stub_22, 0x08, IDT_EXCEPTION); + idt_set_gate(0x17, isr_stub_23, 0x08, IDT_EXCEPTION); + idt_set_gate(0x18, isr_stub_24, 0x08, IDT_EXCEPTION); + idt_set_gate(0x19, isr_stub_25, 0x08, IDT_EXCEPTION); + idt_set_gate(0x1A, isr_stub_26, 0x08, IDT_EXCEPTION); + idt_set_gate(0x1B, isr_stub_27, 0x08, IDT_EXCEPTION); + idt_set_gate(0x1C, isr_stub_28, 0x08, IDT_EXCEPTION); + idt_set_gate(0x1D, isr_stub_29, 0x08, IDT_EXCEPTION); + idt_set_gate(0x1E, isr_stub_30, 0x08, IDT_EXCEPTION); + idt_set_gate(0x1F, isr_stub_31, 0x08, IDT_EXCEPTION); + + idt_set_gate(0x20, irq_stub_0, 0x08, IDT_INTERRUPT); + idt_set_gate(0x21, irq_stub_1, 0x08, IDT_INTERRUPT); + idt_set_gate(0x22, irq_stub_2, 0x08, IDT_INTERRUPT); + idt_set_gate(0x23, irq_stub_3, 0x08, IDT_INTERRUPT); + idt_set_gate(0x24, irq_stub_4, 0x08, IDT_INTERRUPT); + idt_set_gate(0x25, irq_stub_5, 0x08, IDT_INTERRUPT); + idt_set_gate(0x26, irq_stub_6, 0x08, IDT_INTERRUPT); + idt_set_gate(0x27, irq_stub_7, 0x08, IDT_INTERRUPT); + idt_set_gate(0x28, irq_stub_8, 0x08, IDT_INTERRUPT); + idt_set_gate(0x29, irq_stub_9, 0x08, IDT_INTERRUPT); + idt_set_gate(0x2A, irq_stub_10, 0x08, IDT_INTERRUPT); + idt_set_gate(0x2B, irq_stub_11, 0x08, IDT_INTERRUPT); + idt_set_gate(0x2C, irq_stub_12, 0x08, IDT_INTERRUPT); + idt_set_gate(0x2D, irq_stub_13, 0x08, IDT_INTERRUPT); + idt_set_gate(0x2E, irq_stub_14, 0x08, IDT_INTERRUPT); + idt_set_gate(0x2F, irq_stub_15, 0x08, IDT_INTERRUPT); + + idt_set_gate(0x80, isr_stub_128, 0x08, IDT_INTERRUPT); + + __asm__ volatile("lidt %0" : : "memory"(idtr)); +} diff --git a/kernel/arch/x86/kernel/kmalloc.c b/kernel/arch/x86/kernel/kmalloc.c new file mode 100644 index 0000000..9e5254c --- /dev/null +++ b/kernel/arch/x86/kernel/kmalloc.c @@ -0,0 +1,70 @@ +#include +#include +#include +#include +#include +#include +#include + +static uintptr_t heap_start = KEND + 0xC0001000; +static uintptr_t heap_end = 0xFFBFF000; + +static void *kbrk = NULL; +static struct mem_block *first = NULL; + +void _request_page(void) { + uintptr_t paddr = pfa_alloc(1); + uintptr_t vaddr = PGROUNDDN((uintptr_t)kbrk + PAGE_SIZE); + kbrk += PAGE_SIZE; + map_page(paddr, vaddr, PD_PRES | PD_RW); +} + +void kmalloc_init(void) { + kbrk = PGROUNDDN(heap_start); + _request_page(); + first = (struct mem_block*)kbrk; + first->start = (uintptr_t)kbrk + sizeof(struct mem_block); + first->size = 0; + first->alloc = 1; + first->next = NULL; +} + +void* kmalloc(size_t sz) { + if (kbrk == NULL) + panic("Attmpted to malloc before initialization"); + if ((uintptr_t)kbrk >= heap_end) + return NULL; + + struct mem_block *temp = first; + while (temp->next != NULL) { + if (temp->next->size <= sz && temp->next->alloc == 0) { + temp->next->alloc = 1; + return (void*)temp->next->start; + } + temp = temp->next; + } + + temp->next = (struct mem_block*)((uintptr_t)temp + sizeof(struct mem_block) + temp->size); + if (temp->next > kbrk) + _request_page(); + temp->next->prev = temp; + temp->next->start = (uintptr_t)(temp->next + sizeof(struct mem_block)); + temp->next->size = sz; + temp->next->alloc = 1; + temp->next->next = NULL; + return (void*)temp->start; +} + +void kfree(void *ptr) { + if (ptr == NULL) + return; + struct mem_block *temp = first; + while (temp != NULL) { + if (temp->start == (uintptr_t)ptr) { + temp->alloc = 0; + return; + } + temp = temp->next; + } + panic("Attempted to free memory not alloc'd"); +} diff --git a/kernel/arch/x86/kernel/multiboot.c b/kernel/arch/x86/kernel/multiboot.c new file mode 100644 index 0000000..dedf163 --- /dev/null +++ b/kernel/arch/x86/kernel/multiboot.c @@ -0,0 +1,49 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +void kernel_main(char *cmdline); + +void i386_entry(uint32_t mboot_magic, struct mboot_info *header) { + map_page(0xB8000, (uintptr_t)VGA_MEMORY, PD_RW); + fb_init(); + + if (mboot_magic != MBOOT_LOADER_MAGIC) { + disable_ints(); + panic("Not booted with multiboot bootloader"); + } + + map_page(0x9000, 0x9000, PD_RW); + if (!(header->flags >> 6 & 0x1)) { + disable_ints(); + panic("Physical memory map not provided by bootloader"); + } + + char cmdline[4096]; + map_page(header->cmdline, PAGE_TMP_MAP, 0); + memcpy(cmdline, (char*)PAGE_TMP_MAP, strlen((char*)PAGE_TMP_MAP)); + unmap_page(PAGE_TMP_MAP); + pfa_init(header); + gdt_install(); + idt_install(); + paging_init(); + map_page(0xB8000, (uintptr_t)VGA_MEMORY, PD_RW); + pic_remap(); + timer_init(); + + enable_ints(); + kernel_main(cmdline); + + while (1); +} diff --git a/kernel/arch/x86/kernel/paging.c b/kernel/arch/x86/kernel/paging.c new file mode 100644 index 0000000..a0bbb92 --- /dev/null +++ b/kernel/arch/x86/kernel/paging.c @@ -0,0 +1,130 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +static int paging_enabled = 0; + +void paging_init(void) { + if (paging_enabled == 1) + return; + + uintptr_t phys_pt = pfa_alloc(1); + map_page(phys_pt, PAGE_TMP_MAP, PD_PRES | PD_RW); + uintptr_t *pt = (uintptr_t*)PAGE_TMP_MAP; + for (uintptr_t i = KSTART; i < KEND; i += PAGE_SIZE) + pt[GET_PTX(GET_VADDR(i))] = i | PD_PRES; + unmap_page(PAGE_TMP_MAP); + + uintptr_t temp_pt = pfa_alloc(1); + + uintptr_t phys_pd = pfa_alloc(1); + map_page(phys_pd, PAGE_TMP_MAP, PD_PRES | PD_RW); + uintptr_t *pd = (uintptr_t*)PAGE_TMP_MAP; + pd[GET_PDX(GET_VADDR(KSTART))] = phys_pt | PD_PRES | PD_RW; + pd[GET_PDX(PAGE_TMP_MAP)] = temp_pt | PD_PRES | PD_RW; + pd[1023] = phys_pd | PD_PRES | PD_RW; + unmap_page(PAGE_TMP_MAP); + + enable_paging(phys_pd); + paging_enabled = 1; + return; +} + +void init_page_table(int pdindex, uint32_t flags) { + uintptr_t *pd = (uintptr_t*)PAGE_DIR_MAP; + if ((pd[pdindex] & PD_PRES) != 0) + return; + + uintptr_t paddr = pfa_alloc(1); + pd[pdindex] = paddr | PD_PRES | PD_RW | flags; + + uintptr_t *pt = ((uintptr_t*)PAGE_TAB_MAP) + (pdindex << 12); + pd[GET_PDX(pt)] = paddr | PD_PRES | PD_RW; +} + +uintptr_t init_page_directory(void) { + uintptr_t ret = pfa_alloc(1); + map_page(ret, PAGE_TMP_MAP, PD_RW); + + uintptr_t *new_pd = (uintptr_t*)PAGE_TMP_MAP; + uintptr_t *cur_pd = (uintptr_t*)PAGE_DIR_MAP; + int kernel_pdx = GET_PDX(GET_VADDR(KSTART)); + new_pd[kernel_pdx] = cur_pd[kernel_pdx]; + + unmap_page(PAGE_TMP_MAP); + return ret; +} + +void map_page(uintptr_t paddr, uintptr_t vaddr, uint32_t flags) { + paddr = PGROUNDDN(paddr); + vaddr = PGROUNDDN(vaddr); + + int pdindex = GET_PDX(vaddr); + int ptindex = GET_PTX(vaddr); + + uintptr_t *pd = (uintptr_t*)PAGE_DIR_MAP; + if ((pd[pdindex] & PD_PRES) == 0) + init_page_table(pdindex, 0); + + uintptr_t *pt = (uintptr_t*)(PAGE_TAB_MAP + (pdindex << 12)); + pt[ptindex] = paddr | PD_PRES | flags; + invlpg((void*)vaddr); +} + +void unmap_page(uintptr_t vaddr) { + uintptr_t pdindex = GET_PDX(vaddr); + uintptr_t ptindex = GET_PTX(vaddr); + + uintptr_t *pd = (uintptr_t*)PAGE_DIR_MAP; + if ((pd[pdindex] & PD_PRES) == 0) + return; + + uintptr_t *pt = (uintptr_t*)(PAGE_TAB_MAP + (pdindex << 12)); + pt[ptindex] = 0; + invlpg((void*)vaddr); +} + +void page_fault_handler(struct isr_frame *frame) { + uintptr_t fault_addr; + __asm__ volatile("movl %%cr2, %0" : "=r"(fault_addr)); + + kprintf("Faulting address: %x\n", fault_addr); + panic("Page fault not operational"); + switch (frame->isr_err) { + case 0: + //map_page((uintptr_t*)GET_VADDR(frame->cr3), pfa_alloc(), fault_addr, PD_PRES); + break; + case 1: + panic("Kernel process caused protection fault on read\n"); + break; + case 2: + //map_page((uintptr_t*)GET_VADDR(frame->cr3), pfa_alloc(), fault_addr, PD_PRES | PD_RW); + break; + case 3: + panic("Kernel process caused protection fault on write\n"); + break; + case 4: + //map_page((uintptr_t*)GET_VADDR(frame->cr3), pfa_alloc(), fault_addr, PD_PRES | PD_USR); + break; + case 5: + // TODO: instead of panicking, kill process + panic("User process caused protection fault on read\n"); + break; + case 6: + //map_page((uintptr_t*)GET_VADDR(frame->cr3), pfa_alloc(), fault_addr, PD_PRES | PD_RW | PD_USR); + break; + case 7: + // TODO: see case 101 + panic("USER process caused protection fault on write\n"); + break; + default: + kprintf("Unknown paging error occured on address %x\n", fault_addr); + panic("Paging error"); + break; + } +} diff --git a/kernel/arch/x86/kernel/pic.c b/kernel/arch/x86/kernel/pic.c new file mode 100644 index 0000000..0d29473 --- /dev/null +++ b/kernel/arch/x86/kernel/pic.c @@ -0,0 +1,79 @@ +#include + +static void (*irq_handlers[16])(struct isr_frame *frame); + +void pic_eoi(uint8_t irq) { + if (irq >= 8) + outb(PIC2_COMMAND, 0x20); + outb(PIC1_COMMAND, 0x20); +} + +void pic_remap(void) { + unsigned char a1 = inb(PIC1_DATA); + unsigned char a2 = inb(PIC2_DATA); + + outb(PIC1_COMMAND, ICW1_INIT | ICW1_ICW4); + outb(PIC2_COMMAND, ICW1_INIT | ICW1_ICW4); + outb(PIC1_DATA, PIC1); + outb(PIC2_DATA, PIC2); + outb(PIC1_DATA, 4); + outb(PIC2_DATA, 2); + outb(PIC1_DATA, ICW4_8086); + outb(PIC2_DATA, ICW4_8086); + outb(PIC1_DATA, a1); + outb(PIC2_DATA, a2); +} + +static uint16_t _pic_get_irq_reg(int ocw3) { + outb(PIC1_COMMAND, ocw3); + outb(PIC2_COMMAND, ocw3); + return (inb(PIC2_COMMAND) << 8) | inb(PIC1_COMMAND); +} + +uint16_t pic_get_irr(void) { + return _pic_get_irq_reg(PIC_READ_IRR); +} + +uint16_t pic_get_isr(void) { + return _pic_get_irq_reg(PIC_READ_ISR); +} + +void register_irq_handler(uint8_t irq, void (*handler)(struct isr_frame *frame)) { + irq_handlers[irq] = handler; +} + +void irq_dispatch(struct isr_frame *frame) { + (*irq_handlers[frame->isr_vector-32])(frame); + pic_eoi(frame->isr_vector-32); + return; +} + +void irq_set_mask(uint8_t irq) { + uint16_t port; + uint8_t data; + + if (irq < 8) { + port = PIC1_DATA; + } else { + port = PIC2_DATA; + irq -= 8; + } + + data = inb(port) | (1 << irq); + outb(port, data); +} + +void irq_clear_mask(uint8_t irq) { + uint16_t port; + uint8_t data; + + if (irq < 8) { + port = PIC1_DATA; + } else { + port = PIC2_DATA; + irq -= 8; + } + + data = inb(port) & ~(1 << irq); + outb(port, data); +} diff --git a/kernel/arch/x86/kernel/pmem.c b/kernel/arch/x86/kernel/pmem.c new file mode 100644 index 0000000..edf71d9 --- /dev/null +++ b/kernel/arch/x86/kernel/pmem.c @@ -0,0 +1,66 @@ +#include +#include +#include +#include +#include +#include +#include + +static uintptr_t bitmap[5]; +static struct pfa_page freelist; + +void pfa_init(struct mboot_info *header) { + struct mboot_mmap_entry *mme; + for (uintptr_t i = 0; i < header->mmap_length; i += sizeof(struct mboot_mmap_entry)) { + mme = (struct mboot_mmap_entry*)(header->mmap_addr + i); + if (mme->type == MBOOT_MEM_AVAILABLE) + pfa_free(mme->addr_low, mme->len_low / PAGE_SIZE); + } +} + +uintptr_t pfa_alloc_dma(size_t num_pages) { +} + +uintptr_t pfa_alloc(size_t num_pages) { + struct pfa_page *temp = (struct pfa_page*)PAGE_TMP_MAP; + map_page(freelist.next, PAGE_TMP_MAP, PD_PRES | PD_RW); + uintptr_t ret = freelist.next; + freelist.next = temp->next; + memset(temp, 0, 32); + unmap_page(PAGE_TMP_MAP); + return ret; +} + +void pfa_free_dma(uintptr_t paddr, size_t num_pages) { + if (paddr % PAGE_SIZE != 0) + panic("Task attempted to free non-aligned memory"); + if (paddr >= KSTART && paddr < KEND) + return; + if (paddr >= 0x00080000 && paddr < 0x00100000) + return; + + int index = 0; + int bit = 0; + for (uintptr_t i = paddr; i < paddr + (num_pages * PAGE_SIZE); i += PAGE_SIZE) { + index = i / PAGE_SIZE / 32; + bit = i / PAGE_SIZE % 32; + bitmap[index] |= 1 << bit; + } +} + +void pfa_free(uintptr_t paddr, size_t num_pages) { + uintptr_t addr; + struct pfa_page *temp = (struct pfa_page*)PAGE_TMP_MAP; + for (size_t i = 0; i < num_pages; i++) { + addr = (i * PAGE_SIZE + paddr); + if (addr >= KSTART && addr < KEND) + continue; + if (addr == 0) + continue; + map_page(addr, PAGE_TMP_MAP, PD_PRES | PD_RW); + memset(PAGE_TMP_MAP, 1, 32); + temp->next = freelist.next; + freelist.next = addr; + unmap_page(PAGE_TMP_MAP); + } +} diff --git a/kernel/arch/x86/kernel/serial.c b/kernel/arch/x86/kernel/serial.c new file mode 100644 index 0000000..dc2a8bd --- /dev/null +++ b/kernel/arch/x86/kernel/serial.c @@ -0,0 +1,42 @@ +#include +#include +#include +#include + +#define PORT 0x3f8 + +static inline int _serial_received(void) { + return inb(PORT + 5) & 1; +} + +static inline int _is_transmit_empty(void) { + return inb(PORT + 5) & 0x20; +} + +int serial_init(void) { + outb(PORT + 1, 0x00); + outb(PORT + 3, 0x80); + outb(PORT + 0, 0x03); + outb(PORT + 1, 0x00); + outb(PORT + 3, 0x03); + outb(PORT + 2, 0xC7); + outb(PORT + 4, 0x0B); + outb(PORT + 4, 0x1E); + outb(PORT + 0, 0xAE); + + if (inb(PORT + 0) != 0xAE) + return -1; + + outb(PORT + 4, 0x0F); + return 0; +} + +void serial_putchar(char c) { + while (_is_transmit_empty() == 0); + outb(PORT, c); +} + +char serial_getchar(void) { + while (_serial_received() == 0); + return inb(PORT); +} diff --git a/kernel/arch/x86/kernel/syscall.c b/kernel/arch/x86/kernel/syscall.c new file mode 100644 index 0000000..1fa73e9 --- /dev/null +++ b/kernel/arch/x86/kernel/syscall.c @@ -0,0 +1,25 @@ +#include +#include +#include +#include +#include + +void sys_read(struct isr_frame *frame) { +} + +void sys_write(struct isr_frame *frame) { +} + +void handle_syscall(struct isr_frame *frame) { + switch (frame->eax) { + case SYS_READ: + sys_read(frame); + break; + case SYS_WRITE: + sys_write(frame); + break; + default: + kprintf("Invalid system call number %d\n", frame->eax); + break; + } +} diff --git a/kernel/arch/x86/kernel/timer.c b/kernel/arch/x86/kernel/timer.c new file mode 100644 index 0000000..bd57cc2 --- /dev/null +++ b/kernel/arch/x86/kernel/timer.c @@ -0,0 +1,25 @@ +#include +#include +#include + +static uint32_t num_ticks = 0; + +void timer_handler(struct isr_frame *frame) { + num_ticks++; + if (num_ticks == 3) { + num_ticks = 0; + //schedule_next(); + } + pic_eoi(frame->isr_vector-32); +} + +void timer_init(void) { + disable_ints(); + int divisor = 1193182 / 100; + outb(0x43, 0x34); + outb(0x40, divisor && 0xFF); + outb(0x40, divisor && 0xFF00 >> 8); + enable_ints(); + + //register_isr_handler(32, timer_handler); +} diff --git a/kernel/core/interrupt.c b/kernel/core/interrupt.c new file mode 100644 index 0000000..6d9e69d --- /dev/null +++ b/kernel/core/interrupt.c @@ -0,0 +1,21 @@ +#include +#include +#include + +static void (*isr_handlers[MAX_ISR])(struct isr_frame *frame); + +void register_isr_handler(unsigned int isr, void (*handler)(struct isr_frame *frame)) { + if (isr > MAX_ISR) + panic("Attempted to set non-existant interrupt vector"); + isr_handlers[isr] = handler; +} + +void clear_isr_handler(unsigned int isr) { + if (isr > MAX_ISR) + panic("Attempted to clear non-existant interrupt vector"); + isr_handlers[isr] = NULL; +} + +void isr_dispatch(struct isr_frame frame) { + (*isr_handlers[frame.isr_vector])(&frame); +} diff --git a/kernel/core/panic.c b/kernel/core/panic.c new file mode 100644 index 0000000..a44a73c --- /dev/null +++ b/kernel/core/panic.c @@ -0,0 +1,31 @@ +#include +#include +#include +#include +#include + +static struct spinlock panic_lock = {0}; +static int panicked = 0; + +void walk_stack(uintptr_t *addrs, size_t n); + +void stack_trace(void) { + kprintf("PRINTING STACK TRACE\n"); + uintptr_t strace[32]; + walk_stack(strace, 32); + for (int i = 0; i < 32; i++) { + if (strace[i] == 0) + break; + kprintf("#%d: %x\n", i, strace[i]); + } +} + +void panic(const char *str) { + disable_ints(); + spin_lock(&panic_lock); + panicked = 1; + spin_unlock(&panic_lock); + kprintf("KERNEL PANIC - NOT SYNCING: %s\n", str); + stack_trace(); + while (1); +} diff --git a/kernel/core/sched.c b/kernel/core/sched.c new file mode 100644 index 0000000..b6096da --- /dev/null +++ b/kernel/core/sched.c @@ -0,0 +1,74 @@ +#include +#include +#include +#include +#include +#include +#include + +static struct kthread *run_queue = NULL; +static struct kthread *wait_queue = NULL; +static struct kthread *cur = NULL; + +static int scheduler_enabled = 0; +static struct kmutex scheduler_lock; + +void sched_init(void) { + disable_ints(); + cur = kthread_create(NULL, NULL); + cur->stack = NULL; + switch_thread(cur, cur); + cur->state = THREAD_RUNNING; + scheduler_enabled = 1; + enable_ints(); +} + +void schedule_next(void) { + if (scheduler_enabled == 0) + return; + if (run_queue == NULL) + return; + + struct kthread *thread = cur; + schedule_thread(cur); + cur = run_queue; + run_queue = run_queue->next; + cur->next = NULL; + cur->state = THREAD_RUNNING; + switch_thread(thread, cur); +} + +void schedule_thread(struct kthread *thread) { + if (run_queue == NULL) { + run_queue = thread; + return; + } + + kmutex_lock(&scheduler_lock); + struct kthread *temp = run_queue; + while (temp->next != NULL) + temp = temp->next; + temp->next = thread; + thread->state = THREAD_READY; + kmutex_unlock(&scheduler_lock); +} + +void block_thread(struct kthread *thread) { + kmutex_lock(&scheduler_lock); + thread->next = wait_queue; + wait_queue = thread; + kmutex_unlock(&scheduler_lock); +} + +void unblock_thread(struct kthread *thread) { + kmutex_lock(&scheduler_lock); + struct kthread *temp = wait_queue; + while (temp != NULL) { + if (temp->next == thread) { + temp->next = thread->next; + return; + } + temp = temp->next; + } + kmutex_unlock(&scheduler_lock); +} diff --git a/kernel/drivers/input/keyboard.c b/kernel/drivers/input/keyboard.c new file mode 100644 index 0000000..f2a8eba --- /dev/null +++ b/kernel/drivers/input/keyboard.c @@ -0,0 +1,142 @@ +#include +#include +#include +#include +#include +#include + +static uint8_t keymap_modifiers[256] = { + [0x1D] KB_CTL, + [0x2A] KB_SHIFT, + [0x36] KB_SHIFT, + [0x38] KB_ALT, + [0x9D] KB_CTL, + [0xB8] KB_ALT +}; + +static uint8_t keymap_toggles[256] = { + [0x3A] KB_CPSLK, + [0x45] KB_NUMLK, + [0x46] KB_SCLLK +}; + +static uint8_t keymap_normal[256] = { + 0, 0x1B, '1', '2', '3', '4', '5', '6', + '7', '8', '9', '0', '-', '=', '\b', '\t', + 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', + 'o', 'p', '[', ']', '\n', 0, 'a', 's', + 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', + '\'', '`', 0, '\\', 'z', 'x', 'c', 'v', + 'b', 'n', 'm', ',', '.', '/', 0, '*', + 0, ' ', 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, '7', + '8', '9', '-', '4', '5', '6', '+', '1', + '2', '3', '0', '.', 0, 0, 0, 0, + [0x9C] '\n', + [0xB5] '/', + [0xC8] KB_UP, + [0xD0] KB_DOWN, + [0xC9] KB_PGUP, + [0xD1] KB_PGDN, + [0xCB] KB_LEFT, + [0xCD] KB_RGHT, + [0x97] KB_HOME, + [0xCF] KB_END, + [0xD2] KB_INS, + [0xD3] KB_DEL +}; + +static uint8_t keymap_shifted[256] = { + 0, 0x33, '!', '@', '#', '$', '%', '^', + '&', '*', '(', ')', '_', '+', '\b', '\t', + 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', + 'O', 'P', '{', '}', '\n', 0, 'A', 'S', + 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', + '"', '~', 0, '|', 'Z', 'X', 'C', 'V', + 'B', 'N', 'M', '<', '>', '?', 0, '*', + 0, ' ', 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, '7', + '8', '9', '-', '4', '5', '6', '+', '1', + '2', '3', '0', '.', 0, 0, 0, 0, + [0x9C] '\n', + [0xB5] '/', + [0xC8] KB_UP, + [0xD0] KB_DOWN, + [0xC9] KB_PGUP, + [0xD1] KB_PGDN, + [0xCB] KB_LEFT, + [0xCD] KB_RGHT, + [0x97] KB_HOME, + [0xCF] KB_END, + [0xD2] KB_INS, + [0xD3] KB_DEL +}; + +static uint8_t keymap_control[256] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + C('Q'), C('W'), C('E'), C('R'), C('T'), C('Y'), C('U'), C('I'), + C('O'), C('P'), 0, 0, '\r', 0, C('A'), C('S'), + C('D'), C('F'), C('G'), C('H'), C('J'), C('K'), C('L'), 0, + 0, 0, 0, C('\\'), C('Z'), C('X'), C('C'), C('V'), + C('B'), C('N'), C('M'), 0, 0, C('/'), 0, 0, + [0x9C] '\r', + [0xB5] C('/'), + [0xC8] KB_UP, + [0xD0] KB_DOWN, + [0xC9] KB_PGUP, + [0xD1] KB_PGDN, + [0xCB] KB_LEFT, + [0xCD] KB_RGHT, + [0x97] KB_HOME, + [0xCF] KB_END, + [0xD2] KB_INS, + [0xD3] KB_DEL +}; + +static uint8_t* keymaps[4] = { + keymap_normal, + keymap_shifted, + keymap_control, + keymap_control, +}; + +char keyboard_getchar(void) { + static int shift = 0; + uint8_t st = inb(KB_STAT); + if ((st & KB_DIB) == 0) + return -1; + + uint8_t data = inb(KB_DATA); + + if (data == 0xE0) { + shift |= KB_E0ESC; + return -1; + } else if (data & 0x80) { + if (!(shift & KB_E0ESC)) + data &= 0x7F; + shift &= ~(keymap_modifiers[data] | KB_E0ESC); + return -1; + } else if (shift & KB_E0ESC) { + data |= 0x80; + shift &= ~KB_E0ESC; + } + + shift |= keymap_modifiers[data]; + shift ^= keymap_toggles[data]; + char c = keymaps[shift & (KB_CTL | KB_SHIFT)][data]; + if (shift & KB_CPSLK) { + if ('a' <= c && c <= 'z') + c += 'A' - 'a'; + else if ('A' <= c && c <= 'Z') + c += 'a' - 'A'; + } + return c; +} + +void keyboard_handler(struct isr_frame *frame) { + char c = keyboard_getchar(); + if (c != -1) + tty_getchar(c); + return; +} diff --git a/kernel/drivers/video/framebuffer.c b/kernel/drivers/video/framebuffer.c new file mode 100644 index 0000000..3df3df4 --- /dev/null +++ b/kernel/drivers/video/framebuffer.c @@ -0,0 +1,109 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static size_t fb_row; +static size_t fb_column; +static uint8_t fb_color; +static uint16_t *framebuffer; + +void _enable_cursor(uint8_t cursor_start, uint8_t cursor_end) { + outb(0x3D4, 0x0A); + outb(0x3D5, (inb(0x3D5) & 0xC0) | cursor_start); + + outb(0x3D4, 0x0B); + outb(0x3D5, (inb(0x3D5) & 0xE0) | cursor_end); +} + +void _update_cursor(size_t x, size_t y) { + uint16_t pos = y * VGA_WIDTH + x; + + outb(0x3D4, 0x0F); + outb(0x3D5, (uint8_t)(pos & 0xFF)); + outb(0x3D4, 0x0E); + outb(0x3D5, (uint8_t)((pos >> 8) & 0xFF)); +} + +void _fb_putentryat(unsigned char c, uint8_t color, size_t x, size_t y) { + const size_t index = y * VGA_WIDTH + x; + framebuffer[index] = vga_entry(c, color); +} + +void _fb_scroll(void) { + for (size_t i = 0; i < VGA_HEIGHT-1; i++) { + for (size_t j = 0; j < VGA_WIDTH; j++) + framebuffer[i * VGA_WIDTH + j] = VGA_MEMORY[(i+1) * VGA_WIDTH + j]; + } +} + +void fb_init(void) { + fb_row = 0; + fb_column = 0; + fb_color = vga_entry_color(VGA_COLOR_LIGHT_GREY, VGA_COLOR_BLACK); + framebuffer = VGA_MEMORY; + for (size_t y = 0; y < VGA_HEIGHT; y++) { + for (size_t x = 0; x < VGA_WIDTH; x++) + _fb_putentryat(' ', fb_color, x, y); + } + _enable_cursor(0, 0); + _update_cursor(0, 0); +} + +void fb_setcolor(uint8_t color) { + fb_color = color; +} + +void fb_setpos(int x, int y) { + fb_row = y; + fb_column = x; + _update_cursor(fb_column, fb_row+1); +} + +void fb_offsetpos(int dx, int dy) { + fb_row += dy; + fb_column += dx; + _update_cursor(fb_column, fb_row+1); +} + +void fb_putchar(char c) { + unsigned char uc = c; + switch (uc) { + case '\r': + fb_column = 0; + break; + case '\n': + fb_column = 0; + if (++fb_row == VGA_HEIGHT) { + fb_row--; + _fb_scroll(); + } + break; + case '\t': + fb_column += 4; + if (++fb_column == VGA_WIDTH) { + fb_column = 4; + if (++fb_row == VGA_HEIGHT) { + fb_row--; + _fb_scroll(); + } + } + break; + default: + _fb_putentryat(uc, fb_color, fb_column, fb_row); + if (++fb_column == VGA_WIDTH) { + fb_column = 0; + if (++fb_row == VGA_HEIGHT) { + fb_row--; + _fb_scroll(); + } + } + break; + } + _update_cursor(fb_column, fb_row+1); +} diff --git a/kernel/init.c b/kernel/init.c deleted file mode 100644 index d4a3638..0000000 --- a/kernel/init.c +++ /dev/null @@ -1,35 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -void jump_userspace(void); - -char rootfs[1024]; -char init_bin[1024]; -int gdbstub = 0; - -void process_cmd(char *cmdline) { - char *token = strtok(cmdline, " "); - while (token != NULL) { - if (strncmp(token, "root=", 5) == 0) - strcpy(rootfs, &token[5]); - if (strncmp(token, "init=", 5) == 0) - strcpy(init_bin, &token[5]); - if (strncmp(token, "gdb", 3) == 0) - gdbstub = 1; - token = strtok(NULL, " "); - } -} - -void kernel_main(char *cmdline) { - kprintf("Box kernel version %s\n", VERSION); - process_cmd(cmdline); - - serial_init(); - sched_init(); - //pci_check_buses(); -} diff --git a/kernel/interrupt.c b/kernel/interrupt.c deleted file mode 100644 index 9639aea..0000000 --- a/kernel/interrupt.c +++ /dev/null @@ -1,20 +0,0 @@ -#include -#include - -static void (*isr_handlers[MAX_ISR])(struct isr_frame *frame); - -void register_isr_handler(unsigned int isr, void (*handler)(struct isr_frame *frame)) { - if (isr > MAX_ISR) - panic("Attempted to set non-existant interrupt vector"); - isr_handlers[isr] = handler; -} - -void clear_isr_handler(unsigned int isr) { - if (isr > MAX_ISR) - panic("Attempted to clear non-existant interrupt vector"); - isr_handlers[isr] = NULL; -} - -void isr_dispatch(struct isr_frame frame) { - (*isr_handlers[frame.isr_vector])(&frame); -} diff --git a/kernel/libk/io.c b/kernel/libk/io.c new file mode 100644 index 0000000..eedc171 --- /dev/null +++ b/kernel/libk/io.c @@ -0,0 +1,78 @@ +#include +#include +#include +#include + +char* convert(unsigned int num, int base) { + static char rep[] = "0123456789ABCDEF"; + static char buffer[50]; + char *ptr; + + ptr = &buffer[49]; + *ptr = '\0'; + + do { + *--ptr = rep[num%base]; + num /= base; + } while (num != 0); + + return ptr; +} + +int vkprintf(const char *fmt, va_list args) { + char *s; + int i; + + char buffer[4096]; + memset(buffer, 0, 4096); + for (size_t n = 0; n < strlen(fmt); n++) { + if (fmt[n] != '%') { + buffer[strlen(buffer)] = fmt[n]; + continue; + } else { + n++; + } + + switch (fmt[n]) { + case 'c': + i = va_arg(args, int); + buffer[strlen(buffer)] = i; + break; + case 's': + s = va_arg(args, char*); + strcat(buffer, s); + break; + case 'd': + i = va_arg(args, int); + if (i < 0) { + i = -i; + strcat(buffer, "-"); + } + strcat(buffer, convert(i, 10)); + break; + case 'o': + i = va_arg(args, unsigned int); + strcat(buffer, convert(i, 10)); + break; + case 'x': + i = va_arg(args, unsigned int); + strcat(buffer, convert(i, 16)); + break; + } + } + //tty_write(buffer, strlen(buffer)); + fb_write(buffer, strlen(buffer)); + memset(buffer, 0, 4096); + return 0; +} + +int kprintf(const char *fmt, ...) { + va_list args; + int done; + + va_start(args, fmt); + done = vkprintf(fmt, args); + va_end(args); + + return done; +} diff --git a/kernel/libk/string.c b/kernel/libk/string.c new file mode 100644 index 0000000..be59397 --- /dev/null +++ b/kernel/libk/string.c @@ -0,0 +1,133 @@ +#include + +int memcmp(const void *str1, const void *str2, size_t n) { + unsigned char const *p1 = str1; + unsigned char const *p2 = str2; + int ret = 0; + + if (str1 == str2) + return 0; + + while (n > 0) { + if (*p1 != *p2) { + ret = (*p1 > *p2)?1:-1; + break; + } + n--; + p1++; + p2++; + } + return ret; +} + +void* memcpy(void* __restrict dest, const void* __restrict src, size_t n) { + if (dest == src) + return dest; + + unsigned char *pdest = dest; + unsigned char const *psrc = src; + for (size_t i = 0; i < n; i++) + pdest[i] = psrc[i]; + return dest; +} + +char* strncpy(char* __restrict dest, const char* __restrict src, size_t n) { + for (size_t i = 0; i < n; i++) { + if (src[i] == '\0') + break; + dest[i] = src[i]; + } + return dest; +} + +char* strcpy(char* __restrict dest, const char* __restrict src) { + return (char*)memcpy(dest, src, strlen(src)); +} + +char* strcat(char* __restrict dest, const char* __restrict src) { + return (char*)memcpy(&dest[strlen(dest)], src, strlen(src)); +} + +char* strncat(char* __restrict dest, const char* __restrict src, size_t n) { + return (char*)memcpy(&dest[strlen(dest)], src, n); +} + +void* memmove(void* __restrict dest, const void* __restrict src, size_t n) { + if (dest == src) + return dest; + + unsigned char const *psrc = src; + unsigned char buffer[n]; + + for (size_t i = 0; i < n; i++) + buffer[i] = psrc[i]; + return memcpy(dest, (void*)buffer, n); +} + +void* memset(void *str, int c, size_t n) { + unsigned char *p = str; + for (size_t i = 0; i < n; i++) + p[i] = (unsigned char)c; + return str; +} + +int strncmp(const char *str1, const char *str2, size_t n) { + return memcmp(str1, str2, n); +} + +int strcmp(const char *str1, const char *str2) { + size_t str1_sz = strlen(str1); + size_t str2_sz = strlen(str2); + if (str1_sz > str2_sz) + return memcmp(str1, str2, str2_sz); + return memcmp(str1, str2, str1_sz); +} + +size_t strlen(const char *str) { + size_t i = 0; + while (str[i] != '\0') + i++; + return i; +} + +int _is_delim(char c, const char *delim) { + while (*delim != '\0') { + if (c == *delim) + return 1; + delim++; + } + return 0; +} + +char* strtok(char* __restrict str, const char* __restrict delim) { + static char *old_str; + + if (str == NULL) + str = old_str; + + while (1) { + if (_is_delim(*str, delim)) { + str++; + continue; + } + + if (*str == '\0') + return NULL; + break; + } + + char *ret = str; + while (1) { + if (*str == '\0') { + old_str = str; + return ret; + } + + if (_is_delim(*str, delim)) { + *str = '\0'; + old_str = str + 1; + return ret; + } + str++; + } +} diff --git a/kernel/panic.c b/kernel/panic.c deleted file mode 100644 index 65279f0..0000000 --- a/kernel/panic.c +++ /dev/null @@ -1,26 +0,0 @@ -#include -#include -#include -#include - -static int panicked = 0; - -void walk_stack(uintptr_t *addrs, size_t n); - -void stack_trace(void) { - kprintf("PRINTING STACK TRACE\n"); - uintptr_t strace[32]; - walk_stack(strace, 32); - for (int i = 0; i < 32; i++) { - if (strace[i] == 0) - break; - kprintf("#%d: %x\n", i, strace[i]); - } -} - -void panic(const char *str) { - panicked = 1; - kprintf("KERNEL PANIC: %s\n", str); - stack_trace(); - while (1); -} diff --git a/kernel/sched.c b/kernel/sched.c deleted file mode 100644 index b6096da..0000000 --- a/kernel/sched.c +++ /dev/null @@ -1,74 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -static struct kthread *run_queue = NULL; -static struct kthread *wait_queue = NULL; -static struct kthread *cur = NULL; - -static int scheduler_enabled = 0; -static struct kmutex scheduler_lock; - -void sched_init(void) { - disable_ints(); - cur = kthread_create(NULL, NULL); - cur->stack = NULL; - switch_thread(cur, cur); - cur->state = THREAD_RUNNING; - scheduler_enabled = 1; - enable_ints(); -} - -void schedule_next(void) { - if (scheduler_enabled == 0) - return; - if (run_queue == NULL) - return; - - struct kthread *thread = cur; - schedule_thread(cur); - cur = run_queue; - run_queue = run_queue->next; - cur->next = NULL; - cur->state = THREAD_RUNNING; - switch_thread(thread, cur); -} - -void schedule_thread(struct kthread *thread) { - if (run_queue == NULL) { - run_queue = thread; - return; - } - - kmutex_lock(&scheduler_lock); - struct kthread *temp = run_queue; - while (temp->next != NULL) - temp = temp->next; - temp->next = thread; - thread->state = THREAD_READY; - kmutex_unlock(&scheduler_lock); -} - -void block_thread(struct kthread *thread) { - kmutex_lock(&scheduler_lock); - thread->next = wait_queue; - wait_queue = thread; - kmutex_unlock(&scheduler_lock); -} - -void unblock_thread(struct kthread *thread) { - kmutex_lock(&scheduler_lock); - struct kthread *temp = wait_queue; - while (temp != NULL) { - if (temp->next == thread) { - temp->next = thread->next; - return; - } - temp = temp->next; - } - kmutex_unlock(&scheduler_lock); -} diff --git a/lib/Makefile b/lib/Makefile new file mode 100644 index 0000000..c307643 --- /dev/null +++ b/lib/Makefile @@ -0,0 +1,16 @@ +SUBDIRS:= + +export ARCH VERSION PREFIX + +.PHONY: all clean $(SUBDIRS) + +all: $(SUBDIRS) + +subdirs: $(SUBDIRS) + +$(SUBDIRS): + $(MAKE) $(MAKECMDGOALS) -C $@ + +clean: $(SUBDIRS) + +install: $(SUBDIRS) diff --git a/libk/io.c b/libk/io.c deleted file mode 100644 index eedc171..0000000 --- a/libk/io.c +++ /dev/null @@ -1,78 +0,0 @@ -#include -#include -#include -#include - -char* convert(unsigned int num, int base) { - static char rep[] = "0123456789ABCDEF"; - static char buffer[50]; - char *ptr; - - ptr = &buffer[49]; - *ptr = '\0'; - - do { - *--ptr = rep[num%base]; - num /= base; - } while (num != 0); - - return ptr; -} - -int vkprintf(const char *fmt, va_list args) { - char *s; - int i; - - char buffer[4096]; - memset(buffer, 0, 4096); - for (size_t n = 0; n < strlen(fmt); n++) { - if (fmt[n] != '%') { - buffer[strlen(buffer)] = fmt[n]; - continue; - } else { - n++; - } - - switch (fmt[n]) { - case 'c': - i = va_arg(args, int); - buffer[strlen(buffer)] = i; - break; - case 's': - s = va_arg(args, char*); - strcat(buffer, s); - break; - case 'd': - i = va_arg(args, int); - if (i < 0) { - i = -i; - strcat(buffer, "-"); - } - strcat(buffer, convert(i, 10)); - break; - case 'o': - i = va_arg(args, unsigned int); - strcat(buffer, convert(i, 10)); - break; - case 'x': - i = va_arg(args, unsigned int); - strcat(buffer, convert(i, 16)); - break; - } - } - //tty_write(buffer, strlen(buffer)); - fb_write(buffer, strlen(buffer)); - memset(buffer, 0, 4096); - return 0; -} - -int kprintf(const char *fmt, ...) { - va_list args; - int done; - - va_start(args, fmt); - done = vkprintf(fmt, args); - va_end(args); - - return done; -} diff --git a/libk/stack_protector.c b/libk/stack_protector.c deleted file mode 100644 index a929ae0..0000000 --- a/libk/stack_protector.c +++ /dev/null @@ -1,9 +0,0 @@ -#include -#include - -uintptr_t __stack_chk_guard; - -__attribute__((noreturn)) void __stack_chk_fail(void) { - panic("Detected attempted stack manipulation in kernel"); - while(1); -} diff --git a/libk/string.c b/libk/string.c deleted file mode 100644 index be59397..0000000 --- a/libk/string.c +++ /dev/null @@ -1,133 +0,0 @@ -#include - -int memcmp(const void *str1, const void *str2, size_t n) { - unsigned char const *p1 = str1; - unsigned char const *p2 = str2; - int ret = 0; - - if (str1 == str2) - return 0; - - while (n > 0) { - if (*p1 != *p2) { - ret = (*p1 > *p2)?1:-1; - break; - } - n--; - p1++; - p2++; - } - return ret; -} - -void* memcpy(void* __restrict dest, const void* __restrict src, size_t n) { - if (dest == src) - return dest; - - unsigned char *pdest = dest; - unsigned char const *psrc = src; - for (size_t i = 0; i < n; i++) - pdest[i] = psrc[i]; - return dest; -} - -char* strncpy(char* __restrict dest, const char* __restrict src, size_t n) { - for (size_t i = 0; i < n; i++) { - if (src[i] == '\0') - break; - dest[i] = src[i]; - } - return dest; -} - -char* strcpy(char* __restrict dest, const char* __restrict src) { - return (char*)memcpy(dest, src, strlen(src)); -} - -char* strcat(char* __restrict dest, const char* __restrict src) { - return (char*)memcpy(&dest[strlen(dest)], src, strlen(src)); -} - -char* strncat(char* __restrict dest, const char* __restrict src, size_t n) { - return (char*)memcpy(&dest[strlen(dest)], src, n); -} - -void* memmove(void* __restrict dest, const void* __restrict src, size_t n) { - if (dest == src) - return dest; - - unsigned char const *psrc = src; - unsigned char buffer[n]; - - for (size_t i = 0; i < n; i++) - buffer[i] = psrc[i]; - return memcpy(dest, (void*)buffer, n); -} - -void* memset(void *str, int c, size_t n) { - unsigned char *p = str; - for (size_t i = 0; i < n; i++) - p[i] = (unsigned char)c; - return str; -} - -int strncmp(const char *str1, const char *str2, size_t n) { - return memcmp(str1, str2, n); -} - -int strcmp(const char *str1, const char *str2) { - size_t str1_sz = strlen(str1); - size_t str2_sz = strlen(str2); - if (str1_sz > str2_sz) - return memcmp(str1, str2, str2_sz); - return memcmp(str1, str2, str1_sz); -} - -size_t strlen(const char *str) { - size_t i = 0; - while (str[i] != '\0') - i++; - return i; -} - -int _is_delim(char c, const char *delim) { - while (*delim != '\0') { - if (c == *delim) - return 1; - delim++; - } - return 0; -} - -char* strtok(char* __restrict str, const char* __restrict delim) { - static char *old_str; - - if (str == NULL) - str = old_str; - - while (1) { - if (_is_delim(*str, delim)) { - str++; - continue; - } - - if (*str == '\0') - return NULL; - break; - } - - char *ret = str; - while (1) { - if (*str == '\0') { - old_str = str; - return ret; - } - - if (_is_delim(*str, delim)) { - *str = '\0'; - old_str = str + 1; - return ret; - } - str++; - } -} diff --git a/sbin/Makefile b/sbin/Makefile new file mode 100644 index 0000000..73669f8 --- /dev/null +++ b/sbin/Makefile @@ -0,0 +1,17 @@ +SUBDIRS:=nologin \ + +export VERSION PREFIX + +.PHONY: all clean $(SUBDIRS) + +all: $(SUBDIRS) + +subdirs: $(SUBDIRS) + +$(SUBDIRS): + $(MAKE) $(MAKECMDGOALS) -C $@ + +clean: $(SUBDIRS) + +install: $(SUBDIRS) + diff --git a/usr.bin/Makefile b/usr.bin/Makefile new file mode 100644 index 0000000..62e125c --- /dev/null +++ b/usr.bin/Makefile @@ -0,0 +1,17 @@ +SUBDIRS:= + +export ARCH VERSION PREFIX + +.PHONY: all clean $(SUBDIRS) + +all: $(SUBDIRS) + +subdirs: $(SUBDIRS) + +$(SUBDIRS): + $(MAKE) $(MAKECMDGOALS) -C $@ + +clean: $(SUBDIRS) + +install: $(SUBDIRS) + diff --git a/usr.sbin/Makefile b/usr.sbin/Makefile new file mode 100644 index 0000000..c68d120 --- /dev/null +++ b/usr.sbin/Makefile @@ -0,0 +1,17 @@ +SUBDIRS:=bxpkg \ + gfdisk \ + +export ARCH VERSION PREFIX + +.PHONY: all clean $(SUBDIRS) + +all: $(SUBDIRS) + +subdirs: $(SUBDIRS) + +$(SUBDIRS): + $(MAKE) $(MAKECMDGOALS) -C $@ + +clean: $(SUBDIRS) + +install: $(SUBDIRS) -- cgit v1.2.3