├── run_bochs.sh ├── bin ├── image.iso └── libIncitatus.a ├── dissertation.pdf ├── bootloader ├── initrd.tar ├── boot.catalog └── boot │ └── grub │ ├── stage2_eltorito │ └── menu.lst ├── user ├── include │ └── Lib │ │ ├── libc │ │ ├── stdint.h │ │ ├── stdlib.h │ │ ├── limits.h │ │ ├── string.h │ │ └── stdio.h │ │ └── Incitatus.h └── src │ ├── Apps │ ├── apps.ld │ ├── HelloWorld.c │ ├── InputTest.c │ ├── Calculator.c │ └── Shell.c │ └── Lib │ ├── libc │ ├── stdio.c │ └── string.c │ └── Incitatus.c ├── bochsrc.txt ├── run_qemu.sh ├── kernel ├── src │ ├── Linker.ld │ ├── Drivers │ │ ├── VGA.c │ │ ├── Console.c │ │ └── Mouse.c │ ├── Sys.c │ ├── Lib │ │ ├── Stack.c │ │ ├── Math.c │ │ ├── Bitmap.c │ │ ├── CircularFIFOBuffer.c │ │ ├── String.c │ │ ├── LinkedList.c │ │ └── ArrayList.c │ ├── Process │ │ ├── FCFS.c │ │ ├── Scheduler.c │ │ └── RoundRobin.c │ ├── Memory │ │ ├── PhysicalMemory.c │ │ ├── DumbHeapManager.c │ │ ├── StackPMM.c │ │ ├── BitmapPMM.c │ │ └── HeapMemory.c │ ├── Kernel.c │ ├── X86 │ │ ├── CPU.c │ │ ├── Usermode.c │ │ └── PIT8253.c │ ├── Start.s │ ├── Module.c │ └── FileSystem │ │ └── Tar.c └── include │ ├── Lib │ ├── Math.h │ ├── CircularFIFOBuffer.h │ ├── String.h │ ├── Bitmap.h │ ├── Stack.h │ ├── ArrayList.h │ └── LinkedList.h │ ├── Process │ ├── Mutex.h │ ├── FCFS.h │ ├── RoundRobin.h │ ├── Scheduler.h │ └── ProcessManager.h │ ├── FileSystem │ ├── RamDisk.h │ └── Tar.h │ ├── X86 │ ├── Usermode.h │ ├── GDT.h │ ├── PIT8253.h │ ├── PIC8259.h │ ├── CPU.h │ └── IDT.h │ ├── Drivers │ ├── Mouse.h │ ├── Keyboard.h │ ├── PS2Controller.h │ ├── VGA.h │ └── Console.h │ ├── Common.h │ ├── Memory.h │ ├── Memory │ ├── StackPMM.h │ ├── BitmapPMM.h │ ├── DumbHeapManager.h │ ├── PhysicalMemory.h │ ├── HeapMemory.h │ └── VirtualMemory.h │ ├── Sys.h │ ├── Debug.h │ ├── IO.h │ ├── Module.h │ └── Multiboot.h └── README.md /run_bochs.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | bochs -f bochsrc.txt -------------------------------------------------------------------------------- /bin/image.iso: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ersenal/Incitatus-OS/HEAD/bin/image.iso -------------------------------------------------------------------------------- /dissertation.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ersenal/Incitatus-OS/HEAD/dissertation.pdf -------------------------------------------------------------------------------- /bin/libIncitatus.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ersenal/Incitatus-OS/HEAD/bin/libIncitatus.a -------------------------------------------------------------------------------- /bootloader/initrd.tar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ersenal/Incitatus-OS/HEAD/bootloader/initrd.tar -------------------------------------------------------------------------------- /bootloader/boot.catalog: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ersenal/Incitatus-OS/HEAD/bootloader/boot.catalog -------------------------------------------------------------------------------- /bootloader/boot/grub/stage2_eltorito: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ersenal/Incitatus-OS/HEAD/bootloader/boot/grub/stage2_eltorito -------------------------------------------------------------------------------- /user/include/Lib/libc/stdint.h: -------------------------------------------------------------------------------- 1 | #ifndef STDINT_H 2 | #define STDINT_H 3 | 4 | typedef signed int ptrdiff_t; 5 | typedef unsigned int uintptr_t; 6 | 7 | #endif -------------------------------------------------------------------------------- /bochsrc.txt: -------------------------------------------------------------------------------- 1 | #gdbstub: enabled=1, port=4224, text_base=0, data_base=0, bss_base=0 2 | display_library: sdl 3 | ata0-slave: type=cdrom, path="bin/image.iso", status=inserted 4 | boot: cdrom, floppy, disk -------------------------------------------------------------------------------- /bootloader/boot/grub/menu.lst: -------------------------------------------------------------------------------- 1 | timeout 0 2 | 3 | title Incitatus OS(Text-Mode) 4 | kernel /kernel 5 | module /initrd.tar 6 | boot 7 | 8 | title Incitatus OS(VESA) 9 | kernel /kernel 10 | vbeset=0x115 11 | boot -------------------------------------------------------------------------------- /run_qemu.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | qemu-system-i386 \ 4 | -net none \ 5 | -m 4 \ 6 | -cdrom bin/image.iso \ 7 | -monitor stdio \ 8 | #-s \ 9 | #-S \ 10 | 11 | -------------------------------------------------------------------------------- /user/include/Lib/libc/stdlib.h: -------------------------------------------------------------------------------- 1 | #ifndef STDLIB_H 2 | #define STDLIB_H 3 | 4 | #define size_t unsigned int 5 | #define NULL ((void*) 0) 6 | 7 | /* Doug lea */ 8 | void* malloc(size_t size); 9 | void* calloc(size_t numberOfElements, size_t elementSize); 10 | void* realloc(void* oldmem, size_t bytes); 11 | void free(void* ptr); 12 | 13 | #endif -------------------------------------------------------------------------------- /user/src/Apps/apps.ld: -------------------------------------------------------------------------------- 1 | OUTPUT_FORMAT("binary") 2 | ENTRY(main) 3 | SECTIONS 4 | { 5 | 6 | .text 0x40000000: AT(0) 7 | { 8 | 9 | *(.text) 10 | . = ALIGN(4); 11 | *(.eh_frame) 12 | . = ALIGN(4); 13 | *(.data) 14 | . = ALIGN(4); 15 | *(.rodata) 16 | . = ALIGN(4); 17 | *(.bss) 18 | . = ALIGN(4); 19 | *(.COMMON) 20 | . = ALIGN(4); 21 | 22 | } 23 | 24 | } -------------------------------------------------------------------------------- /user/include/Lib/libc/limits.h: -------------------------------------------------------------------------------- 1 | #ifndef LIMITS_H 2 | #define LIMITS_H 3 | 4 | #define CHAR_MIN (-128) 5 | #define CHAR_MAX 127 6 | 7 | /* Some universal constants... */ 8 | 9 | #define CHAR_BIT 8 10 | #define SCHAR_MIN (-128) 11 | #define SCHAR_MAX 127 12 | #define UCHAR_MAX 255 13 | #define SHRT_MIN (-1-0x7fff) 14 | #define SHRT_MAX 0x7fff 15 | #define USHRT_MAX 0xffff 16 | #define INT_MIN (-1-0x7fffffff) 17 | #define INT_MAX 0x7fffffff 18 | #define UINT_MAX 0xffffffffU 19 | 20 | #endif -------------------------------------------------------------------------------- /kernel/src/Linker.ld: -------------------------------------------------------------------------------- 1 | ENTRY (Start) 2 | 3 | SECTIONS 4 | { 5 | 6 | .text 0x100000 : 7 | { 8 | text = .; _text = .; __text = .; 9 | *(.text) 10 | . = ALIGN(4096); 11 | } 12 | 13 | .data : 14 | { 15 | data = .; _data = .; __data = .; 16 | *(.data) 17 | *(.rodata) 18 | . = ALIGN(4096); 19 | } 20 | 21 | .bss : 22 | { 23 | bss = .; _bss = .; __bss = .; 24 | *(.bss) 25 | . = ALIGN(4096); 26 | } 27 | 28 | end = .; _end = .; __end = .; 29 | } 30 | -------------------------------------------------------------------------------- /user/src/Apps/HelloWorld.c: -------------------------------------------------------------------------------- 1 | /** 2 | | Copyright(C) 2012 Ali Ersenal 3 | | License: WTFPL v2 4 | | URL: http://sam.zoy.org/wtfpl/COPYING 5 | | 6 | |-------------------------------------------------------------------------- 7 | | HelloWorld.c 8 | |-------------------------------------------------------------------------- 9 | | 10 | | DESCRIPTION: Used mainly for testing userspace process exec/kill. 11 | | 12 | | AUTHOR: Ali Ersenal, aliersenal@gmail.com 13 | \------------------------------------------------------------------------*/ 14 | 15 | 16 | #include 17 | 18 | int main(void) { 19 | 20 | puts("\nHello World!\n"); 21 | exit(0); 22 | 23 | } -------------------------------------------------------------------------------- /user/include/Lib/libc/string.h: -------------------------------------------------------------------------------- 1 | #ifndef STRING_H 2 | #define STRING_H 3 | 4 | #include 5 | 6 | void *memset(void *dest, int c, size_t n); 7 | void *memcpy(void *restrict dest, const void *restrict src, size_t n); 8 | void *memmove(void *dest, const void *src, size_t n); 9 | size_t strlen(const char *s); 10 | int strcmp(const char *l, const char *r); 11 | char *strcpy(char *restrict dest, const char *restrict src); 12 | char *strcat(char *restrict dest, const char *restrict src); 13 | char *strchrnul(const char *s, int c); 14 | size_t strspn(const char *s, const char *c); 15 | size_t strcspn(const char *s, const char *c); 16 | char *strtok(char *restrict s, const char *restrict sep); 17 | 18 | #endif -------------------------------------------------------------------------------- /kernel/include/Lib/Math.h: -------------------------------------------------------------------------------- 1 | /** 2 | | Copyright(C) 2012 Ali Ersenal 3 | | License: WTFPL v2 4 | | URL: http://sam.zoy.org/wtfpl/COPYING 5 | | 6 | |-------------------------------------------------------------------------- 7 | | Math.h 8 | |-------------------------------------------------------------------------- 9 | | 10 | | DESCRIPTION: Very simple kernel math library. 11 | | 12 | | AUTHOR: Ali Ersenal, aliersenal@gmail.com 13 | \------------------------------------------------------------------------*/ 14 | 15 | 16 | #ifndef MATH_H 17 | #define MATH_H 18 | 19 | double Math_abs(double number); 20 | double Math_sqrt(double number); 21 | double Math_sin(double number); 22 | double Math_cos(double number); 23 | double Math_tan(double number); 24 | 25 | #endif -------------------------------------------------------------------------------- /kernel/include/Process/Mutex.h: -------------------------------------------------------------------------------- 1 | /** 2 | | Copyright(C) 2012 Ali Ersenal 3 | | License: WTFPL v2 4 | | URL: http://sam.zoy.org/wtfpl/COPYING 5 | | 6 | |-------------------------------------------------------------------------- 7 | | Mutex.h 8 | |-------------------------------------------------------------------------- 9 | | 10 | | DESCRIPTION: Lock or unlock access to a critical section. 11 | | 12 | | NOTES: Current implementation exploits(assumes) the fact that 13 | | we have only one executing CPU. 14 | | 15 | | AUTHOR: Ali Ersenal, aliersenal@gmail.com 16 | \------------------------------------------------------------------------*/ 17 | 18 | 19 | #ifndef MUTEX_H 20 | #define MUTEX_H 21 | 22 | #include 23 | 24 | static inline void Mutex_lock() { 25 | 26 | Sys_disableInterrupts(); 27 | 28 | } 29 | 30 | static inline void Mutex_unlock() { 31 | 32 | Sys_enableInterrupts(); 33 | 34 | } 35 | 36 | #endif -------------------------------------------------------------------------------- /kernel/include/Lib/CircularFIFOBuffer.h: -------------------------------------------------------------------------------- 1 | /** 2 | | Copyright(C) 2012 Ali Ersenal 3 | | License: WTFPL v2 4 | | URL: http://sam.zoy.org/wtfpl/COPYING 5 | | 6 | |-------------------------------------------------------------------------- 7 | | CircularFIFOBuffer.h 8 | |-------------------------------------------------------------------------- 9 | | 10 | | DESCRIPTION: First input, first output circular buffer implementation. 11 | | 12 | | AUTHOR: Ali Ersenal, aliersenal@gmail.com 13 | \------------------------------------------------------------------------*/ 14 | 15 | 16 | #ifndef FIFO_H 17 | #define FIFO_H 18 | 19 | #include 20 | 21 | typedef struct CircularFIFOBuffer CircularFIFOBuffer; 22 | 23 | CircularFIFOBuffer* CircularFIFOBuffer_new(u32int size); 24 | void CircularFIFOBuffer_destroy(CircularFIFOBuffer* buf); 25 | char CircularFIFOBuffer_read(CircularFIFOBuffer* buf); 26 | void CircularFIFOBuffer_write (CircularFIFOBuffer* buf, char val); 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /kernel/include/FileSystem/RamDisk.h: -------------------------------------------------------------------------------- 1 | /** 2 | | Copyright(C) 2012 Ali Ersenal 3 | | License: WTFPL v2 4 | | URL: http://sam.zoy.org/wtfpl/COPYING 5 | | 6 | |-------------------------------------------------------------------------- 7 | | RamDisk.h 8 | |-------------------------------------------------------------------------- 9 | | 10 | | DESCRIPTION: Tar-based ramdisk(RAM as disk drive) implementation. 11 | | 12 | | AUTHOR: Ali Ersenal, aliersenal@gmail.com 13 | \------------------------------------------------------------------------*/ 14 | 15 | 16 | #ifndef RAMDISK_H 17 | #define RAMDISK_H 18 | 19 | #include 20 | 21 | /*------------------------------------------------------------------------- 22 | | Init ram disk 23 | |-------------------------------------------------------------------------- 24 | | DESCRIPTION: Parse initrd tar archive and initialise the ram disk. 25 | | 26 | \------------------------------------------------------------------------*/ 27 | VFS* RamDisk_init(void); 28 | 29 | #endif -------------------------------------------------------------------------------- /kernel/include/X86/Usermode.h: -------------------------------------------------------------------------------- 1 | /** 2 | | Copyright(C) 2012 Ali Ersenal 3 | | License: WTFPL v2 4 | | URL: http://sam.zoy.org/wtfpl/COPYING 5 | | 6 | |-------------------------------------------------------------------------- 7 | | Usermode.h 8 | |-------------------------------------------------------------------------- 9 | | 10 | | DESCRIPTION: Handles ring0 to ring3 switch and syscalls. 11 | | 12 | | AUTHOR: Ali Ersenal, aliersenal@gmail.com 13 | \------------------------------------------------------------------------*/ 14 | 15 | 16 | #ifndef USER_MODE_H 17 | #define USER_MODE_H 18 | 19 | #include 20 | 21 | /*------------------------------------------------------------------------- 22 | | Get usermode module 23 | |-------------------------------------------------------------------------- 24 | | DESCRIPTION: Returns the usermode module. 25 | | 26 | | NOTES: After loading this module, OS executes at ring 3. 27 | \------------------------------------------------------------------------*/ 28 | Module* Usermode_getModule(void); 29 | 30 | #endif -------------------------------------------------------------------------------- /kernel/include/Drivers/Mouse.h: -------------------------------------------------------------------------------- 1 | /** 2 | | Copyright(C) 2012 Ali Ersenal 3 | | License: WTFPL v2 4 | | URL: http://sam.zoy.org/wtfpl/COPYING 5 | | 6 | |-------------------------------------------------------------------------- 7 | | Mouse.h 8 | |-------------------------------------------------------------------------- 9 | | 10 | | DESCRIPTION: Interrupt based PS/2 mouse driver. 11 | | 12 | | AUTHOR: Ali Ersenal, aliersenal@gmail.com 13 | \------------------------------------------------------------------------*/ 14 | 15 | 16 | #ifndef MOUSE_H 17 | #define MOUSE_H 18 | 19 | /*------------------------------------------------------------------------- 20 | | Mouse driver installation 21 | |-------------------------------------------------------------------------- 22 | | DESCRIPTION: Initialises PS/2 mouse driver. Gets called while 23 | | initialising the PS/2 controller. 24 | | (refer to PS2Controller.c : PS2Controller_init) 25 | | 26 | \------------------------------------------------------------------------*/ 27 | void Mouse_init(void); 28 | #endif -------------------------------------------------------------------------------- /kernel/include/Lib/String.h: -------------------------------------------------------------------------------- 1 | /** 2 | | Copyright(C) 2012 Ali Ersenal 3 | | License: WTFPL v2 4 | | URL: http://sam.zoy.org/wtfpl/COPYING 5 | | 6 | |-------------------------------------------------------------------------- 7 | | String.h 8 | |-------------------------------------------------------------------------- 9 | | 10 | | DESCRIPTION: String related functions. 11 | | 12 | | AUTHOR: Ali Ersenal, aliersenal@gmail.com 13 | \------------------------------------------------------------------------*/ 14 | 15 | 16 | #ifndef STRING_H 17 | #define STRING_H 18 | 19 | #include 20 | 21 | bool String_startsWith(const char* string, const char* prefix); 22 | bool String_endsWith(const char* string, const char* suffix); 23 | char String_charAt(const char* string, int index); 24 | u32int String_length(const char* string); 25 | int String_charToInt(char c); 26 | u32int String_stringToInt(const char* str, u32int base); 27 | char* String_numberToString(int val, int base); 28 | char* String_copy(char* restrict dest, const char* restrict src); 29 | int String_compare(const char* left, const char* right); 30 | u32int String_countChar(const char* s, char c); 31 | #endif 32 | -------------------------------------------------------------------------------- /user/src/Apps/InputTest.c: -------------------------------------------------------------------------------- 1 | /** 2 | | Copyright(C) 2012 Ali Ersenal 3 | | License: WTFPL v2 4 | | URL: http://sam.zoy.org/wtfpl/COPYING 5 | | 6 | |-------------------------------------------------------------------------- 7 | | InputTest.c 8 | |-------------------------------------------------------------------------- 9 | | 10 | | DESCRIPTION: Used for testing userspace keyboard input. 11 | | 12 | | AUTHOR: Ali Ersenal, aliersenal@gmail.com 13 | \------------------------------------------------------------------------*/ 14 | 15 | 16 | #include 17 | #include 18 | 19 | int main(void) { 20 | 21 | char c = 0; 22 | char buf[32]; 23 | int i = 0; 24 | 25 | while((c = getch()) != '\n') { 26 | 27 | putc(c); /* Echo input */ 28 | 29 | /* Handle backspace */ 30 | if(c == '\b') { 31 | 32 | i--; 33 | buf[i] = '\0'; 34 | 35 | } else { 36 | 37 | buf[i] = c; 38 | i++; 39 | 40 | } 41 | 42 | } 43 | 44 | /* Handle enter */ 45 | putc('\n'); 46 | buf[i] = '\0'; 47 | 48 | printf("%s%s%c", "You typed: ", buf, '\n'); 49 | exit(0); 50 | } -------------------------------------------------------------------------------- /user/include/Lib/libc/stdio.h: -------------------------------------------------------------------------------- 1 | #ifndef STDIO_H 2 | #define STDIO_H 3 | 4 | /* Console foreground, background colors */ 5 | #define BLACK 0x00 6 | #define _BLACK 0x00 7 | #define BLUE 0x01 8 | #define _BLUE 0x10 9 | #define GREEN 0x02 10 | #define _GREEN 0x20 11 | #define CYAN 0x03 12 | #define _CYAN 0x30 13 | #define RED 0x04 14 | #define _RED 0x40 15 | #define MAGENTA 0x05 16 | #define _MAGENTA 0x50 17 | #define BROWN 0x06 18 | #define _BROWN 0x60 19 | #define LGREY 0x07 20 | #define _LGREY 0x70 21 | #define DGREY 0x08 22 | #define _DGREY 0x80 23 | #define LBLUE 0x09 24 | #define _LBLUE 0x90 25 | #define LGREEN 0x0A 26 | #define _LGREEN 0xA0 27 | #define LCYAN 0x0B 28 | #define _LCYAN 0xB0 29 | #define LRED 0x0C 30 | #define _LRED 0xC0 31 | #define LMAGENTA 0x0D 32 | #define _LMAGENTA 0xD0 33 | #define YELLOW 0x0E 34 | #define _YELLOW 0xE0 35 | #define WHITE 0x0F 36 | #define _WHITE 0xF0 37 | #define INTENSE 0x08 38 | #define _BLINK 0x80 39 | 40 | 41 | int isspace(int c); 42 | int isdigit(int c); 43 | int atoi(const char *s); 44 | long atol(const char *s); 45 | char* itoa(int val, int base); 46 | void printf(const char* template, ...); 47 | 48 | #endif -------------------------------------------------------------------------------- /kernel/include/Lib/Bitmap.h: -------------------------------------------------------------------------------- 1 | /** 2 | | Copyright(C) 2012 Ali Ersenal 3 | | License: WTFPL v2 4 | | URL: http://sam.zoy.org/wtfpl/COPYING 5 | | 6 | |-------------------------------------------------------------------------- 7 | | Bitmap.h 8 | |-------------------------------------------------------------------------- 9 | | 10 | | DESCRIPTION: Bit array data structure implementation. 11 | | 12 | | AUTHOR: Ali Ersenal, aliersenal@gmail.com 13 | \------------------------------------------------------------------------*/ 14 | 15 | 16 | #ifndef BITMAP_H 17 | #define BITMAP_H 18 | 19 | #include 20 | 21 | /*======================================================= 22 | STRUCT 23 | =========================================================*/ 24 | typedef struct Bitmap Bitmap; 25 | 26 | struct Bitmap { 27 | 28 | void* start; /* Bitmap start address */ 29 | u32int length; /* Length of bitmap in bytes */ 30 | 31 | }; 32 | 33 | /*======================================================= 34 | FUNCTION 35 | =========================================================*/ 36 | void Bitmap_setBit(Bitmap* self, u32int index); 37 | void Bitmap_clearBit(Bitmap* self, u32int index); 38 | bool Bitmap_isSet(Bitmap* self, u32int index); 39 | void Bitmap_toggle(Bitmap* self, u32int index); 40 | void Bitmap_init(Bitmap* self, void* start, u32int length); 41 | #endif -------------------------------------------------------------------------------- /kernel/include/Lib/Stack.h: -------------------------------------------------------------------------------- 1 | /** 2 | | Copyright(C) 2012 Ali Ersenal 3 | | License: WTFPL v2 4 | | URL: http://sam.zoy.org/wtfpl/COPYING 5 | | 6 | |-------------------------------------------------------------------------- 7 | | Stack.h 8 | |-------------------------------------------------------------------------- 9 | | 10 | | DESCRIPTION: Stack data structure implementation. 11 | | - Stores pointers(4 bytes in 32-bit) 12 | | - Grows upwards 13 | | 14 | | AUTHOR: Ali Ersenal, aliersenal@gmail.com 15 | \------------------------------------------------------------------------*/ 16 | 17 | 18 | #ifndef STACK_H 19 | #define STACK_H 20 | 21 | #include 22 | 23 | /*======================================================= 24 | STRUCT 25 | =========================================================*/ 26 | typedef struct Stack Stack; 27 | 28 | struct Stack { 29 | 30 | void* start; /* Stack start address */ 31 | u32int length; /* Length of stack in bytes */ 32 | u32int size; /* Number of items(void*) in stack */ 33 | 34 | }; 35 | 36 | /*======================================================= 37 | FUNCTION 38 | =========================================================*/ 39 | 40 | void Stack_push(Stack* self, void* item); 41 | void* Stack_pop(Stack* self); 42 | void* Stack_peek(Stack* self); 43 | void Stack_init(Stack* self, void* start, u32int length); 44 | #endif -------------------------------------------------------------------------------- /kernel/src/Drivers/VGA.c: -------------------------------------------------------------------------------- 1 | /** 2 | | Copyright(C) 2012 Ali Ersenal 3 | | License: WTFPL v2 4 | | URL: http://sam.zoy.org/wtfpl/COPYING 5 | | 6 | |-------------------------------------------------------------------------- 7 | | VGA.c 8 | |-------------------------------------------------------------------------- 9 | | 10 | | DESCRIPTION: VGA text-mode buffer driver. 11 | | 12 | | AUTHOR: Ali Ersenal, aliersenal@gmail.com 13 | \------------------------------------------------------------------------*/ 14 | 15 | 16 | #include 17 | 18 | /*======================================================= 19 | PRIVATE DATA 20 | =========================================================*/ 21 | PRIVATE Module vga; 22 | 23 | /*======================================================= 24 | PUBLIC DATA 25 | =========================================================*/ 26 | PUBLIC char* vgaRam; 27 | PUBLIC u8int vgaHeight; 28 | PUBLIC u8int vgaWidth; 29 | 30 | /*======================================================= 31 | FUNCTION 32 | =========================================================*/ 33 | PRIVATE void VGA_init(void) { 34 | 35 | vgaRam = (char*) 0xB8000; 36 | vgaWidth = 80; 37 | vgaHeight = 25; 38 | 39 | } 40 | 41 | PUBLIC Module* VGA_getModule(void) { 42 | 43 | vga.moduleName = "VGA Buffer Driver"; 44 | vga.moduleID = MODULE_VGA; 45 | vga.init = &VGA_init; 46 | 47 | return &vga; 48 | 49 | } -------------------------------------------------------------------------------- /kernel/src/Sys.c: -------------------------------------------------------------------------------- 1 | /** 2 | | Copyright(C) 2012 Ali Ersenal 3 | | License: WTFPL v2 4 | | URL: http://sam.zoy.org/wtfpl/COPYING 5 | | 6 | |-------------------------------------------------------------------------- 7 | | Sys.c 8 | |-------------------------------------------------------------------------- 9 | | 10 | | DESCRIPTION: Provides important system functions. 11 | | 12 | | AUTHOR: Ali Ersenal, aliersenal@gmail.com 13 | \------------------------------------------------------------------------*/ 14 | 15 | 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | /*======================================================= 23 | DEFINE 24 | =========================================================*/ 25 | #define SYS_C_RESET 0xFE 26 | 27 | /*======================================================= 28 | FUNCTION 29 | =========================================================*/ 30 | PUBLIC void Sys_restart(void) { 31 | 32 | IO_outB(PS2_STATE, SYS_C_RESET); 33 | 34 | } 35 | 36 | /* Works in emulators such as qemu and bochs */ 37 | PUBLIC void Sys_powerOff(void) { 38 | 39 | IO_outW(0xB004, 0x0 | 0x2000); 40 | 41 | } 42 | 43 | PUBLIC void Sys_panic(const char* str) { 44 | 45 | Console_setColor(CONSOLE_ERROR); 46 | Console_printf("%s%s", "[PANIC] ", str); 47 | Sys_disableInterrupts(); /* We don't want CPU to wake up */ 48 | Sys_haltCPU(); 49 | } 50 | -------------------------------------------------------------------------------- /kernel/src/Lib/Stack.c: -------------------------------------------------------------------------------- 1 | /** 2 | | Copyright(C) 2012 Ali Ersenal 3 | | License: WTFPL v2 4 | | URL: http://sam.zoy.org/wtfpl/COPYING 5 | | 6 | |-------------------------------------------------------------------------- 7 | | Stack.c 8 | |-------------------------------------------------------------------------- 9 | | 10 | | DESCRIPTION: Stack data structure implementation. 11 | | - Stores 4-byte items 12 | | - Grows upwards 13 | | 14 | | AUTHOR: Ali Ersenal, aliersenal@gmail.com 15 | \------------------------------------------------------------------------*/ 16 | 17 | 18 | #include 19 | #include 20 | 21 | PUBLIC void Stack_push(Stack* self, void* item) { 22 | 23 | Debug_assert(self->size * sizeof(void*) < self->length); 24 | 25 | *((int*) (self->start + self->size * sizeof(void*))) = (int) item; 26 | self->size++; 27 | 28 | } 29 | 30 | PUBLIC void* Stack_pop(Stack* self) { 31 | 32 | Debug_assert(self->size > 0); 33 | 34 | int item = *((int*) (self->start + ((self->size - 1) * sizeof(void*)))); 35 | self->size--; 36 | return (void*) item; 37 | 38 | } 39 | 40 | PUBLIC void* Stack_peek(Stack* self) { 41 | 42 | return (void*) *((int*) (self->start + ((self->size - 1) * sizeof(void*)))); 43 | 44 | } 45 | 46 | PUBLIC void Stack_init(Stack* self, void* start, u32int length) { 47 | 48 | self->start = start; 49 | self->length = length; 50 | self->size = 0; 51 | 52 | }; -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Incitatus-OS 2 | ============ 3 | 4 | Stage 3 Dissertation project. The aim is to create an X86-32bit operating system as a vehicle to learn about operating systems from a student perspective. 5 | 6 | 7 | ##Progress 8 | 9 | ![ScreenShot](http://oi45.tinypic.com/2rqf3t5.jpg) 10 | 11 | ##Running the OS 12 | 13 | › The simplest and most risk-free way is to run it on emulators such as VirtualBox, Qemu or Bochs 14 | › Boot from "image.iso"(inside bin folder) CD image. 15 | 16 | › Or, you may test-run(at your own risk) the OS on a 32-bit or 64-bit X86 PC. 17 | › Burn "image.iso" and boot from CD. 18 | 19 | ##Tasks 20 | 21 | ✔ Setup development environment 22 | ✔ OS 23 | Linux 3.2.0 X86-64bit 24 | ✔ Cross-compiler toolchain 25 | Binutils 2.22 26 | GCC-i586-elf 4.6.3 27 | ✔ Editor-Debugger 28 | Sublime Text v2 29 | GDB 7.4 30 | 31 | Programming 32 | ✔ Rudimentary debugging functions, screen output 33 | ✔ Module manager 34 | ✔ Global descriptor table 35 | ✔ Interrupt descriptor table 36 | ✔ Interrupt service routines 37 | ✔ Physical memory management 38 | ✔ Virtual memory management 39 | ✔ Kernel heap memory management 40 | ✔ Context switching, multi-tasking 41 | ✔ PS/2 Controller, keyboard driver 42 | ✔ Virtual File System, ramdisk 43 | ✔ Ring 0 to Ring 3 switch 44 | ✔ System call interface 45 | ✔ Shell 46 | 47 | ##License 48 | 49 | Copyright 2013 Ali Ersenal. Licensed under WTFPL V2. 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /kernel/include/Lib/ArrayList.h: -------------------------------------------------------------------------------- 1 | /** 2 | | Copyright(C) 2012 Ali Ersenal 3 | | License: WTFPL v2 4 | | URL: http://sam.zoy.org/wtfpl/COPYING 5 | | 6 | |-------------------------------------------------------------------------- 7 | | ArrayList.h 8 | |-------------------------------------------------------------------------- 9 | | 10 | | DESCRIPTION: ArrayList(dynamic array) data structure implementation. 11 | | 12 | | AUTHOR: Ali Ersenal, aliersenal@gmail.com 13 | \------------------------------------------------------------------------*/ 14 | 15 | 16 | #ifndef ARRAYLIST_H 17 | #define ARRAYLIST_H 18 | 19 | #include 20 | 21 | /*======================================================= 22 | TYPE 23 | =========================================================*/ 24 | typedef struct ArrayList ArrayList; 25 | 26 | /*======================================================= 27 | FUNCTION 28 | =========================================================*/ 29 | void* ArrayList_get (ArrayList* self, u32int index); 30 | int ArrayList_getIndex (ArrayList* self, void* dataPointer); 31 | bool ArrayList_exists (ArrayList* self, void* dataPointer); 32 | u32int ArrayList_getSize (ArrayList* self); 33 | void ArrayList_add (ArrayList* self, void* dataPointer); 34 | void ArrayList_remove (ArrayList* self, void* dataPointer); 35 | void ArrayList_removeAt (ArrayList* self, u32int index); 36 | bool ArrayList_isEmpty (ArrayList* self); 37 | 38 | void ArrayList_destroy(ArrayList* self); 39 | ArrayList* ArrayList_new (u32int initialLength); 40 | 41 | #endif 42 | -------------------------------------------------------------------------------- /kernel/src/Lib/Math.c: -------------------------------------------------------------------------------- 1 | /** 2 | | Copyright(C) 2012 Ali Ersenal 3 | | License: WTFPL v2 4 | | URL: http://sam.zoy.org/wtfpl/COPYING 5 | | 6 | |-------------------------------------------------------------------------- 7 | | Math.c 8 | |-------------------------------------------------------------------------- 9 | | 10 | | DESCRIPTION: Very simple kernel math library. 11 | | 12 | | AUTHOR: Ali Ersenal, aliersenal@gmail.com 13 | \------------------------------------------------------------------------*/ 14 | 15 | 16 | #include 17 | #include 18 | 19 | PUBLIC double Math_abs(double number) { 20 | 21 | asm volatile("fld %0;" 22 | "fabs;" 23 | "fst %0" 24 | : "+t" (number)); 25 | 26 | return number; 27 | } 28 | 29 | PUBLIC double Math_sqrt(double number) { 30 | 31 | asm volatile("fld %0;" 32 | "fsqrt;" 33 | "fst %0" 34 | : "+t" (number)); 35 | 36 | return number; 37 | 38 | } 39 | 40 | PUBLIC double Math_sin(double radian) { 41 | 42 | asm volatile("fld %0;" 43 | "fsin;" 44 | "fst %0" 45 | : "+t" (radian)); 46 | 47 | return radian; 48 | 49 | } 50 | 51 | PUBLIC double Math_cos(double radian) { 52 | 53 | asm volatile("fld %0;" 54 | "fcos;" 55 | "fst %0" 56 | : "+t" (radian)); 57 | 58 | return radian; 59 | 60 | } 61 | 62 | PUBLIC double Math_tan(double radian) { 63 | 64 | asm volatile("fld %0;" 65 | "fptan;" 66 | "fstp %0;" 67 | "fst %0" 68 | : "+t" (radian)); 69 | 70 | return radian; 71 | 72 | } -------------------------------------------------------------------------------- /kernel/include/Lib/LinkedList.h: -------------------------------------------------------------------------------- 1 | /** 2 | | Copyright(C) 2012 Ali Ersenal 3 | | License: WTFPL v2 4 | | URL: http://sam.zoy.org/wtfpl/COPYING 5 | | 6 | |-------------------------------------------------------------------------- 7 | | LinkedList.h 8 | |-------------------------------------------------------------------------- 9 | | 10 | | DESCRIPTION: Doubly linked list data structure implementation. 11 | | 12 | | AUTHOR: Ali Ersenal, aliersenal@gmail.com 13 | \------------------------------------------------------------------------*/ 14 | 15 | 16 | #ifndef LINKEDLIST_H 17 | #define LINKEDLIST_H 18 | 19 | #include 20 | 21 | /*======================================================= 22 | DEFINE 23 | =========================================================*/ 24 | #define LinkedList_FOREACH(item, list) \ 25 | for(Node* item = list->first; item != NULL; item = item->next) 26 | 27 | #define LinkedList_getSize(list) ((list)->count) 28 | 29 | /*======================================================= 30 | STRUCT 31 | =========================================================*/ 32 | typedef struct LinkedList LinkedList; 33 | typedef struct Node Node; 34 | 35 | struct Node { 36 | 37 | void* data; 38 | Node* next; 39 | Node* prev; 40 | 41 | }; 42 | 43 | struct LinkedList { 44 | 45 | Node* first; 46 | Node* last; 47 | u32int count; 48 | 49 | }; 50 | 51 | /*======================================================= 52 | FUNCTION 53 | =========================================================*/ 54 | void LinkedList_add(LinkedList* self, void* data); 55 | void* LinkedList_remove(LinkedList* self, void* data); 56 | void* LinkedList_removeFromFront(LinkedList* self); 57 | void* LinkedList_getFront(LinkedList* self); 58 | LinkedList* LinkedList_new(); 59 | void LinkedList_destroy(LinkedList* self); 60 | 61 | #endif 62 | -------------------------------------------------------------------------------- /kernel/src/Lib/Bitmap.c: -------------------------------------------------------------------------------- 1 | /** 2 | | Copyright(C) 2012 Ali Ersenal 3 | | License: WTFPL v2 4 | | URL: http://sam.zoy.org/wtfpl/COPYING 5 | | 6 | |-------------------------------------------------------------------------- 7 | | Bitmap.c 8 | |-------------------------------------------------------------------------- 9 | | 10 | | DESCRIPTION: Bit array data structure implementation. 11 | | 12 | | AUTHOR: Ali Ersenal, aliersenal@gmail.com 13 | \------------------------------------------------------------------------*/ 14 | 15 | 16 | #include 17 | #include 18 | 19 | /*======================================================= 20 | DEFINE 21 | =========================================================*/ 22 | #define CHECK_INDEX Debug_assert((index / 8) < self->length); 23 | 24 | /*======================================================= 25 | FUNCTION 26 | =========================================================*/ 27 | PUBLIC void Bitmap_setBit(Bitmap* self, u32int index) { 28 | 29 | CHECK_INDEX 30 | 31 | char* byte = self->start + (index / 8); 32 | *byte |= (1 << (index % 8)); 33 | 34 | } 35 | 36 | PUBLIC void Bitmap_clearBit(Bitmap* self, u32int index) { 37 | 38 | CHECK_INDEX 39 | 40 | char* byte = self->start + (index / 8); 41 | *byte &= ~(1 << (index % 8)); 42 | 43 | } 44 | 45 | PUBLIC bool Bitmap_isSet(Bitmap* self, u32int index) { 46 | 47 | CHECK_INDEX 48 | 49 | char* byte = self->start + (index / 8); 50 | return *byte & (1 << (index % 8)); 51 | 52 | } 53 | 54 | PUBLIC void Bitmap_toggle(Bitmap* self, u32int index) { 55 | 56 | CHECK_INDEX 57 | 58 | if(Bitmap_isSet(self, index)) 59 | Bitmap_clearBit(self, index); 60 | else 61 | Bitmap_setBit(self, index); 62 | 63 | } 64 | 65 | PUBLIC void Bitmap_init(Bitmap* self, void* start, u32int length) { 66 | 67 | self->start = start; 68 | self->length = length; 69 | 70 | } -------------------------------------------------------------------------------- /kernel/src/Process/FCFS.c: -------------------------------------------------------------------------------- 1 | /** 2 | | Copyright(C) 2012 Ali Ersenal 3 | | License: WTFPL v2 4 | | URL: http://sam.zoy.org/wtfpl/COPYING 5 | | 6 | |-------------------------------------------------------------------------- 7 | | FCFS.c (implements Scheduler) 8 | |-------------------------------------------------------------------------- 9 | | 10 | | DESCRIPTION: First-Come, First-Served non-preemptive scheduler implementation. 11 | | 12 | | AUTHOR: Ali Ersenal, aliersenal@gmail.com 13 | \------------------------------------------------------------------------*/ 14 | 15 | 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | /*======================================================= 23 | PRIVATE DATA 24 | =========================================================*/ 25 | PRIVATE LinkedList* processes; 26 | PRIVATE Process* currentProcess; 27 | 28 | /*======================================================= 29 | FUNCTION 30 | =========================================================*/ 31 | 32 | PUBLIC void FCFS_addProcess(Process* process) { 33 | 34 | Debug_assert(process != NULL); 35 | 36 | if(processes == NULL) { /* FCFS initialisation */ 37 | 38 | processes = LinkedList_new(); 39 | currentProcess = process; 40 | 41 | } 42 | 43 | process->status = PROCESS_WAITING; 44 | LinkedList_add(processes, process); 45 | 46 | } 47 | 48 | PUBLIC void FCFS_removeProcess(Process* process) { 49 | 50 | Debug_assert(process != NULL && processes != NULL); 51 | Debug_assert(process->pid != KERNEL_PID); /* Can't kill kernel process */ 52 | 53 | LinkedList_remove(processes, process); 54 | process->status = PROCESS_TERMINATED; 55 | 56 | } 57 | 58 | PUBLIC Process* FCFS_getNextProcess(void) { 59 | 60 | currentProcess = LinkedList_getFront(processes); 61 | return currentProcess; 62 | 63 | } 64 | 65 | PUBLIC Process* FCFS_getCurrentProcess(void) { 66 | 67 | return currentProcess; 68 | 69 | } 70 | -------------------------------------------------------------------------------- /kernel/src/Process/Scheduler.c: -------------------------------------------------------------------------------- 1 | /** 2 | | Copyright(C) 2012 Ali Ersenal 3 | | License: WTFPL v2 4 | | URL: http://sam.zoy.org/wtfpl/COPYING 5 | | 6 | |-------------------------------------------------------------------------- 7 | | Scheduler.c 8 | |-------------------------------------------------------------------------- 9 | | 10 | | DESCRIPTION: Process scheduler interface. 11 | | 12 | | AUTHOR: Ali Ersenal, aliersenal@gmail.com 13 | \------------------------------------------------------------------------*/ 14 | 15 | 16 | #include 17 | #include 18 | 19 | /* Include scheduler implementation */ 20 | /* #include */ 21 | #include 22 | 23 | /*======================================================= 24 | PRIVATE DATA 25 | =========================================================*/ 26 | PRIVATE bool isPreemptive; 27 | 28 | /*======================================================= 29 | PUBLIC DATA 30 | =========================================================*/ 31 | PUBLIC void (*Scheduler_addProcess) (Process* process); 32 | PUBLIC void (*Scheduler_removeProcess) (Process* process); 33 | PUBLIC Process* (*Scheduler_getNextProcess) (void); 34 | PUBLIC Process* (*Scheduler_getCurrentProcess) (void); 35 | 36 | /*======================================================= 37 | FUNCTION 38 | =========================================================*/ 39 | 40 | PUBLIC void Scheduler_init(void) { 41 | 42 | Debug_logInfo("%s", "Initialising Scheduler"); 43 | 44 | /* Point to scheduler implementation */ 45 | Scheduler_addProcess = &RoundRobin_addProcess; 46 | Scheduler_removeProcess = &RoundRobin_removeProcess; 47 | Scheduler_getNextProcess = &RoundRobin_getNextProcess; 48 | Scheduler_getCurrentProcess = &RoundRobin_getCurrentProcess; 49 | 50 | /* Is this scheduler implementation preemptive or not */ 51 | isPreemptive = TRUE; 52 | 53 | } 54 | 55 | PUBLIC bool Scheduler_isPreemptive(void) { 56 | 57 | return isPreemptive; 58 | 59 | } -------------------------------------------------------------------------------- /kernel/include/Drivers/Keyboard.h: -------------------------------------------------------------------------------- 1 | /** 2 | | Copyright(C) 2012 Ali Ersenal 3 | | License: WTFPL v2 4 | | URL: http://sam.zoy.org/wtfpl/COPYING 5 | | 6 | |-------------------------------------------------------------------------- 7 | | Keyboard.h 8 | |-------------------------------------------------------------------------- 9 | | 10 | | DESCRIPTION: Interrupt based PS/2 keyboard driver. 11 | | 12 | | AUTHOR: Ali Ersenal, aliersenal@gmail.com 13 | \------------------------------------------------------------------------*/ 14 | 15 | 16 | #ifndef KEYBOARD_H 17 | #define KEYBOARD_H 18 | 19 | #include 20 | 21 | /*------------------------------------------------------------------------- 22 | | Keyboard driver installation 23 | |-------------------------------------------------------------------------- 24 | | DESCRIPTION: Initialises PS/2 keyboard driver. Gets called while 25 | | initialising the PS/2 controller. 26 | | (refer to PS2Controller.c : PS2Controller_init) 27 | | 28 | \------------------------------------------------------------------------*/ 29 | void Keyboard_init(void); 30 | 31 | /*------------------------------------------------------------------------- 32 | | Keyboard set leds 33 | |-------------------------------------------------------------------------- 34 | | DESCRIPTION: Sets the keyboard led status. 35 | | 36 | | PARAMS: 'numLock' -\ 37 | | 'capsLock' -=> TRUE = Turn on, FALSE = Turn off. 38 | | 'scrollLock' -/ 39 | \------------------------------------------------------------------------*/ 40 | void Keyboard_setLeds(bool numLock, bool capsLock, bool scrollLock); 41 | 42 | /*------------------------------------------------------------------------- 43 | | Keyboard get char 44 | |-------------------------------------------------------------------------- 45 | | DESCRIPTION: Reads and returns a character stored inside circular key 46 | | buffer. 47 | | 48 | | RETURN: 'char' char value 49 | \------------------------------------------------------------------------*/ 50 | char Keyboard_getChar(void); 51 | #endif 52 | -------------------------------------------------------------------------------- /kernel/src/Memory/PhysicalMemory.c: -------------------------------------------------------------------------------- 1 | /** 2 | | Copyright(C) 2012 Ali Ersenal 3 | | License: WTFPL v2 4 | | URL: http://sam.zoy.org/wtfpl/COPYING 5 | | 6 | |-------------------------------------------------------------------------- 7 | | PhysicalMemory.c 8 | |-------------------------------------------------------------------------- 9 | | 10 | | DESCRIPTION: Physical memory manager interface. 11 | | Sets up and manages physical memory. 12 | | 13 | | AUTHOR: Ali Ersenal, aliersenal@gmail.com 14 | \------------------------------------------------------------------------*/ 15 | 16 | 17 | #include 18 | #include 19 | 20 | /* Include PMM implementation */ 21 | /* #include Memory/BitmapPMM.h */ 22 | #include 23 | 24 | 25 | /*======================================================= 26 | PRIVATE DATA 27 | =========================================================*/ 28 | PRIVATE Module pmmModule; 29 | 30 | /*======================================================= 31 | PUBLIC DATA 32 | =========================================================*/ 33 | PUBLIC PhysicalMemoryInfo* (*PhysicalMemory_getInfo) (PhysicalMemoryInfo* buf); 34 | PUBLIC void* (*PhysicalMemory_allocateFrame) (void); 35 | PUBLIC void (*PhysicalMemory_freeFrame) (void* frame); 36 | 37 | /*======================================================= 38 | FUNCTION 39 | =========================================================*/ 40 | 41 | PRIVATE void _PhysicalMemory_init() { 42 | 43 | Debug_logInfo("%s%s", "Initialising ", pmmModule.moduleName); 44 | 45 | /* Point to PMM implementation */ 46 | PhysicalMemory_getInfo = StackPMM_getInfo; 47 | PhysicalMemory_allocateFrame = StackPMM_allocateFrame; 48 | PhysicalMemory_freeFrame = StackPMM_freeFrame; 49 | 50 | /* Call PMM init function */ 51 | StackPMM_init(); 52 | 53 | } 54 | 55 | PUBLIC Module* PhysicalMemory_getModule(void) { 56 | 57 | if(!pmmModule.isLoaded) { 58 | 59 | pmmModule.moduleName = "Physical Memory Manager"; 60 | pmmModule.moduleID = MODULE_PMM; 61 | pmmModule.init = _PhysicalMemory_init; 62 | 63 | } 64 | 65 | return &pmmModule; 66 | } 67 | 68 | 69 | 70 | -------------------------------------------------------------------------------- /kernel/include/Common.h: -------------------------------------------------------------------------------- 1 | /** 2 | | Copyright(C) 2012 Ali Ersenal 3 | | License: WTFPL v2 4 | | URL: http://sam.zoy.org/wtfpl/COPYING 5 | | 6 | |-------------------------------------------------------------------------- 7 | | Common.h 8 | |-------------------------------------------------------------------------- 9 | | 10 | | DESCRIPTION: Provides common definitions and typedefs. 11 | | 12 | | 13 | | AUTHOR: Ali Ersenal, aliersenal@gmail.com 14 | \------------------------------------------------------------------------*/ 15 | 16 | 17 | #ifndef COMMON_H 18 | #define COMMON_H 19 | 20 | /* User stack size and virtual address(just below page directory recursive-map) */ 21 | #define USER_STACK_SIZE 4096 22 | #define USER_STACK_TOP_VADDR 0xFFC00000 - 0x1000 23 | #define USER_STACK_BASE_VADDR (USER_STACK_TOP_VADDR - USER_STACK_SIZE) 24 | 25 | /* User heap, 2GB-4GB(ish) virtual address*/ 26 | #define USER_HEAP_BASE_VADDR 0x80000000 27 | #define USER_HEAP_TOP_VADDR USER_STACK_BASE_VADDR 28 | 29 | /* User code */ 30 | #define USER_CODE_BASE_VADDR 0x40000000 31 | 32 | /* Kernel heap, 512MB-1GB virtual address*/ 33 | #define KERNEL_HEAP_BASE_VADDR 0x20000000 34 | #define KERNEL_HEAP_TOP_VADDR 0x40000000 35 | 36 | /* Get the number of elements in an array */ 37 | #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof(arr[0])) 38 | 39 | /* Null type */ 40 | #define NULL ((void *)0) 41 | 42 | /* Mark a variable as unused */ 43 | #define UNUSED(var) ((void) var) 44 | 45 | /** Used mainly for casting structs */ 46 | #define FORCE_CAST(var, type) *(type*)&var 47 | 48 | /** 32 bit X86 types */ 49 | typedef unsigned long long u64int; 50 | typedef unsigned int u32int; 51 | typedef unsigned short u16int; 52 | typedef unsigned char u8int; 53 | 54 | typedef unsigned int size_t; 55 | typedef signed int ptrdiff_t; 56 | 57 | /** Boolean type **/ 58 | typedef unsigned char bool; 59 | #define TRUE 1 60 | #define FALSE 0 61 | 62 | /** Scope, helps with code documentation/structure(used in .c files) 63 | ** PUBLIC - Functions or variables can be accessed from other compilation units 64 | ** PRIVATE - Functions or variables can NOT be accessed from other compilation units 65 | **/ 66 | #define PRIVATE static 67 | #define PUBLIC 68 | 69 | #endif 70 | -------------------------------------------------------------------------------- /kernel/include/X86/GDT.h: -------------------------------------------------------------------------------- 1 | /** 2 | | Copyright(C) 2012 Ali Ersenal 3 | | License: WTFPL v2 4 | | URL: http://sam.zoy.org/wtfpl/COPYING 5 | | 6 | |-------------------------------------------------------------------------- 7 | | GDT.h 8 | |-------------------------------------------------------------------------- 9 | | 10 | | DESCRIPTION: Sets up Global Descriptor Table. 11 | | 12 | | 13 | | AUTHOR: Ali Ersenal, aliersenal@gmail.com 14 | \------------------------------------------------------------------------*/ 15 | 16 | 17 | #ifndef GDT_H 18 | #define GDT_H 19 | 20 | #include 21 | 22 | /*======================================================= 23 | DEFINE 24 | =========================================================*/ 25 | 26 | /* Segment selectors */ 27 | #define NULL_SEGMENT 0x00 28 | #define KERNEL_CODE_SEGMENT 0x08 /* Base 0, Limit 4GB, Privilege 0 */ 29 | #define KERNEL_DATA_SEGMENT 0x10 /* Base 0, Limit 4GB, Privilege 0 */ 30 | #define USER_CODE_SEGMENT 0x18 /* Base 0, Limit 4GB, Privilege 3 */ 31 | #define USER_DATA_SEGMENT 0x20 /* Base 0, Limit 4GB, Privilege 3 */ 32 | #define TSS_SEGMENT 0x28 /* Task state segment selector */ 33 | 34 | /* Privilege levels */ 35 | #define KERNEL_MODE 0 36 | #define USER_MODE 3 37 | 38 | /*======================================================= 39 | FUNCTION 40 | =========================================================*/ 41 | 42 | /*------------------------------------------------------------------------- 43 | | Set TSS 44 | |-------------------------------------------------------------------------- 45 | | DESCRIPTION: Sets the task state segment to specified values. 46 | | 47 | | PARAM: 'dataSegment' kernel data segment 48 | | 'esp0' the kernel stack 49 | \------------------------------------------------------------------------*/ 50 | void GDT_setTSS(u32int dataSegment, u32int esp0); 51 | 52 | /*------------------------------------------------------------------------- 53 | | Get GDT module 54 | |-------------------------------------------------------------------------- 55 | | DESCRIPTION: Returns the GDT module. 56 | | 57 | \------------------------------------------------------------------------*/ 58 | Module* GDT_getModule(void); 59 | #endif 60 | -------------------------------------------------------------------------------- /kernel/src/Process/RoundRobin.c: -------------------------------------------------------------------------------- 1 | /** 2 | | Copyright(C) 2012 Ali Ersenal 3 | | License: WTFPL v2 4 | | URL: http://sam.zoy.org/wtfpl/COPYING 5 | | 6 | |-------------------------------------------------------------------------- 7 | | RoundRobin.c (implements Scheduler) 8 | |-------------------------------------------------------------------------- 9 | | 10 | | DESCRIPTION: Round robin process scheduler implementation. 11 | | 12 | | AUTHOR: Ali Ersenal, aliersenal@gmail.com 13 | \------------------------------------------------------------------------*/ 14 | 15 | 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | /*======================================================= 23 | PRIVATE DATA 24 | =========================================================*/ 25 | PRIVATE LinkedList* processes; 26 | PRIVATE Process* currentProcess; 27 | 28 | /*======================================================= 29 | FUNCTION 30 | =========================================================*/ 31 | 32 | PUBLIC void RoundRobin_addProcess(Process* process) { 33 | 34 | Debug_assert(process != NULL); 35 | Debug_assert(process->status = PROCESS_CREATED); 36 | 37 | if(processes == NULL) { /* RoundRobin initialisation */ 38 | 39 | processes = LinkedList_new(); 40 | currentProcess = process; 41 | 42 | } 43 | 44 | process->status = PROCESS_WAITING; 45 | LinkedList_add(processes, process); 46 | 47 | } 48 | 49 | PUBLIC void RoundRobin_removeProcess(Process* process) { 50 | 51 | Debug_assert(process != NULL && processes != NULL); 52 | Debug_assert(process->pid != KERNEL_PID); /* Can't remove kernel process */ 53 | 54 | process->status = PROCESS_TERMINATED; 55 | LinkedList_remove(processes, process); 56 | 57 | } 58 | 59 | PUBLIC Process* RoundRobin_getNextProcess(void) { 60 | 61 | /* Remove process from head of queue and add as the last element */ 62 | Process* p = LinkedList_removeFromFront(processes); 63 | 64 | LinkedList_add(processes, p); 65 | currentProcess = p; 66 | return p; 67 | 68 | } 69 | 70 | PUBLIC Process* RoundRobin_getCurrentProcess(void) { 71 | 72 | return currentProcess; 73 | 74 | } 75 | -------------------------------------------------------------------------------- /kernel/src/Memory/DumbHeapManager.c: -------------------------------------------------------------------------------- 1 | /** 2 | | Copyright(C) 2012 Ali Ersenal 3 | | License: WTFPL v2 4 | | URL: http://sam.zoy.org/wtfpl/COPYING 5 | | 6 | |-------------------------------------------------------------------------- 7 | | DumbHeapManager.c (implements HeapMemory) 8 | |-------------------------------------------------------------------------- 9 | | 10 | | DESCRIPTION: A useless heap manager implementation, only supports malloc. 11 | | 12 | | AUTHOR: Ali Ersenal, aliersenal@gmail.com 13 | \------------------------------------------------------------------------*/ 14 | 15 | 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | /*======================================================= 24 | PRIVATE DATA 25 | =========================================================*/ 26 | PRIVATE char* lastAllocAddr = (char*) KERNEL_HEAP_BASE_VADDR; 27 | PRIVATE u32int allocatedPages; 28 | 29 | /*======================================================= 30 | FUNCTION 31 | =========================================================*/ 32 | 33 | PUBLIC void* DumbHeapManager_malloc(size_t bytes) { 34 | 35 | /* out of heap memory? */ 36 | if(((lastAllocAddr - ((char*) KERNEL_HEAP_BASE_VADDR) + bytes) / FRAME_SIZE) + 1 > allocatedPages) { 37 | 38 | HeapMemory_expand(FRAME_SIZE); 39 | allocatedPages++; 40 | 41 | } 42 | 43 | void* temp = lastAllocAddr; 44 | lastAllocAddr += bytes; 45 | return temp; 46 | 47 | } 48 | 49 | PUBLIC void* DumbHeapManager_realloc(void* oldmem, size_t bytes) { 50 | 51 | /* This manager does not implement reallocate */ 52 | UNUSED(oldmem); 53 | UNUSED(bytes); 54 | Debug_assert(FALSE); 55 | return NULL; 56 | 57 | } 58 | 59 | PUBLIC void* DumbHeapManager_calloc(size_t numberOfElements, size_t elementSize) { 60 | 61 | /* This manager does not implement calloc */ 62 | UNUSED(numberOfElements); 63 | UNUSED(elementSize); 64 | Debug_assert(FALSE); 65 | return NULL; 66 | 67 | } 68 | 69 | PUBLIC void DumbHeapManager_free(void* mem) { 70 | 71 | /* This manager does not implement free */ 72 | UNUSED(mem); 73 | Debug_assert(FALSE); 74 | 75 | } 76 | -------------------------------------------------------------------------------- /kernel/src/Kernel.c: -------------------------------------------------------------------------------- 1 | /** 2 | | Copyright(C) 2012 Ali Ersenal 3 | | License: WTFPL v2 4 | | URL: http://sam.zoy.org/wtfpl/COPYING 5 | | 6 | |-------------------------------------------------------------------------- 7 | | Kernel.c 8 | |-------------------------------------------------------------------------- 9 | | 10 | | DESCRIPTION: Main C entry point for kernel, Kernel() function gets 11 | | called in Start.s. 12 | | 13 | | AUTHOR: Ali Ersenal, aliersenal@gmail.com 14 | \------------------------------------------------------------------------*/ 15 | 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | 35 | PUBLIC MultibootInfo* multibootInfo; 36 | 37 | PUBLIC void Kernel_idle(void) { 38 | 39 | while(1) 40 | Sys_haltCPU(); 41 | 42 | } 43 | 44 | PUBLIC void Kernel(MultibootInfo* mbInfo, u32int mbMagic) { 45 | 46 | extern MultibootHeader mbHead; /* Defined in Start.s */ 47 | multibootInfo = mbInfo; 48 | 49 | Debug_assert(mbMagic == MULTIBOOT_BOOTLOADER_MAGIC); 50 | Debug_assert(mbHead.magic == MULTIBOOT_HEADER_MAGIC); 51 | Debug_assert(mbInfo->modsCount > 0); /* Make sure initrd(ram disk) is in memory */ 52 | 53 | Module* modules[] = { 54 | 55 | VGA_getModule(), 56 | Console_getModule(), 57 | GDT_getModule(), 58 | PIC8259_getModule(), 59 | IDT_getModule(), 60 | PIT8253_getModule(), 61 | PhysicalMemory_getModule(), 62 | VirtualMemory_getModule(), 63 | HeapMemory_getModule(), 64 | PS2Controller_getModule(), 65 | VFS_getModule(), 66 | ProcessManager_getModule(), 67 | Usermode_getModule(), 68 | 69 | }; 70 | 71 | for(u32int i = 0; i < ARRAY_SIZE(modules); i++) 72 | Module_load(modules[i]); 73 | 74 | Sys_enableInterrupts(); 75 | Kernel_idle(); 76 | Sys_panic("Should not reach here!"); 77 | 78 | } 79 | 80 | -------------------------------------------------------------------------------- /kernel/src/X86/CPU.c: -------------------------------------------------------------------------------- 1 | /** 2 | | Copyright(C) 2012 Ali Ersenal 3 | | License: WTFPL v2 4 | | URL: http://sam.zoy.org/wtfpl/COPYING 5 | | 6 | |-------------------------------------------------------------------------- 7 | | CPU.c 8 | |-------------------------------------------------------------------------- 9 | | 10 | | DESCRIPTION: Provides functions to alter or retrieve CPU control 11 | | registers. Control registers(CR0..CR4) control the general 12 | | function of CPU. 13 | | 14 | | EXAMPLE: You may use FORCE_CAST(refer to Common.h) to modify 15 | | or read the control registers: 16 | | 17 | | u32int tmp = CPU_getCR(0); 18 | | CR0 cr0 = FORCE_CAST(tmp, CR0); 19 | | cr0.PG = 1; 20 | | CPU_setCR(0, FORCE_CAST(cr0, u32int)); 21 | | 22 | | NOTES: Control registers are 32-bit registers(on X86-32). 23 | | 24 | | AUTHOR: Ali Ersenal, aliersenal@gmail.com 25 | \------------------------------------------------------------------------*/ 26 | 27 | 28 | #include 29 | 30 | PUBLIC u32int CPU_getCR(u8int n) { 31 | 32 | u32int ret = 0; 33 | 34 | switch(n) { 35 | 36 | case 0: 37 | asm volatile("mov %%cr0, %0 " : "=a" (ret)); 38 | break; 39 | 40 | case 1: 41 | asm volatile("mov %%cr1, %0 " : "=a" (ret)); 42 | break; 43 | 44 | case 2: 45 | asm volatile("mov %%cr2, %0 " : "=a" (ret)); 46 | break; 47 | 48 | case 3: 49 | asm volatile("mov %%cr3, %0 " : "=a" (ret)); 50 | break; 51 | 52 | case 4: 53 | asm volatile("mov %%cr4, %0 " : "=a" (ret)); 54 | break; 55 | 56 | } 57 | 58 | return ret; 59 | } 60 | 61 | PUBLIC void CPU_setCR(u8int n, u32int val) { 62 | 63 | switch(n) { 64 | 65 | case 0: 66 | asm volatile("mov %0, %%cr0" : : "a" (val)); 67 | break; 68 | 69 | case 1: 70 | asm volatile("mov %0, %%cr1" : : "a" (val)); 71 | break; 72 | 73 | case 2: 74 | asm volatile("mov %0, %%cr2" : : "a" (val)); 75 | break; 76 | 77 | case 3: 78 | asm volatile("mov %0, %%cr3" : : "a" (val)); 79 | break; 80 | 81 | case 4: 82 | asm volatile("mov %0, %%cr4" : : "a" (val)); 83 | break; 84 | 85 | } 86 | 87 | } 88 | 89 | -------------------------------------------------------------------------------- /kernel/include/Process/FCFS.h: -------------------------------------------------------------------------------- 1 | /** 2 | | Copyright(C) 2012 Ali Ersenal 3 | | License: WTFPL v2 4 | | URL: http://sam.zoy.org/wtfpl/COPYING 5 | | 6 | |-------------------------------------------------------------------------- 7 | | FCFS.h (implements Scheduler) 8 | |-------------------------------------------------------------------------- 9 | | 10 | | DESCRIPTION: First-Come, First-Served non-preemptive scheduler implementation. 11 | | 12 | | AUTHOR: Ali Ersenal, aliersenal@gmail.com 13 | \------------------------------------------------------------------------*/ 14 | 15 | 16 | #ifndef FCFS_H 17 | #define FCFS_H 18 | 19 | #include 20 | 21 | /*------------------------------------------------------------------------- 22 | | Add process 23 | |-------------------------------------------------------------------------- 24 | | DESCRIPTION: Adds a new process to scheduler's process list. 25 | | 26 | | PARAM: 'process' the process to add 27 | \------------------------------------------------------------------------*/ 28 | void FCFS_addProcess(Process* process); 29 | 30 | /*------------------------------------------------------------------------- 31 | | Remove process 32 | |-------------------------------------------------------------------------- 33 | | DESCRIPTION: Removes a process from scheduler's process list. 34 | | 35 | | PARAM: 'process' the process to remove 36 | \------------------------------------------------------------------------*/ 37 | void FCFS_removeProcess(Process* process); 38 | 39 | /*------------------------------------------------------------------------- 40 | | Get next process 41 | |-------------------------------------------------------------------------- 42 | | DESCRIPTION: Returns the next process to be switched to 43 | | 44 | | RETURN: 'Process*' the next process 45 | \------------------------------------------------------------------------*/ 46 | Process* FCFS_getNextProcess(void); 47 | 48 | /*------------------------------------------------------------------------- 49 | | Get current process 50 | |-------------------------------------------------------------------------- 51 | | DESCRIPTION: Returns the current process. 52 | | 53 | | RETURN: 'Process*' the current process 54 | \------------------------------------------------------------------------*/ 55 | Process* FCFS_getCurrentProcess(void); 56 | 57 | #endif -------------------------------------------------------------------------------- /kernel/include/Process/RoundRobin.h: -------------------------------------------------------------------------------- 1 | /** 2 | | Copyright(C) 2012 Ali Ersenal 3 | | License: WTFPL v2 4 | | URL: http://sam.zoy.org/wtfpl/COPYING 5 | | 6 | |-------------------------------------------------------------------------- 7 | | RoundRobin.h (implements Scheduler) 8 | |-------------------------------------------------------------------------- 9 | | 10 | | DESCRIPTION: Round robin process scheduler implementation. 11 | | 12 | | AUTHOR: Ali Ersenal, aliersenal@gmail.com 13 | \------------------------------------------------------------------------*/ 14 | 15 | 16 | #ifndef ROUND_ROBIN_H 17 | #define ROUND_ROBIN_H 18 | 19 | #include 20 | 21 | /*------------------------------------------------------------------------- 22 | | Add process 23 | |-------------------------------------------------------------------------- 24 | | DESCRIPTION: Adds a new process to scheduler's process list. 25 | | 26 | | PARAM: 'process' the process to add 27 | \------------------------------------------------------------------------*/ 28 | void RoundRobin_addProcess(Process* process); 29 | 30 | /*------------------------------------------------------------------------- 31 | | Remove process 32 | |-------------------------------------------------------------------------- 33 | | DESCRIPTION: Removes a process from scheduler's process list. 34 | | 35 | | PARAM: 'process' the process to remove 36 | \------------------------------------------------------------------------*/ 37 | void RoundRobin_removeProcess(Process* process); 38 | 39 | /*------------------------------------------------------------------------- 40 | | Get next process 41 | |-------------------------------------------------------------------------- 42 | | DESCRIPTION: Returns the next process to be switched to 43 | | 44 | | RETURN: 'Process*' the next process 45 | \------------------------------------------------------------------------*/ 46 | Process* RoundRobin_getNextProcess(void); 47 | 48 | /*------------------------------------------------------------------------- 49 | | Get current process 50 | |-------------------------------------------------------------------------- 51 | | DESCRIPTION: Returns the current process. 52 | | 53 | | RETURN: 'Process*' the current process 54 | \------------------------------------------------------------------------*/ 55 | Process* RoundRobin_getCurrentProcess(void); 56 | 57 | #endif -------------------------------------------------------------------------------- /kernel/include/X86/PIT8253.h: -------------------------------------------------------------------------------- 1 | /** 2 | | Copyright(C) 2012 Ali Ersenal 3 | | License: WTFPL v2 4 | | URL: http://sam.zoy.org/wtfpl/COPYING 5 | | 6 | |-------------------------------------------------------------------------- 7 | | PIT8253.h 8 | |-------------------------------------------------------------------------- 9 | | 10 | | DESCRIPTION: Provides an interface for Intel 8253 Programmable Interval 11 | | Timer(PIT). 12 | | 13 | | PIT consists of three timers(channels). Each has a different 14 | | purpose. 15 | | 16 | | First Timer - Used as the System timer 17 | | Second Timer - Used for RAM refreshing 18 | | Third Timer - Connected to PC speaker(that annoying beeper) 19 | | 20 | | AUTHOR: Ali Ersenal, aliersenal@gmail.com 21 | | 22 | | TYPE comments source: 23 | | http://stanislavs.org/helppc/8259.html 24 | \------------------------------------------------------------------------*/ 25 | 26 | 27 | #ifndef PIT_H 28 | #define PIT_H 29 | 30 | #include 31 | #include 32 | 33 | /*------------------------------------------------------------------------- 34 | | Measure runtime 35 | |-------------------------------------------------------------------------- 36 | | DESCRIPTION: Returns the number of ticks it takes to compute 37 | | specified function. 38 | | 39 | | PARAM: "functionAddr" the function to be measured 40 | | 41 | | RETURN: "u32int" the number of ticks 42 | \------------------------------------------------------------------------*/ 43 | u32int PIT8253_measureRuntime(void* functionAddr); 44 | 45 | /*------------------------------------------------------------------------- 46 | | Sleep 47 | |-------------------------------------------------------------------------- 48 | | DESCRIPTION: Puts the entire system on a busy-wait 49 | | 50 | | PARAM: "ms" time in milliseconds 51 | \------------------------------------------------------------------------*/ 52 | void PIT8253_sleep(u32int ms); 53 | 54 | /*------------------------------------------------------------------------- 55 | | Get PIT module 56 | |-------------------------------------------------------------------------- 57 | | DESCRIPTION: Returns the PIT module. 58 | \------------------------------------------------------------------------*/ 59 | Module* PIT8253_getModule(void); 60 | #endif -------------------------------------------------------------------------------- /kernel/include/X86/PIC8259.h: -------------------------------------------------------------------------------- 1 | /** 2 | | Copyright(C) 2012 Ali Ersenal 3 | | License: WTFPL v2 4 | | URL: http://sam.zoy.org/wtfpl/COPYING 5 | | 6 | |-------------------------------------------------------------------------- 7 | | PIC8259.h 8 | |-------------------------------------------------------------------------- 9 | | 10 | | DESCRIPTION: Provides an interface for Intel 8259 programmable interrupt 11 | | controller. 12 | | 13 | | AUTHOR: Ali Ersenal, aliersenal@gmail.com 14 | | 15 | | TYPE comments source: 16 | | http://stanislavs.org/helppc/8259.html 17 | \------------------------------------------------------------------------*/ 18 | 19 | 20 | #ifndef PIC_H 21 | #define PIC_H 22 | 23 | #include 24 | #include 25 | 26 | /*======================================================= 27 | DEFINE 28 | =========================================================*/ 29 | #define CLEAR_MASK 0 30 | #define SET_MASK 1 31 | 32 | /*======================================================= 33 | FUNCTION 34 | =========================================================*/ 35 | 36 | /*------------------------------------------------------------------------- 37 | | Set IRQ mask 38 | |-------------------------------------------------------------------------- 39 | | DESCRIPTION: Masks a given IRQ. 40 | | 41 | | PARAM: "irqNo" the irq to mask 42 | | "state" 0 = unmasked, 1 = masked 43 | \------------------------------------------------------------------------*/ 44 | void PIC8259_setMask(u8int irqNo, bool state); 45 | 46 | /*------------------------------------------------------------------------- 47 | | End of interrupt 48 | |-------------------------------------------------------------------------- 49 | | DESCRIPTION: Sends an end of interrupt command to appropriate PIC 50 | | (or PICs if the request originated from slave) 51 | | 52 | | PARAM: "interruptNo" the interrupt number of IRQ 53 | \------------------------------------------------------------------------*/ 54 | void PIC8259_sendEOI(u8int interruptNo); 55 | 56 | /*------------------------------------------------------------------------- 57 | | Get PIC module 58 | |-------------------------------------------------------------------------- 59 | | DESCRIPTION: Returns the PIC module. 60 | \------------------------------------------------------------------------*/ 61 | Module* PIC8259_getModule(void); 62 | 63 | #endif -------------------------------------------------------------------------------- /kernel/include/Memory.h: -------------------------------------------------------------------------------- 1 | /** 2 | | Copyright(C) 2012 Ali Ersenal 3 | | License: WTFPL v2 4 | | URL: http://sam.zoy.org/wtfpl/COPYING 5 | | 6 | |-------------------------------------------------------------------------- 7 | | Memory.h 8 | |-------------------------------------------------------------------------- 9 | | 10 | | DESCRIPTION: Provides functions which modify memory. 11 | | 12 | | AUTHOR: Ali Ersenal, aliersenal@gmail.com 13 | \------------------------------------------------------------------------*/ 14 | 15 | 16 | #ifndef MEMORY_H 17 | #define MEMORY_H 18 | 19 | #include 20 | #include 21 | 22 | /*------------------------------------------------------------------------- 23 | | Set memory 24 | |-------------------------------------------------------------------------- 25 | | DESCRIPTION: Sets every single byte in specified memory 26 | | space of length "length" to "valueToSet". 27 | | 28 | | PARAM: "ptrToMem" pointer to memory space 29 | | "valueToSet" new byte value 30 | | "length" number of bytes to be modified 31 | \------------------------------------------------------------------------*/ 32 | static inline void Memory_set(void* ptrToMem, char valueToSet, u32int length) { 33 | 34 | Debug_assert(ptrToMem != NULL); 35 | 36 | char* ptr = (char*) ptrToMem; 37 | 38 | for(u32int i = 0; i < length; i++) { 39 | 40 | *ptr = valueToSet; 41 | ptr++; 42 | 43 | } 44 | 45 | } 46 | 47 | /*------------------------------------------------------------------------- 48 | | Copy memory 49 | |-------------------------------------------------------------------------- 50 | | DESCRIPTION: Copies "sourceLength" bytes from "source" to 51 | | "destination". 52 | | 53 | | PARAM: "destination" pointer to destination memory 54 | | "source" pointer to source memory 55 | | "sourceLength" size of source 56 | | 57 | | PRECONDITION: "destination" and "source" should not overlap 58 | \------------------------------------------------------------------------*/ 59 | static inline void Memory_copy(void* destination,const void* source, u32int sourceLength) { 60 | 61 | Debug_assert(destination != NULL); 62 | Debug_assert(source != NULL); 63 | 64 | char* dest = (char*) destination; 65 | char* src = (char*) source; 66 | 67 | for(u32int i = 0; i < sourceLength; i++) { 68 | 69 | *(dest + i) = *(src + i); 70 | 71 | } 72 | 73 | } 74 | 75 | #endif 76 | -------------------------------------------------------------------------------- /kernel/include/Drivers/PS2Controller.h: -------------------------------------------------------------------------------- 1 | /** 2 | | Copyright(C) 2012 Ali Ersenal 3 | | License: WTFPL v2 4 | | URL: http://sam.zoy.org/wtfpl/COPYING 5 | | 6 | |-------------------------------------------------------------------------- 7 | | PS2Controller.h 8 | |-------------------------------------------------------------------------- 9 | | 10 | | DESCRIPTION: PS/2 Controller driver. 11 | | 12 | | AUTHOR: Ali Ersenal, aliersenal@gmail.com 13 | \------------------------------------------------------------------------*/ 14 | 15 | 16 | #ifndef PS2_H 17 | #define PS2_H 18 | 19 | #include 20 | #include 21 | 22 | /*======================================================= 23 | DEFINE 24 | =========================================================*/ 25 | 26 | /* PS/2 IO ports */ 27 | #define PS2_DATA 0x60 /* used for reading/writing data from PS/2 device or PS/2 controller */ 28 | #define PS2_PORTB 0x61 /* used for controlling various parts of the chipset */ 29 | #define PS2_STATE 0x64 /* used for retrieving/changing the state of PS/2 controller */ 30 | 31 | /*======================================================= 32 | FUNCTION 33 | =========================================================*/ 34 | 35 | /*------------------------------------------------------------------------- 36 | | Send PS/2 command 37 | |-------------------------------------------------------------------------- 38 | | DESCRIPTION: Sends a command byte to specified PS/2 port. 39 | | 40 | | PARAM: "port" ps/2 port to send command to 41 | | "command" command byte 42 | \------------------------------------------------------------------------*/ 43 | void PS2Controller_send(u8int port, u8int command); 44 | 45 | /*------------------------------------------------------------------------- 46 | | Receive PS/2 data 47 | |-------------------------------------------------------------------------- 48 | | DESCRIPTION: Retrieves a data byte from "port". 49 | | 50 | | PARAM: "port" port to receive data from 51 | | 52 | | RETURN: u8int retrieved data byte 53 | \------------------------------------------------------------------------*/ 54 | u8int PS2Controller_receive(u8int port); 55 | 56 | /*------------------------------------------------------------------------- 57 | | Get PS/2 controller module 58 | |-------------------------------------------------------------------------- 59 | | DESCRIPTION: Returns the PS/2 controller module. 60 | | 61 | \------------------------------------------------------------------------*/ 62 | Module* PS2Controller_getModule(void); 63 | #endif 64 | -------------------------------------------------------------------------------- /kernel/include/Memory/StackPMM.h: -------------------------------------------------------------------------------- 1 | /** 2 | | Copyright(C) 2012 Ali Ersenal 3 | | License: WTFPL v2 4 | | URL: http://sam.zoy.org/wtfpl/COPYING 5 | | 6 | |-------------------------------------------------------------------------- 7 | | StackPMM.h (implements PhysicalMemory) 8 | |-------------------------------------------------------------------------- 9 | | 10 | | DESCRIPTION: Stack based physical memory manager implementation. 11 | | 12 | | AUTHOR: Ali Ersenal, aliersenal@gmail.com 13 | \------------------------------------------------------------------------*/ 14 | 15 | 16 | #ifndef STACK_PMM 17 | #define STACK_PMM 18 | 19 | #include 20 | #include 21 | 22 | /*------------------------------------------------------------------------- 23 | | Allocate frame 24 | |-------------------------------------------------------------------------- 25 | | DESCRIPTION: Allocates and returns a frame address(4096 bytes). 26 | | 27 | | RETURN: void* allocated frame address 28 | | 29 | | NOTES: Returns NULL if out of physical memory. 30 | \------------------------------------------------------------------------*/ 31 | void* StackPMM_allocateFrame(void); 32 | 33 | /*------------------------------------------------------------------------- 34 | | Free frame 35 | |-------------------------------------------------------------------------- 36 | | DESCRIPTION: Deallocates the frame at address "b". 37 | | 38 | | PARAM: "b" the address of frame to be deallocated 39 | \------------------------------------------------------------------------*/ 40 | void StackPMM_freeFrame(void* b); 41 | 42 | /*------------------------------------------------------------------------- 43 | | Physical memory initialisation 44 | |-------------------------------------------------------------------------- 45 | | DESCRIPTION: Sets up physical memory. 46 | | 47 | \------------------------------------------------------------------------*/ 48 | void StackPMM_init(void); 49 | 50 | /*------------------------------------------------------------------------- 51 | | Get current memory information 52 | |-------------------------------------------------------------------------- 53 | | DESCRIPTION: Returns a structure containing physical memory info. 54 | | 55 | | PARAM: 'buf' memory info structure to be filled with the info. 56 | | 57 | | RETURN: 'PhysicalMemoryInfo*' pointer to filled memory info structure. 58 | \------------------------------------------------------------------------*/ 59 | PhysicalMemoryInfo* StackPMM_getInfo(PhysicalMemoryInfo* buf); 60 | 61 | #endif -------------------------------------------------------------------------------- /kernel/include/Memory/BitmapPMM.h: -------------------------------------------------------------------------------- 1 | /** 2 | | Copyright(C) 2012 Ali Ersenal 3 | | License: WTFPL v2 4 | | URL: http://sam.zoy.org/wtfpl/COPYING 5 | | 6 | |-------------------------------------------------------------------------- 7 | | BitmapPMM.h (implements PhysicalMemory) 8 | |-------------------------------------------------------------------------- 9 | | 10 | | DESCRIPTION: Bitmap based physical memory manager implementation. 11 | | 12 | | AUTHOR: Ali Ersenal, aliersenal@gmail.com 13 | \------------------------------------------------------------------------*/ 14 | 15 | 16 | #ifndef BIT_PMM 17 | #define BIT_PMM 18 | 19 | #include 20 | #include 21 | 22 | /*------------------------------------------------------------------------- 23 | | Allocate frame 24 | |-------------------------------------------------------------------------- 25 | | DESCRIPTION: Allocates and returns a frame address(4096 bytes). 26 | | 27 | | RETURN: void* allocated frame address 28 | | 29 | | NOTES: Returns NULL if out of physical memory. 30 | \------------------------------------------------------------------------*/ 31 | void* BitmapPMM_allocateFrame(void); 32 | 33 | /*------------------------------------------------------------------------- 34 | | Free frame 35 | |-------------------------------------------------------------------------- 36 | | DESCRIPTION: Deallocates the frame at address "b". 37 | | 38 | | PARAM: "b" the address of frame to be deallocated 39 | \------------------------------------------------------------------------*/ 40 | void BitmapPMM_freeFrame(void* b); 41 | 42 | /*------------------------------------------------------------------------- 43 | | Physical memory initialisation 44 | |-------------------------------------------------------------------------- 45 | | DESCRIPTION: Sets up physical memory. 46 | | 47 | \------------------------------------------------------------------------*/ 48 | void BitmapPMM_init(void); 49 | 50 | /*------------------------------------------------------------------------- 51 | | Get current memory information 52 | |-------------------------------------------------------------------------- 53 | | DESCRIPTION: Returns a structure containing physical memory info. 54 | | 55 | | PARAM: 'buf' memory info structure to be filled with the info. 56 | | 57 | | RETURN: 'PhysicalMemoryInfo*' pointer to filled memory info structure. 58 | \------------------------------------------------------------------------*/ 59 | PhysicalMemoryInfo* BitmapPMM_getInfo(PhysicalMemoryInfo* buf); 60 | 61 | #endif -------------------------------------------------------------------------------- /kernel/src/Start.s: -------------------------------------------------------------------------------- 1 | ; 2 | ; Copyright(C) 2012 Ali Ersenal 3 | ; License: WTFPL v2 4 | ; URL: http://sam.zoy.org/wtfpl/COPYING 5 | ; 6 | ;-------------------------------------------------------------------------- 7 | ; Start.s 8 | ;-------------------------------------------------------------------------- 9 | ; 10 | ; DESCRIPTION: This is the first entry point for the kernel before jumping 11 | ; to Kernel() in Kernel.c. After GRUB finishes its job it jumps 12 | ; to Start in this file(we tell this to GRUB using the mbHead 13 | ; Multiboot struct). 14 | ; 15 | ; GRUB drops us in this state: 16 | ; 17 | ; - CPU is in protected mode(A20 gate enabled) 18 | ; - Interrupts are disabled 19 | ; - Paging is disabled 20 | ; - EAX register contains multiboot magic value 21 | ; - EBX register contains pointer to multiboot info 22 | ; - ESP(stack) register is undefined 23 | ; 24 | ; 25 | ; AUTHOR: Ali Ersenal, aliersenal@gmail.com 26 | ;-------------------------------------------------------------------------- 27 | 28 | [BITS 32] 29 | 30 | ; Setup multiboot 31 | MBOOT_PAGE_ALIGN equ 1<<0 32 | MBOOT_MEM_INFO equ 1<<1 33 | MBOOT_HEADER_MAGIC equ 0x1BADB002 34 | MBOOT_HEADER_FLAGS equ MBOOT_PAGE_ALIGN | MBOOT_MEM_INFO 35 | MBOOT_CHECKSUM equ -(MBOOT_HEADER_MAGIC + MBOOT_HEADER_FLAGS) 36 | 37 | STACKSIZE equ 0xFF00; Kernel stack size, 64 Kilobytes 38 | 39 | [GLOBAL mbHead] 40 | [GLOBAL Start] 41 | [EXTERN text] 42 | [EXTERN bss] 43 | [EXTERN end] 44 | [EXTERN Kernel]; Main C kernel entry point 45 | 46 | section .text 47 | 48 | mbHead: 49 | dd MBOOT_HEADER_MAGIC ; Magic value 50 | dd MBOOT_HEADER_FLAGS ; Multiboot flags 51 | dd MBOOT_CHECKSUM ; Multiboot checksum value 52 | 53 | dd mbHead ; Address of this structure 54 | dd text ; Kernel start address 55 | dd bss ; End of data segment 56 | dd end ; End of bss segment 57 | dd Start ; GRUB will call this 58 | 59 | Start: 60 | mov esp, stack + STACKSIZE ; Set up the stack 61 | push eax ; Push multiboot magic number 62 | push ebx ; Push multiboot info pointer 63 | call Kernel ; Jump to Kernel() in Kernel.c 64 | 65 | section .bss 66 | 67 | stack: 68 | resb STACKSIZE ; Reserve STACKSIZE bytes in bss segment -------------------------------------------------------------------------------- /kernel/src/Lib/CircularFIFOBuffer.c: -------------------------------------------------------------------------------- 1 | /** 2 | | Copyright(C) 2012 Ali Ersenal 3 | | License: WTFPL v2 4 | | URL: http://sam.zoy.org/wtfpl/COPYING 5 | | 6 | |-------------------------------------------------------------------------- 7 | | CircularFIFOBuffer.c 8 | |-------------------------------------------------------------------------- 9 | | 10 | | DESCRIPTION: First input, first output circular buffer implementation. 11 | | 12 | | AUTHOR: Ali Ersenal, aliersenal@gmail.com 13 | \------------------------------------------------------------------------*/ 14 | 15 | 16 | #include 17 | #include 18 | #include 19 | 20 | /*======================================================= 21 | STRUCT 22 | =========================================================*/ 23 | 24 | struct CircularFIFOBuffer { 25 | 26 | char* start; 27 | char* end; 28 | char* readPtr; 29 | char* writePtr; 30 | u32int size; 31 | u32int count; 32 | 33 | }; 34 | 35 | /*======================================================= 36 | FUNCTION 37 | =========================================================*/ 38 | 39 | PUBLIC CircularFIFOBuffer* CircularFIFOBuffer_new(u32int size) { 40 | 41 | CircularFIFOBuffer* buffer = HeapMemory_calloc(1, sizeof(CircularFIFOBuffer)); 42 | Debug_assert(buffer); 43 | 44 | buffer->start = HeapMemory_calloc(1, size); 45 | Debug_assert(buffer->start); 46 | 47 | buffer->readPtr = buffer->start; 48 | buffer->writePtr = buffer->start; 49 | buffer->end = buffer->start + size; 50 | buffer->size = size; 51 | buffer->count = 0; 52 | 53 | return buffer; 54 | 55 | } 56 | 57 | PUBLIC void CircularFIFOBuffer_destroy(CircularFIFOBuffer* buf) { 58 | 59 | HeapMemory_free(buf->start); 60 | HeapMemory_free(buf); 61 | 62 | } 63 | 64 | PUBLIC char CircularFIFOBuffer_read(CircularFIFOBuffer* buf) { 65 | 66 | Debug_assert(buf); 67 | 68 | if(buf->count == 0) /* Buffer should not be empty */ 69 | return -1; 70 | 71 | char val = *buf->readPtr; 72 | buf->count--; 73 | buf->readPtr++; 74 | 75 | if (buf->readPtr == buf->end) 76 | buf->readPtr = buf->start; 77 | 78 | return val; 79 | } 80 | 81 | PUBLIC void CircularFIFOBuffer_write(CircularFIFOBuffer* buf, char val) { 82 | 83 | Debug_assert(buf); 84 | Debug_assert(buf->count != buf->size); /* Buffer should not be full */ 85 | 86 | *buf->writePtr = val; 87 | buf->count++; 88 | buf->writePtr++; 89 | 90 | if (buf->writePtr == buf->end) 91 | buf->writePtr = buf->start; 92 | 93 | } -------------------------------------------------------------------------------- /kernel/src/Module.c: -------------------------------------------------------------------------------- 1 | /** 2 | | Copyright(C) 2012 Ali Ersenal 3 | | License: WTFPL v2 4 | | URL: http://sam.zoy.org/wtfpl/COPYING 5 | | 6 | |-------------------------------------------------------------------------- 7 | | Module.c 8 | |-------------------------------------------------------------------------- 9 | | 10 | | DESCRIPTION: Manages OS modules(components). 11 | | 12 | | AUTHOR: Ali Ersenal, aliersenal@gmail.com 13 | \------------------------------------------------------------------------*/ 14 | 15 | 16 | #include 17 | #include 18 | 19 | /*======================================================= 20 | DEFINE 21 | =========================================================*/ 22 | #define MAX_LOADED_MODULES 32 23 | 24 | /*======================================================= 25 | PRIVATE DATA 26 | =========================================================*/ 27 | PRIVATE Module* loadedModules[MAX_LOADED_MODULES]; 28 | PRIVATE u32int numberOfLoadedModules; 29 | 30 | /*======================================================= 31 | FUNCTION 32 | =========================================================*/ 33 | PUBLIC void Module_load(Module* module) { 34 | 35 | /* Check if there is any place in loadedModules */ 36 | Debug_assert(numberOfLoadedModules < MAX_LOADED_MODULES); 37 | 38 | /* Module should not be loaded already */ 39 | Debug_assert(!module->isLoaded); 40 | 41 | /* Module should not share the same ID with another loaded module */ 42 | for(u32int i = 0; i < numberOfLoadedModules; i++) 43 | Debug_assert(loadedModules[i]->moduleID != module->moduleID); 44 | 45 | /* Check dependencies, every dependency needs to be in loadedModules */ 46 | for(u32int i = 0; i < module->numberOfDependencies; i++) { 47 | 48 | bool found = FALSE; 49 | 50 | for(u32int y = 0; y < numberOfLoadedModules; y++) { 51 | 52 | if(module->dependencies[i] == loadedModules[y]->moduleID) { 53 | 54 | found = TRUE; 55 | break; 56 | } 57 | 58 | } 59 | 60 | Debug_assert(found); 61 | } 62 | 63 | /* call initialisation function of module */ 64 | module->init(); 65 | 66 | /* insert in loadedModules */ 67 | loadedModules[numberOfLoadedModules] = module; 68 | module->isLoaded = 1; 69 | numberOfLoadedModules++; 70 | 71 | } 72 | 73 | PUBLIC void Module_getLoadedModuleNames(char** buffer) { 74 | 75 | for(u32int i = 0; i < numberOfLoadedModules; i++) { 76 | 77 | *(buffer + i) = loadedModules[i]->moduleName; 78 | 79 | } 80 | 81 | } 82 | 83 | PUBLIC u32int Module_getNumberOfLoadedModules(void) { 84 | 85 | return numberOfLoadedModules; 86 | 87 | } -------------------------------------------------------------------------------- /user/src/Apps/Calculator.c: -------------------------------------------------------------------------------- 1 | /** 2 | | Copyright(C) 2012 Ali Ersenal 3 | | License: WTFPL v2 4 | | URL: http://sam.zoy.org/wtfpl/COPYING 5 | | 6 | |-------------------------------------------------------------------------- 7 | | Calculator.c 8 | |-------------------------------------------------------------------------- 9 | | 10 | | DESCRIPTION: Dumb(only +,-,*,/) userspace calculator. 11 | | 12 | | AUTHOR: Ali Ersenal, aliersenal@gmail.com 13 | \------------------------------------------------------------------------*/ 14 | 15 | 16 | #include 17 | #include 18 | #include 19 | 20 | static void parseInput(char* entry); 21 | static int add(int x, int y); 22 | static int sub(int x, int y); 23 | static int multp(int x, int y); 24 | static int div(int x, int y); 25 | 26 | int main(void) { 27 | 28 | char c = 0; 29 | char entry[64]; 30 | int i = 0; 31 | 32 | while(1) { 33 | 34 | puts("Input: "); 35 | 36 | while((c = getch()) != '\n' && c != 'e') { 37 | 38 | putc(c); /* Echo input */ 39 | 40 | /* Handle backspace */ 41 | if(c == '\b') { 42 | 43 | i--; 44 | entry[i] = '\0'; 45 | 46 | } else { 47 | 48 | entry[i] = c; 49 | i++; 50 | 51 | } 52 | 53 | } 54 | 55 | if(c == 'e') 56 | break; 57 | 58 | /* Handle enter */ 59 | puts("\nAnswer: "); 60 | entry[i] = '\0'; 61 | i = 0; 62 | parseInput(entry); 63 | putc('\n'); 64 | 65 | } 66 | 67 | exit(0); 68 | } 69 | 70 | static void parseInput(char* entry) { 71 | 72 | char* left = strtok(entry, " "); 73 | char* op = strtok(NULL, " "); 74 | char* right = strtok(NULL, " "); 75 | 76 | int x = atoi(left); 77 | int y = atoi(right); 78 | 79 | switch(op[0]) { 80 | 81 | case '+': 82 | printf("%d", add(x, y)); 83 | break; 84 | 85 | case '-': 86 | printf("%d", sub(x, y)); 87 | break; 88 | 89 | case '*': 90 | printf("%d", multp(x, y)); 91 | break; 92 | 93 | case '/': 94 | printf("%d", div(x, y)); 95 | break; 96 | 97 | } 98 | 99 | } 100 | 101 | static int add(int x, int y) { 102 | 103 | return x + y; 104 | 105 | } 106 | 107 | static int sub(int x, int y) { 108 | 109 | return x - y; 110 | 111 | } 112 | 113 | static int multp(int x, int y) { 114 | 115 | return x * y; 116 | 117 | } 118 | 119 | static int div(int x, int y) { 120 | 121 | return x / y; 122 | 123 | } -------------------------------------------------------------------------------- /kernel/src/FileSystem/Tar.c: -------------------------------------------------------------------------------- 1 | /** 2 | | Copyright(C) 2012 Ali Ersenal 3 | | License: WTFPL v2 4 | | URL: http://sam.zoy.org/wtfpl/COPYING 5 | | 6 | |-------------------------------------------------------------------------- 7 | | Tar.c 8 | |-------------------------------------------------------------------------- 9 | | 10 | | DESCRIPTION: Tar archive parser. 11 | | 12 | | For more info on Tar: 13 | | http://en.wikipedia.org/wiki/Tar_file_format 14 | | 15 | | With thanks to: 16 | | https://github.com/Jezze/fudge 17 | | 18 | | AUTHOR: Ali Ersenal, aliersenal@gmail.com 19 | \------------------------------------------------------------------------*/ 20 | 21 | 22 | #include 23 | #include 24 | #include 25 | 26 | PRIVATE u32int Tar_validateEntry(const TarEntryHeader* header) { 27 | 28 | Debug_assert(header != NULL); 29 | 30 | u8int* address = (u8int*) header; 31 | u32int checksum = String_stringToInt(header->checksum, 8); 32 | 33 | for (u32int i = 0; i < TAR_BLOCK_SIZE; i++) 34 | checksum -= (i >= 148 && i < 156) ? 32 : address[i]; 35 | 36 | return !checksum; 37 | 38 | } 39 | 40 | PUBLIC TarEntryHeader* Tar_nextHeader(const TarEntryHeader* header) { 41 | 42 | Debug_assert(header != NULL); 43 | 44 | u32int fileSize = String_stringToInt(header->fileSize, 8); 45 | u32int address = (u32int) header + (((fileSize / 512) + 1) * 512); 46 | 47 | if (fileSize % 512) 48 | address += 512; 49 | 50 | header = (TarEntryHeader*) address; 51 | 52 | if(Tar_validateEntry(header)) 53 | return (TarEntryHeader*) header; 54 | 55 | return NULL; 56 | 57 | } 58 | 59 | PUBLIC TarEntryHeader* Tar_getHeader(const TarEntryHeader* firstHeader, u32int index) { 60 | 61 | u32int i = 0; 62 | 63 | /* For every file in archive */ 64 | while(TRUE) { 65 | 66 | if (firstHeader->fileName[0] == '\0') 67 | break; 68 | 69 | if(index == i) 70 | return (TarEntryHeader*) firstHeader; 71 | 72 | firstHeader = Tar_nextHeader(firstHeader); 73 | i++; 74 | 75 | if(firstHeader == NULL) 76 | break; 77 | 78 | } 79 | 80 | return NULL; 81 | 82 | } 83 | 84 | PUBLIC u32int Tar_getNumberOfFiles(const TarEntryHeader* firstHeader) { 85 | 86 | Debug_assert(firstHeader != NULL); 87 | 88 | u32int fileCount = 0; 89 | 90 | /* For every file in archive */ 91 | while(TRUE) { 92 | 93 | if (firstHeader->fileName[0] == '\0') 94 | break; 95 | 96 | firstHeader = Tar_nextHeader(firstHeader); 97 | fileCount++; 98 | 99 | if(firstHeader == NULL) 100 | break; 101 | 102 | } 103 | 104 | return fileCount; 105 | 106 | } -------------------------------------------------------------------------------- /kernel/include/Sys.h: -------------------------------------------------------------------------------- 1 | /** 2 | | Copyright(C) 2012 Ali Ersenal 3 | | License: WTFPL v2 4 | | URL: http://sam.zoy.org/wtfpl/COPYING 5 | | 6 | |-------------------------------------------------------------------------- 7 | | Sys.h 8 | |-------------------------------------------------------------------------- 9 | | 10 | | DESCRIPTION: Provides important system functions. 11 | | 12 | | AUTHOR: Ali Ersenal, aliersenal@gmail.com 13 | \------------------------------------------------------------------------*/ 14 | 15 | 16 | #ifndef SYS_H 17 | #define SYS_H 18 | 19 | /*------------------------------------------------------------------------- 20 | | Restart machine 21 | |-------------------------------------------------------------------------- 22 | | DESCRIPTION: Restarts the machine 23 | | 24 | \------------------------------------------------------------------------*/ 25 | void Sys_restart(void); 26 | 27 | /*------------------------------------------------------------------------- 28 | | Shutdown machine 29 | |-------------------------------------------------------------------------- 30 | | DESCRIPTION: Shuts down the machine 31 | | 32 | \------------------------------------------------------------------------*/ 33 | void Sys_powerOff(void); 34 | 35 | /*------------------------------------------------------------------------- 36 | | Kernel panic 37 | |-------------------------------------------------------------------------- 38 | | DESCRIPTION: Throws a kernel panic message, disables interrupts 39 | | and halts the CPU. 40 | | 41 | | PARAM: "str" the panic message 42 | | 43 | | NOTES: System becomes unresponsive after this call. 44 | \------------------------------------------------------------------------*/ 45 | void Sys_panic(const char* str); 46 | 47 | /*------------------------------------------------------------------------- 48 | | Halt CPU 49 | |-------------------------------------------------------------------------- 50 | | DESCRIPTION: Halts the CPU, the system becomes idle. 51 | | 52 | | NOTES: Interrupts wake up the CPU. 53 | \------------------------------------------------------------------------*/ 54 | static inline void Sys_haltCPU(void) { 55 | 56 | /* NOTE: "memory" clobber prevents gcc optimisation(which we don't want) */ 57 | asm volatile("hlt" ::: "memory"); 58 | 59 | } 60 | 61 | /*------------------------------------------------------------------------- 62 | | Enable/Disable interrupts 63 | |------------------------------------------------------------------------*/ 64 | static inline void Sys_enableInterrupts(void) { 65 | 66 | /* NOTE: "memory" clobber prevents gcc optimisation(which we don't want) */ 67 | asm volatile("sti" ::: "memory"); 68 | 69 | } 70 | 71 | static inline void Sys_disableInterrupts(void) { 72 | 73 | /* NOTE: "memory" clobber prevents gcc optimisation(which we don't want) */ 74 | asm volatile("cli" ::: "memory"); 75 | 76 | } 77 | 78 | #endif 79 | -------------------------------------------------------------------------------- /kernel/include/Debug.h: -------------------------------------------------------------------------------- 1 | /** 2 | | Copyright(C) 2012 Ali Ersenal 3 | | License: WTFPL v2 4 | | URL: http://sam.zoy.org/wtfpl/COPYING 5 | | 6 | |-------------------------------------------------------------------------- 7 | | Debug.h 8 | |-------------------------------------------------------------------------- 9 | | 10 | | DESCRIPTION: Provides macro functions for printing debug messages. 11 | | 12 | | 13 | | AUTHOR: Ali Ersenal, aliersenal@gmail.com 14 | \------------------------------------------------------------------------*/ 15 | 16 | 17 | #ifndef DEBUG_H 18 | #define DEBUG_H 19 | 20 | #include 21 | #include 22 | 23 | 24 | #ifdef NO_DEBUG 25 | 26 | #define Debug_logError(M, ...) 27 | #define Debug_logWarning(M, ...) 28 | #define Debug_logInfo(M, ...) 29 | #define Debug_assert(C) ((void) (C)) 30 | 31 | #else 32 | 33 | /*------------------------------------------------------------------------- 34 | | Debug Logging 35 | |-------------------------------------------------------------------------- 36 | | 37 | | PARAM: M printf template(refer to Console.h) 38 | | ... printf tokens 39 | | 40 | | EXAMPLE: Debug_logInfo("%s%d", "Debug info test", 0x1); 41 | \------------------------------------------------------------------------*/ 42 | #define Debug_logError(M, ...) Console_setColor(CONSOLE_ERROR); \ 43 | Console_printf("%s%s%c%d%s"M, "[ERROR] ", __FILE__, ':', __LINE__, " -> ", ##__VA_ARGS__); \ 44 | Console_setColor(CONSOLE_NORMAL); \ 45 | Console_printChar('\n') 46 | 47 | #define Debug_logWarning(M, ...) Console_setColor(CONSOLE_WARN); \ 48 | Console_printf("%s%s%c%d%s"M, "[WARN] ", __FILE__, ':', __LINE__, " -> ", ##__VA_ARGS__); \ 49 | Console_setColor(CONSOLE_NORMAL); \ 50 | Console_printChar('\n') 51 | 52 | #define Debug_logInfo(M, ...) Console_setColor(CONSOLE_INFO); \ 53 | Console_printf("%s%s%c%d%s"M, "[INFO] ", __FILE__, ':', __LINE__, " -> ", ##__VA_ARGS__); \ 54 | Console_setColor(CONSOLE_NORMAL); \ 55 | Console_printChar('\n') 56 | 57 | /*------------------------------------------------------------------------- 58 | | Assertion 59 | |-------------------------------------------------------------------------- 60 | | 61 | | DESCRIPTION: Kernel panic if the condition "C" is NOT true 62 | | 63 | | PARAM: C condition 64 | | 65 | | EXAMPLE: Debug_assert(index <= lastIndex) 66 | \------------------------------------------------------------------------*/ 67 | #define Debug_assert(C) if(!(C)) {Debug_logError(""); Sys_panic("Assert failure!");} 68 | 69 | #endif 70 | 71 | #endif 72 | -------------------------------------------------------------------------------- /kernel/include/Drivers/VGA.h: -------------------------------------------------------------------------------- 1 | /** 2 | | Copyright(C) 2012 Ali Ersenal 3 | | License: WTFPL v2 4 | | URL: http://sam.zoy.org/wtfpl/COPYING 5 | | 6 | |-------------------------------------------------------------------------- 7 | | VGA.h 8 | |-------------------------------------------------------------------------- 9 | | 10 | | DESCRIPTION: VGA text-mode buffer driver. 11 | | 12 | | AUTHOR: Ali Ersenal, aliersenal@gmail.com 13 | \------------------------------------------------------------------------*/ 14 | 15 | 16 | /** VGA 80x25 16-color text mode */ 17 | #ifndef VGA_H 18 | #define VGA_H 19 | 20 | #include 21 | #include 22 | #include 23 | 24 | /*======================================================= 25 | DEFINE 26 | =========================================================*/ 27 | #define CRTC_SELECT 0x3D4 28 | #define CRTC_MODIFY 0x3D5 29 | 30 | /*======================================================= 31 | PUBLIC DATA 32 | =========================================================*/ 33 | extern char* vgaRam; 34 | extern u8int vgaHeight; 35 | extern u8int vgaWidth; 36 | 37 | /*======================================================= 38 | FUNCTION 39 | =========================================================*/ 40 | 41 | /*------------------------------------------------------------------------- 42 | | Get VGA module 43 | |-------------------------------------------------------------------------- 44 | | DESCRIPTION: Returns the VGA module. 45 | | 46 | \------------------------------------------------------------------------*/ 47 | Module* VGA_getModule(void); 48 | 49 | /*------------------------------------------------------------------------- 50 | | Put character 51 | |-------------------------------------------------------------------------- 52 | | DESCRIPTION: Puts a character in text buffer 53 | | 54 | | PARAM: "index" buffer offset 55 | | "data" two-byte data representing color and character 56 | | higher byte is color attribute 57 | | lower byte is the character itself 58 | \------------------------------------------------------------------------*/ 59 | static inline void VGA_put(u16int index, u16int data) { 60 | 61 | *((u16int*) vgaRam + index) = data; 62 | 63 | } 64 | 65 | /*------------------------------------------------------------------------- 66 | | Move cursor 67 | |-------------------------------------------------------------------------- 68 | | DESCRIPTION: Moves the text-mode cursor to specified offset. 69 | | 70 | | PARAM: "cursorLoc" buffer offset 71 | \------------------------------------------------------------------------*/ 72 | static inline void VGA_moveCursor(u16int cursorLoc) { 73 | 74 | /* Select register 14 */ 75 | IO_outB(CRTC_SELECT, 14); 76 | /* Modify register 14 */ 77 | IO_outB(CRTC_MODIFY, cursorLoc >> 8); /* Send low byte */ 78 | 79 | /* Select register 15 */ 80 | IO_outB(CRTC_SELECT, 15); 81 | /* Modify register 15 */ 82 | IO_outB(CRTC_MODIFY, cursorLoc); /* Send high byte */ 83 | 84 | } 85 | 86 | #endif -------------------------------------------------------------------------------- /kernel/include/IO.h: -------------------------------------------------------------------------------- 1 | /** 2 | | Copyright(C) 2012 Ali Ersenal 3 | | License: WTFPL v2 4 | | URL: http://sam.zoy.org/wtfpl/COPYING 5 | | 6 | |-------------------------------------------------------------------------- 7 | | IO.h 8 | |-------------------------------------------------------------------------- 9 | | 10 | | DESCRIPTION: Provides functions to read/write I/O ports. 11 | | 12 | | 13 | | AUTHOR: Ali Ersenal, aliersenal@gmail.com 14 | \------------------------------------------------------------------------*/ 15 | 16 | 17 | #ifndef IO_H 18 | #define IO_H 19 | 20 | #include 21 | 22 | /*======================================================= 23 | DEFINE 24 | =========================================================*/ 25 | 26 | /* Serial I/O ports */ 27 | #define COM1 0x3F8 28 | #define COM2 0x2F8 29 | #define COM3 0x3E8 30 | #define COM4 0x2E8 31 | 32 | /*======================================================= 33 | FUNCTION 34 | =========================================================*/ 35 | 36 | /*------------------------------------------------------------------------- 37 | | I/O Write 38 | |-------------------------------------------------------------------------- 39 | | DESCRIPTION: Writes n bytes to specified I/O port. 40 | | 41 | | PARAM: "port" port to write 42 | | "value" value to be written 43 | | 44 | | NOTES: outL n = 4 45 | | outW n = 2 46 | | outB n = 1 47 | \------------------------------------------------------------------------*/ 48 | static inline void IO_outB(u16int port, u8int value) { 49 | 50 | asm volatile ("outb %1, %0" : : "dN" (port), "a" (value)); 51 | 52 | } 53 | 54 | static inline void IO_outW(u16int port, u16int value) { 55 | 56 | asm volatile ("outw %1, %0" : : "dN" (port), "a" (value)); 57 | 58 | } 59 | 60 | static inline void IO_outL(u16int port, u32int value) { 61 | 62 | asm volatile ("outl %1, %0" : : "dN" (port), "a" (value)); 63 | 64 | } 65 | 66 | /*------------------------------------------------------------------------- 67 | | I/O Read 68 | |-------------------------------------------------------------------------- 69 | | DESCRIPTION: Reads n bytes from specified I/O port. 70 | | 71 | | PARAM: "port" port to read 72 | | 73 | | RETURN: n bytes 74 | | 75 | | NOTES: inL n = 4 76 | | inW n = 2 77 | | inB n = 1 78 | \------------------------------------------------------------------------*/ 79 | static inline u8int IO_inB(u16int port) { 80 | 81 | u8int ret; 82 | asm volatile("inb %1, %0" : "=a" (ret) : "dN" (port)); 83 | return ret; 84 | 85 | } 86 | 87 | static inline u16int IO_inW(u16int port) { 88 | 89 | u16int ret; 90 | asm volatile("inw %1, %0" : "=a" (ret) : "dN" (port)); 91 | return ret; 92 | 93 | } 94 | 95 | static inline u32int IO_inL(u16int port) { 96 | 97 | u32int ret; 98 | asm volatile("inl %1, %0" : "=a" (ret) : "dN" (port)); 99 | return ret; 100 | 101 | } 102 | 103 | #endif 104 | -------------------------------------------------------------------------------- /kernel/include/Memory/DumbHeapManager.h: -------------------------------------------------------------------------------- 1 | /** 2 | | Copyright(C) 2012 Ali Ersenal 3 | | License: WTFPL v2 4 | | URL: http://sam.zoy.org/wtfpl/COPYING 5 | | 6 | |-------------------------------------------------------------------------- 7 | | DumbHeapManager.h (implements HeapMemory) 8 | |-------------------------------------------------------------------------- 9 | | 10 | | DESCRIPTION: A useless heap manager implementation, only supports malloc. 11 | | 12 | | AUTHOR: Ali Ersenal, aliersenal@gmail.com 13 | \------------------------------------------------------------------------*/ 14 | 15 | 16 | #ifndef DHM_H 17 | #define DHM_H 18 | 19 | #include 20 | #include 21 | 22 | /*------------------------------------------------------------------------- 23 | | Heap allocation 24 | |-------------------------------------------------------------------------- 25 | | DESCRIPTION: Allocates "bytes" number of bytes of space in heap 26 | | and returns the allocated address. 27 | | 28 | | PARAM: "bytes" number of bytes to allocate 29 | | 30 | | RETURN: void* pointer to allocated space 31 | | 32 | \------------------------------------------------------------------------*/ 33 | void* DumbHeapManager_malloc(size_t bytes); 34 | 35 | /*------------------------------------------------------------------------- 36 | | Heap reallocation (Not implemented) 37 | |-------------------------------------------------------------------------- 38 | | DESCRIPTION: Reallocates the given memory block to a new block of 39 | | size "bytes". 40 | | 41 | | PARAM: "oldmem" pointer to old memory block 42 | | "bytes" new size of memory block in bytes 43 | | 44 | | RETURN: void* pointer to reallocated space 45 | | 46 | \------------------------------------------------------------------------*/ 47 | void* DumbHeapManager_realloc(void* oldmem, size_t bytes); 48 | 49 | /*------------------------------------------------------------------------- 50 | | Heap clear allocation (Not implemented) 51 | |-------------------------------------------------------------------------- 52 | | DESCRIPTION: Allocates an array of "numberOfElements" elements and 53 | | sets all bits as zero. Each element has "elementSize" 54 | | length. 55 | | 56 | | PARAM: "numberOfElements" number of elements to be allocated 57 | | "elementSize" size of an element in bytes 58 | | 59 | | RETURN: void* pointer to cleared and allocated space 60 | | 61 | \------------------------------------------------------------------------*/ 62 | void* DumbHeapManager_calloc(size_t numberOfElements, size_t elementSize); 63 | 64 | /*------------------------------------------------------------------------- 65 | | Heap free (Not implemented) 66 | |-------------------------------------------------------------------------- 67 | | DESCRIPTION: Deallocates the specified memory block. 68 | | 69 | | PARAM: "mem" pointer to memory block 70 | \------------------------------------------------------------------------*/ 71 | void DumbHeapManager_free(void* mem); 72 | 73 | #endif -------------------------------------------------------------------------------- /kernel/include/Module.h: -------------------------------------------------------------------------------- 1 | /** 2 | | Copyright(C) 2012 Ali Ersenal 3 | | License: WTFPL v2 4 | | URL: http://sam.zoy.org/wtfpl/COPYING 5 | | 6 | |-------------------------------------------------------------------------- 7 | | Module.h 8 | |-------------------------------------------------------------------------- 9 | | 10 | | DESCRIPTION: Manages OS modules(components). 11 | | 12 | | AUTHOR: Ali Ersenal, aliersenal@gmail.com 13 | \------------------------------------------------------------------------*/ 14 | 15 | 16 | #ifndef MODULE_H 17 | #define MODULE_H 18 | 19 | #include 20 | 21 | /*======================================================= 22 | DEFINE 23 | =========================================================*/ 24 | #define MAX_MODULE_DEPENDENCY 8 25 | 26 | /* Module IDs */ 27 | #define MODULE_VGA 100 28 | #define MODULE_CONSOLE 101 29 | #define MODULE_GDT 102 30 | #define MODULE_IDT 103 31 | #define MODULE_PIC8259 104 32 | #define MODULE_PIT8253 105 33 | #define MODULE_PMM 106 34 | #define MODULE_VMM 107 35 | #define MODULE_HEAP 108 36 | #define MODULE_PROCESS 109 37 | #define MODULE_PS2 110 38 | #define MODULE_VFS 111 39 | #define MODULE_USERMODE 112 40 | 41 | /*======================================================= 42 | STRUCT 43 | =========================================================*/ 44 | typedef struct Module Module; 45 | 46 | struct Module { 47 | 48 | void (*init) (void); 49 | bool isLoaded; 50 | char* moduleName; 51 | u32int moduleID; 52 | u32int dependencies[MAX_MODULE_DEPENDENCY]; 53 | u32int numberOfDependencies; 54 | 55 | }; 56 | 57 | /*======================================================= 58 | FUNCTION 59 | =========================================================*/ 60 | 61 | /*------------------------------------------------------------------------- 62 | | Load module 63 | |-------------------------------------------------------------------------- 64 | | DESCRIPTION: Loads a given module. 65 | | 66 | | PARAM: "module" the module to load 67 | \------------------------------------------------------------------------*/ 68 | void Module_load(Module* module); 69 | 70 | /*------------------------------------------------------------------------- 71 | | Get loaded module names 72 | |-------------------------------------------------------------------------- 73 | | DESCRIPTION: Fills the specified char* array with loaded module 74 | | names. 75 | | 76 | | PARAM: "buffer" the buffer to store module names 77 | \------------------------------------------------------------------------*/ 78 | void Module_getLoadedModuleNames(char** buffer); 79 | 80 | /*------------------------------------------------------------------------- 81 | | Get number of loaded modules 82 | |-------------------------------------------------------------------------- 83 | | DESCRIPTION: Returns the number of loaded modules 84 | | 85 | | RETURN: "u32int" the number of loaded modules 86 | \------------------------------------------------------------------------*/ 87 | u32int Module_getNumberOfLoadedModules(void); 88 | 89 | #endif -------------------------------------------------------------------------------- /kernel/include/X86/CPU.h: -------------------------------------------------------------------------------- 1 | /** 2 | | Copyright(C) 2012 Ali Ersenal 3 | | License: WTFPL v2 4 | | URL: http://sam.zoy.org/wtfpl/COPYING 5 | | 6 | |-------------------------------------------------------------------------- 7 | | CPU.h 8 | |-------------------------------------------------------------------------- 9 | | 10 | | DESCRIPTION: Provides functions to alter or retrieve CPU control 11 | | registers. Control registers(CR0..CR4) control the general 12 | | function of CPU. 13 | | 14 | | EXAMPLE: You may use FORCE_CAST(refer to Common.h) to modify 15 | | or read the control registers: 16 | | 17 | | u32int tmp = CPU_getCR(0); 18 | | CR0 cr0 = FORCE_CAST(tmp, CR0); 19 | | cr0.PG = 1; 20 | | CPU_setCR(0, FORCE_CAST(cr0, u32int)); 21 | | 22 | | NOTES: Control registers are 32-bit registers(on X86-32). 23 | | 24 | | AUTHOR: Ali Ersenal, aliersenal@gmail.com 25 | \------------------------------------------------------------------------*/ 26 | 27 | 28 | #ifndef CPU_H 29 | #define CPU_H 30 | 31 | #include 32 | 33 | /*======================================================= 34 | STRUCT 35 | =========================================================*/ 36 | typedef struct CR0 CR0; 37 | typedef struct CR3 CR3; 38 | 39 | struct CR0 { 40 | 41 | u8int PE : 1; /* 0: real mode, 1: protected mode */ 42 | u8int MP : 1; /* Monitor co-processor */ 43 | u8int EM : 1; /* 0: x87 FPU present, 1: x87 FPU NOT present */ 44 | u8int TS : 1; /* Task switched */ 45 | u8int ET : 1; /* Extension type */ 46 | u8int NE : 1; /* Numeric error */ 47 | u16int : 10; 48 | u8int WP : 1; /* Write protect */ 49 | u8int : 1; 50 | u8int AM : 1; /* Alignment mask */ 51 | u16int : 10; 52 | u8int NW : 1; /* Enable/Disable write-back caching */ 53 | u8int CD : 1; /* Enable/Disable memory cache */ 54 | u8int PG : 1; /* 0: disable paging, 1: enable paging */ 55 | 56 | } __attribute__((packed)); 57 | 58 | struct CR3 { 59 | 60 | u16int : 12; 61 | u32int PDBR : 20; /* Page directory base register */ 62 | 63 | } __attribute__((packed)); 64 | 65 | /*======================================================= 66 | FUNCTION 67 | =========================================================*/ 68 | 69 | /*------------------------------------------------------------------------- 70 | | Get control register n(0..4) 71 | |-------------------------------------------------------------------------- 72 | | DESCRIPTION: Returns the contents of the specified control register. 73 | | 74 | | PARAM: "n" "n"th control register 75 | | 76 | | PRECONDITION: "n" needs to be 1..4 77 | | 78 | | RETURN: u32int contents of the "n"th control register 79 | \------------------------------------------------------------------------*/ 80 | u32int CPU_getCR(u8int n); 81 | 82 | /*------------------------------------------------------------------------- 83 | | Set control register n(0..4) 84 | |-------------------------------------------------------------------------- 85 | | DESCRIPTION: Alters the contents of the specified control register. 86 | | 87 | | PARAM: "n" "n"th control register 88 | | "val" new contents of the "n"th control register 89 | | 90 | | PRECONDITION: "n" needs to be 1..4 91 | \------------------------------------------------------------------------*/ 92 | void CPU_setCR(u8int n, u32int val); 93 | #endif -------------------------------------------------------------------------------- /kernel/include/Process/Scheduler.h: -------------------------------------------------------------------------------- 1 | /** 2 | | Copyright(C) 2012 Ali Ersenal 3 | | License: WTFPL v2 4 | | URL: http://sam.zoy.org/wtfpl/COPYING 5 | | 6 | |-------------------------------------------------------------------------- 7 | | Scheduler.h 8 | |-------------------------------------------------------------------------- 9 | | 10 | | DESCRIPTION: Process scheduler interface. 11 | | 12 | | AUTHOR: Ali Ersenal, aliersenal@gmail.com 13 | \------------------------------------------------------------------------*/ 14 | 15 | 16 | #ifndef SCHEDULER_H 17 | #define SCHEDULER_H 18 | 19 | #include 20 | 21 | /*======================================================= 22 | INTERFACE 23 | =========================================================*/ 24 | 25 | /*------------------------------------------------------------------------- 26 | | Add process 27 | |-------------------------------------------------------------------------- 28 | | DESCRIPTION: Adds a new process to scheduler's process list. 29 | | 30 | | PARAM: 'process' the process to add 31 | \------------------------------------------------------------------------*/ 32 | extern void (*Scheduler_addProcess) (Process* process); 33 | 34 | /*------------------------------------------------------------------------- 35 | | Remove process 36 | |-------------------------------------------------------------------------- 37 | | DESCRIPTION: Removes a process from scheduler's process list. 38 | | 39 | | PARAM: 'process' the process to remove 40 | \------------------------------------------------------------------------*/ 41 | extern void (*Scheduler_removeProcess) (Process* process); 42 | 43 | /*------------------------------------------------------------------------- 44 | | Get next process 45 | |-------------------------------------------------------------------------- 46 | | DESCRIPTION: Returns the next process to be switched to 47 | | 48 | | RETURN: 'Process*' the next process 49 | \------------------------------------------------------------------------*/ 50 | extern Process* (*Scheduler_getNextProcess) (void); 51 | 52 | /*------------------------------------------------------------------------- 53 | | Get current process 54 | |-------------------------------------------------------------------------- 55 | | DESCRIPTION: Returns the current process. 56 | | 57 | | RETURN: 'Process*' the current process 58 | \------------------------------------------------------------------------*/ 59 | extern Process* (*Scheduler_getCurrentProcess) (void); 60 | 61 | /*======================================================= 62 | FUNCTION 63 | =========================================================*/ 64 | 65 | /*------------------------------------------------------------------------- 66 | | Initialise Scheduler 67 | |-------------------------------------------------------------------------- 68 | | DESCRIPTION: Initialises the Scheduler. 69 | | 70 | \------------------------------------------------------------------------*/ 71 | void Scheduler_init(void); 72 | 73 | /*------------------------------------------------------------------------- 74 | | Is Scheduler preemptive? 75 | |-------------------------------------------------------------------------- 76 | | RETURN: true if scheduler is preemptive. 77 | | false if secheduler is NOT preemptive. 78 | | 79 | \------------------------------------------------------------------------*/ 80 | bool Scheduler_isPreemptive(void); 81 | 82 | #endif -------------------------------------------------------------------------------- /user/src/Lib/libc/stdio.c: -------------------------------------------------------------------------------- 1 | /* musl as a whole is licensed under the following standard MIT license: 2 | 3 | Copyright © 2005-2013 Rich Felker 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining 6 | a copy of this software and associated documentation files (the 7 | "Software"), to deal in the Software without restriction, including 8 | without limitation the rights to use, copy, modify, merge, publish, 9 | distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so, subject to 11 | the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be 14 | included in all copies or substantial portions of the Software. */ 15 | 16 | #include 17 | #include 18 | #include /* we need var-args for printf */ 19 | 20 | /* Borrowed from musl libc */ 21 | int isspace(int c) 22 | { 23 | return c == ' ' || (unsigned)c-'\t' < 5; 24 | } 25 | 26 | /* Borrowed from musl libc */ 27 | int isdigit(int c) 28 | { 29 | return (unsigned)c-'0' < 10; 30 | } 31 | 32 | /* Borrowed from musl libc */ 33 | int atoi(const char *s) 34 | { 35 | int n=0, neg=0; 36 | while (isspace(*s)) s++; 37 | switch (*s) { 38 | case '-': neg=1; 39 | case '+': s++; 40 | } 41 | /* Compute n as a negative number to avoid overflow on INT_MIN */ 42 | while (isdigit(*s)) 43 | n = 10*n - (*s++ - '0'); 44 | return neg ? n : -n; 45 | } 46 | 47 | /* Borrowed from musl libc */ 48 | long atol(const char *s) 49 | { 50 | long n=0; 51 | int neg=0; 52 | while (isspace(*s)) s++; 53 | switch (*s) { 54 | case '-': neg=1; 55 | case '+': s++; 56 | } 57 | /* Compute n as a negative number to avoid overflow on LONG_MIN */ 58 | while (isdigit(*s)) 59 | n = 10*n - (*s++ - '0'); 60 | return neg ? n : -n; 61 | } 62 | 63 | char* itoa(int val, int base) { 64 | 65 | static char buf[32] = {0}; 66 | 67 | if(val == 0) { 68 | buf[0] = '0'; 69 | buf[1] = '\0'; 70 | return buf; 71 | } 72 | 73 | unsigned char isNegative = val < 0; 74 | if(isNegative) val = val * -1; 75 | int i = 30; 76 | 77 | while(val && i) { 78 | 79 | buf[i] = "0123456789abcdef"[val % base]; 80 | i--; 81 | val /= base; 82 | 83 | } 84 | 85 | if(isNegative) { 86 | buf[i] = '-'; 87 | return &buf[i]; 88 | } 89 | 90 | return &buf[i+1]; 91 | } 92 | 93 | void printf(const char* template, ...) { 94 | 95 | va_list args; 96 | va_start(args, template); 97 | 98 | while(*(template) != '\0') { 99 | 100 | if(*template == '%') { 101 | switch(*(template + 1)) { 102 | 103 | case 'a': 104 | color(va_arg(args, int)); 105 | break; 106 | 107 | case 'd': 108 | puts(itoa(va_arg(args, int), 10)); 109 | break; 110 | 111 | case 'h': 112 | puts(itoa(va_arg(args, int), 16)); 113 | break; 114 | 115 | case 'c': 116 | putc(va_arg(args, int)); 117 | break; 118 | 119 | case 's': 120 | puts(va_arg(args, char*)); 121 | break; 122 | } 123 | } 124 | 125 | template++; 126 | } 127 | 128 | va_end(args); 129 | } 130 | -------------------------------------------------------------------------------- /kernel/src/Memory/StackPMM.c: -------------------------------------------------------------------------------- 1 | /** 2 | | Copyright(C) 2012 Ali Ersenal 3 | | License: WTFPL v2 4 | | URL: http://sam.zoy.org/wtfpl/COPYING 5 | | 6 | |-------------------------------------------------------------------------- 7 | | StackPMM.c (implements PhysicalMemory) 8 | |-------------------------------------------------------------------------- 9 | | 10 | | DESCRIPTION: Stack based physical memory manager implementation. 11 | | 12 | | AUTHOR: Ali Ersenal, aliersenal@gmail.com 13 | \------------------------------------------------------------------------*/ 14 | 15 | 16 | #include 17 | #include 18 | #include 19 | #include 20 | 21 | 22 | /*======================================================= 23 | PRIVATE DATA 24 | =========================================================*/ 25 | PRIVATE u32int totalPhysicalMemory; 26 | PRIVATE u32int totalFrames; 27 | PRIVATE Stack stack; 28 | 29 | /*======================================================= 30 | FUNCTION 31 | =========================================================*/ 32 | 33 | PUBLIC void* StackPMM_allocateFrame(void) { 34 | 35 | if(stack.size == 0) /* out of memory */ 36 | return NULL; 37 | 38 | void* frame = Stack_pop(&stack); 39 | return frame; 40 | } 41 | 42 | PUBLIC void StackPMM_freeFrame(void* b) { 43 | 44 | Debug_assert(b != NULL && (u32int) b % FRAME_SIZE == 0); 45 | Stack_push(&stack, b); 46 | 47 | } 48 | 49 | PUBLIC void StackPMM_init(void) { 50 | 51 | extern MultibootHeader mbHead; /* Defined in Start.s */ 52 | extern MultibootInfo* multibootInfo; /* Defined in Kernel.c */ 53 | 54 | MultibootMemEntry* entry = (MultibootMemEntry*) multibootInfo->mmapAddr; 55 | u32int initrdEnd = *(u32int*)(multibootInfo->modsAddr + 4); 56 | u32int kernelEnd = mbHead.bssEndAddr; 57 | 58 | if(initrdEnd != 0) 59 | kernelEnd = initrdEnd; 60 | 61 | /* calculate total physical memory */ 62 | while((u32int) entry < multibootInfo->mmapAddr + multibootInfo->mmapLength) { 63 | 64 | totalPhysicalMemory += entry->len; 65 | entry++; 66 | 67 | } 68 | 69 | totalFrames = totalPhysicalMemory / FRAME_SIZE; /* total number of frames = physical memory / 4kB */ 70 | Stack_init(&stack, (char*) kernelEnd, totalFrames * sizeof(void *)); 71 | entry = (MultibootMemEntry*) multibootInfo->mmapAddr; 72 | 73 | /* Push usable frames to stack */ 74 | while((u32int) entry < multibootInfo->mmapAddr + multibootInfo->mmapLength) { 75 | 76 | if(entry->type == MULTIBOOT_MEMORY_AVAILABLE) { 77 | 78 | u32int numberOfFrames = entry->len / FRAME_SIZE; 79 | 80 | for(u32int i = 0; i < numberOfFrames; i++) { 81 | 82 | void* frameAddr = (void*) (u32int) entry->addr + (i * FRAME_SIZE); 83 | 84 | /* Frame 0(Starting at address 0) + Kernel + PMM stack is reserved */ 85 | if(frameAddr != NULL && (frameAddr < (void*) mbHead.loadAddr || frameAddr > (void*) kernelEnd + totalFrames * sizeof(void *))) 86 | StackPMM_freeFrame(frameAddr); 87 | 88 | } 89 | 90 | } 91 | 92 | entry++; 93 | } 94 | 95 | } 96 | 97 | PUBLIC PhysicalMemoryInfo* StackPMM_getInfo(PhysicalMemoryInfo* buf) { 98 | 99 | buf->totalMemory = totalPhysicalMemory; 100 | buf->totalFrames = totalFrames; 101 | buf->freeFrames = stack.size; 102 | 103 | return buf; 104 | 105 | } -------------------------------------------------------------------------------- /user/include/Lib/Incitatus.h: -------------------------------------------------------------------------------- 1 | /** 2 | | Copyright(C) 2012 Ali Ersenal 3 | | License: WTFPL v2 4 | | URL: http://sam.zoy.org/wtfpl/COPYING 5 | | 6 | |-------------------------------------------------------------------------- 7 | | Incitatus.h 8 | |-------------------------------------------------------------------------- 9 | | 10 | | DESCRIPTION: User-space system call library. 11 | | 12 | | AUTHOR: Ali Ersenal, aliersenal@gmail.com 13 | \------------------------------------------------------------------------*/ 14 | 15 | 16 | #ifndef INCITATUS_H 17 | #define INCITATUS_H 18 | 19 | /*======================================================= 20 | STRUCT 21 | =========================================================*/ 22 | 23 | struct stat { 24 | 25 | char fileName[128]; /* The file name */ 26 | unsigned int index; /* Index of the node in a specific device*/ 27 | unsigned int permission; /* rwx Permission mask similar to Unix systems (for example 644, 777, etc.) */ 28 | unsigned int mode; /* 0 = file is not open, 1 = read mode, 2 = write mode */ 29 | unsigned int uid; /* Owner id */ 30 | unsigned int gid; /* Group id */ 31 | unsigned int fileType; /* Directory, normal, link, etc. */ 32 | unsigned int fileSize; /* Size of the file in bytes */ 33 | void* vfs; /* File system this node belongs to */ 34 | void** ptr; /* Used by mountpoints and symlinks */ 35 | 36 | }; 37 | 38 | /*======================================================= 39 | DEFINE 40 | =========================================================*/ 41 | #define SYSCALL_PUTS 0 42 | #define SYSCALL_PUTC 1 43 | #define SYSCALL_EXIT 2 44 | #define SYSCALL_SPAWN 3 45 | #define SYSCALL_FCHDIR 4 46 | #define SYSCALL_FPARENT 5 47 | #define SYSCALL_GETCWD 6 48 | #define SYSCALL_READDIR 7 49 | #define SYSCALL_FGETCWD 8 50 | #define SYSCALL_FSTAT 9 51 | #define SYSCALL_GETCH 10 52 | #define SYSCALL_CLS 11 53 | #define SYSCALL_RESTART 12 54 | #define SYSCALL_OPEN 13 55 | #define SYSCALL_CLOSE 14 56 | #define SYSCALL_READ 15 57 | #define SYSCALL_WRITE 16 58 | #define SYSCALL_MKDIR 17 59 | #define SYSCALL_SBRK 18 60 | #define SYSCALL_FINDDIR 19 61 | #define SYSCALL_CHDIR 20 62 | #define SYSCALL_SETCOLOR 21 63 | #define SYSCALL_POWEROFF 22 64 | #define SYSCALL_WAITPID 23 65 | 66 | #define FILE int 67 | 68 | /*======================================================= 69 | FUNCTION 70 | =========================================================*/ 71 | void puts(const char* str); 72 | void putc(char c); 73 | void exit(int exitCode); 74 | int spawn(const char* binary); 75 | FILE* readdir(FILE* fd, int index); 76 | FILE* finddir(FILE* fs, const char* childname); 77 | FILE* fchdir(FILE* fd); 78 | FILE* chdir(const char* dir); 79 | FILE* fparent(FILE* fd); 80 | FILE* fgetcwd(void); 81 | void fstat(FILE* fd, struct stat* buf); 82 | char* getcwd(char* buf); 83 | char getch(void); 84 | void cls(void); 85 | void restart(void); 86 | void poweroff(void); 87 | FILE* open(const char* path, const char* mode); 88 | void close(FILE* file); 89 | unsigned int read(FILE* file, unsigned int offset, unsigned int count, char* buffer); 90 | unsigned int write(FILE* file, unsigned int offset, unsigned int count, const char* buffer); 91 | FILE* mkdir(const char* pathname); 92 | void* sbrk(int size); 93 | void color(unsigned int attr); 94 | void waitpid(int pid); 95 | #endif -------------------------------------------------------------------------------- /kernel/src/Lib/String.c: -------------------------------------------------------------------------------- 1 | /** 2 | | Copyright(C) 2012 Ali Ersenal 3 | | License: WTFPL v2 4 | | URL: http://sam.zoy.org/wtfpl/COPYING 5 | | 6 | |-------------------------------------------------------------------------- 7 | | String.c 8 | |-------------------------------------------------------------------------- 9 | | 10 | | DESCRIPTION: String related functions. 11 | | 12 | | AUTHOR: Ali Ersenal, aliersenal@gmail.com 13 | \------------------------------------------------------------------------*/ 14 | 15 | 16 | #include 17 | #include 18 | 19 | PUBLIC bool String_startsWith(const char* self, const char* prefix) { 20 | 21 | int prefixLen = String_length(prefix); 22 | 23 | for(int i = 0; i < prefixLen; i++) { 24 | 25 | if(*(self + i) == *(prefix + i)) 26 | continue; 27 | else 28 | return FALSE; 29 | } 30 | 31 | return TRUE; 32 | } 33 | 34 | PUBLIC bool String_endsWith(const char* self, const char* suffix) { 35 | 36 | int suffixLen = String_length(suffix); 37 | int selfLen = String_length(self); 38 | int y = 0; 39 | 40 | for(int i = selfLen - suffixLen; i < selfLen ; i++, y++) { 41 | 42 | if(*(self + i) == *(suffix + y)) 43 | continue; 44 | else 45 | return FALSE; 46 | } 47 | 48 | return TRUE; 49 | } 50 | 51 | PUBLIC char String_charAt(const char* self, int index) { 52 | 53 | return *(self + index); 54 | 55 | } 56 | 57 | PUBLIC u32int String_length(const char* string) { 58 | 59 | u32int len = 0; 60 | while(*string++ != '\0') len++; 61 | return len; 62 | } 63 | 64 | PUBLIC int String_charToInt(char c) { 65 | 66 | return c - '0'; 67 | 68 | } 69 | 70 | PUBLIC u32int String_stringToInt(const char* str, u32int base) { 71 | 72 | const char* ip; 73 | u32int num = 0; 74 | 75 | for (ip = str; (*ip >= '0' && *ip <= '9') || (base > 10 && (*ip >= 'a' && *ip <= 'f')); ip++) { 76 | 77 | u32int offset = (*ip > '9') ? *ip - 'a' + 10 : *ip - '0'; 78 | num = num * base + offset; 79 | 80 | } 81 | 82 | return num; 83 | 84 | } 85 | 86 | PUBLIC char* String_numberToString(int val, int base) { 87 | 88 | static char buf[32] = {0}; 89 | 90 | if(val == 0) { 91 | buf[0] = '0'; 92 | buf[1] = '\0'; 93 | return buf; 94 | } 95 | 96 | bool isNegative = val < 0; 97 | if(isNegative) val = val * -1; 98 | int i = 30; 99 | 100 | while(val && i) { 101 | 102 | buf[i] = "0123456789abcdef"[val % base]; 103 | i--; 104 | val /= base; 105 | 106 | } 107 | 108 | if(isNegative) { 109 | buf[i] = '-'; 110 | return &buf[i]; 111 | } 112 | 113 | return &buf[i+1]; 114 | } 115 | 116 | /* Borrowed from: http://git.musl-libc.org/cgit/musl/tree/src/string/strcpy.c */ 117 | PUBLIC char* String_copy(char* restrict dest, const char* restrict src) { 118 | 119 | const u8int* s = (u8int*) src; 120 | u8int* d = (u8int*) dest; 121 | while ((*d++ = *s++)); 122 | return dest; 123 | 124 | } 125 | 126 | /* Borrowed from: http://git.musl-libc.org/cgit/musl/tree/src/string/strcmp.c */ 127 | PUBLIC int String_compare(const char* left, const char* right) { 128 | 129 | for (; *left==*right && *left && *right; left++, right++); 130 | return *(unsigned char *)left - *(unsigned char *)right; 131 | 132 | } 133 | 134 | PUBLIC u32int String_countChar(const char* s, char c) { 135 | 136 | u32int i; 137 | 138 | for (i = 0; s[i]; s[i] == c ? i++ : (u32int) s++); 139 | 140 | return i; 141 | } 142 | -------------------------------------------------------------------------------- /kernel/src/Lib/LinkedList.c: -------------------------------------------------------------------------------- 1 | /** 2 | | Copyright(C) 2012 Ali Ersenal 3 | | License: WTFPL v2 4 | | URL: http://sam.zoy.org/wtfpl/COPYING 5 | | 6 | |-------------------------------------------------------------------------- 7 | | LinkedList.h 8 | |-------------------------------------------------------------------------- 9 | | 10 | | DESCRIPTION: Doubly linked list data structure implementation. 11 | | 12 | | AUTHOR: Ali Ersenal, aliersenal@gmail.com 13 | \------------------------------------------------------------------------*/ 14 | 15 | 16 | #include 17 | #include 18 | #include 19 | 20 | /*======================================================= 21 | FUNCTION 22 | =========================================================*/ 23 | 24 | PRIVATE Node* LinkedList_getNode(LinkedList* self, void* data) { 25 | 26 | LinkedList_FOREACH(node, self) 27 | if(node->data == data) 28 | return node; 29 | 30 | return NULL; /* Return if not found */ 31 | 32 | } 33 | 34 | PRIVATE void* LinkedList_removeNode(LinkedList* self, Node* node) { 35 | 36 | Debug_assert(self->first != NULL && self->last != NULL); 37 | Debug_assert(node != NULL); 38 | 39 | if(node == self->first && node == self->last) { /* node is the only element */ 40 | 41 | self->first = NULL; 42 | self->last = NULL; 43 | 44 | } else if(node == self->first) { /* node is the first element */ 45 | 46 | self->first = node->next; 47 | self->first->prev = NULL; 48 | 49 | } else if(node == self->last) { /* node is the last element */ 50 | 51 | self->last = node->prev; 52 | self->last->next = NULL; 53 | 54 | } else { /* node is a middle element */ 55 | 56 | Node* next = node->next; 57 | Node* prev = node->prev; 58 | 59 | next->prev = prev; 60 | prev->next = next; 61 | 62 | } 63 | 64 | self->count--; 65 | void* val = node->data; 66 | HeapMemory_free(node); 67 | 68 | return val; 69 | 70 | } 71 | 72 | PUBLIC void LinkedList_add(LinkedList* self, void* data) { 73 | 74 | Node* node = HeapMemory_calloc(1, sizeof(Node)); 75 | Debug_assert(node != NULL); 76 | Debug_assert(data != NULL); 77 | node->data = data; 78 | 79 | if(self->last == NULL) { /* linked list element count is 0 */ 80 | 81 | self->first = node; 82 | self->last = node; 83 | 84 | } else { 85 | 86 | self->last->next = node; 87 | node->prev = self->last; 88 | self->last = node; 89 | 90 | } 91 | 92 | self->count++; 93 | 94 | } 95 | 96 | PUBLIC void* LinkedList_remove(LinkedList* self, void* data) { 97 | 98 | Debug_assert(data != NULL); 99 | Node* node = LinkedList_getNode(self, data); 100 | return LinkedList_removeNode(self, node); 101 | 102 | } 103 | 104 | PUBLIC void* LinkedList_removeFromFront(LinkedList* self) { 105 | 106 | return LinkedList_removeNode(self, self->first); 107 | 108 | } 109 | 110 | void* LinkedList_getFront(LinkedList* self) { 111 | 112 | return self->first->data; 113 | 114 | } 115 | 116 | PUBLIC LinkedList* LinkedList_new() { 117 | 118 | return HeapMemory_calloc(1, sizeof(LinkedList)); 119 | 120 | } 121 | 122 | PUBLIC void LinkedList_destroy(LinkedList* self) { 123 | 124 | /* Free all nodes in linked list */ 125 | Node* node = self->first; 126 | 127 | while(node != NULL) { 128 | 129 | Node* temp = node; 130 | node = node->next; 131 | HeapMemory_free(temp); 132 | 133 | } 134 | 135 | /* Free linked list */ 136 | HeapMemory_free(self); 137 | 138 | } -------------------------------------------------------------------------------- /kernel/include/X86/IDT.h: -------------------------------------------------------------------------------- 1 | /** 2 | | Copyright(C) 2012 Ali Ersenal 3 | | License: WTFPL v2 4 | | URL: http://sam.zoy.org/wtfpl/COPYING 5 | | 6 | |-------------------------------------------------------------------------- 7 | | IDT.h 8 | |-------------------------------------------------------------------------- 9 | | 10 | | DESCRIPTION: Initialises and stores Interrupt Descriptor Table entries. 11 | | Also provides C-level interrupt handlers for exceptions and 12 | | IRQs. 13 | | 14 | | 15 | | AUTHOR: Ali Ersenal, aliersenal@gmail.com 16 | \------------------------------------------------------------------------*/ 17 | 18 | 19 | #ifndef IDT_H 20 | #define IDT_H 21 | 22 | #include 23 | 24 | /*======================================================= 25 | DEFINE 26 | =========================================================*/ 27 | 28 | /* IRQ Number - Interrupt Number */ 29 | #define IRQ0 32 30 | #define IRQ1 33 31 | #define IRQ2 34 32 | #define IRQ3 35 33 | #define IRQ4 36 34 | #define IRQ5 37 35 | #define IRQ6 38 36 | #define IRQ7 39 37 | #define IRQ8 40 38 | #define IRQ9 41 39 | #define IRQ10 42 40 | #define IRQ11 43 41 | #define IRQ12 44 42 | #define IRQ13 45 43 | #define IRQ14 46 44 | #define IRQ15 47 45 | 46 | /*======================================================= 47 | STRUCT 48 | =========================================================*/ 49 | typedef struct Regs Regs; 50 | 51 | /* CPU state just before interrupt + interrupt info(intNo, errCode) */ 52 | struct Regs { 53 | 54 | /* Segment selectors */ 55 | u32int gs, fs, es, ds; 56 | 57 | /* Pushed by pusha. */ 58 | u32int edi, esi, ebp, esp, ebx, edx, ecx, eax; 59 | 60 | /* Interrupt number and error code (if applicable). */ 61 | u32int intNo, errCode; 62 | 63 | /* Pushed by the processor automatically. */ 64 | u32int eip, cs, eflags, esp0, ss0; 65 | 66 | } __attribute__((packed)); 67 | 68 | /*======================================================= 69 | FUNCTION 70 | =========================================================*/ 71 | 72 | /*------------------------------------------------------------------------- 73 | | Register high-level interrupt handler 74 | |-------------------------------------------------------------------------- 75 | | DESCRIPTION: Registers a function which gets called whenever 76 | | interrupt "interruptNo" is raised. 77 | | 78 | | PARAM: "functionAddr" pointer to handler function 79 | | "interruptNo" interrupt to handle 80 | \------------------------------------------------------------------------*/ 81 | void IDT_registerHandler(void* functionAddr, u8int interruptNo); 82 | 83 | /*------------------------------------------------------------------------- 84 | | High-level interrupt handler 85 | |-------------------------------------------------------------------------- 86 | | DESCRIPTION: C-level common interrupt handler, called from: 87 | | IDT_commonHandler() (see IDT.s) 88 | | 89 | | PARAM: "regs" cpu registers 90 | \------------------------------------------------------------------------*/ 91 | void IDT_interruptHandler(Regs* regs); 92 | 93 | /*------------------------------------------------------------------------- 94 | | Get IDT module 95 | |-------------------------------------------------------------------------- 96 | | DESCRIPTION: Returns the IDT module. 97 | | 98 | | NOTES: OS will not respond to software and hardware interrupts 99 | | unless this module is loaded. 100 | \------------------------------------------------------------------------*/ 101 | Module* IDT_getModule(void); 102 | #endif 103 | -------------------------------------------------------------------------------- /kernel/src/Lib/ArrayList.c: -------------------------------------------------------------------------------- 1 | /** 2 | | Copyright(C) 2012 Ali Ersenal 3 | | License: WTFPL v2 4 | | URL: http://sam.zoy.org/wtfpl/COPYING 5 | | 6 | |-------------------------------------------------------------------------- 7 | | ArrayList.c 8 | |-------------------------------------------------------------------------- 9 | | 10 | | DESCRIPTION: ArrayList(dynamic array) data structure implementation. 11 | | 12 | | AUTHOR: Ali Ersenal, aliersenal@gmail.com 13 | \------------------------------------------------------------------------*/ 14 | 15 | 16 | #include 17 | #include 18 | #include 19 | 20 | /*======================================================= 21 | STRUCT 22 | =========================================================*/ 23 | 24 | struct ArrayList { 25 | 26 | void** arrayPointer; 27 | u32int usedSize; 28 | u32int totalSize; 29 | 30 | }; 31 | 32 | /*======================================================= 33 | FUNCTION 34 | =========================================================*/ 35 | 36 | PUBLIC void* ArrayList_get(ArrayList* self, u32int index) { 37 | 38 | Debug_assert(index < self->usedSize); 39 | return *(self->arrayPointer + index); 40 | 41 | } 42 | 43 | PUBLIC void ArrayList_add(ArrayList* self, void* dataPointer) { 44 | 45 | if(self->usedSize == self->totalSize) { /* grow array */ 46 | 47 | self->totalSize = self->totalSize * 2; 48 | self->arrayPointer = (void**) HeapMemory_realloc(self->arrayPointer, self->totalSize * sizeof(void*)); 49 | Debug_assert(self->arrayPointer); 50 | 51 | } 52 | 53 | *(self->arrayPointer + self->usedSize) = dataPointer; /* insert data pointer */ 54 | self->usedSize++; 55 | 56 | } 57 | 58 | PUBLIC int ArrayList_getIndex(ArrayList* self, void* dataPointer) { 59 | 60 | for(u32int i = 0; i < self->usedSize; i++) 61 | if(*(self->arrayPointer + i) == dataPointer) 62 | return i; 63 | 64 | return -1; /* not found */ 65 | 66 | } 67 | 68 | PUBLIC bool ArrayList_exists(ArrayList* self, void* dataPointer) { 69 | 70 | if(ArrayList_getIndex(self, dataPointer) == -1) 71 | return FALSE; 72 | else 73 | return TRUE; 74 | 75 | } 76 | 77 | PUBLIC u32int ArrayList_getSize(ArrayList* self) { 78 | 79 | return self->usedSize; 80 | 81 | } 82 | 83 | PUBLIC void ArrayList_remove(ArrayList* self, void* dataPointer) { 84 | 85 | u32int index = ArrayList_getIndex(self, dataPointer); 86 | ArrayList_removeAt(self, index); 87 | 88 | } 89 | 90 | PUBLIC void ArrayList_removeAt(ArrayList* self, u32int index) { 91 | 92 | Debug_assert(index < self->usedSize); 93 | 94 | *(self->arrayPointer + index) = NULL; 95 | 96 | /* shift every element to the right of index to left */ 97 | for(u32int i = index; i < self->usedSize - 1; i++) 98 | /* set the current element val to the val of element on the right */ 99 | *(self->arrayPointer + i) = *(self->arrayPointer + (i + 1)); 100 | 101 | self->usedSize--; 102 | } 103 | 104 | PUBLIC bool ArrayList_isEmpty(ArrayList* self) { 105 | 106 | if(self->arrayPointer != NULL && *(self->arrayPointer) != NULL) 107 | return TRUE; 108 | else 109 | return FALSE; 110 | 111 | } 112 | 113 | PUBLIC void ArrayList_destroy(ArrayList* self) { 114 | 115 | HeapMemory_free(self->arrayPointer); 116 | HeapMemory_free(self); 117 | 118 | } 119 | 120 | PUBLIC ArrayList* ArrayList_new(u32int initialLength) { 121 | 122 | /* allocate memory */ 123 | ArrayList* self = (ArrayList*) HeapMemory_alloc(sizeof(ArrayList)); 124 | Debug_assert(self); 125 | 126 | Debug_assert(initialLength > 0); 127 | self->arrayPointer = (void**) HeapMemory_alloc(sizeof(void*) * initialLength); 128 | Debug_assert(self->arrayPointer); 129 | 130 | /* set properties */ 131 | self->totalSize = initialLength; 132 | self->usedSize = 0; 133 | 134 | return self; 135 | } 136 | -------------------------------------------------------------------------------- /user/src/Lib/Incitatus.c: -------------------------------------------------------------------------------- 1 | /** 2 | | Copyright(C) 2012 Ali Ersenal 3 | | License: WTFPL v2 4 | | URL: http://sam.zoy.org/wtfpl/COPYING 5 | | 6 | |-------------------------------------------------------------------------- 7 | | Incitatus.c 8 | |-------------------------------------------------------------------------- 9 | | 10 | | DESCRIPTION: User-space system call library. 11 | | 12 | | AUTHOR: Ali Ersenal, aliersenal@gmail.com 13 | \------------------------------------------------------------------------*/ 14 | 15 | 16 | #include 17 | 18 | static int syscall(int type, int p1, int p2, int p3, int p4, int p5) { 19 | 20 | int ret; 21 | asm volatile("int $0x80" : "=a" (ret) : "0" (type), "b" ((int)p1), "c" ((int)p2), 22 | "d" ((int)p3), "S" ((int)p4), "D" ((int)p5)); 23 | return ret; 24 | 25 | } 26 | 27 | void puts(const char* str) { 28 | 29 | syscall(SYSCALL_PUTS, (int) str, 0, 0, 0, 0); 30 | 31 | } 32 | 33 | void putc(char c) { 34 | 35 | syscall(SYSCALL_PUTC, c, 0, 0, 0, 0); 36 | 37 | } 38 | 39 | void exit(int exitCode) { 40 | 41 | syscall(SYSCALL_EXIT, exitCode, 0, 0, 0, 0); 42 | 43 | } 44 | 45 | int spawn(const char* binary) { 46 | 47 | return syscall(SYSCALL_SPAWN, (int) binary, 0, 0, 0, 0); 48 | 49 | } 50 | 51 | FILE* fchdir(FILE* fd) { 52 | 53 | return (FILE*) syscall(SYSCALL_FCHDIR, (int) fd, 0, 0, 0, 0); 54 | 55 | } 56 | 57 | FILE* chdir(const char* dir) { 58 | 59 | return (FILE*) syscall(SYSCALL_CHDIR, (int) dir, 0, 0, 0, 0); 60 | 61 | } 62 | 63 | FILE* fparent(FILE* fd) { 64 | 65 | return (FILE*) syscall(SYSCALL_FPARENT, (int) fd, 0, 0, 0, 0); 66 | 67 | } 68 | 69 | FILE* readdir(FILE* fd, int index) { 70 | 71 | return (FILE*) syscall(SYSCALL_READDIR, (int) fd, index, 0, 0, 0); 72 | 73 | } 74 | 75 | FILE* finddir(FILE* fs, const char* childname) { 76 | 77 | return (FILE*) syscall(SYSCALL_FINDDIR, (int) fs, (int) childname, 0, 0, 0); 78 | 79 | } 80 | 81 | FILE* fgetcwd(void) { 82 | 83 | return (FILE*) syscall(SYSCALL_FGETCWD, 0, 0, 0, 0, 0); 84 | 85 | } 86 | 87 | FILE* open(const char* path, const char* mode) { 88 | 89 | return (FILE*) syscall(SYSCALL_OPEN, (int) path, (int) mode, 0, 0, 0); 90 | 91 | } 92 | 93 | void close(FILE* fd) { 94 | 95 | syscall(SYSCALL_CLOSE, (int) fd, 0, 0, 0, 0); 96 | 97 | } 98 | 99 | unsigned int read(FILE* fd, unsigned int offset, unsigned int count, char* buffer) { 100 | 101 | return syscall(SYSCALL_READ, (int) fd, offset, count, (int) buffer, 0); 102 | 103 | } 104 | 105 | unsigned int write(FILE* fd, unsigned int offset, unsigned int count, const char* buffer) { 106 | 107 | return syscall(SYSCALL_WRITE, (int) fd, offset, count, (int) buffer, 0); 108 | 109 | } 110 | 111 | FILE* mkdir(const char* pathname) { 112 | 113 | return (FILE*) syscall(SYSCALL_MKDIR, (int) pathname, 0, 0, 0, 0); 114 | 115 | } 116 | 117 | void* sbrk(int size) { 118 | 119 | return (void*) syscall(SYSCALL_SBRK, size, 0, 0, 0, 0); 120 | 121 | } 122 | 123 | void fstat(FILE* fd, struct stat* buf) { 124 | 125 | syscall(SYSCALL_FSTAT, (int) fd, (int) buf, 0, 0, 0); 126 | 127 | } 128 | 129 | char* getcwd(char* buf) { 130 | 131 | return (char*) syscall(SYSCALL_GETCWD, (int) buf, 0, 0, 0, 0); 132 | 133 | } 134 | 135 | char getch(void) { 136 | 137 | return syscall(SYSCALL_GETCH, 0, 0, 0, 0, 0); 138 | 139 | } 140 | 141 | void cls(void) { 142 | 143 | syscall(SYSCALL_CLS, 0, 0, 0, 0, 0); 144 | 145 | } 146 | 147 | void restart(void) { 148 | 149 | syscall(SYSCALL_RESTART, 0, 0, 0, 0, 0); 150 | 151 | } 152 | 153 | void poweroff(void) { 154 | 155 | syscall(SYSCALL_POWEROFF, 0, 0, 0, 0, 0); 156 | 157 | } 158 | 159 | void color(unsigned int attr) { 160 | 161 | syscall(SYSCALL_SETCOLOR, attr, 0, 0, 0, 0); 162 | 163 | } 164 | 165 | void waitpid(int pid) { 166 | 167 | syscall(SYSCALL_WAITPID, pid, 0, 0, 0, 0); 168 | for(int i = 0; i < 5000000; i++); /* FIX: race condition */ 169 | 170 | } -------------------------------------------------------------------------------- /kernel/include/FileSystem/Tar.h: -------------------------------------------------------------------------------- 1 | /** 2 | | Copyright(C) 2012 Ali Ersenal 3 | | License: WTFPL v2 4 | | URL: http://sam.zoy.org/wtfpl/COPYING 5 | | 6 | |-------------------------------------------------------------------------- 7 | | Tar.h 8 | |-------------------------------------------------------------------------- 9 | | 10 | | DESCRIPTION: Tar archive parser. 11 | | 12 | | For more info on Tar: 13 | | http://en.wikipedia.org/wiki/Tar_file_format 14 | | 15 | | AUTHOR: Ali Ersenal, aliersenal@gmail.com 16 | \------------------------------------------------------------------------*/ 17 | 18 | 19 | #ifndef TAR_H 20 | #define TAR_H 21 | 22 | #include 23 | 24 | /*======================================================= 25 | DEFINE 26 | =========================================================*/ 27 | #define TAR_BLOCK_SIZE 512 28 | #define TAR_FILE_NAME_SIZE 100 29 | #define TAR_FILE_MODE_SIZE 8 30 | #define TAR_UID_SIZE 8 31 | #define TAR_GID_SIZE 8 32 | #define TAR_FILE_SIZE_SIZE 12 33 | #define TAR_LAST_MODIFIED_SIZE 12 34 | #define TAR_CHECKSUM_SIZE 8 35 | #define TAR_TYPEFLAG_SIZE 1 36 | #define TAR_LINKNAME_SIZE 100 37 | 38 | #define TAR_FILETYPE_NORMAL '0' 39 | #define TAR_FILETYPE_HARD_LINK '1' 40 | #define TAR_FILETYPE_SYM_LINK '2' 41 | #define TAR_FILETYPE_CHAR_DEVICE '3' 42 | #define TAR_FILETYPE_BLOCK_DEVICE '4' 43 | #define TAR_FILETYPE_DIRECTORY '5' 44 | #define TAR_FILETYPE_NAMED_PIPE '6' 45 | 46 | /*======================================================= 47 | STRUCT 48 | =========================================================*/ 49 | typedef struct TarEntryHeader TarEntryHeader; 50 | 51 | struct TarEntryHeader { 52 | 53 | char fileName [TAR_FILE_NAME_SIZE]; 54 | char fileMode [TAR_FILE_MODE_SIZE]; 55 | char userID [TAR_UID_SIZE]; 56 | char groupID [TAR_GID_SIZE]; 57 | char fileSize [TAR_FILE_SIZE_SIZE]; 58 | char lastModified [TAR_LAST_MODIFIED_SIZE]; 59 | char checksum [TAR_CHECKSUM_SIZE]; 60 | char fileType [TAR_TYPEFLAG_SIZE]; 61 | char linkName [TAR_LINKNAME_SIZE]; 62 | 63 | }; 64 | 65 | /*======================================================= 66 | FUNCTION 67 | =========================================================*/ 68 | 69 | /*------------------------------------------------------------------------- 70 | | Get next tar header 71 | |-------------------------------------------------------------------------- 72 | | DESCRIPTION: Returns the next tar header. 73 | | 74 | | PARAM: 'header' current header 75 | | 76 | | RETURN 'TarEntryHeader*' the next header 77 | \------------------------------------------------------------------------*/ 78 | TarEntryHeader* Tar_nextHeader(const TarEntryHeader* header); 79 | 80 | /*------------------------------------------------------------------------- 81 | | Get tar header 82 | |-------------------------------------------------------------------------- 83 | | DESCRIPTION: Returns the nth tar header. 84 | | 85 | | PARAM: 'firstHeader' the first tar header 86 | | 'index' index of tar header to be returned 87 | | 88 | | RETURN 'TarEntryHeader*' nth tar header 89 | \------------------------------------------------------------------------*/ 90 | TarEntryHeader* Tar_getHeader(const TarEntryHeader* firstHeader, u32int index); 91 | 92 | /*------------------------------------------------------------------------- 93 | | Get number of tar files 94 | |-------------------------------------------------------------------------- 95 | | DESCRIPTION: Returns the number of tar files. 96 | | 97 | | PARAM: 'firstHeader' the first tar header 98 | | 99 | | RETURN 'u32int' the number of tar files 100 | \------------------------------------------------------------------------*/ 101 | u32int Tar_getNumberOfFiles(const TarEntryHeader* firstHeader); 102 | #endif -------------------------------------------------------------------------------- /kernel/include/Memory/PhysicalMemory.h: -------------------------------------------------------------------------------- 1 | /** 2 | | Copyright(C) 2012 Ali Ersenal 3 | | License: WTFPL v2 4 | | URL: http://sam.zoy.org/wtfpl/COPYING 5 | | 6 | |-------------------------------------------------------------------------- 7 | | PhysicalMemory.h 8 | |-------------------------------------------------------------------------- 9 | | 10 | | DESCRIPTION: Physical memory manager interface. 11 | | Sets up and manages physical memory. 12 | | 13 | | AUTHOR: Ali Ersenal, aliersenal@gmail.com 14 | \------------------------------------------------------------------------*/ 15 | 16 | 17 | #ifndef PM_H 18 | #define PM_H 19 | 20 | #include 21 | #include 22 | 23 | /*======================================================= 24 | DEFINE 25 | =========================================================*/ 26 | #define FRAME_SIZE 4096 27 | 28 | /*======================================================= 29 | STRUCT 30 | =========================================================*/ 31 | typedef struct PhysicalMemoryInfo PhysicalMemoryInfo; 32 | 33 | struct PhysicalMemoryInfo { 34 | 35 | u32int totalMemory; /* Total physical memory in bytes */ 36 | u32int totalFrames; /* Number of page frames */ 37 | u32int freeFrames; /* Number of free(not in use) page frames */ 38 | 39 | }; 40 | 41 | /*======================================================= 42 | INTERFACE 43 | =========================================================*/ 44 | 45 | /*------------------------------------------------------------------------- 46 | | Physical memory initialisation 47 | |-------------------------------------------------------------------------- 48 | | DESCRIPTION: Sets up physical memory. 49 | | 50 | | PARAM: "mbI" points to multiboot information 51 | | "mbH" points to multiboot header 52 | | (refer to Multiboot.h) 53 | \------------------------------------------------------------------------*/ 54 | extern void (*PhysicalMemory_init) (MultibootInfo* mbI, MultibootHeader* mbH); 55 | 56 | /*------------------------------------------------------------------------- 57 | | Get current memory information 58 | |-------------------------------------------------------------------------- 59 | | DESCRIPTION: Returns a structure containing physical memory info. 60 | | 61 | | PARAM: 'buf' memory info structure to be filled with the info. 62 | | 63 | | RETURN: 'PhysicalMemoryInfo*' pointer to filled memory info structure. 64 | \------------------------------------------------------------------------*/ 65 | extern PhysicalMemoryInfo* (*PhysicalMemory_getInfo) (PhysicalMemoryInfo* buf); 66 | 67 | /*------------------------------------------------------------------------- 68 | | Allocate frame 69 | |-------------------------------------------------------------------------- 70 | | DESCRIPTION: Allocates and returns a frame address(4096 bytes). 71 | | 72 | | RETURN: void* allocated frame address 73 | | 74 | | NOTES: Returns NULL if out of physical memory. 75 | \------------------------------------------------------------------------*/ 76 | extern void* (*PhysicalMemory_allocateFrame) (void); 77 | 78 | /*------------------------------------------------------------------------- 79 | | Free frame 80 | |-------------------------------------------------------------------------- 81 | | DESCRIPTION: Deallocates the frame at address "b". 82 | | 83 | | PARAM: "b" the address of frame to be deallocated 84 | \------------------------------------------------------------------------*/ 85 | extern void (*PhysicalMemory_freeFrame) (void* frame); 86 | 87 | /*======================================================= 88 | FUNCTION 89 | =========================================================*/ 90 | 91 | /*------------------------------------------------------------------------- 92 | | Get PMM module 93 | |-------------------------------------------------------------------------- 94 | | DESCRIPTION: Returns the physical memory management module. 95 | | 96 | \------------------------------------------------------------------------*/ 97 | Module* PhysicalMemory_getModule(void); 98 | 99 | #endif -------------------------------------------------------------------------------- /kernel/include/Multiboot.h: -------------------------------------------------------------------------------- 1 | /* Multiboot.h - Multiboot header file. */ 2 | 3 | /* Copyright (C) 1999,2003,2007,2008,2009 Free Software Foundation, Inc. 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy 6 | * of this software and associated documentation files (the "Software"), to 7 | * deal in the Software without restriction, including without limitation the 8 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 9 | * sell copies of the Software, and to permit persons to whom the Software is 10 | * furnished to do so, subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in 13 | * all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ANY 18 | * DEVELOPER OR DISTRIBUTOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 19 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR 20 | * IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | 24 | #ifndef MULTI_H 25 | #define MULTI_H 26 | 27 | #include 28 | 29 | /* The magic field should contain this. */ 30 | #define MULTIBOOT_HEADER_MAGIC 0x1BADB002 31 | 32 | /* This should be in %eax. */ 33 | #define MULTIBOOT_BOOTLOADER_MAGIC 0x2BADB002 34 | 35 | typedef struct MultibootHeader MultibootHeader; 36 | typedef struct MultibootInfo MultibootInfo; 37 | typedef struct MultibootMemEntry MultibootMemEntry; 38 | typedef struct MultibootAout MultibootAout; 39 | typedef struct MultibootELF MultibootELF; 40 | 41 | struct MultibootMemEntry 42 | { 43 | 44 | u32int size; 45 | u64int addr; 46 | u64int len; 47 | #define MULTIBOOT_MEMORY_AVAILABLE 1 48 | #define MULTIBOOT_MEMORY_RESERVED 2 49 | u32int type; 50 | 51 | } __attribute__((packed)); 52 | 53 | /* The symbol table for a.out. */ 54 | struct MultibootAout 55 | { 56 | 57 | u32int tabsize; 58 | u32int strsize; 59 | u32int addr; 60 | u32int reserved; 61 | 62 | } __attribute__((packed)); 63 | 64 | 65 | /* The section header table for ELF. */ 66 | struct MultibootELF 67 | { 68 | 69 | u32int num; 70 | u32int size; 71 | u32int addr; 72 | u32int shndx; 73 | 74 | } __attribute__((packed)); 75 | 76 | struct MultibootInfo { 77 | 78 | /* Multiboot info version number */ 79 | u32int flags; 80 | 81 | /* Available memory from BIOS */ 82 | u32int memLower; 83 | u32int memUpper; 84 | 85 | /* "root" partition */ 86 | u32int bootDevice; 87 | 88 | /* Kernel command line */ 89 | u32int cmdline; 90 | 91 | /* Boot-Module list */ 92 | u32int modsCount; 93 | u32int modsAddr; 94 | 95 | union 96 | { 97 | MultibootAout aoutSym; 98 | MultibootELF elfSec; 99 | } u; 100 | 101 | /* Memory Mapping buffer */ 102 | u32int mmapLength; 103 | u32int mmapAddr; 104 | 105 | /* Drive Info buffer */ 106 | u32int drivesLength; 107 | u32int drivesAddr; 108 | 109 | /* ROM configuration table */ 110 | u32int configTable; 111 | 112 | /* Boot Loader Name */ 113 | u32int bootLoaderName; 114 | 115 | /* APM table */ 116 | u32int apmTable; 117 | 118 | /* Video */ 119 | u32int vbeControlInfo; 120 | u32int vbeModeInfo; 121 | u16int vbeMode; 122 | u16int vbeInterfaceSeg; 123 | u16int vbeInterfaceOff; 124 | u16int vbeInterfaceLen; 125 | 126 | } __attribute__((packed)); 127 | 128 | struct MultibootHeader { 129 | 130 | /* Must be MULTIBOOT_MAGIC - see above. */ 131 | u32int magic; 132 | 133 | /* Feature flags. */ 134 | u32int flags; 135 | 136 | /* The above fields plus this one must equal 0 mod 2^32. */ 137 | u32int checksum; 138 | 139 | /* These are only valid if MULTIBOOT_AOUT_KLUDGE is set. */ 140 | u32int headerAddr; 141 | u32int loadAddr; 142 | u32int loadEndAddr; 143 | u32int bssEndAddr; 144 | u32int entryAddr; 145 | 146 | } __attribute__((packed)); 147 | 148 | #endif 149 | -------------------------------------------------------------------------------- /kernel/include/Drivers/Console.h: -------------------------------------------------------------------------------- 1 | /** 2 | | Copyright(C) 2012 Ali Ersenal 3 | | License: WTFPL v2 4 | | URL: http://sam.zoy.org/wtfpl/COPYING 5 | | 6 | |-------------------------------------------------------------------------- 7 | | Console.h 8 | |-------------------------------------------------------------------------- 9 | | 10 | | DESCRIPTION: Text-Mode console driver. 11 | | 12 | | 13 | | AUTHOR: Ali Ersenal, aliersenal@gmail.com 14 | \------------------------------------------------------------------------*/ 15 | 16 | 17 | #ifndef CONSOLE_H 18 | #define CONSOLE_H 19 | 20 | #include 21 | #include 22 | 23 | /*======================================================= 24 | DEFINE 25 | =========================================================*/ 26 | 27 | /** Console colors */ 28 | #define CONSOLE_ERROR 0x0C //light-red 29 | #define CONSOLE_INFO 0x09 //light-blue 30 | #define CONSOLE_WARN 0x0E //yellow 31 | #define CONSOLE_NORMAL 0x07 //grey 32 | 33 | /*======================================================= 34 | FUNCTION 35 | =========================================================*/ 36 | 37 | /*------------------------------------------------------------------------- 38 | | Print formatted string 39 | |-------------------------------------------------------------------------- 40 | | DESCRIPTION: Constructs a string using the specified template and 41 | | variable arguments and then prints it. 42 | | 43 | | PARAM: "template" is used to construct the string 44 | | "var-args" replaces the format specifier in template 45 | | 46 | | PRECONDITION: "template" tokens which are valid: 47 | | 48 | | %a set console color 49 | | %d base-10 number 50 | | %c ASCII char 51 | | %s string(char*) 52 | | 53 | | 54 | | EXAMPLE: Console_printf("%s%d", "The meaning of life: ", 42); 55 | | 56 | \------------------------------------------------------------------------*/ 57 | void Console_printf(const char* template, ...); 58 | 59 | /*------------------------------------------------------------------------- 60 | | Print character 61 | |-------------------------------------------------------------------------- 62 | | DESCRIPTION: Prints an ASCII character. 63 | | 64 | | PARAM: "c" char to print 65 | | 66 | | EXAMPLE: Console_printChar('A'); 67 | | 68 | \------------------------------------------------------------------------*/ 69 | void Console_printChar(u8int c); 70 | 71 | /*------------------------------------------------------------------------- 72 | | Print string 73 | |-------------------------------------------------------------------------- 74 | | DESCRIPTION: Prints a null terminated string. 75 | | 76 | | PARAM: "str" null terminated string pointer 77 | | 78 | | PRECONDITION: "str" needs to be null terminated 79 | | 80 | | EXAMPLE: Console_printString("Hello World!"); 81 | | 82 | \------------------------------------------------------------------------*/ 83 | void Console_printString(const char* str); 84 | 85 | /*------------------------------------------------------------------------- 86 | | Clear screen 87 | |-------------------------------------------------------------------------- 88 | | DESCRIPTION: Removes all characters from console screen. 89 | | 90 | \------------------------------------------------------------------------*/ 91 | void Console_clearScreen(void); 92 | 93 | /*------------------------------------------------------------------------- 94 | | Set print color 95 | |-------------------------------------------------------------------------- 96 | | DESCRIPTION: Sets the background and foreground colors of next char 97 | | to be printed. 98 | | 99 | | PARAM: "colorAttribute" color to set 100 | | 101 | | EXAMPLE: Console_setColor(CONSOLE_ERROR); 102 | | 103 | \------------------------------------------------------------------------*/ 104 | void Console_setColor(u8int colorAttribute); 105 | 106 | /*------------------------------------------------------------------------- 107 | | Get console module 108 | |-------------------------------------------------------------------------- 109 | | DESCRIPTION: Returns the console module. 110 | | 111 | \------------------------------------------------------------------------*/ 112 | Module* Console_getModule(void); 113 | #endif 114 | -------------------------------------------------------------------------------- /kernel/include/Process/ProcessManager.h: -------------------------------------------------------------------------------- 1 | /** 2 | | Copyright(C) 2012 Ali Ersenal 3 | | License: WTFPL v2 4 | | URL: http://sam.zoy.org/wtfpl/COPYING 5 | | 6 | |-------------------------------------------------------------------------- 7 | | ProcessManager.h 8 | |-------------------------------------------------------------------------- 9 | | 10 | | DESCRIPTION: Handles process creation, destruction, switch. 11 | | 12 | | AUTHOR: Ali Ersenal, aliersenal@gmail.com 13 | \------------------------------------------------------------------------*/ 14 | 15 | 16 | #ifndef PROCESS_M_H 17 | #define PROCESS_M_H 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | /*======================================================= 25 | DEFINE 26 | =========================================================*/ 27 | 28 | /* Kernel process id */ 29 | #define KERNEL_PID 0 30 | 31 | /* Process Type */ 32 | #define KERNEL_PROCESS 0 33 | #define USER_PROCESS 1 34 | 35 | /* Process State */ 36 | #define PROCESS_CREATED 1 37 | #define PROCESS_WAITING 2 38 | #define PROCESS_RUNNING 3 39 | #define PROCESS_BLOCKED 4 40 | #define PROCESS_TERMINATED 5 41 | 42 | /*======================================================= 43 | STRUCT 44 | =========================================================*/ 45 | typedef struct Process Process; 46 | 47 | struct Process { 48 | 49 | u32int pid; 50 | u8int status; 51 | char name[64]; 52 | void* userHeapTop; 53 | void* kernelStack; 54 | void* kernelStackBase; 55 | void* userStack; 56 | void* userStackBase; 57 | void* pageDir; 58 | 59 | VFSNode* workingDirectory; 60 | ArrayList* fileNodes; 61 | 62 | }; 63 | 64 | /*======================================================= 65 | FUNCTION 66 | =========================================================*/ 67 | 68 | /*------------------------------------------------------------------------- 69 | | Process switch 70 | |-------------------------------------------------------------------------- 71 | | DESCRIPTION: Performs a process switch. 72 | | Called by PIT(See PIT.c : PIT8253_timerHandler) 73 | | 74 | | PARAM: 'Regs*' the context 75 | \------------------------------------------------------------------------*/ 76 | void ProcessManager_switch(Regs* context); 77 | 78 | /*------------------------------------------------------------------------- 79 | | Kill process 80 | |-------------------------------------------------------------------------- 81 | | DESCRIPTION: Terminates the current process and switches to next one. 82 | | 83 | | PARAM: 'exitCode' the exit code 84 | \------------------------------------------------------------------------*/ 85 | void ProcessManager_killProcess(int exitCode); 86 | 87 | /*------------------------------------------------------------------------- 88 | | Spawn process 89 | |-------------------------------------------------------------------------- 90 | | DESCRIPTION: Spawns a new process from an executable binary file. 91 | | 92 | | PARAM: 'binary' the binary pathname 93 | | 94 | | RETURN: 'Process*' the process that was spawned 95 | \------------------------------------------------------------------------*/ 96 | Process* ProcessManager_spawnProcess(const char* binary); 97 | 98 | /*------------------------------------------------------------------------- 99 | | Wait process ID 100 | |-------------------------------------------------------------------------- 101 | | DESCRIPTION: Causes the current process to wait for specified process' termination. 102 | | 103 | | PARAM: 'Process*' the process to wait for 104 | \------------------------------------------------------------------------*/ 105 | void ProcessManager_waitPID(Process* process); 106 | 107 | /*------------------------------------------------------------------------- 108 | | Block current process 109 | |-------------------------------------------------------------------------- 110 | | DESCRIPTION: Blocks the current process from further execution. 111 | | 112 | \------------------------------------------------------------------------*/ 113 | void ProcessManager_blockCurrentProcess(void); 114 | 115 | /*------------------------------------------------------------------------- 116 | | Get process management module 117 | |-------------------------------------------------------------------------- 118 | | DESCRIPTION: Returns the process management module. 119 | | 120 | \------------------------------------------------------------------------*/ 121 | Module* ProcessManager_getModule(void); 122 | 123 | #endif -------------------------------------------------------------------------------- /kernel/src/Memory/BitmapPMM.c: -------------------------------------------------------------------------------- 1 | /** 2 | | Copyright(C) 2012 Ali Ersenal 3 | | License: WTFPL v2 4 | | URL: http://sam.zoy.org/wtfpl/COPYING 5 | | 6 | |-------------------------------------------------------------------------- 7 | | BitmapPMM.c (implements PhysicalMemory) 8 | |-------------------------------------------------------------------------- 9 | | 10 | | DESCRIPTION: Bitmap based physical memory manager implementation. 11 | | 12 | | AUTHOR: Ali Ersenal, aliersenal@gmail.com 13 | \------------------------------------------------------------------------*/ 14 | 15 | 16 | #include 17 | #include 18 | #include 19 | #include 20 | 21 | 22 | /*======================================================= 23 | PRIVATE DATA 24 | =========================================================*/ 25 | PRIVATE u32int totalPhysicalMemory; 26 | PRIVATE u32int usedFrames; 27 | PRIVATE u32int totalFrames; 28 | 29 | PRIVATE char* frames; 30 | PRIVATE Bitmap bitmap; 31 | 32 | /*======================================================= 33 | FUNCTION 34 | =========================================================*/ 35 | 36 | PRIVATE void BitmapPMM_clearRegion(void* regionStart, u32int regionLength) { 37 | 38 | u32int frameIndex = (u32int) regionStart / FRAME_SIZE; 39 | 40 | for(u32int i = 0; i < regionLength / FRAME_SIZE; i++) { 41 | 42 | if(frameIndex + i < totalFrames) { 43 | Bitmap_clearBit(&bitmap, frameIndex + i); 44 | usedFrames--; 45 | } else 46 | break; 47 | 48 | } 49 | 50 | } 51 | 52 | PRIVATE void BitmapPMM_setRegion(void* regionStart, u32int regionLength) { 53 | 54 | u32int frameIndex = (u32int) regionStart / FRAME_SIZE; 55 | 56 | for(u32int i = 0; i < regionLength / FRAME_SIZE; i++) { 57 | 58 | if(frameIndex + i < totalFrames) { 59 | Bitmap_setBit(&bitmap, frameIndex + i); 60 | usedFrames++; 61 | } else 62 | break; 63 | } 64 | 65 | } 66 | 67 | PUBLIC void* BitmapPMM_allocateFrame(void) { 68 | 69 | int frameIndex = 0; 70 | 71 | if(usedFrames == totalFrames) /* out of memory */ 72 | return NULL; 73 | 74 | for(u32int i = 0; i < totalFrames; i++) 75 | if(!Bitmap_isSet(&bitmap, i)) { 76 | frameIndex = i; 77 | break; 78 | } 79 | 80 | Bitmap_setBit(&bitmap, frameIndex); 81 | usedFrames++; 82 | 83 | return (void*) (frameIndex * FRAME_SIZE); 84 | } 85 | 86 | PUBLIC void BitmapPMM_freeFrame(void* b) { 87 | 88 | Debug_assert(b != NULL); 89 | 90 | int frameIndex = (u32int) b / FRAME_SIZE; 91 | Bitmap_clearBit(&bitmap, frameIndex); 92 | usedFrames--; 93 | 94 | } 95 | 96 | PUBLIC PhysicalMemoryInfo* BitmapPMM_getInfo(PhysicalMemoryInfo* buf) { 97 | 98 | buf->totalMemory = totalPhysicalMemory; 99 | buf->totalFrames = totalFrames; 100 | buf->freeFrames = totalFrames - usedFrames; 101 | 102 | return buf; 103 | 104 | } 105 | 106 | PUBLIC void BitmapPMM_init(void) { 107 | 108 | extern MultibootHeader mbHead; /* Defined in Start.s */ 109 | extern MultibootInfo* multibootInfo; /* Defined in Kernel.c */ 110 | 111 | MultibootMemEntry* entry = (MultibootMemEntry*) multibootInfo->mmapAddr; 112 | u32int initrdEnd = *(u32int*)(multibootInfo->modsAddr + 4); 113 | u32int kernelEnd = mbHead.bssEndAddr; 114 | 115 | if(initrdEnd != 0) 116 | kernelEnd = initrdEnd; 117 | 118 | /* calculate total physical memory */ 119 | while((u32int) entry < multibootInfo->mmapAddr + multibootInfo->mmapLength) { 120 | 121 | totalPhysicalMemory += entry->len; 122 | entry++; 123 | 124 | } 125 | 126 | totalFrames = totalPhysicalMemory / FRAME_SIZE; /* total number of frames = physical memory / 4kB */ 127 | frames = (char*) kernelEnd; /* put frames array at the end of kernel */ 128 | usedFrames = totalFrames; 129 | Memory_set(frames, 1, (totalFrames / 8) + 1);/* initially set all frames as used */ 130 | Bitmap_init(&bitmap, frames, (totalFrames / 8) + 1); 131 | 132 | entry = (MultibootMemEntry*) multibootInfo->mmapAddr; 133 | 134 | /* clear usable regions */ 135 | while((u32int) entry < multibootInfo->mmapAddr + multibootInfo->mmapLength) { 136 | 137 | if(entry->type == MULTIBOOT_MEMORY_AVAILABLE) 138 | BitmapPMM_clearRegion((void*) (u32int) entry->addr, entry->len); 139 | 140 | entry++; 141 | } 142 | 143 | /* set kernel + frames array + 1 frame(to be safe) as reserved/used */ 144 | u32int reserved = (kernelEnd - mbHead.loadAddr) + ((totalFrames / 8) + 1) + FRAME_SIZE; 145 | BitmapPMM_setRegion((void*) mbHead.loadAddr, reserved); 146 | 147 | BitmapPMM_allocateFrame(); /* reserve frame starting at address 0(NULL) */ 148 | 149 | } -------------------------------------------------------------------------------- /kernel/include/Memory/HeapMemory.h: -------------------------------------------------------------------------------- 1 | /** 2 | | Copyright(C) 2012 Ali Ersenal 3 | | License: WTFPL v2 4 | | URL: http://sam.zoy.org/wtfpl/COPYING 5 | | 6 | |-------------------------------------------------------------------------- 7 | | HeapMemory.h 8 | |-------------------------------------------------------------------------- 9 | | 10 | | DESCRIPTION: Heap memory manager interface. 11 | | Sets up and manages heap memory. 12 | | 13 | | AUTHOR: Ali Ersenal, aliersenal@gmail.com 14 | \------------------------------------------------------------------------*/ 15 | 16 | 17 | #ifndef HEAP_H 18 | #define HEAP_H 19 | 20 | #include 21 | #include 22 | 23 | 24 | /*======================================================= 25 | INTERFACE 26 | =========================================================*/ 27 | 28 | /*------------------------------------------------------------------------- 29 | | Heap allocation 30 | |-------------------------------------------------------------------------- 31 | | DESCRIPTION: Allocates "bytes" number of bytes of space in heap 32 | | and returns the allocated address. 33 | | 34 | | PARAM: "bytes" number of bytes to allocate 35 | | 36 | | RETURN: void* pointer to allocated space 37 | | 38 | \------------------------------------------------------------------------*/ 39 | extern void* (*HeapMemory_alloc) (size_t bytes); 40 | 41 | /*------------------------------------------------------------------------- 42 | | Heap reallocation 43 | |-------------------------------------------------------------------------- 44 | | DESCRIPTION: Reallocates the given memory block to a new block of 45 | | size "bytes". 46 | | 47 | | PARAM: "oldmem" pointer to old memory block 48 | | "bytes" new size of memory block in bytes 49 | | 50 | | RETURN: void* pointer to reallocated space 51 | | 52 | \------------------------------------------------------------------------*/ 53 | extern void* (*HeapMemory_realloc) (void* oldmem, size_t bytes); 54 | 55 | /*------------------------------------------------------------------------- 56 | | Heap clear allocation 57 | |-------------------------------------------------------------------------- 58 | | DESCRIPTION: Allocates an array of "numberOfElements" elements and 59 | | sets all bits as zero. Each element has "elementSize" 60 | | length. 61 | | 62 | | PARAM: "numberOfElements" number of elements to be allocated 63 | | "elementSize" size of an element in bytes 64 | | 65 | | RETURN: void* pointer to cleared and allocated space 66 | | 67 | \------------------------------------------------------------------------*/ 68 | extern void* (*HeapMemory_calloc) (size_t numberOfElements, size_t elementSize); 69 | 70 | /*------------------------------------------------------------------------- 71 | | Heap free 72 | |-------------------------------------------------------------------------- 73 | | DESCRIPTION: Deallocates the specified memory block. 74 | | 75 | | PARAM: "mem" pointer to memory block 76 | \------------------------------------------------------------------------*/ 77 | extern void (*HeapMemory_free) (void* mem); 78 | 79 | /*======================================================= 80 | FUNCTION 81 | =========================================================*/ 82 | 83 | /*------------------------------------------------------------------------- 84 | | Kernel heap expand 85 | |-------------------------------------------------------------------------- 86 | | DESCRIPTION: Expands or contracts(if negative value given) the kernel heap 87 | | space by "size" bytes. "size" needs to be page aligned. 88 | | 89 | | PARAM: "size" Page aligned number of bytes 90 | \------------------------------------------------------------------------*/ 91 | void* HeapMemory_expand(ptrdiff_t size); 92 | 93 | /*------------------------------------------------------------------------- 94 | | User heap expand 95 | |-------------------------------------------------------------------------- 96 | | DESCRIPTION: Expands or contracts(if negative value given) the user heap 97 | | space by "size" bytes. "size" needs to be page aligned. 98 | | 99 | | PARAM: "size" Page aligned number of bytes 100 | \------------------------------------------------------------------------*/ 101 | void* HeapMemory_expandUser(ptrdiff_t size); 102 | 103 | 104 | /*------------------------------------------------------------------------- 105 | | Get kernel heap manager module 106 | |-------------------------------------------------------------------------- 107 | | DESCRIPTION: Returns the kernel heap memory management module. 108 | | 109 | \------------------------------------------------------------------------*/ 110 | Module* HeapMemory_getModule(void); 111 | 112 | #endif -------------------------------------------------------------------------------- /kernel/src/X86/Usermode.c: -------------------------------------------------------------------------------- 1 | /** 2 | | Copyright(C) 2012 Ali Ersenal 3 | | License: WTFPL v2 4 | | URL: http://sam.zoy.org/wtfpl/COPYING 5 | | 6 | |-------------------------------------------------------------------------- 7 | | Usermode.c 8 | |-------------------------------------------------------------------------- 9 | | 10 | | DESCRIPTION: Handles ring0 to ring3 switch and syscalls. 11 | | 12 | | AUTHOR: Ali Ersenal, aliersenal@gmail.com 13 | \------------------------------------------------------------------------*/ 14 | 15 | 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | /*======================================================= 29 | DEFINE 30 | =========================================================*/ 31 | #define SYSCALL_INTERRUPT 0x80 32 | #define NUMBER_OF_CALLS 24 33 | 34 | /*======================================================= 35 | PRIVATE DATA 36 | =========================================================*/ 37 | PRIVATE Module userModule; 38 | 39 | PRIVATE void* syscalls[NUMBER_OF_CALLS] = { 40 | 41 | &Console_printString, 42 | &Console_printChar, 43 | &ProcessManager_killProcess, 44 | &ProcessManager_spawnProcess, 45 | &VFS_changeDirectoryPtr, 46 | &VFS_getParent, 47 | &VFS_getWorkingDirectoryStr, 48 | &VFS_readDir, 49 | &VFS_getWorkingDirectoryPtr, 50 | &VFS_getFileStats, 51 | &Keyboard_getChar, 52 | &Console_clearScreen, 53 | &Sys_restart, 54 | &VFS_openFile, 55 | &VFS_closeFile, 56 | &VFS_read, 57 | &VFS_write, 58 | &VFS_mkdir, 59 | &HeapMemory_expandUser, 60 | &VFS_findDir, 61 | &VFS_changeDirectoryStr, 62 | &Console_setColor, 63 | &Sys_powerOff, 64 | &ProcessManager_waitPID, 65 | 66 | }; 67 | 68 | /*======================================================= 69 | FUNCTION 70 | =========================================================*/ 71 | 72 | PRIVATE void Usermode_syscallHandler(Regs* regs) { 73 | 74 | /* Valid call request? */ 75 | Debug_assert(regs->eax < NUMBER_OF_CALLS); 76 | 77 | int ret = 0; 78 | 79 | asm volatile("\ 80 | push %1; \ 81 | push %2; \ 82 | push %3; \ 83 | push %4; \ 84 | push %5; \ 85 | call *%6; \ 86 | pop %%ebx; \ 87 | pop %%ebx; \ 88 | pop %%ebx; \ 89 | pop %%ebx; \ 90 | pop %%ebx; \ 91 | " : "=a" (ret) : "r" (regs->edi), "r" (regs->esi), "r" (regs->edx), "r" (regs->ecx), "r" (regs->ebx), "r" (syscalls[regs->eax])); 92 | 93 | regs->eax = ret; /* Store return value in eax */ 94 | 95 | } 96 | 97 | PRIVATE void Usermode_init(void) { 98 | 99 | Debug_logInfo("%s", "Jumping to user space"); 100 | IDT_registerHandler(&Usermode_syscallHandler, SYSCALL_INTERRUPT); 101 | 102 | /* This is our initial user mode process */ 103 | Process* init = ProcessManager_spawnProcess("/Shell"); 104 | 105 | /* Add idle kernel process to process queue if the scheduler is preemptive */ 106 | if(Scheduler_isPreemptive()) { 107 | 108 | extern Process* kernelProcess; /* Defined in ProcessManager.c */ 109 | Scheduler_addProcess(kernelProcess); 110 | 111 | } 112 | 113 | /* Set task state segment and switch to initial process' stack and address space */ 114 | GDT_setTSS(KERNEL_DATA_SEGMENT, (u32int) init->kernelStack); 115 | asm volatile("mov %0, %%esp" : : "r" (init->userStack)); 116 | VirtualMemory_switchPageDir(init->pageDir); 117 | 118 | /* Change segments to user mode and jump to user code base address(defined in Common.h) */ 119 | asm volatile(" \ 120 | cli; \ 121 | mov $0x23, %%ax; \ 122 | mov %%ax, %%ds; \ 123 | mov %%ax, %%es; \ 124 | mov %%ax, %%fs; \ 125 | mov %%ax, %%gs; \ 126 | \ 127 | mov %%esp, %%eax; \ 128 | pushl $0x23; \ 129 | pushl %%eax; \ 130 | pushf; \ 131 | pop %%eax; \ 132 | or $0x200, %%eax; \ 133 | push %%eax; \ 134 | pushl $0x1B; \ 135 | push %0; \ 136 | iret; \ 137 | " : : "S" (USER_CODE_BASE_VADDR)); 138 | 139 | } 140 | 141 | PUBLIC Module* Usermode_getModule(void) { 142 | 143 | if(!userModule.isLoaded) { 144 | 145 | userModule.moduleName = "Usermode"; 146 | userModule.init = &Usermode_init; 147 | userModule.moduleID = MODULE_USERMODE; 148 | userModule.numberOfDependencies = 1; 149 | userModule.dependencies[0] = MODULE_PROCESS; 150 | 151 | } 152 | 153 | return &userModule; 154 | } -------------------------------------------------------------------------------- /kernel/src/Drivers/Console.c: -------------------------------------------------------------------------------- 1 | /** 2 | | Copyright(C) 2012 Ali Ersenal 3 | | License: WTFPL v2 4 | | URL: http://sam.zoy.org/wtfpl/COPYING 5 | | 6 | |-------------------------------------------------------------------------- 7 | | Console.c 8 | |-------------------------------------------------------------------------- 9 | | 10 | | DESCRIPTION: Text-Mode console driver. 11 | | 12 | | 13 | | AUTHOR: Ali Ersenal, aliersenal@gmail.com 14 | \------------------------------------------------------------------------*/ 15 | 16 | 17 | #include 18 | #include 19 | #include /* we need var-args for printf */ 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | /*======================================================= 26 | PRIVATE DATA 27 | =========================================================*/ 28 | PRIVATE Module console; 29 | PRIVATE u8int cursorX; 30 | PRIVATE u8int cursorY; 31 | PRIVATE u8int colorAttribute; 32 | 33 | /*======================================================= 34 | FUNCTION 35 | =========================================================*/ 36 | PRIVATE void Console_clearLine(u32int lineNo) { 37 | 38 | Debug_assert(lineNo < vgaHeight); 39 | 40 | for(int i = 0; i < vgaWidth; i++) { 41 | 42 | VGA_put(lineNo * vgaWidth + i, (CONSOLE_NORMAL << 0x8) + ' '); 43 | 44 | } 45 | } 46 | 47 | PRIVATE void Console_nextLine(void) { 48 | 49 | cursorX = 0; 50 | cursorY++; 51 | 52 | } 53 | 54 | PRIVATE void Console_previousLine(void) { 55 | 56 | cursorX = vgaWidth; 57 | cursorY--; 58 | 59 | } 60 | 61 | PRIVATE void Console_scrollDown(void) { 62 | 63 | /* move every line i to line i-1 */ 64 | for(int i = 1; i < vgaHeight; i++) { 65 | 66 | char* src = (char*) vgaRam + ((i) * vgaWidth * 2); 67 | char* dest = (char*) vgaRam + ((i - 1) * vgaWidth * 2); 68 | Memory_copy(dest, src, vgaWidth * 2); 69 | 70 | } 71 | 72 | /* clear last row */ 73 | cursorY = vgaHeight - 1; 74 | Console_clearLine(cursorY); 75 | 76 | } 77 | 78 | PRIVATE void Console_printInt(int integer) { 79 | 80 | char* s = String_numberToString(integer, 10); 81 | Console_printString(s); 82 | 83 | } 84 | 85 | PRIVATE void Console_init(void) { 86 | 87 | colorAttribute = CONSOLE_NORMAL; 88 | Console_clearScreen(); 89 | 90 | Debug_logInfo("%s%s", "Initialised ", console.moduleName); 91 | 92 | } 93 | 94 | PUBLIC void Console_printf(const char* template, ...) { 95 | 96 | va_list args; 97 | va_start(args, template); 98 | 99 | while(*(template) != '\0') { 100 | 101 | if(*template == '%') { 102 | switch(*(template + 1)) { 103 | 104 | case 'a': 105 | Console_setColor(va_arg(args, int)); 106 | break; 107 | 108 | case 'd': 109 | Console_printInt(va_arg(args, int)); 110 | break; 111 | 112 | case 'c': 113 | Console_printChar(va_arg(args, int)); 114 | break; 115 | 116 | case 's': 117 | Console_printString(va_arg(args, char*)); 118 | break; 119 | } 120 | } 121 | 122 | template++; 123 | } 124 | 125 | va_end(args); 126 | } 127 | 128 | PUBLIC void Console_printChar(u8int c) { 129 | 130 | switch(c) { 131 | 132 | case '\n': 133 | Console_nextLine(); 134 | break; 135 | 136 | case '\b': 137 | if(cursorX <= 0) 138 | Console_previousLine(); 139 | 140 | VGA_put(cursorY * vgaWidth + (cursorX - 1), (colorAttribute << 0x8) + ' '); 141 | cursorX--; 142 | break; 143 | 144 | default: 145 | VGA_put(cursorY * vgaWidth + cursorX, (colorAttribute << 0x8) + c); 146 | cursorX++; 147 | 148 | if(cursorX >= vgaWidth) 149 | Console_nextLine(); 150 | break; 151 | } 152 | 153 | if(cursorY >= vgaHeight) Console_scrollDown(); 154 | VGA_moveCursor(cursorY * vgaWidth + cursorX); 155 | 156 | } 157 | 158 | PUBLIC void Console_printString(const char* str) { 159 | 160 | while(*str != '\0') { 161 | Console_printChar(*str); 162 | str++; 163 | } 164 | 165 | } 166 | 167 | PUBLIC void Console_clearScreen(void) { 168 | 169 | for(int i = 0; i < vgaHeight; i++) 170 | Console_clearLine(i); 171 | 172 | cursorX = 0; 173 | cursorY = 0; 174 | VGA_moveCursor(cursorY * vgaWidth + cursorX); 175 | } 176 | 177 | PUBLIC void Console_setColor(u8int attribute) { 178 | 179 | colorAttribute = attribute; 180 | 181 | } 182 | 183 | PUBLIC Module* Console_getModule(void) { 184 | 185 | console.moduleName = "Console Driver"; 186 | console.numberOfDependencies = 1; 187 | console.dependencies[0] = MODULE_VGA; 188 | console.init = &Console_init; 189 | console.moduleID = MODULE_CONSOLE; 190 | 191 | return &console; 192 | 193 | } 194 | 195 | -------------------------------------------------------------------------------- /user/src/Apps/Shell.c: -------------------------------------------------------------------------------- 1 | /** 2 | | Copyright(C) 2012 Ali Ersenal 3 | | License: WTFPL v2 4 | | URL: http://sam.zoy.org/wtfpl/COPYING 5 | | 6 | |-------------------------------------------------------------------------- 7 | | Shell.c 8 | |-------------------------------------------------------------------------- 9 | | 10 | | DESCRIPTION: Simplistic user-space shell. 11 | | 12 | | AUTHOR: Ali Ersenal, aliersenal@gmail.com 13 | \------------------------------------------------------------------------*/ 14 | 15 | 16 | #include 17 | #include 18 | #include 19 | 20 | static char workingDirectory[64]; 21 | 22 | static void suicide(void); 23 | static void parseInput(char* in); 24 | static void cat(const char* path); 25 | static void ls(void); 26 | static void help(void); 27 | 28 | int main(void) { 29 | 30 | char entry[64]; 31 | char c = 0; 32 | int i = 0; 33 | 34 | cls(); 35 | color(WHITE); 36 | cat("logo.ascii"); 37 | color(LGREY); 38 | getcwd(workingDirectory); 39 | printf("%s%c", workingDirectory, '>'); 40 | 41 | while(1) { 42 | 43 | while((c = getch()) != '\n') { 44 | 45 | putc(c); /* Echo input */ 46 | 47 | /* Handle backspace */ 48 | if(c == '\b') { 49 | 50 | i--; 51 | entry[i] = '\0'; 52 | 53 | } else { 54 | 55 | entry[i] = c; 56 | i++; 57 | 58 | } 59 | 60 | } 61 | 62 | /* Handle enter */ 63 | putc('\n'); 64 | entry[i] = '\0'; 65 | i = 0; 66 | parseInput(entry); 67 | printf("%s%c", workingDirectory, '>'); 68 | 69 | } 70 | 71 | } 72 | 73 | static void parseInput(char* in) { 74 | 75 | char* command = strtok(in, " "); 76 | char* param = strtok(NULL, " "); 77 | 78 | if(command == NULL) 79 | return; 80 | 81 | if(strcmp(command, "exec") == 0) { /* Execute binary */ 82 | 83 | if(param == NULL) { 84 | puts("No parameter given\n"); 85 | return; 86 | } 87 | 88 | int pid = spawn(param); 89 | 90 | if(!pid) 91 | puts("Couldn't find that binary\n"); 92 | else 93 | waitpid(pid); 94 | 95 | } else if(strcmp(command, "cat") == 0) { /* Display file contents */ 96 | 97 | if(param == NULL) { 98 | puts("No parameter given\n"); 99 | return; 100 | } 101 | 102 | cat(param); 103 | 104 | } else if(strcmp(command, "cd") == 0) { /* change directory */ 105 | 106 | if(param == NULL) { 107 | puts("No parameter given\n"); 108 | return; 109 | } 110 | 111 | if(chdir(param) == NULL) 112 | puts("No such directory\n"); 113 | else 114 | getcwd(workingDirectory); 115 | 116 | } else if(strcmp(command, "ls") == 0) { /* list directory */ 117 | 118 | ls(); 119 | 120 | } else if(strcmp(command, "cls") == 0) { /* clear console */ 121 | 122 | cls(); 123 | 124 | } else if(strcmp(command, "restart") == 0) { /* restart machine */ 125 | 126 | restart(); 127 | 128 | } else if(strcmp(command, "shutdown") == 0) { /* shut down machine */ 129 | 130 | poweroff(); 131 | suicide(); /* panic if not successful */ 132 | 133 | } else if(strcmp(command, "help") == 0) { /* list valid commands */ 134 | 135 | help(); 136 | 137 | } else if(strcmp(command, "suicide") == 0) { /* kills the shell */ 138 | 139 | suicide(); 140 | 141 | } else { 142 | 143 | puts("Unknown command\n"); 144 | 145 | } 146 | 147 | } 148 | 149 | static void suicide(void) { 150 | 151 | /* raise a page fault */ 152 | char* f = 0; 153 | *f = 0; 154 | 155 | } 156 | 157 | static void cat(const char* path) { 158 | 159 | FILE* file = open(path, "r"); 160 | if(file == NULL) { 161 | puts("Couldn't find that file\n"); 162 | return; 163 | } 164 | 165 | struct stat fileStat; 166 | fstat(file, &fileStat); 167 | char buf[fileStat.fileSize + 1]; 168 | read(file, 0, fileStat.fileSize, buf); 169 | printf("%s%c", buf, '\n'); 170 | close(file); 171 | 172 | } 173 | 174 | static void ls(void) { 175 | 176 | FILE* cwd = fgetcwd(); 177 | FILE* file = 0; 178 | int i = 0; 179 | struct stat buf; 180 | 181 | while((file = readdir(cwd, i))) { 182 | 183 | fstat(file, &buf); 184 | printf("%s%s%d%s", buf.fileName, ", ", buf.fileSize, "bytes\n"); 185 | i++; 186 | 187 | } 188 | 189 | } 190 | 191 | static void help(void) { 192 | 193 | puts( 194 | "ls - list files inside current working directory\n" 195 | "cd [dir] - change working directory\n" 196 | "cls - clear console\n" 197 | "cat [file] - display file contents\n" 198 | "restart - restart machine\n" 199 | "exec [file] - execute binary file\n" 200 | "suicide - kills the shell\n" 201 | "shutdown - shuts down the machine\n" 202 | ); 203 | 204 | } -------------------------------------------------------------------------------- /kernel/src/Drivers/Mouse.c: -------------------------------------------------------------------------------- 1 | /** 2 | | Copyright(C) 2012 Ali Ersenal 3 | | License: WTFPL v2 4 | | URL: http://sam.zoy.org/wtfpl/COPYING 5 | | 6 | |-------------------------------------------------------------------------- 7 | | Mouse.c 8 | |-------------------------------------------------------------------------- 9 | | 10 | | DESCRIPTION: Interrupt based PS/2 mouse driver. 11 | | 12 | | AUTHOR: Ali Ersenal, aliersenal@gmail.com 13 | \------------------------------------------------------------------------*/ 14 | 15 | 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #pragma GCC diagnostic ignored "-Wstrict-aliasing" /* ignore FORCE_CAST compiler warning */ 23 | 24 | /*======================================================= 25 | DEFINE 26 | =========================================================*/ 27 | 28 | #define MS_INT 44 /* ps/2 mouse interrupt number(IRQ 12) */ 29 | 30 | /** Command Bytes - sent from PS/2 controller to mouse */ 31 | #define MS_C_SELECT_PORT_2 0xD4 /* next byte will be sent to port 2(mouse) */ 32 | #define MS_C_RESET 0xFF /* resets mouse */ 33 | #define MS_C_ENABLE_AUX 0xA8 /* enables auxiliary mouse device */ 34 | #define MS_C_GET_COMPAQ 0x20 /* retrieve compaq status byte */ 35 | #define MS_C_SET_COMPAQ 0x60 /* sets the compaq status byte */ 36 | #define MS_C_DEFAULT 0xF6 /* default mouse settings */ 37 | #define MS_C_ENABLE 0xF4 /* enables packet streaming */ 38 | #define MS_C_DISABLE 0xF5 /* disables packet streaming */ 39 | 40 | /** Response Bytes - sent from mouse to PS/2 controller */ 41 | #define MS_R_ACK 0xFA /* command acknowledged */ 42 | 43 | /** Debug Messages */ 44 | #define MS_M_DEFAULT_1 "Mouse set to default" 45 | #define MS_M_DEFAULT_0 "Mouse could not be set to default" 46 | #define MS_M_ENABLE_1 "Mouse packet streaming enabled" 47 | #define MS_M_ENABLE_0 "Mouse packet streaming could not be enabled" 48 | 49 | /*======================================================= 50 | STRUCTS 51 | =========================================================*/ 52 | typedef struct MByte0 MByte0; 53 | typedef struct MByte1 MByte1; 54 | typedef struct MByte2 MByte2; 55 | typedef struct MousePacket MousePacket; 56 | 57 | struct MByte0 { 58 | 59 | u8int leftBtn : 1; /* is left button being pressed? */ 60 | u8int rightBtn : 1; /* is right button being pressed? */ 61 | u8int middleBtn : 1; /* is middle button being pressed? */ 62 | u8int always1 : 1; 63 | u8int xSign : 1; /* indicates MByte1 sign */ 64 | u8int ySign : 1; /* indicates MByte2 sign */ 65 | u8int xOverflow : 1; 66 | u8int yOverflow : 1; 67 | 68 | } __attribute__((packed)); 69 | 70 | struct MByte1 { 71 | u8int xMovement : 8; 72 | } __attribute__((packed)); 73 | 74 | struct MByte2 { 75 | u8int yMovement : 8; 76 | } __attribute__((packed)); 77 | 78 | struct MousePacket { 79 | 80 | MByte0 byte0; 81 | MByte1 byte1; 82 | MByte2 byte2; 83 | 84 | }; 85 | 86 | /*======================================================= 87 | PRIVATE DATA 88 | =========================================================*/ 89 | PRIVATE MousePacket packet; 90 | PRIVATE u8int cycle; 91 | 92 | /*======================================================= 93 | FUNCTION 94 | =========================================================*/ 95 | 96 | /** No commands are SENT to the mouse after enabling interrupts(IRQ) 97 | * should receive an ack after sending a command */ 98 | PRIVATE bool Mouse_sendCommand(u8int command) { 99 | 100 | PS2Controller_send(PS2_STATE, MS_C_SELECT_PORT_2); 101 | PS2Controller_send(PS2_DATA, command); 102 | 103 | if(PS2Controller_receive(PS2_DATA) != MS_R_ACK) return 0; 104 | else return 1; 105 | 106 | } 107 | 108 | PRIVATE void Mouse_callback(void) { 109 | 110 | u8int b = PS2Controller_receive(PS2_DATA); 111 | 112 | switch(cycle) { 113 | 114 | case 0: 115 | packet.byte0 = FORCE_CAST(b, MByte0); 116 | cycle++; 117 | break; 118 | 119 | case 1: 120 | packet.byte1 = FORCE_CAST(b, MByte1); 121 | cycle++; 122 | break; 123 | 124 | case 2: 125 | packet.byte2 = FORCE_CAST(b, MByte2); 126 | cycle = 0; 127 | 128 | /* discard if overflows are set */ 129 | if(packet.byte0.xOverflow || packet.byte0.yOverflow) break; 130 | 131 | /* mouse packet ready to use */ 132 | // Console_printf("%d%c%d", packet.byte1.xMovement, ',', packet.byte2.yMovement); 133 | break; 134 | 135 | } 136 | 137 | } 138 | 139 | PUBLIC void Mouse_init(void) { 140 | 141 | Debug_logInfo("%s", "Initialising Mouse"); 142 | 143 | /* Enable auxiliary mouse device */ 144 | PS2Controller_send(PS2_STATE,MS_C_ENABLE_AUX); 145 | PS2Controller_receive(PS2_DATA); /* flush */ 146 | 147 | /* tell mouse to use default settings */ 148 | if(Mouse_sendCommand(MS_C_DEFAULT)) { 149 | 150 | Debug_logInfo("%s", MS_M_DEFAULT_1); 151 | 152 | } else { 153 | 154 | Debug_logError("%s", MS_M_DEFAULT_0); 155 | 156 | } 157 | 158 | /* Enable packet streaming */ 159 | if(Mouse_sendCommand(MS_C_ENABLE)) { 160 | 161 | Debug_logInfo("%s", MS_M_ENABLE_1); 162 | 163 | } else { 164 | 165 | Debug_logError("%s", MS_M_ENABLE_0); 166 | 167 | } 168 | 169 | IDT_registerHandler(&Mouse_callback, MS_INT); 170 | 171 | /* Unmask IRQ12 */ 172 | PIC8259_setMask(12, CLEAR_MASK); 173 | 174 | /* Also unmask IRQ2 - cascade IRQ(enables access to slave IRQs ranging 8 - 15) */ 175 | PIC8259_setMask(2, CLEAR_MASK); 176 | 177 | } -------------------------------------------------------------------------------- /user/src/Lib/libc/string.c: -------------------------------------------------------------------------------- 1 | /** 2 | | 3 | | Code borrowed from musl libc. 4 | | 5 | \------------------------------*/ 6 | 7 | /* musl as a whole is licensed under the following standard MIT license: 8 | 9 | Copyright © 2005-2013 Rich Felker 10 | 11 | Permission is hereby granted, free of charge, to any person obtaining 12 | a copy of this software and associated documentation files (the 13 | "Software"), to deal in the Software without restriction, including 14 | without limitation the rights to use, copy, modify, merge, publish, 15 | distribute, sublicense, and/or sell copies of the Software, and to 16 | permit persons to whom the Software is furnished to do so, subject to 17 | the following conditions: 18 | 19 | The above copyright notice and this permission notice shall be 20 | included in all copies or substantial portions of the Software. */ 21 | 22 | #include 23 | #include 24 | #include 25 | 26 | /* Silence the compiler warnings, I trust musl */ 27 | #pragma GCC diagnostic push 28 | #pragma GCC diagnostic ignored "-Wparentheses" 29 | #pragma GCC diagnostic ignored "-Wpointer-sign" 30 | 31 | void *memset(void *dest, int c, size_t n) 32 | { 33 | unsigned char *s = dest; 34 | c = (unsigned char)c; 35 | for (; ((uintptr_t)s & (sizeof(size_t)-1)) && n; n--) *s++ = c; 36 | if (n) { 37 | size_t *w, k = ((size_t)-1/UCHAR_MAX) * c; 38 | for (w = (void *)s; n>=(sizeof(size_t)); n-=(sizeof(size_t)), w++) *w = k; 39 | for (s = (void *)w; n; n--, s++) *s = c; 40 | } 41 | return dest; 42 | } 43 | 44 | void *memcpy(void *restrict dest, const void *restrict src, size_t n) 45 | { 46 | unsigned char *d = dest; 47 | const unsigned char *s = src; 48 | 49 | if (((uintptr_t)d & (sizeof(size_t)-1)) != ((uintptr_t)s & (sizeof(size_t)-1))) 50 | goto misaligned; 51 | 52 | for (; ((uintptr_t)d & (sizeof(size_t)-1)) && n; n--) *d++ = *s++; 53 | if (n) { 54 | size_t *wd = (void *)d; 55 | const size_t *ws = (const void *)s; 56 | 57 | for (; n>=(sizeof(size_t)); n-=(sizeof(size_t))) *wd++ = *ws++; 58 | d = (void *)wd; 59 | s = (const void *)ws; 60 | misaligned: 61 | for (; n; n--) *d++ = *s++; 62 | } 63 | return dest; 64 | } 65 | 66 | void *memmove(void *dest, const void *src, size_t n) 67 | { 68 | char *d = dest; 69 | const char *s = src; 70 | 71 | if (d==s) return d; 72 | if (s+n <= d || d+n <= s) return memcpy(d, s, n); 73 | 74 | if (d=(sizeof(size_t)); n-=(sizeof(size_t)), d+=(sizeof(size_t)), s+=(sizeof(size_t))) *(size_t *)d = *(size_t *)s; 81 | } 82 | for (; n; n--) *d++ = *s++; 83 | } else { 84 | if ((uintptr_t)s % (sizeof(size_t)) == (uintptr_t)d % (sizeof(size_t))) { 85 | while ((uintptr_t)(d+n) % (sizeof(size_t))) { 86 | if (!n--) return dest; 87 | d[n] = s[n]; 88 | } 89 | while (n>=(sizeof(size_t))) n-=(sizeof(size_t)), *(size_t *)(d+n) = *(size_t *)(s+n); 90 | } 91 | while (n) n--, d[n] = s[n]; 92 | } 93 | 94 | return dest; 95 | } 96 | 97 | size_t strlen(const char *s) 98 | { 99 | const char *a = s; 100 | const size_t *w; 101 | for (; (uintptr_t)s % (sizeof(size_t)); s++) if (!*s) return s-a; 102 | for (w = (const void *)s; !((*w)-((size_t)-1/UCHAR_MAX) & ~(*w) & (((size_t)-1/UCHAR_MAX) * (UCHAR_MAX/2+1))); w++); 103 | for (s = (const void *)w; *s; s++); 104 | return s-a; 105 | } 106 | 107 | int strcmp(const char *l, const char *r) 108 | { 109 | for (; *l==*r && *l && *r; l++, r++); 110 | return *(unsigned char *)l - *(unsigned char *)r; 111 | } 112 | 113 | char *strcpy(char *restrict dest, const char *restrict src) 114 | { 115 | const unsigned char *s = src; 116 | unsigned char *d = dest; 117 | while ((*d++ = *s++)); 118 | return dest; 119 | } 120 | 121 | char *strcat(char *restrict dest, const char *restrict src) 122 | { 123 | strcpy(dest + strlen(dest), src); 124 | return dest; 125 | } 126 | 127 | char *strchrnul(const char *s, int c) 128 | { 129 | #define HASZERO_chrnul(x) ((x)-((size_t)-1/UCHAR_MAX) & ~(x) & (((size_t)-1/UCHAR_MAX) * (UCHAR_MAX/2+1))) 130 | 131 | size_t *w, k; 132 | 133 | c = (unsigned char)c; 134 | if (!c) return (char *)s + strlen(s); 135 | 136 | for (; (uintptr_t)s % (sizeof(size_t)); s++) 137 | if (!*s || *(unsigned char *)s == c) return (char *)s; 138 | k = ((size_t)-1/UCHAR_MAX) * c; 139 | for (w = (void *)s; !HASZERO_chrnul(*w) && !HASZERO_chrnul(*w^k); w++); 140 | for (s = (void *)w; *s && *(unsigned char *)s != c; s++); 141 | return (char *)s; 142 | } 143 | 144 | 145 | size_t strspn(const char *s, const char *c) 146 | { 147 | 148 | #define BITOP(a,b,op) ((a)[(size_t)(b)/(8*sizeof *(a))] op (size_t)1<<((size_t)(b)%(8*sizeof *(a)))) 149 | 150 | const char *a = s; 151 | size_t byteset[32/sizeof(size_t)] = { 0 }; 152 | 153 | if (!c[0]) return 0; 154 | if (!c[1]) { 155 | for (; *s == *c; s++); 156 | return s-a; 157 | } 158 | 159 | for (; *c && BITOP(byteset, *(unsigned char *)c, |=); c++); 160 | for (; *s && BITOP(byteset, *(unsigned char *)s, &); s++); 161 | return s-a; 162 | } 163 | 164 | size_t strcspn(const char *s, const char *c) 165 | { 166 | #define BITOP_CSPN(a,b,op) ((a)[(size_t)(b)/(8*sizeof *(a))] op (size_t)1<<((size_t)(b)%(8*sizeof *(a)))) 167 | 168 | const char *a = s; 169 | size_t byteset[32/sizeof(size_t)]; 170 | 171 | if (!c[0] || !c[1]) return strchrnul(s, *c)-a; 172 | 173 | memset(byteset, 0, sizeof byteset); 174 | for (; *c && BITOP_CSPN(byteset, *(unsigned char *)c, |=); c++); 175 | for (; *s && !BITOP_CSPN(byteset, *(unsigned char *)s, &); s++); 176 | return s-a; 177 | } 178 | 179 | char *strtok(char *restrict s, const char *restrict sep) 180 | { 181 | static char *p; 182 | if (!s && !(s = p)) return NULL; 183 | s += strspn(s, sep); 184 | if (!*s) return p = 0; 185 | p = s + strcspn(s, sep); 186 | if (*p) *p++ = 0; 187 | else p = 0; 188 | return s; 189 | } 190 | 191 | #pragma GCC diagnostic pop -------------------------------------------------------------------------------- /kernel/src/X86/PIT8253.c: -------------------------------------------------------------------------------- 1 | /** 2 | | Copyright(C) 2012 Ali Ersenal 3 | | License: WTFPL v2 4 | | URL: http://sam.zoy.org/wtfpl/COPYING 5 | | 6 | |-------------------------------------------------------------------------- 7 | | PIT8253.c 8 | |-------------------------------------------------------------------------- 9 | | 10 | | DESCRIPTION: Provides an interface for Intel 8253 Programmable Interval 11 | | Timer(PIT). 12 | | 13 | | PIT consists of three timers(channels). Each has a different 14 | | purpose. 15 | | 16 | | First Timer - Used as the System timer 17 | | Second Timer - Used for RAM refreshing 18 | | Third Timer - Connected to PC speaker(that annoying beeper) 19 | | 20 | | AUTHOR: Ali Ersenal, aliersenal@gmail.com 21 | | 22 | | TYPE comments source: 23 | | http://stanislavs.org/helppc/8259.html 24 | \------------------------------------------------------------------------*/ 25 | 26 | 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | 35 | /*======================================================= 36 | DEFINE 37 | =========================================================*/ 38 | 39 | /* 8253 Register I/O Ports */ 40 | #define PORT_CHANNEL_0 0x40 /* System timer - connected to PIC IRQ0, generates an interrupt every clock tick. */ 41 | #define PORT_CHANNEL_1 0x41 /* We do not utilise this channel */ 42 | #define PORT_CHANNEL_2 0x42 /* We do not utilise this channel */ 43 | #define PORT_CONTROL 0x43 /* Sets PIT operation modes - Write only register */ 44 | 45 | /* The system timer fires IRQ0 every 10 ms 46 | * 47 | * DIVIDER = (INPUT_HZ / OUTPUT_HZ) = 11931.8 48 | * (INPUT_HZ / DIVIDER) = 100Hz, each clock tick 10ms 49 | */ 50 | #define INPUT_HZ 1193180 /* Input frequency */ 51 | #define OUTPUT_HZ 100 /* Output frequency */ 52 | 53 | /*======================================================= 54 | TYPE 55 | =========================================================*/ 56 | 57 | /* Control Register 58 | 59 | |7|6|5|4|3|2|1|0| Mode Control Register 60 | | | | | | | | `---- 0=16 binary counter, 1=4 decade BCD counter 61 | | | | | `--------- counter mode bits 62 | | | `------------ read/write/latch format bits 63 | `--------------- counter select bits 64 | 65 | Bits Counter Select Bits 66 | 00 select counter 0 67 | 01 select counter 1 68 | 10 select counter 2 69 | 70 | Bits Read/Write/Latch Format Bits 71 | 00 latch present counter value 72 | 01 read/write of MSB only 73 | 10 read/write of LSB only 74 | 11 read/write LSB, followed by write of MSB 75 | 76 | Bits Counter Mode Bits 77 | 000 mode 0, interrupt on terminal count; countdown, interrupt, 78 | then wait for a new mode or count; loading a new count in the 79 | middle of a count stops the countdown 80 | 001 mode 1, programmable one-shot; countdown with optional 81 | restart; reloading the counter will not affect the countdown 82 | until after the following trigger 83 | 010 mode 2, rate generator; generate one pulse after 'count' CLK 84 | cycles; output remains high until after the new countdown has 85 | begun; reloading the count mid-period does not take affect 86 | until after the period 87 | 011 mode 3, square wave rate generator; generate one pulse after 88 | 'count' CLK cycles; output remains high until 1/2 of the next 89 | countdown; it does this by decrementing by 2 until zero, at 90 | which time it lowers the output signal, reloads the counter 91 | and counts down again until interrupting at 0; reloading the 92 | count mid-period does not take affect until after the period 93 | 100 mode 4, software triggered strobe; countdown with output high 94 | until counter zero; at zero output goes low for one CLK 95 | period; countdown is triggered by loading counter; reloading 96 | counter takes effect on next CLK pulse 97 | 101 mode 5, hardware triggered strobe; countdown after triggering 98 | with output high until counter zero; at zero output goes low 99 | */ 100 | typedef u8int ControlRegister; 101 | 102 | /*======================================================= 103 | PRIVATE DATA 104 | =========================================================*/ 105 | PRIVATE Module pitModule; 106 | PRIVATE u32int tick; 107 | 108 | /*======================================================= 109 | FUNCTION 110 | =========================================================*/ 111 | 112 | PRIVATE void PIT8253_timerHandler(Regs* regs) { 113 | 114 | tick++; 115 | 116 | /* Do context switch only if the process management module is loaded */ 117 | if(ProcessManager_getModule()->isLoaded) { 118 | 119 | if(tick % 2 == 0) /* context switch every 20ms */ 120 | ProcessManager_switch(regs); 121 | else /* Set DR0(stores process ESP) to NULL if we don't call the scheduler */ 122 | asm volatile("mov %0, %%DR0" : : "a" (0)); 123 | 124 | } 125 | 126 | } 127 | 128 | PRIVATE void PIT8253_init(void) { 129 | 130 | Debug_logInfo("%s%s", "Initialising ", pitModule.moduleName); 131 | 132 | u16int divisor = INPUT_HZ / OUTPUT_HZ; 133 | 134 | /* Set channel 0 control mode */ 135 | ControlRegister cr = 0b00110110; 136 | IO_outB(PORT_CONTROL, cr); 137 | 138 | /* Send the frequency divisor. */ 139 | IO_outB(PORT_CHANNEL_0, divisor); /* Send lower byte */ 140 | IO_outB(PORT_CHANNEL_0, divisor >> 8); /* Send higher byte */ 141 | 142 | /* Register timer IRQ0 handler */ 143 | IDT_registerHandler(&PIT8253_timerHandler, IRQ0); 144 | 145 | /* Unmask IRQ0 */ 146 | PIC8259_setMask(0, 0); 147 | 148 | } 149 | 150 | PUBLIC u32int PIT8253_measureRuntime(void* functionAddr) { 151 | 152 | u32int beforeTick = tick; 153 | 154 | void (*function) (void) = functionAddr; 155 | function(); 156 | 157 | return tick - beforeTick; 158 | 159 | } 160 | 161 | /* GCC without O0 tends to optimise busy waits, prevent that for this function */ 162 | #pragma GCC push_options 163 | #pragma GCC optimize ("O0") 164 | PUBLIC void PIT8253_sleep(u32int ms) { 165 | 166 | ms /= 10; 167 | u32int begin = tick; 168 | while(tick < (ms + begin)) 169 | Sys_haltCPU(); 170 | 171 | } 172 | #pragma GCC pop_options 173 | 174 | PUBLIC Module* PIT8253_getModule(void) { 175 | 176 | if(!pitModule.isLoaded) { 177 | 178 | pitModule.moduleName = "8253 PIT"; 179 | pitModule.moduleID = MODULE_PIT8253; 180 | pitModule.init = &PIT8253_init; 181 | pitModule.numberOfDependencies = 1; 182 | pitModule.dependencies[0] = MODULE_IDT; 183 | 184 | } 185 | 186 | return &pitModule; 187 | } 188 | -------------------------------------------------------------------------------- /kernel/include/Memory/VirtualMemory.h: -------------------------------------------------------------------------------- 1 | /** 2 | | Copyright(C) 2012 Ali Ersenal 3 | | License: WTFPL v2 4 | | URL: http://sam.zoy.org/wtfpl/COPYING 5 | | 6 | |-------------------------------------------------------------------------- 7 | | VirtualMemory.h 8 | |-------------------------------------------------------------------------- 9 | | 10 | | DESCRIPTION: Platform dependent X86 virtual memory manager, initialiser. 11 | | 12 | | AUTHOR: Ali Ersenal, aliersenal@gmail.com 13 | \------------------------------------------------------------------------*/ 14 | 15 | 16 | #ifndef VMM_H 17 | #define VMM_H 18 | 19 | #include 20 | #include 21 | 22 | /*======================================================= 23 | DEFINE 24 | =========================================================*/ 25 | #define MODE_KERNEL 0 26 | #define MODE_USER 1 27 | 28 | #define TEMPORARY_MAP_VADDR 0xF00000 29 | 30 | /*======================================================= 31 | TYPE 32 | =========================================================*/ 33 | typedef struct PageDirectory PageDirectory; 34 | 35 | /*======================================================= 36 | FUNCTION 37 | =========================================================*/ 38 | 39 | /*------------------------------------------------------------------------- 40 | | Get VMM module 41 | |-------------------------------------------------------------------------- 42 | | DESCRIPTION: Returns virtual memory manager module. 43 | | 44 | \------------------------------------------------------------------------*/ 45 | Module* VirtualMemory_getModule(void); 46 | 47 | /*------------------------------------------------------------------------- 48 | | Map virtual address 49 | |-------------------------------------------------------------------------- 50 | | DESCRIPTION: Maps a virtual address to a physical address 51 | | 52 | | PARAM: "virtualAddr" 4KB aligned virtual address 53 | | "physicalAddr" 4KB aligned physical address 54 | | "mode" 0 - Kernel mode, 1 - User mode 55 | | 56 | | RETURN: 'void*' mapped virtual address 57 | \------------------------------------------------------------------------*/ 58 | void* VirtualMemory_mapPage(PageDirectory* dir, void* virtualAddr, void* physicalAddr, bool mode); 59 | 60 | /*------------------------------------------------------------------------- 61 | | Unmap virtual address 62 | |-------------------------------------------------------------------------- 63 | | DESCRIPTION: Unmaps a virtual address 64 | | 65 | | PARAM: "virtualAddr" 4KB aligned virtual address 66 | \------------------------------------------------------------------------*/ 67 | void VirtualMemory_unmapPage(PageDirectory* dir, void* virtualAddr); 68 | 69 | /*------------------------------------------------------------------------- 70 | | Get physical address 71 | |-------------------------------------------------------------------------- 72 | | DESCRIPTION: Returns the physical address of a mapped virtual address. 73 | | 74 | | PARAM: "virtualAddr" 4KB aligned virtual address 75 | | 76 | | RETURN: 'void*' the physical address 77 | \------------------------------------------------------------------------*/ 78 | void* VirtualMemory_getPhysicalAddress(void* virtualAddr); 79 | 80 | /*------------------------------------------------------------------------- 81 | | Quick map 82 | |-------------------------------------------------------------------------- 83 | | DESCRIPTION: Temporarily maps a virtual address to a physical address. 84 | | Maps to current page directory. 85 | | 86 | | PARAM: "virtualAddr" 4KB aligned virtual address 87 | | "physicalAddr" 4KB aligned physical address 88 | | 89 | | RETURN: 'void*' the virtual address 90 | \------------------------------------------------------------------------*/ 91 | void* VirtualMemory_quickMap(void* virtualAddr, void* physicalAddr); 92 | 93 | /*------------------------------------------------------------------------- 94 | | Quick unmap 95 | |-------------------------------------------------------------------------- 96 | | DESCRIPTION: Unmaps a virtual address from current page directory. 97 | | 98 | | PARAM: "virtualAddr" 4KB aligned virtual address 99 | \------------------------------------------------------------------------*/ 100 | void VirtualMemory_quickUnmap(void* virtualAddr); 101 | 102 | /*------------------------------------------------------------------------- 103 | | Get kernel directory 104 | |-------------------------------------------------------------------------- 105 | | DESCRIPTION: Returns the kernel's page directory 106 | | 107 | | RETURN: 'PageDirectory*' the kernel page directory 108 | \------------------------------------------------------------------------*/ 109 | PageDirectory* VirtualMemory_getKernelDir(void); 110 | 111 | /*------------------------------------------------------------------------- 112 | | Switch page directory 113 | |-------------------------------------------------------------------------- 114 | | DESCRIPTION: Changes the current page directory(address space) to specified one. 115 | | 116 | | PARAM: "dir" the page directory to switch to 117 | \------------------------------------------------------------------------*/ 118 | void VirtualMemory_switchPageDir(PageDirectory* dir); 119 | 120 | /*------------------------------------------------------------------------- 121 | | Map kernel 122 | |-------------------------------------------------------------------------- 123 | | DESCRIPTION: Maps the OS kernel to specified process' page directory 124 | | 125 | | PARAM: 'process' the process to map to 126 | \------------------------------------------------------------------------*/ 127 | void VirtualMemory_mapKernel(Process* process); 128 | 129 | /*------------------------------------------------------------------------- 130 | | Create page directory 131 | |-------------------------------------------------------------------------- 132 | | DESCRIPTION: Creates a new page directory for the specified process. 133 | | 134 | | PARAM: 'process' the process to create page directory for 135 | \------------------------------------------------------------------------*/ 136 | void VirtualMemory_createPageDirectory(Process* process); 137 | 138 | /*------------------------------------------------------------------------- 139 | | Destroy page directory 140 | |-------------------------------------------------------------------------- 141 | | DESCRIPTION: Destroys(deallocates) a page directory from the specified process. 142 | | 143 | | PARAM: 'process' the process to destroy page directory from 144 | \------------------------------------------------------------------------*/ 145 | void VirtualMemory_destroyPageDirectory(Process* process); 146 | #endif -------------------------------------------------------------------------------- /kernel/src/Memory/HeapMemory.c: -------------------------------------------------------------------------------- 1 | /** 2 | | Copyright(C) 2012 Ali Ersenal 3 | | License: WTFPL v2 4 | | URL: http://sam.zoy.org/wtfpl/COPYING 5 | | 6 | |-------------------------------------------------------------------------- 7 | | HeapMemory.c 8 | |-------------------------------------------------------------------------- 9 | | 10 | | DESCRIPTION: Heap memory manager interface. 11 | | Sets up and manages heap memory. 12 | | 13 | | AUTHOR: Ali Ersenal, aliersenal@gmail.com 14 | \------------------------------------------------------------------------*/ 15 | 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | /* Include Heap manager implementation */ 25 | /* #include */ 26 | #include 27 | 28 | /*======================================================= 29 | PRIVATE DATA 30 | =========================================================*/ 31 | PRIVATE Module heapModule; 32 | PRIVATE char* kernelHeapTop; 33 | 34 | /*======================================================= 35 | PUBLIC DATA 36 | =========================================================*/ 37 | PUBLIC void* (*HeapMemory_alloc) (size_t bytes); 38 | PUBLIC void* (*HeapMemory_realloc) (void* oldmem, size_t bytes); 39 | PUBLIC void* (*HeapMemory_calloc) (size_t numberOfElements, size_t elementSize); 40 | PUBLIC void (*HeapMemory_free) (void* mem); 41 | 42 | /*======================================================= 43 | FUNCTION 44 | =========================================================*/ 45 | 46 | PRIVATE void HeapMemory_init(void) { 47 | 48 | Debug_logInfo("%s%s", "Initialising ", heapModule.moduleName); 49 | 50 | kernelHeapTop = (void*) KERNEL_HEAP_BASE_VADDR; 51 | 52 | /* Point to heap manager implementation */ 53 | HeapMemory_alloc = &DougLea_malloc; 54 | HeapMemory_realloc = &DougLea_realloc; 55 | HeapMemory_calloc = &DougLea_calloc; 56 | HeapMemory_free = &DougLea_free; 57 | 58 | } 59 | 60 | PUBLIC void* HeapMemory_expand(ptrdiff_t size) { 61 | 62 | Debug_assert(size % FRAME_SIZE == 0); /* requested size needs to be page aligned */ 63 | Debug_assert((u32int) kernelHeapTop % FRAME_SIZE == 0); /* heap top needs to be page aligned */ 64 | 65 | /* The number of needed pages */ 66 | u32int pages = size / FRAME_SIZE; 67 | 68 | if(size >= 0) { /* Expand heap */ 69 | 70 | Debug_assert((u32int) kernelHeapTop + size < KERNEL_HEAP_TOP_VADDR); /* heap should not overflow */ 71 | void* ret = kernelHeapTop; 72 | 73 | for(u32int i = 0; i < pages; i++) { 74 | 75 | void* physicalAddress = PhysicalMemory_allocateFrame(); 76 | 77 | if(physicalAddress == NULL) /* Are we out of physical memory? */ 78 | Sys_panic("Out of physical memory!"); 79 | 80 | if(Scheduler_getCurrentProcess == NULL || Scheduler_getCurrentProcess() == NULL) 81 | VirtualMemory_mapPage(VirtualMemory_getKernelDir(), kernelHeapTop, physicalAddress, MODE_KERNEL); 82 | else 83 | VirtualMemory_mapPage(Scheduler_getCurrentProcess()->pageDir, kernelHeapTop, physicalAddress, MODE_KERNEL); 84 | 85 | Memory_set(kernelHeapTop, 0, FRAME_SIZE); /* Nullify allocated frame */ 86 | kernelHeapTop += FRAME_SIZE; 87 | 88 | } 89 | 90 | return ret; 91 | 92 | } else { /* Contract heap */ 93 | 94 | Debug_assert((u32int) kernelHeapTop - size >= KERNEL_HEAP_BASE_VADDR); /* heap should not underflow */ 95 | 96 | for(u32int i = 0; i < pages * -1; i++) { 97 | 98 | kernelHeapTop -= FRAME_SIZE; 99 | Debug_assert(kernelHeapTop >= (char*) KERNEL_HEAP_BASE_VADDR); 100 | 101 | void* physicalAddress = VirtualMemory_getPhysicalAddress(kernelHeapTop); 102 | Debug_assert(physicalAddress != NULL); 103 | PhysicalMemory_freeFrame(physicalAddress); 104 | 105 | if(Scheduler_getCurrentProcess == NULL || Scheduler_getCurrentProcess() == NULL) 106 | VirtualMemory_unmapPage(VirtualMemory_getKernelDir(), kernelHeapTop); 107 | else 108 | VirtualMemory_unmapPage(Scheduler_getCurrentProcess()->pageDir, kernelHeapTop); 109 | 110 | } 111 | 112 | return kernelHeapTop; 113 | 114 | } 115 | 116 | } 117 | 118 | PUBLIC void* HeapMemory_expandUser(ptrdiff_t size) { 119 | 120 | Process* currentProcess = Scheduler_getCurrentProcess(); 121 | 122 | Debug_assert(size % FRAME_SIZE == 0); /* requested size needs to be page aligned */ 123 | Debug_assert((u32int) currentProcess->userHeapTop % FRAME_SIZE == 0); /* heap top needs to be page aligned */ 124 | 125 | /* The number of needed pages */ 126 | u32int pages = size / FRAME_SIZE; 127 | 128 | if(size >= 0) { /* Expand heap */ 129 | 130 | Debug_assert((u32int) currentProcess->userHeapTop + size < USER_HEAP_TOP_VADDR); /* heap should not overflow */ 131 | void* ret = currentProcess->userHeapTop; 132 | 133 | for(u32int i = 0; i < pages; i++) { 134 | 135 | void* physicalAddress = PhysicalMemory_allocateFrame(); 136 | 137 | if(physicalAddress == NULL) /* Are we out of physical memory? */ 138 | Sys_panic("Out of physical memory!"); 139 | 140 | VirtualMemory_mapPage(Scheduler_getCurrentProcess()->pageDir, currentProcess->userHeapTop, physicalAddress, MODE_USER); 141 | 142 | Memory_set(currentProcess->userHeapTop, 0, FRAME_SIZE); /* Nullify allocated frame */ 143 | currentProcess->userHeapTop += FRAME_SIZE; 144 | 145 | } 146 | 147 | return ret; 148 | 149 | } else { /* Contract heap */ 150 | 151 | Debug_assert((u32int) currentProcess->userHeapTop - size >= USER_HEAP_BASE_VADDR); /* heap should not underflow */ 152 | 153 | for(u32int i = 0; i < pages * -1; i++) { 154 | 155 | currentProcess->userHeapTop -= FRAME_SIZE; 156 | Debug_assert((char*) currentProcess->userHeapTop >= (char*) USER_HEAP_BASE_VADDR); 157 | 158 | void* physicalAddress = VirtualMemory_getPhysicalAddress(currentProcess->userHeapTop); 159 | Debug_assert(physicalAddress != NULL); 160 | PhysicalMemory_freeFrame(physicalAddress); 161 | VirtualMemory_unmapPage(Scheduler_getCurrentProcess()->pageDir, currentProcess->userHeapTop); 162 | 163 | } 164 | 165 | return currentProcess->userHeapTop; 166 | 167 | } 168 | 169 | } 170 | 171 | PUBLIC Module* HeapMemory_getModule(void) { 172 | 173 | if(!heapModule.isLoaded) { 174 | 175 | heapModule.moduleName = "Kernel Heap Manager"; 176 | heapModule.init = &HeapMemory_init; 177 | heapModule.moduleID = MODULE_HEAP; 178 | heapModule.numberOfDependencies = 1; 179 | heapModule.dependencies[0] = MODULE_VMM; 180 | 181 | } 182 | 183 | return &heapModule; 184 | } --------------------------------------------------------------------------------