├── LICENSE ├── Makefile ├── README.md ├── Terminal.iso ├── config ├── grub.cfg └── linker.ld ├── include ├── 8259_pic.h ├── console.h ├── gdt.h ├── idt.h ├── io_ports.h ├── isr.h ├── kernel.h ├── keyboard.h ├── string.h ├── types.h └── vga.h ├── obj ├── 8259_pic.o ├── asm │ ├── entry.o │ ├── exception.o │ ├── irq.o │ ├── load_gdt.o │ └── load_idt.o ├── console.o ├── gdt.o ├── idt.o ├── io_ports.o ├── isr.o ├── kernel.o ├── keyboard.o ├── string.o └── vga.o ├── out ├── Terminal.iso └── isodir │ └── boot │ ├── Terminal.bin │ └── grub │ └── grub.cfg ├── run ├── run.sh ├── screen.jpg └── src ├── 8259_pic.c ├── FileSystem ├── fs.c └── fs.h ├── asm ├── entry.asm ├── exception.asm ├── irq.asm ├── load_gdt.asm └── load_idt.asm ├── boot.asm ├── console.c ├── ctypes.h ├── framebuffer.c ├── framebuffer.h ├── gdt.c ├── idt.c ├── io_ports.c ├── isr.c ├── kernel.c ├── keyboard.c ├── multiboot.h ├── qemu.h ├── quantum_funcs.c ├── romfont.h ├── stdint-gcc.h ├── string.c ├── todo.txt └── vga.c /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (C) 2022-2023 mintsuki and contributors. 2 | 3 | Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted. 4 | 5 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 6 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # assembler 2 | ASM = nasm 3 | # compiler 4 | CC = gcc 5 | # linker 6 | LD = ld 7 | # grub iso creator 8 | GRUB = grub-mkrescue 9 | # sources 10 | SRC = src 11 | ASM_SRC = $(SRC)/asm 12 | # objects 13 | OBJ = obj 14 | ASM_OBJ = $(OBJ)/asm 15 | CONFIG = ./config 16 | OUT = out 17 | INC = ./include 18 | INCLUDE=-I$(INC) 19 | 20 | MKDIR= mkdir -p 21 | CP = cp -f 22 | DEFINES= 23 | 24 | # assembler flags 25 | ASM_FLAGS = -f elf32 26 | # compiler flags 27 | CC_FLAGS = $(INCLUDE) $(DEFINES) -m32 -std=gnu99 -ffreestanding -Wall -Wextra 28 | # linker flags, for linker add linker.ld file too 29 | LD_FLAGS = -m elf_i386 -T $(CONFIG)/linker.ld -nostdlib 30 | 31 | # target file to create in linking 32 | TARGET=$(OUT)/Terminal.bin 33 | 34 | # iso file target to create 35 | TARGET_ISO=$(OUT)/Terminal.iso 36 | ISO_DIR=$(OUT)/isodir 37 | 38 | OBJECTS=$(ASM_OBJ)/entry.o $(ASM_OBJ)/load_gdt.o\ 39 | $(ASM_OBJ)/load_idt.o $(ASM_OBJ)/exception.o $(ASM_OBJ)/irq.o\ 40 | $(OBJ)/io_ports.o $(OBJ)/vga.o\ 41 | $(OBJ)/string.o $(OBJ)/console.o\ 42 | $(OBJ)/gdt.o $(OBJ)/idt.o $(OBJ)/isr.o $(OBJ)/8259_pic.o\ 43 | $(OBJ)/keyboard.o\ 44 | $(OBJ)/kernel.o 45 | 46 | 47 | all: $(OBJECTS) 48 | @printf "[ linking... ]\n" 49 | $(LD) $(LD_FLAGS) -o $(TARGET) $(OBJECTS) 50 | grub-file --is-x86-multiboot $(TARGET) 51 | @printf "\n" 52 | @printf "[ building ISO... ]\n" 53 | $(MKDIR) $(ISO_DIR)/boot/grub 54 | $(CP) $(TARGET) $(ISO_DIR)/boot/ 55 | $(CP) $(CONFIG)/grub.cfg $(ISO_DIR)/boot/grub/ 56 | $(GRUB) -o $(TARGET_ISO) $(ISO_DIR) 57 | rm -f $(TARGET) 58 | 59 | $(ASM_OBJ)/entry.o : $(ASM_SRC)/entry.asm 60 | @printf "[ $(ASM_SRC)/entry.asm ]\n" 61 | $(ASM) $(ASM_FLAGS) $(ASM_SRC)/entry.asm -o $(ASM_OBJ)/entry.o 62 | @printf "\n" 63 | 64 | $(ASM_OBJ)/load_gdt.o : $(ASM_SRC)/load_gdt.asm 65 | @printf "[ $(ASM_SRC)/load_gdt.asm ]\n" 66 | $(ASM) $(ASM_FLAGS) $(ASM_SRC)/load_gdt.asm -o $(ASM_OBJ)/load_gdt.o 67 | @printf "\n" 68 | 69 | $(ASM_OBJ)/load_idt.o : $(ASM_SRC)/load_idt.asm 70 | @printf "[ $(ASM_SRC)/load_idt.asm ]\n" 71 | $(ASM) $(ASM_FLAGS) $(ASM_SRC)/load_idt.asm -o $(ASM_OBJ)/load_idt.o 72 | @printf "\n" 73 | 74 | $(ASM_OBJ)/exception.o : $(ASM_SRC)/exception.asm 75 | @printf "[ $(ASM_SRC)/exception.asm ]\n" 76 | $(ASM) $(ASM_FLAGS) $(ASM_SRC)/exception.asm -o $(ASM_OBJ)/exception.o 77 | @printf "\n" 78 | 79 | $(ASM_OBJ)/irq.o : $(ASM_SRC)/irq.asm 80 | @printf "[ $(ASM_SRC)/irq.asm ]\n" 81 | $(ASM) $(ASM_FLAGS) $(ASM_SRC)/irq.asm -o $(ASM_OBJ)/irq.o 82 | @printf "\n" 83 | 84 | $(OBJ)/io_ports.o : $(SRC)/io_ports.c 85 | @printf "[ $(SRC)/io_ports.c ]\n" 86 | $(CC) $(CC_FLAGS) -c $(SRC)/io_ports.c -o $(OBJ)/io_ports.o 87 | @printf "\n" 88 | 89 | $(OBJ)/vga.o : $(SRC)/vga.c 90 | @printf "[ $(SRC)/vga.c ]\n" 91 | $(CC) $(CC_FLAGS) -c $(SRC)/vga.c -o $(OBJ)/vga.o 92 | @printf "\n" 93 | 94 | $(OBJ)/string.o : $(SRC)/string.c 95 | @printf "[ $(SRC)/string.c ]\n" 96 | $(CC) $(CC_FLAGS) -c $(SRC)/string.c -o $(OBJ)/string.o 97 | @printf "\n" 98 | 99 | $(OBJ)/console.o : $(SRC)/console.c 100 | @printf "[ $(SRC)/console.c ]\n" 101 | $(CC) $(CC_FLAGS) -c $(SRC)/console.c -o $(OBJ)/console.o 102 | @printf "\n" 103 | 104 | $(OBJ)/gdt.o : $(SRC)/gdt.c 105 | @printf "[ $(SRC)/gdt.c ]\n" 106 | $(CC) $(CC_FLAGS) -c $(SRC)/gdt.c -o $(OBJ)/gdt.o 107 | @printf "\n" 108 | 109 | $(OBJ)/idt.o : $(SRC)/idt.c 110 | @printf "[ $(SRC)/idt.c ]\n" 111 | $(CC) $(CC_FLAGS) -c $(SRC)/idt.c -o $(OBJ)/idt.o 112 | @printf "\n" 113 | 114 | $(OBJ)/isr.o : $(SRC)/isr.c 115 | @printf "[ $(SRC)/isr.c ]\n" 116 | $(CC) $(CC_FLAGS) -c $(SRC)/isr.c -o $(OBJ)/isr.o 117 | @printf "\n" 118 | 119 | $(OBJ)/8259_pic.o : $(SRC)/8259_pic.c 120 | @printf "[ $(SRC)/8259_pic.c ]\n" 121 | $(CC) $(CC_FLAGS) -c $(SRC)/8259_pic.c -o $(OBJ)/8259_pic.o 122 | @printf "\n" 123 | 124 | $(OBJ)/keyboard.o : $(SRC)/keyboard.c 125 | @printf "[ $(SRC)/keyboard.c ]\n" 126 | $(CC) $(CC_FLAGS) -c $(SRC)/keyboard.c -o $(OBJ)/keyboard.o 127 | @printf "\n" 128 | 129 | 130 | $(OBJ)/kernel.o : $(SRC)/kernel.c 131 | @printf "[ $(SRC)/kernel.c ]\n" 132 | $(CC) $(CC_FLAGS) -c $(SRC)/kernel.c -o $(OBJ)/kernel.o 133 | @printf "\n" 134 | 135 | clean: 136 | rm -f $(OBJ)/*.o 137 | rm -f $(ASM_OBJ)/*.o 138 | rm -rf $(OUT)/* 139 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # The Quantix Operating System! 2 | 3 | Like cool low-level projects? Check out Quplexity on github! Its a fast, lightweight, modular Quantum Computing Simulation library written in x86 and ARM64 Assembly. 4 | 5 | ##For Arch Based systems put the following line of code at the start of kernel.c & console.c!! ( #pragma GCC optimize ("no-stack-protector") ) 6 | 7 | # Objective 8 | QuantixOS is a UNIX-Like operating system written in x86 Intel Assembly and C. QuantixOS aims to be a cool "toy" OS that can be used to learn low-level development. 9 | 10 | # Commands 11 | Supported commands/features: 12 | * A basic file system 13 | * Terminal/CLI based system 14 | * help(lists all system commands.) 15 | * mkfile(makes a file with specified text) 16 | * ls(lists files in directory) 17 | * clear(clears text on screen) 18 | * exec(execute a program (not fully working)) 19 | * login system for ROOT. 20 | * IO 21 | * cpuid(System Info) 22 | * whoami(Info about current user) 23 | * shutdown(Shuts the operating system down.) 24 | -------------------------------------------------------------------------------- /Terminal.iso: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MrGilli/Quantix-OS/c228b3a2e03fa2c12f383b902be0df91b3182fdb/Terminal.iso -------------------------------------------------------------------------------- /config/grub.cfg: -------------------------------------------------------------------------------- 1 | menuentry "Quantix Operating System" { 2 | multiboot /boot/Terminal.bin 3 | } 4 | -------------------------------------------------------------------------------- /config/linker.ld: -------------------------------------------------------------------------------- 1 | ENTRY(_start) 2 | 3 | SECTIONS 4 | { 5 | __kernel_section_start = .; 6 | /* text section */ 7 | .text 0x0100000 : { 8 | __kernel_text_section_start = .; 9 | . = ALIGN(4); 10 | /* set multiboot header */ 11 | LONG(0x1BADB002) 12 | LONG(0x00000003) 13 | LONG(0xE4524FFB) 14 | code = .; _code = .; __code = .; 15 | *(.text) 16 | *(.rodata) 17 | . = ALIGN(4096); 18 | __kernel_text_section_end = .; 19 | } 20 | 21 | /* initialized data section */ 22 | .data : { 23 | __kernel_data_section_start = .; 24 | data = .; _data = .; __data = .; 25 | *(.data) 26 | . = ALIGN(4096); 27 | __kernel_data_section_end = .; 28 | } 29 | 30 | /* constant data section */ 31 | .rodata : { 32 | __kernel_rodata_section_start = .; 33 | *(.rodata) 34 | __kernel_rodata_section_end = .; 35 | } 36 | 37 | /* un-initialized data section */ 38 | .bss : { 39 | __kernel_bss_section_start = .; 40 | bss = .; _bss = .; __bss = .; 41 | *(.bss) 42 | . = ALIGN(4096); 43 | __kernel_bss_section_end = .; 44 | } 45 | 46 | end = .; _end = .; __end = .; 47 | __kernel_section_end = .; 48 | } 49 | 50 | -------------------------------------------------------------------------------- /include/8259_pic.h: -------------------------------------------------------------------------------- 1 | /** 2 | * 8259 Programmable Interrupt Controller(8259 PIC) setup 3 | */ 4 | 5 | #ifndef _8259_PIC_H 6 | #define _8259_PIC_H 7 | 8 | #include "types.h" 9 | 10 | /* for more, see https://wiki.osdev.org/8259_PIC */ 11 | #define PIC1 0x20 /* IO base address for master PIC */ 12 | #define PIC2 0xA0 /* IO base address for slave PIC */ 13 | #define PIC1_COMMAND PIC1 14 | #define PIC1_DATA (PIC1+1) /* master data */ 15 | #define PIC2_COMMAND PIC2 16 | #define PIC2_DATA (PIC2+1) /* slave data */ 17 | 18 | #define PIC_EOI 0x20 /* end of interrupt */ 19 | 20 | #define ICW1 0x11 /* interrupt control command word PIC for initialization */ 21 | #define ICW4_8086 0x01 /* 8086/88 (MCS-80/85) mode */ 22 | 23 | /** 24 | * initialize 8259 PIC with default IRQ's defined in isr.h 25 | */ 26 | void pic8259_init(); 27 | 28 | /** 29 | * send end of interrupt command to PIC 8259 30 | */ 31 | void pic8259_eoi(uint8 irq); 32 | 33 | #endif 34 | 35 | -------------------------------------------------------------------------------- /include/console.h: -------------------------------------------------------------------------------- 1 | #ifndef CONSOLE_H 2 | #define CONSOLE_H 3 | 4 | #include "vga.h" 5 | 6 | #define MAXIMUM_PAGES 16 7 | 8 | #define SCROLL_UP 1 9 | #define SCROLL_DOWN 2 10 | 11 | void console_clear(VGA_COLOR_TYPE fore_color, VGA_COLOR_TYPE back_color); 12 | 13 | //initialize console 14 | void console_init(VGA_COLOR_TYPE fore_color, VGA_COLOR_TYPE back_color); 15 | void console_scroll(int line_count); 16 | void console_putchar(char ch); 17 | // revert back the printed character and add 0 to it 18 | void console_ungetchar(); 19 | // revert back the printed character until n characters 20 | void console_ungetchar_bound(uint8 n); 21 | 22 | void console_gotoxy(uint16 x, uint16 y); 23 | 24 | void console_putstr(const char *str); 25 | void printf(const char *format, ...); 26 | 27 | // read string from console, but no backing 28 | void getstr(char *buffer); 29 | 30 | // read string from console, and erase or go back util bound occurs 31 | void getstr_bound(char *buffer, uint8 bound); 32 | 33 | #endif 34 | 35 | -------------------------------------------------------------------------------- /include/gdt.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Global Descriptor Table(GDT) setup 3 | */ 4 | 5 | #ifndef GDT_H 6 | #define GDT_H 7 | 8 | #include "types.h" 9 | 10 | #define NO_GDT_DESCRIPTORS 8 11 | 12 | typedef struct { 13 | uint16 segment_limit; // segment limit first 0-15 bits 14 | uint16 base_low; // base first 0-15 bits 15 | uint8 base_middle; // base 16-23 bits 16 | uint8 access; // access byte 17 | uint8 granularity; // high 4 bits (flags) low 4 bits (limit 4 last bits)(limit is 20 bit wide) 18 | uint8 base_high; // base 24-31 bits 19 | } __attribute__((packed)) GDT; 20 | 21 | typedef struct { 22 | uint16 limit; // limit size of all GDT segments 23 | uint32 base_address; // base address of the first GDT segment 24 | } __attribute__((packed)) GDT_PTR; 25 | 26 | // asm gdt functions, define in load_gdt.asm 27 | extern void load_gdt(uint32 gdt_ptr); 28 | 29 | /** 30 | * fill entries of GDT 31 | */ 32 | void gdt_set_entry(int index, uint32 base, uint32 limit, uint8 access, uint8 gran); 33 | 34 | // initialize GDT 35 | void gdt_init(); 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /include/idt.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Interrupt Descriptor Table(GDT) setup 3 | */ 4 | 5 | #ifndef IDT_H 6 | #define IDT_H 7 | 8 | #include "types.h" 9 | 10 | #define NO_IDT_DESCRIPTORS 256 11 | 12 | typedef struct { 13 | uint16 base_low; // lower 16 bits 0-15 of the address to jump to when this interrupt fires 14 | uint16 segment_selector; // code segment selector in GDT 15 | uint8 zero; // unused, always be zero 16 | uint8 type; // types trap, interrupt gates 17 | uint16 base_high; // upper 16 bits 16-31 of the address to jump to 18 | } __attribute__((packed)) IDT; 19 | 20 | typedef struct { 21 | uint16 limit; // limit size of all IDT segments 22 | uint32 base_address; // base address of the first IDT segment 23 | } __attribute__((packed)) IDT_PTR; 24 | 25 | 26 | // asm gdt functions, define in load_idt.asm 27 | extern void load_idt(uint32 idt_ptr); 28 | 29 | /** 30 | * fill entries of IDT 31 | */ 32 | void idt_set_entry(int index, uint32 base, uint16 seg_sel, uint8 flags); 33 | 34 | void idt_init(); 35 | 36 | #endif 37 | -------------------------------------------------------------------------------- /include/io_ports.h: -------------------------------------------------------------------------------- 1 | #ifndef IO_PORTS_H 2 | #define IO_PORTS_H 3 | 4 | #include "types.h" 5 | 6 | /** 7 | * read a byte from given port number 8 | */ 9 | uint8 inportb(uint16 port); 10 | 11 | /** 12 | * write a given byte to given port number 13 | */ 14 | void outportb(uint16 port, uint8 val); 15 | 16 | /** 17 | * read 2 bytes(short) from given port number 18 | */ 19 | uint16 inports(uint16 port); 20 | 21 | /** 22 | * write given 2(short) bytes to given port number 23 | */ 24 | void outports(uint16 port, uint16 data); 25 | 26 | /** 27 | * read 4 bytes(long) from given port number 28 | */ 29 | uint32 inportl(uint16 port); 30 | 31 | /** 32 | * write given 4 bytes(long) to given port number 33 | */ 34 | void outportl(uint16 port, uint32 data); 35 | 36 | #endif 37 | -------------------------------------------------------------------------------- /include/isr.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Interrupt Service Routine(ISR) setup 3 | */ 4 | 5 | #ifndef ISR_H 6 | #define ISR_H 7 | 8 | #include "types.h" 9 | 10 | #define NO_INTERRUPT_HANDLERS 256 11 | 12 | typedef struct { 13 | uint32 ds; 14 | uint32 edi, esi, ebp, esp, ebx, edx, ecx, eax; // pushed by pusha 15 | uint32 int_no, err_code; // interrupt number and error code 16 | uint32 eip, cs, eflags, useresp, ss; // pushed by the processor automatically 17 | } REGISTERS; 18 | 19 | // ISR function prototype 20 | typedef void (*ISR)(REGISTERS *); 21 | 22 | /** 23 | * register given handler to interrupt handlers at given num 24 | */ 25 | void isr_register_interrupt_handler(int num, ISR handler); 26 | 27 | /* 28 | * turn off current interrupt 29 | */ 30 | void isr_end_interrupt(int num); 31 | 32 | /** 33 | * invoke exception routine, 34 | * being called in exception.asm 35 | */ 36 | void isr_exception_handler(REGISTERS reg); 37 | 38 | /** 39 | * invoke isr routine and send eoi to pic, 40 | * being called in irq.asm 41 | */ 42 | void isr_irq_handler(REGISTERS *reg); 43 | 44 | 45 | // defined in exception.asm 46 | extern void exception_0(); 47 | extern void exception_1(); 48 | extern void exception_2(); 49 | extern void exception_3(); 50 | extern void exception_4(); 51 | extern void exception_5(); 52 | extern void exception_6(); 53 | extern void exception_7(); 54 | extern void exception_8(); 55 | extern void exception_9(); 56 | extern void exception_10(); 57 | extern void exception_11(); 58 | extern void exception_12(); 59 | extern void exception_13(); 60 | extern void exception_14(); 61 | extern void exception_15(); 62 | extern void exception_16(); 63 | extern void exception_17(); 64 | extern void exception_18(); 65 | extern void exception_19(); 66 | extern void exception_20(); 67 | extern void exception_21(); 68 | extern void exception_22(); 69 | extern void exception_23(); 70 | extern void exception_24(); 71 | extern void exception_25(); 72 | extern void exception_26(); 73 | extern void exception_27(); 74 | extern void exception_28(); 75 | extern void exception_29(); 76 | extern void exception_30(); 77 | extern void exception_31(); 78 | extern void exception_128(); 79 | 80 | // defined in irq.asm 81 | extern void irq_0(); 82 | extern void irq_1(); 83 | extern void irq_2(); 84 | extern void irq_3(); 85 | extern void irq_4(); 86 | extern void irq_5(); 87 | extern void irq_6(); 88 | extern void irq_7(); 89 | extern void irq_8(); 90 | extern void irq_9(); 91 | extern void irq_10(); 92 | extern void irq_11(); 93 | extern void irq_12(); 94 | extern void irq_13(); 95 | extern void irq_14(); 96 | extern void irq_15(); 97 | 98 | // IRQ default constants 99 | #define IRQ_BASE 0x20 100 | #define IRQ0_TIMER 0x00 101 | #define IRQ1_KEYBOARD 0x01 102 | #define IRQ2_CASCADE 0x02 103 | #define IRQ3_SERIAL_PORT2 0x03 104 | #define IRQ4_SERIAL_PORT1 0x04 105 | #define IRQ5_RESERVED 0x05 106 | #define IRQ6_DISKETTE_DRIVE 0x06 107 | #define IRQ7_PARALLEL_PORT 0x07 108 | #define IRQ8_CMOS_CLOCK 0x08 109 | #define IRQ9_CGA 0x09 110 | #define IRQ10_RESERVED 0x0A 111 | #define IRQ11_RESERVED 0x0B 112 | #define IRQ12_AUXILIARY 0x0C 113 | #define IRQ13_FPU 0x0D 114 | #define IRQ14_HARD_DISK 0x0E 115 | #define IRQ15_RESERVED 0x0F 116 | 117 | 118 | #endif 119 | -------------------------------------------------------------------------------- /include/kernel.h: -------------------------------------------------------------------------------- 1 | #ifndef KERNEL_H 2 | #define KERNEL_H 3 | 4 | #include "types.h" 5 | 6 | // symbols from linker.ld for section addresses 7 | extern uint8 __kernel_section_start; 8 | extern uint8 __kernel_section_end; 9 | extern uint8 __kernel_text_section_start; 10 | extern uint8 __kernel_text_section_end; 11 | extern uint8 __kernel_data_section_start; 12 | extern uint8 __kernel_data_section_end; 13 | extern uint8 __kernel_rodata_section_start; 14 | extern uint8 __kernel_rodata_section_end; 15 | extern uint8 __kernel_bss_section_start; 16 | extern uint8 __kernel_bss_section_end; 17 | 18 | #endif 19 | 20 | 21 | -------------------------------------------------------------------------------- /include/keyboard.h: -------------------------------------------------------------------------------- 1 | #ifndef KEYBOARD_H 2 | #define KEYBOARD_H 3 | 4 | #define KEYBOARD_DATA_PORT 0x60 5 | #define KEYBOARD_STATUS_PORT 0x64 6 | #define KEYBOARD_COMMAND_PORT 0x64 7 | 8 | /* 9 | scan codes in alphabetical order for QWERTY keyboard 10 | see https://wiki.osdev.org/PS/2_Keyboard 11 | */ 12 | #define SCAN_CODE_KEY_ESC 0x01 13 | #define SCAN_CODE_KEY_1 0x02 14 | #define SCAN_CODE_KEY_2 0x03 15 | #define SCAN_CODE_KEY_3 0x04 16 | #define SCAN_CODE_KEY_4 0x05 17 | #define SCAN_CODE_KEY_5 0x06 18 | #define SCAN_CODE_KEY_6 0x07 19 | #define SCAN_CODE_KEY_7 0x08 20 | #define SCAN_CODE_KEY_8 0x09 21 | #define SCAN_CODE_KEY_9 0x0A 22 | #define SCAN_CODE_KEY_0 0x0B 23 | #define SCAN_CODE_KEY_MINUS 0x0C 24 | #define SCAN_CODE_KEY_EQUAL 0x0D 25 | #define SCAN_CODE_KEY_BACKSPACE 0x0E 26 | #define SCAN_CODE_KEY_TAB 0x0F 27 | #define SCAN_CODE_KEY_Q 0x10 28 | #define SCAN_CODE_KEY_W 0x11 29 | #define SCAN_CODE_KEY_E 0x12 30 | #define SCAN_CODE_KEY_R 0x13 31 | #define SCAN_CODE_KEY_T 0x14 32 | #define SCAN_CODE_KEY_Y 0x15 33 | #define SCAN_CODE_KEY_U 0x16 34 | #define SCAN_CODE_KEY_I 0x17 35 | #define SCAN_CODE_KEY_O 0x18 36 | #define SCAN_CODE_KEY_P 0x19 37 | #define SCAN_CODE_KEY_SQUARE_OPEN_BRACKET 0x1A 38 | #define SCAN_CODE_KEY_SQUARE_CLOSE_BRACKET 0x1B 39 | #define SCAN_CODE_KEY_ENTER 0x1C 40 | #define SCAN_CODE_KEY_LEFT_CTRL 0x1D 41 | #define SCAN_CODE_KEY_A 0x1E 42 | #define SCAN_CODE_KEY_S 0x1F 43 | #define SCAN_CODE_KEY_D 0x20 44 | #define SCAN_CODE_KEY_F 0x21 45 | #define SCAN_CODE_KEY_G 0x22 46 | #define SCAN_CODE_KEY_H 0x23 47 | #define SCAN_CODE_KEY_J 0x24 48 | #define SCAN_CODE_KEY_K 0x25 49 | #define SCAN_CODE_KEY_L 0x26 50 | #define SCAN_CODE_KEY_SEMICOLON 0x27 51 | #define SCAN_CODE_KEY_SINGLE_QUOTE 0x28 52 | #define SCAN_CODE_KEY_ACUTE 0x29 53 | #define SCAN_CODE_KEY_LEFT_SHIFT 0x2A 54 | #define SCAN_CODE_KEY_BACKSLASH 0x2B 55 | #define SCAN_CODE_KEY_Z 0x2C 56 | #define SCAN_CODE_KEY_X 0x2D 57 | #define SCAN_CODE_KEY_C 0x2E 58 | #define SCAN_CODE_KEY_V 0x2F 59 | #define SCAN_CODE_KEY_B 0x30 60 | #define SCAN_CODE_KEY_N 0x31 61 | #define SCAN_CODE_KEY_M 0x32 62 | #define SCAN_CODE_KEY_COMMA 0x33 63 | #define SCAN_CODE_KEY_DOT 0x34 64 | #define SCAN_CODE_KEY_FORESLHASH 0x35 65 | #define SCAN_CODE_KEY_RIGHT_SHIFT 0x36 66 | #define SCAN_CODE_KEY_ASTERISK 0x37 67 | #define SCAN_CODE_KEY_ALT 0x38 68 | #define SCAN_CODE_KEY_SPACE 0x39 69 | #define SCAN_CODE_KEY_CAPS_LOCK 0x3A 70 | #define SCAN_CODE_KEY_F1 0x3B 71 | #define SCAN_CODE_KEY_F2 0x3C 72 | #define SCAN_CODE_KEY_F3 0x3D 73 | #define SCAN_CODE_KEY_F4 0x3E 74 | #define SCAN_CODE_KEY_F5 0x3F 75 | #define SCAN_CODE_KEY_F6 0x40 76 | #define SCAN_CODE_KEY_F7 0x41 77 | #define SCAN_CODE_KEY_F8 0x42 78 | #define SCAN_CODE_KEY_F9 0x43 79 | #define SCAN_CODE_KEY_F10 0x44 80 | #define SCAN_CODE_KEY_NUM_LOCK 0x45 81 | #define SCAN_CODE_KEY_SCROLL_LOCK 0x46 82 | #define SCAN_CODE_KEY_HOME 0x47 83 | #define SCAN_CODE_KEY_UP 0x48 84 | #define SCAN_CODE_KEY_PAGE_UP 0x49 85 | #define SCAN_CODE_KEY_KEYPAD_MINUS 0x4A 86 | #define SCAN_CODE_KEY_LEFT 0x4B 87 | #define SCAN_CODE_KEY_KEYPAD_5 0x4C 88 | #define SCAN_CODE_KEY_RIGHT 0x4D 89 | #define SCAN_CODE_KEY_KEYPAD_PLUS 0x4E 90 | #define SCAN_CODE_KEY_END 0x4F 91 | #define SCAN_CODE_KEY_DOWN 0x50 92 | #define SCAN_CODE_KEY_PAGE_DOWN 0x51 93 | #define SCAN_CODE_KEY_INSERT 0x52 94 | #define SCAN_CODE_KEY_DELETE 0x53 95 | #define SCAN_CODE_KEY_F11 0x57 96 | #define SCAN_CODE_KEY_F12 0x58 97 | 98 | 99 | void keyboard_init(); 100 | 101 | // a blocking character read 102 | char kb_getchar(); 103 | 104 | // a blocking scan code read 105 | char kb_get_scancode(); 106 | 107 | #endif 108 | 109 | -------------------------------------------------------------------------------- /include/string.h: -------------------------------------------------------------------------------- 1 | #ifndef STRING_H 2 | #define STRING_H 3 | 4 | #include "types.h" 5 | 6 | void *memset(void *dst, char c, uint32 n); 7 | 8 | void *memcpy(void *dst, const void *src, uint32 n); 9 | 10 | int memcmp(uint8 *s1, uint8 *s2, uint32 n); 11 | 12 | int strlen(const char *s); 13 | 14 | int strcmp(const char *s1, char *s2); 15 | int strncmp(const char *s1, const char *s2, int c); 16 | 17 | int strcpy(char *dst, const char *src); 18 | 19 | void strcat(char *dest, const char *src); 20 | 21 | int isspace(char c); 22 | 23 | int isalpha(char c); 24 | char upper(char c); 25 | char lower(char c); 26 | 27 | void itoa(char *buf, int base, int d); 28 | 29 | char *strstr(const char *in, const char *str); 30 | 31 | #endif 32 | 33 | -------------------------------------------------------------------------------- /include/types.h: -------------------------------------------------------------------------------- 1 | #ifndef TYPES_H 2 | #define TYPES_H 3 | 4 | #define NULL 0 5 | 6 | typedef unsigned char uint8; 7 | typedef unsigned short uint16; 8 | typedef unsigned int uint32; 9 | typedef signed char sint8; 10 | typedef signed short sint16; 11 | typedef signed int sint32; 12 | typedef uint8 byte; 13 | typedef uint16 word; 14 | typedef uint32 dword; 15 | 16 | typedef enum { 17 | FALSE, 18 | TRUE 19 | } BOOL; 20 | 21 | #endif 22 | 23 | -------------------------------------------------------------------------------- /include/vga.h: -------------------------------------------------------------------------------- 1 | #ifndef VGA_H 2 | #define VGA_H 3 | 4 | #include "types.h" 5 | 6 | #define VGA_ADDRESS 0xB8000 7 | #define VGA_TOTAL_ITEMS 2200 8 | 9 | #define VGA_WIDTH 80 10 | #define VGA_HEIGHT 24 11 | 12 | typedef enum { 13 | COLOR_BLACK, 14 | COLOR_BLUE, 15 | COLOR_GREEN, 16 | COLOR_CYAN, 17 | COLOR_RED, 18 | COLOR_MAGENTA, 19 | COLOR_BROWN, 20 | COLOR_GREY, 21 | COLOR_DARK_GREY, 22 | COLOR_BRIGHT_BLUE, 23 | COLOR_BRIGHT_GREEN, 24 | COLOR_BRIGHT_CYAN, 25 | COLOR_BRIGHT_RED, 26 | COLOR_BRIGHT_MAGENTA, 27 | COLOR_YELLOW, 28 | COLOR_WHITE, 29 | } VGA_COLOR_TYPE; 30 | 31 | /** 32 | * 16 bit video buffer elements(register ax) 33 | * 8 bits(ah) higher : 34 | * lower 4 bits - forec olor 35 | * higher 4 bits - back color 36 | 37 | * 8 bits(al) lower : 38 | * 8 bits : ASCII character to print 39 | * 40 | * returns complete item with fore & back color to be placed at VGA address 41 | */ 42 | uint16 vga_item_entry(uint8 ch, VGA_COLOR_TYPE fore_color, VGA_COLOR_TYPE back_color); 43 | 44 | /** 45 | * set cursor position to given (x, y) 46 | * by writing to CRT controller registers 47 | */ 48 | void vga_set_cursor_pos(uint8 x, uint8 y); 49 | 50 | /** 51 | * disable blinking top-left cursor 52 | * by writing to CRT controller registers 53 | */ 54 | void vga_disable_cursor(); 55 | 56 | #endif 57 | -------------------------------------------------------------------------------- /obj/8259_pic.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MrGilli/Quantix-OS/c228b3a2e03fa2c12f383b902be0df91b3182fdb/obj/8259_pic.o -------------------------------------------------------------------------------- /obj/asm/entry.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MrGilli/Quantix-OS/c228b3a2e03fa2c12f383b902be0df91b3182fdb/obj/asm/entry.o -------------------------------------------------------------------------------- /obj/asm/exception.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MrGilli/Quantix-OS/c228b3a2e03fa2c12f383b902be0df91b3182fdb/obj/asm/exception.o -------------------------------------------------------------------------------- /obj/asm/irq.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MrGilli/Quantix-OS/c228b3a2e03fa2c12f383b902be0df91b3182fdb/obj/asm/irq.o -------------------------------------------------------------------------------- /obj/asm/load_gdt.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MrGilli/Quantix-OS/c228b3a2e03fa2c12f383b902be0df91b3182fdb/obj/asm/load_gdt.o -------------------------------------------------------------------------------- /obj/asm/load_idt.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MrGilli/Quantix-OS/c228b3a2e03fa2c12f383b902be0df91b3182fdb/obj/asm/load_idt.o -------------------------------------------------------------------------------- /obj/console.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MrGilli/Quantix-OS/c228b3a2e03fa2c12f383b902be0df91b3182fdb/obj/console.o -------------------------------------------------------------------------------- /obj/gdt.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MrGilli/Quantix-OS/c228b3a2e03fa2c12f383b902be0df91b3182fdb/obj/gdt.o -------------------------------------------------------------------------------- /obj/idt.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MrGilli/Quantix-OS/c228b3a2e03fa2c12f383b902be0df91b3182fdb/obj/idt.o -------------------------------------------------------------------------------- /obj/io_ports.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MrGilli/Quantix-OS/c228b3a2e03fa2c12f383b902be0df91b3182fdb/obj/io_ports.o -------------------------------------------------------------------------------- /obj/isr.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MrGilli/Quantix-OS/c228b3a2e03fa2c12f383b902be0df91b3182fdb/obj/isr.o -------------------------------------------------------------------------------- /obj/kernel.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MrGilli/Quantix-OS/c228b3a2e03fa2c12f383b902be0df91b3182fdb/obj/kernel.o -------------------------------------------------------------------------------- /obj/keyboard.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MrGilli/Quantix-OS/c228b3a2e03fa2c12f383b902be0df91b3182fdb/obj/keyboard.o -------------------------------------------------------------------------------- /obj/string.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MrGilli/Quantix-OS/c228b3a2e03fa2c12f383b902be0df91b3182fdb/obj/string.o -------------------------------------------------------------------------------- /obj/vga.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MrGilli/Quantix-OS/c228b3a2e03fa2c12f383b902be0df91b3182fdb/obj/vga.o -------------------------------------------------------------------------------- /out/Terminal.iso: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MrGilli/Quantix-OS/c228b3a2e03fa2c12f383b902be0df91b3182fdb/out/Terminal.iso -------------------------------------------------------------------------------- /out/isodir/boot/Terminal.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MrGilli/Quantix-OS/c228b3a2e03fa2c12f383b902be0df91b3182fdb/out/isodir/boot/Terminal.bin -------------------------------------------------------------------------------- /out/isodir/boot/grub/grub.cfg: -------------------------------------------------------------------------------- 1 | menuentry "Quantix Operating System" { 2 | multiboot /boot/Terminal.bin 3 | } 4 | -------------------------------------------------------------------------------- /run: -------------------------------------------------------------------------------- 1 | clear 2 | 3 | make clean 4 | 5 | make 6 | 7 | make run 8 | -------------------------------------------------------------------------------- /run.sh: -------------------------------------------------------------------------------- 1 | clear 2 | 3 | make clean 4 | 5 | make 6 | 7 | qemu-system-x86_64 out/Terminal.iso 8 | -------------------------------------------------------------------------------- /screen.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MrGilli/Quantix-OS/c228b3a2e03fa2c12f383b902be0df91b3182fdb/screen.jpg -------------------------------------------------------------------------------- /src/8259_pic.c: -------------------------------------------------------------------------------- 1 | /** 2 | * 8259 Programmable Interrupt Controller(8259 PIC) setup 3 | * for more, see https://wiki.osdev.org/8259_PIC 4 | */ 5 | 6 | #include "isr.h" 7 | #include "idt.h" 8 | #include "io_ports.h" 9 | #include "8259_pic.h" 10 | 11 | /** 12 | * initialize 8259 PIC with default IRQ's defined in isr.h 13 | */ 14 | void pic8259_init() { 15 | uint8 a1, a2; 16 | 17 | // save mask registers 18 | a1 = inportb(PIC1_DATA); 19 | a2 = inportb(PIC2_DATA); 20 | 21 | // send commands to pic to initialize both master & slave 22 | outportb(PIC1_COMMAND, ICW1); 23 | outportb(PIC2_COMMAND, ICW1); 24 | 25 | // map vector offset of all default IRQ's from 0x20 to 0x27 in master(ICW2) 26 | outportb(PIC1_DATA, 0x20); 27 | // map vector offset of all default IRQ's from 0x28 to 0x2F in slave(ICW2) 28 | outportb(PIC2_DATA, 0x28); 29 | 30 | // ICW3: tell master PIC that there is a slave PIC at IRQ2 (0000 0100) 31 | outportb(PIC1_DATA, 4); 32 | // ICW3: tell slave PIC its cascade identity (0000 0010) 33 | outportb(PIC2_DATA, 2); 34 | 35 | // ICW4, set x86 mode 36 | outportb(PIC1_DATA, ICW4_8086); 37 | outportb(PIC2_DATA, ICW4_8086); 38 | 39 | // restore the mask registers 40 | outportb(PIC1_DATA, a1); 41 | outportb(PIC2_DATA, a2); 42 | } 43 | 44 | /** 45 | * send end of interrupt command to PIC 8259 46 | */ 47 | void pic8259_eoi(uint8 irq) { 48 | if(irq >= 0x28) 49 | outportb(PIC2, PIC_EOI); 50 | outportb(PIC1, PIC_EOI); 51 | } 52 | 53 | -------------------------------------------------------------------------------- /src/FileSystem/fs.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "fs.h" 5 | 6 | #define BRAND_QEMU 1 7 | #define BRAND_VBOX 2 8 | 9 | #define MAX_FILENAME_LENGTH 20 10 | #define MAX_FILE_COUNT 100 11 | #define MAX_FILE_CONTENT_LENGTH 10000 12 | 13 | typedef struct { 14 | char name[MAX_FILENAME_LENGTH]; 15 | int size; 16 | char content[MAX_FILE_CONTENT_LENGTH]; 17 | } File; 18 | 19 | typedef struct { 20 | char name[MAX_FILENAME_LENGTH]; 21 | int file_count; 22 | File files[MAX_FILE_COUNT]; 23 | } Directory; 24 | 25 | Directory root_directory; 26 | 27 | void custom_strcpy(char *dest, const char *src) { 28 | while (*src != '\0') { 29 | *dest = *src; 30 | src++; 31 | dest++; 32 | } 33 | *dest = '\0'; // Null-terminate the destination string 34 | } 35 | 36 | void initFileSystem() { 37 | custom_strcpy(root_directory.name, "root"); 38 | root_directory.file_count = 0; 39 | } 40 | 41 | void createFile(char *name, char *content) { 42 | if (root_directory.file_count < MAX_FILE_COUNT) { 43 | File newFile; 44 | custom_strcpy(newFile.name, name); 45 | newFile.size = strlen(content); 46 | custom_strcpy(newFile.content, content); 47 | newFile.content[MAX_FILE_CONTENT_LENGTH - 1] = '\0'; 48 | 49 | root_directory.files[root_directory.file_count++] = newFile; 50 | printf("File '%s' created successfully.\n", name); 51 | } else { 52 | printf("File system full. Cannot create more files.\n"); 53 | } 54 | } 55 | 56 | void listFiles() { 57 | printf("Files in root directory:\n"); 58 | for (int i = 0; i < root_directory.file_count; ++i) { 59 | printf("- %s, %s\n", root_directory.files[i].name, root_directory.files[i].content); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/FileSystem/fs.h: -------------------------------------------------------------------------------- 1 | #ifndef FS_H 2 | #define FS_H 3 | 4 | #include 5 | #include 6 | 7 | //FUNCS 8 | void custom_strcpy(char *dest, const char *src); 9 | void initFileSystem(); 10 | void createFile(char *name, char *content); 11 | void listFiles(); 12 | 13 | 14 | //CONST 15 | #define BRAND_QEMU 1 16 | #define BRAND_VBOX 2 17 | 18 | #define MAX_FILENAME_LENGTH 20 19 | #define MAX_FILE_COUNT 100 20 | #define MAX_FILE_CONTENT_LENGTH 10000 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /src/asm/entry.asm: -------------------------------------------------------------------------------- 1 | ; constants for multiboot header 2 | MBALIGN equ 1<<0 3 | MEMINFO equ 1<<1 4 | FLAGS equ MBALIGN | MEMINFO 5 | MAGIC equ 0x1BADB002 6 | CHECKSUM equ -(MAGIC + FLAGS) 7 | 8 | ; set multiboot section 9 | section .multiboot 10 | align 4 11 | dd MAGIC 12 | dd FLAGS 13 | dd CHECKSUM 14 | 15 | section .data 16 | align 4096 17 | 18 | ; initial stack 19 | section .initial_stack, nobits 20 | align 4 21 | 22 | stack_bottom: 23 | ; 1 MB of uninitialized data for stack 24 | resb 104856 25 | stack_top: 26 | 27 | ; kernel entry, main text section 28 | section .text 29 | global _start 30 | 31 | 32 | ; define _start, aligned by linker.ld script 33 | _start: 34 | mov esp, stack_top 35 | extern kmain 36 | push ebx 37 | call kmain 38 | loop: 39 | jmp loop 40 | -------------------------------------------------------------------------------- /src/asm/exception.asm: -------------------------------------------------------------------------------- 1 | section .text 2 | extern isr_exception_handler 3 | global exception_0 4 | global exception_1 5 | global exception_2 6 | global exception_3 7 | global exception_4 8 | global exception_5 9 | global exception_6 10 | global exception_7 11 | global exception_8 12 | global exception_9 13 | global exception_10 14 | global exception_11 15 | global exception_12 16 | global exception_13 17 | global exception_14 18 | global exception_15 19 | global exception_16 20 | global exception_17 21 | global exception_18 22 | global exception_19 23 | global exception_20 24 | global exception_21 25 | global exception_22 26 | global exception_23 27 | global exception_24 28 | global exception_25 29 | global exception_26 30 | global exception_27 31 | global exception_28 32 | global exception_29 33 | global exception_30 34 | global exception_31 35 | global exception_128 36 | 37 | 38 | exception_handler: 39 | pusha ; push all registers 40 | mov ax, ds 41 | push eax ; save ds 42 | 43 | mov ax, 0x10 ; load kernel data segment 44 | mov ds, ax 45 | mov es, ax 46 | mov fs, ax 47 | mov gs, ax 48 | 49 | call isr_exception_handler 50 | 51 | pop ebx ; restore kernel data segment 52 | mov ds, bx 53 | mov es, bx 54 | mov fs, bx 55 | mov gs, bx 56 | 57 | popa ; restore all registers 58 | add esp, 0x8 ; restore stack for erro no been pushed 59 | 60 | sti ; re-enable interrupts 61 | iret 62 | 63 | 64 | exception_0: 65 | cli 66 | push byte 0 ; store default err code(0) 67 | push 0 ; push exception number index in IDT 68 | jmp exception_handler 69 | 70 | exception_1: 71 | cli 72 | push byte 0 ; store default err code(0) 73 | push 1 ; push exception number index in IDT 74 | jmp exception_handler 75 | 76 | exception_2: 77 | cli 78 | push byte 0 ; store default err code(0) 79 | push 2 ; push exception number index in IDT 80 | jmp exception_handler 81 | 82 | exception_3: 83 | cli 84 | push byte 0 ; store default err code(0) 85 | push 3 ; push exception number index in IDT 86 | jmp exception_handler 87 | 88 | exception_4: 89 | cli 90 | push byte 0 ; store default err code(0) 91 | push 4 ; push exception number index in IDT 92 | jmp exception_handler 93 | 94 | exception_5: 95 | cli 96 | push byte 0 ; store default err code(0) 97 | push 5 ; push exception number index in IDT 98 | jmp exception_handler 99 | 100 | exception_6: 101 | cli 102 | push byte 0 ; store default err code(0) 103 | push 6 ; push exception number index in IDT 104 | jmp exception_handler 105 | 106 | exception_7: 107 | cli 108 | push byte 0 ; store default err code(0) 109 | push 7 ; push exception number index in IDT 110 | jmp exception_handler 111 | 112 | exception_8: 113 | cli 114 | push 8 ; push exception number index in IDT 115 | jmp exception_handler 116 | 117 | exception_9: 118 | cli 119 | push byte 0 ; store default err code(0) 120 | push 9 ; push exception number index in IDT 121 | jmp exception_handler 122 | 123 | exception_10: 124 | cli 125 | push 10 ; push exception number index in IDT 126 | jmp exception_handler 127 | 128 | exception_11: 129 | cli 130 | push 11 ; push exception number index in IDT 131 | jmp exception_handler 132 | 133 | exception_12: 134 | cli 135 | push 12 ; push exception number index in IDT 136 | jmp exception_handler 137 | 138 | exception_13: 139 | cli 140 | push 13 ; push exception number index in IDT 141 | jmp exception_handler 142 | 143 | exception_14: 144 | cli 145 | push 14 ; push exception number index in IDT 146 | jmp exception_handler 147 | 148 | exception_15: 149 | cli 150 | push byte 0 ; store default err code(0) 151 | push 15 ; push exception number index in IDT 152 | jmp exception_handler 153 | 154 | exception_16: 155 | cli 156 | push byte 0 ; store default err code(0) 157 | push 16 ; push exception number index in IDT 158 | jmp exception_handler 159 | 160 | exception_17: 161 | cli 162 | push byte 0 ; store default err code(0) 163 | push 17 ; push exception number index in IDT 164 | jmp exception_handler 165 | 166 | exception_18: 167 | cli 168 | push byte 0 ; store default err code(0) 169 | push 18 ; push exception number index in IDT 170 | jmp exception_handler 171 | 172 | exception_19: 173 | cli 174 | push byte 0 ; store default err code(0) 175 | push 19 ; push exception number index in IDT 176 | jmp exception_handler 177 | 178 | exception_20: 179 | cli 180 | push byte 0 ; store default err code(0) 181 | push 20 ; push exception number index in IDT 182 | jmp exception_handler 183 | 184 | exception_21: 185 | cli 186 | push byte 0 ; store default err code(0) 187 | push 21 ; push exception number index in IDT 188 | jmp exception_handler 189 | 190 | exception_22: 191 | cli 192 | push byte 0 ; store default err code(0) 193 | push 22 ; push exception number index in IDT 194 | jmp exception_handler 195 | 196 | exception_23: 197 | cli 198 | push byte 0 ; store default err code(0) 199 | push 23 ; push exception number index in IDT 200 | jmp exception_handler 201 | 202 | exception_24: 203 | cli 204 | push byte 0 ; store default err code(0) 205 | push 24 ; push exception number index in IDT 206 | jmp exception_handler 207 | 208 | exception_25: 209 | cli 210 | push byte 0 ; store default err code(0) 211 | push 25 ; push exception number index in IDT 212 | jmp exception_handler 213 | 214 | exception_26: 215 | cli 216 | push byte 0 ; store default err code(0) 217 | push 26 ; push exception number index in IDT 218 | jmp exception_handler 219 | 220 | exception_27: 221 | cli 222 | push byte 0 ; store default err code(0) 223 | push 27 ; push exception number index in IDT 224 | jmp exception_handler 225 | 226 | exception_28: 227 | cli 228 | push byte 0 ; store default err code(0) 229 | push 28 ; push exception number index in IDT 230 | jmp exception_handler 231 | 232 | exception_29: 233 | cli 234 | push byte 0 ; store default err code(0) 235 | push 29 ; push exception number index in IDT 236 | jmp exception_handler 237 | 238 | exception_30: 239 | cli 240 | push byte 0 ; store default err code(0) 241 | push 30 ; push exception number index in IDT 242 | jmp exception_handler 243 | 244 | exception_31: 245 | cli 246 | push byte 0 ; store default err code(0) 247 | push 31 ; push exception number index in IDT 248 | jmp exception_handler 249 | 250 | exception_128: 251 | cli 252 | push byte 0 ; store default err code(0) 253 | push 128 ; push exception number index in IDT 254 | jmp exception_handler 255 | 256 | 257 | -------------------------------------------------------------------------------- /src/asm/irq.asm: -------------------------------------------------------------------------------- 1 | section .text 2 | extern isr_irq_handler 3 | 4 | irq_handler: 5 | pusha ; push all registers 6 | mov ax, ds 7 | push eax ; save ds 8 | 9 | mov ax, 0x10 ; load kernel data segment 10 | mov ds, ax 11 | mov es, ax 12 | mov fs, ax 13 | mov gs, ax 14 | 15 | push esp 16 | call isr_irq_handler 17 | pop esp 18 | 19 | pop ebx ; restore kernel data segment 20 | mov ds, bx 21 | mov es, bx 22 | mov fs, bx 23 | mov gs, bx 24 | 25 | popa ; restore all registers 26 | add esp, 0x8 ; restore stack for erro no been pushed 27 | 28 | sti ; re-enable interrupts 29 | iret 30 | 31 | 32 | %macro IRQ 2 33 | global irq_%1 34 | irq_%1: 35 | cli 36 | push byte 0 37 | push byte %2 38 | jmp irq_handler 39 | %endmacro 40 | 41 | 42 | IRQ 0, 32 43 | IRQ 1, 33 44 | IRQ 2, 34 45 | IRQ 3, 35 46 | IRQ 4, 36 47 | IRQ 5, 37 48 | IRQ 6, 38 49 | IRQ 7, 39 50 | IRQ 8, 40 51 | IRQ 9, 41 52 | IRQ 10, 42 53 | IRQ 11, 43 54 | IRQ 12, 44 55 | IRQ 13, 45 56 | IRQ 14, 46 57 | IRQ 15, 47 58 | 59 | 60 | -------------------------------------------------------------------------------- /src/asm/load_gdt.asm: -------------------------------------------------------------------------------- 1 | section .text 2 | global load_gdt 3 | 4 | load_gdt: 5 | mov eax, [esp + 4] ; get gdt pointer 6 | lgdt [eax] ; load gdt 7 | 8 | mov ax, 0x10 ; kernel data segment 9 | mov ds, ax 10 | mov es, ax 11 | mov fs, ax 12 | mov gs, ax 13 | mov ss, ax 14 | 15 | cli ; clear interrupts 16 | mov eax, cr0 ; set bit 0 in cr0 to enter protected mode 17 | or eax, 1 18 | mov cr0, eax 19 | 20 | jmp 0x08:far_jump ; jump to far with code data segment 21 | far_jump: 22 | ret 23 | 24 | -------------------------------------------------------------------------------- /src/asm/load_idt.asm: -------------------------------------------------------------------------------- 1 | section .text 2 | global load_idt 3 | 4 | load_idt: 5 | mov eax, [esp + 4] 6 | lidt [eax] 7 | ret 8 | -------------------------------------------------------------------------------- /src/boot.asm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MrGilli/Quantix-OS/c228b3a2e03fa2c12f383b902be0df91b3182fdb/src/boot.asm -------------------------------------------------------------------------------- /src/console.c: -------------------------------------------------------------------------------- 1 | #include "console.h" 2 | #include "string.h" 3 | #include "types.h" 4 | #include "vga.h" 5 | #include "keyboard.h" 6 | 7 | static uint16 *g_vga_buffer; 8 | //index for video buffer array 9 | static uint32 g_vga_index; 10 | // cursor positions 11 | static uint8 cursor_pos_x = 0, cursor_pos_y = 0; 12 | //fore & back color values 13 | uint8 g_fore_color = COLOR_WHITE, g_back_color = COLOR_BLACK; 14 | static uint16 g_temp_pages[MAXIMUM_PAGES][VGA_TOTAL_ITEMS]; 15 | uint32 g_current_temp_page = 0; 16 | 17 | // clear video buffer array 18 | void console_clear(VGA_COLOR_TYPE fore_color, VGA_COLOR_TYPE back_color) { 19 | uint32 i; 20 | 21 | for (i = 0; i < VGA_TOTAL_ITEMS; i++) { 22 | g_vga_buffer[i] = vga_item_entry(NULL, fore_color, back_color); 23 | } 24 | g_vga_index = 0; 25 | cursor_pos_x = 0; 26 | cursor_pos_y = 0; 27 | vga_set_cursor_pos(cursor_pos_x, cursor_pos_y); 28 | } 29 | 30 | //initialize console 31 | void console_init(VGA_COLOR_TYPE fore_color, VGA_COLOR_TYPE back_color) { 32 | g_vga_buffer = (uint16 *)VGA_ADDRESS; 33 | g_fore_color = fore_color; 34 | g_back_color = back_color; 35 | cursor_pos_x = 0; 36 | cursor_pos_y = 0; 37 | console_clear(fore_color, back_color); 38 | } 39 | 40 | void console_scroll(int type) { 41 | uint32 i; 42 | if (type == SCROLL_UP) { 43 | // scroll up 44 | if (g_current_temp_page > 0) 45 | g_current_temp_page--; 46 | g_current_temp_page %= MAXIMUM_PAGES; 47 | for (i = 0; i < VGA_TOTAL_ITEMS; i++) { 48 | g_vga_buffer[i] = g_temp_pages[g_current_temp_page][i]; 49 | } 50 | } else { 51 | // scroll down 52 | g_current_temp_page++; 53 | g_current_temp_page %= MAXIMUM_PAGES; 54 | for (i = 0; i < VGA_TOTAL_ITEMS; i++) { 55 | g_vga_buffer[i] = g_temp_pages[g_current_temp_page][i]; 56 | } 57 | } 58 | } 59 | 60 | /* 61 | increase vga_index by width of vga width 62 | */ 63 | static void console_newline() { 64 | uint32 i; 65 | 66 | if (cursor_pos_y >= VGA_HEIGHT) { 67 | for (i = 0; i < VGA_TOTAL_ITEMS; i++) 68 | g_temp_pages[g_current_temp_page][i] = g_vga_buffer[i]; 69 | g_current_temp_page++; 70 | cursor_pos_x = 0; 71 | cursor_pos_y = 0; 72 | console_clear(g_fore_color, g_back_color); 73 | } else { 74 | for (i = 0; i < VGA_TOTAL_ITEMS; i++) 75 | g_temp_pages[g_current_temp_page][i] = g_vga_buffer[i]; 76 | 77 | g_vga_index += VGA_WIDTH - (g_vga_index % VGA_WIDTH); 78 | cursor_pos_x = 0; 79 | ++cursor_pos_y; 80 | vga_set_cursor_pos(cursor_pos_x, cursor_pos_y); 81 | } 82 | } 83 | 84 | 85 | //assign ascii character to video buffer 86 | void console_putchar(char ch) { 87 | if (ch == ' ') { 88 | g_vga_buffer[g_vga_index++] = vga_item_entry(' ', g_fore_color, g_back_color); 89 | vga_set_cursor_pos(cursor_pos_x++, cursor_pos_y); 90 | } 91 | if (ch == '\t') { 92 | for(int i = 0; i < 4; i++) { 93 | g_vga_buffer[g_vga_index++] = vga_item_entry(' ', g_fore_color, g_back_color); 94 | vga_set_cursor_pos(cursor_pos_x++, cursor_pos_y); 95 | } 96 | } else if (ch == '\n') { 97 | console_newline(); 98 | } else { 99 | if (ch > 0) { 100 | g_vga_buffer[g_vga_index++] = vga_item_entry(ch, g_fore_color, g_back_color); 101 | vga_set_cursor_pos(++cursor_pos_x, cursor_pos_y); 102 | } 103 | } 104 | } 105 | 106 | // revert back the printed character and add 0 to it 107 | void console_ungetchar() { 108 | if(g_vga_index > 0) { 109 | g_vga_buffer[g_vga_index--] = vga_item_entry(0, g_fore_color, g_back_color); 110 | if(cursor_pos_x > 0) { 111 | vga_set_cursor_pos(cursor_pos_x--, cursor_pos_y); 112 | } else { 113 | cursor_pos_x = VGA_WIDTH; 114 | if (cursor_pos_y > 0) 115 | vga_set_cursor_pos(cursor_pos_x--, --cursor_pos_y); 116 | else 117 | cursor_pos_y = 0; 118 | } 119 | } 120 | 121 | // set last printed character to 0 122 | g_vga_buffer[g_vga_index] = vga_item_entry(0, g_fore_color, g_back_color); 123 | } 124 | 125 | // revert back the printed character until n characters 126 | void console_ungetchar_bound(uint8 n) { 127 | if(((g_vga_index % VGA_WIDTH) > n) && (n > 0)) { 128 | g_vga_buffer[g_vga_index--] = vga_item_entry(0, g_fore_color, g_back_color); 129 | if(cursor_pos_x >= n) { 130 | vga_set_cursor_pos(cursor_pos_x--, cursor_pos_y); 131 | } else { 132 | cursor_pos_x = VGA_WIDTH; 133 | if (cursor_pos_y > 0) 134 | vga_set_cursor_pos(cursor_pos_x--, --cursor_pos_y); 135 | else 136 | cursor_pos_y = 0; 137 | } 138 | } 139 | 140 | // set last printed character to 0 141 | g_vga_buffer[g_vga_index] = vga_item_entry(0, g_fore_color, g_back_color); 142 | } 143 | 144 | void console_gotoxy(uint16 x, uint16 y) { 145 | g_vga_index = (80 * y) + x; 146 | cursor_pos_x = x; 147 | cursor_pos_y = y; 148 | vga_set_cursor_pos(cursor_pos_x, cursor_pos_y); 149 | } 150 | 151 | //print string by calling print_char 152 | void console_putstr(const char *str) { 153 | uint32 index = 0; 154 | while (str[index]) { 155 | if (str[index] == '\n') 156 | console_newline(); 157 | else 158 | console_putchar(str[index]); 159 | index++; 160 | } 161 | } 162 | 163 | void printf(const char *format, ...) { 164 | g_fore_color = COLOR_WHITE; 165 | char **arg = (char **)&format; 166 | int c; 167 | char buf[32]; 168 | 169 | arg++; 170 | 171 | memset(buf, 0, sizeof(buf)); 172 | while ((c = *format++) != 0) { 173 | if (c != '%') 174 | console_putchar(c); 175 | else { 176 | char *p, *p2; 177 | int pad0 = 0, pad = 0; 178 | 179 | c = *format++; 180 | if (c == '0') { 181 | pad0 = 1; 182 | c = *format++; 183 | } 184 | 185 | if (c >= '0' && c <= '9') { 186 | pad = c - '0'; 187 | c = *format++; 188 | } 189 | 190 | switch (c) { 191 | case 'd': 192 | case 'u': 193 | case 'x': 194 | itoa(buf, c, *((int *)arg++)); 195 | p = buf; 196 | goto string; 197 | break; 198 | 199 | case 's': 200 | p = *arg++; 201 | if (!p) 202 | p = "(null)"; 203 | 204 | string: 205 | for (p2 = p; *p2; p2++) 206 | ; 207 | for (; p2 < p + pad; p2++) 208 | console_putchar(pad0 ? '0' : ' '); 209 | while (*p) 210 | console_putchar(*p++); 211 | break; 212 | 213 | default: 214 | console_putchar(*((int *)arg++)); 215 | break; 216 | } 217 | } 218 | } 219 | } 220 | 221 | void printf_color(char vga_color, const char *format, ...) { 222 | g_fore_color = vga_color; 223 | char **arg = (char **)&format; 224 | int c; 225 | char buf[32]; 226 | 227 | arg++; 228 | 229 | memset(buf, 0, sizeof(buf)); 230 | while ((c = *format++) != 0) { 231 | if (c != '%') 232 | console_putchar(c); 233 | else { 234 | char *p, *p2; 235 | int pad0 = 0, pad = 0; 236 | 237 | c = *format++; 238 | if (c == '0') { 239 | pad0 = 1; 240 | c = *format++; 241 | } 242 | 243 | if (c >= '0' && c <= '9') { 244 | pad = c - '0'; 245 | c = *format++; 246 | } 247 | 248 | switch (c) { 249 | case 'd': 250 | case 'u': 251 | case 'x': 252 | itoa(buf, c, *((int *)arg++)); 253 | p = buf; 254 | goto string; 255 | break; 256 | 257 | case 's': 258 | p = *arg++; 259 | if (!p) 260 | p = "(null)"; 261 | 262 | string: 263 | for (p2 = p; *p2; p2++) 264 | ; 265 | for (; p2 < p + pad; p2++) 266 | console_putchar(pad0 ? '0' : ' '); 267 | while (*p) 268 | console_putchar(*p++); 269 | break; 270 | 271 | default: 272 | console_putchar(*((int *)arg++)); 273 | break; 274 | } 275 | } 276 | } 277 | } 278 | 279 | // read string from console, but no backing 280 | void getstr(char *buffer) { 281 | if (!buffer) return; 282 | while(1) { 283 | char ch = kb_getchar(); 284 | if (ch == '\n') { 285 | printf("\n"); 286 | return ; 287 | } else { 288 | *buffer++ = ch; 289 | printf("%c", ch); 290 | } 291 | } 292 | } 293 | 294 | 295 | 296 | // read string from console, and erase or go back util bound occurs 297 | void getstr_bound(char *buffer, uint8 bound) { 298 | if (!buffer) return; 299 | while(1) { 300 | char ch = kb_getchar(); 301 | if (ch == '\n') { 302 | printf("\n"); 303 | return ; 304 | } else if(ch == '\b') { 305 | console_ungetchar_bound(bound); 306 | buffer--; 307 | *buffer = '\0'; 308 | } else { 309 | *buffer++ = ch; 310 | printf("%c", ch); 311 | } 312 | } 313 | } 314 | 315 | 316 | -------------------------------------------------------------------------------- /src/ctypes.h: -------------------------------------------------------------------------------- 1 | #ifndef TYPES_H 2 | #define TYPES_H 3 | 4 | typedef unsigned char uint8; 5 | typedef unsigned short uint16; 6 | typedef unsigned int uint32; 7 | typedef unsigned char u8int; 8 | typedef unsigned short u16int; 9 | typedef unsigned int u32int; 10 | typedef void process; 11 | typedef int function; 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /src/framebuffer.c: -------------------------------------------------------------------------------- 1 | #include "multiboot.h" 2 | #include "stdint-gcc.h" 3 | #include "ctypes.h" 4 | #include "qemu.h" 5 | 6 | 7 | multiboot_uint32_t* framebuffer_buffer; 8 | multiboot_uint32_t framebuffer_bpp; 9 | multiboot_uint32_t framebuffer_pitch; 10 | multiboot_uint32_t framebuffer_height; 11 | multiboot_uint32_t framebuffer_width; 12 | 13 | uint32_t cur_x = 0; 14 | uint32_t cur_y = 0; 15 | 16 | uint32_t fg_color, bg_color; 17 | //Define Macros 18 | #define CHECK_FLAG(flags,bit) ((flags) & (1 << (bit))) 19 | 20 | int framebuffer_check(multiboot_info_t* multiboot){ 21 | int framebuffer_type; 22 | if (CHECK_FLAG (multiboot->flags, 12)){ 23 | 24 | switch (multiboot->framebuffer_type){ 25 | case MULTIBOOT_FRAMEBUFFER_TYPE_RGB: 26 | 27 | framebuffer_type = 1; 28 | return framebuffer_type; 29 | } 30 | return framebuffer_type; 31 | } 32 | return framebuffer_type; 33 | } 34 | 35 | int init_framebuffer(multiboot_info_t* mbi){ 36 | if(framebuffer_check(mbi)==1){ 37 | framebuffer_buffer = (uint32_t*)((uintptr_t)mbi->framebuffer_addr); 38 | framebuffer_bpp = mbi->framebuffer_bpp; 39 | framebuffer_pitch = mbi->framebuffer_pitch; 40 | framebuffer_height = mbi->framebuffer_height; 41 | framebuffer_width = mbi->framebuffer_width; 42 | } 43 | } 44 | 45 | void framebuffer_putpixel(uint32_t x, uint32_t y, uint32_t color){ 46 | *(uint32_t*)(x + y * framebuffer_width + framebuffer_buffer) = color; 47 | } 48 | 49 | void framebuffer_putchar(char ch, uint32_t color){ 50 | // 51 | } 52 | 53 | void framebuffer_backspace(uint32_t color){ 54 | cur_x--; 55 | framebuffer_putchar(219, color); 56 | cur_x--; 57 | } 58 | 59 | void framebuffer_back(){ 60 | cur_x--; 61 | } 62 | 63 | void framebuffer_putstr(char *str, uint32_t color){ 64 | while(*str!=0){ 65 | framebuffer_putchar(*str, color); 66 | str++; 67 | } 68 | } 69 | 70 | void framebuffer_clscr(uint32_t color){ 71 | for(uint32_t i = 0; i < (framebuffer_height * framebuffer_width); i++){ 72 | framebuffer_buffer[i] = color; 73 | } 74 | cur_x = 0; 75 | cur_y = 0; 76 | } 77 | 78 | void init_tty(multiboot_info_t *mbi, uint32_t fg, uint32_t bg){ 79 | init_framebuffer(mbi); 80 | fg_color = fg; 81 | bg_color = bg; 82 | framebuffer_clscr(bg); 83 | } 84 | 85 | void print_char(char ch){ 86 | framebuffer_putchar(ch, fg_color); 87 | } 88 | 89 | void gotoxy(uint32_t x, uint32_t y){ 90 | cur_x=x; 91 | cur_y=y; 92 | } -------------------------------------------------------------------------------- /src/framebuffer.h: -------------------------------------------------------------------------------- 1 | #ifndef FRAMEBUFFER_H 2 | #define FRAMEBUFFER_H 3 | 4 | #include "multiboot.h" 5 | #include "stdint-gcc.h" 6 | 7 | // Function declarations 8 | void init_tty(multiboot_info_t *mbi, uint32_t fg, uint32_t bg); 9 | void framebuffer_putchar(char ch, uint32_t color); 10 | void framebuffer_putpixel(uint32_t x, uint32_t y, uint32_t color); 11 | void framebuffer_clscr(uint32_t color); 12 | void gotoxy(uint32_t x, uint32_t y); 13 | 14 | // Constants 15 | #define FONT_HEIGHT 8 16 | #define FONT_WIDTH 8 17 | 18 | // Define any additional structures or constants needed for framebuffer operations 19 | 20 | #endif /* FRAMEBUFFER_H */ 21 | -------------------------------------------------------------------------------- /src/gdt.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Global Descriptor Table(GDT) setup 3 | */ 4 | #include "gdt.h" 5 | 6 | GDT g_gdt[NO_GDT_DESCRIPTORS]; 7 | GDT_PTR g_gdt_ptr; 8 | 9 | /** 10 | * fill entries of GDT 11 | */ 12 | void gdt_set_entry(int index, uint32 base, uint32 limit, uint8 access, uint8 gran) { 13 | GDT *this = &g_gdt[index]; 14 | 15 | this->segment_limit = limit & 0xFFFF; 16 | this->base_low = base & 0xFFFF; 17 | this->base_middle = (base >> 16) & 0xFF; 18 | this->access = access; 19 | 20 | this->granularity = (limit >> 16) & 0x0F; 21 | this->granularity = this->granularity | (gran & 0xF0); 22 | 23 | this->base_high = (base >> 24 & 0xFF); 24 | } 25 | 26 | // initialize GDT 27 | void gdt_init() { 28 | g_gdt_ptr.limit = sizeof(g_gdt) - 1; 29 | g_gdt_ptr.base_address = (uint32)g_gdt; 30 | 31 | // NULL segment 32 | gdt_set_entry(0, 0, 0, 0, 0); 33 | // code segment 34 | gdt_set_entry(1, 0, 0xFFFFFFFF, 0x9A, 0xCF); 35 | // data segment 36 | gdt_set_entry(2, 0, 0xFFFFFFFF, 0x92, 0xCF); 37 | // user code segment 38 | gdt_set_entry(3, 0, 0xFFFFFFFF, 0xFA, 0xCF); 39 | // user data segment 40 | gdt_set_entry(4, 0, 0xFFFFFFFF, 0xF2, 0xCF); 41 | 42 | load_gdt((uint32)&g_gdt_ptr); 43 | } 44 | -------------------------------------------------------------------------------- /src/idt.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Interrupt Descriptor Table(GDT) setup 3 | */ 4 | 5 | #include "idt.h" 6 | #include "isr.h" 7 | #include "8259_pic.h" 8 | 9 | IDT g_idt[NO_IDT_DESCRIPTORS]; 10 | IDT_PTR g_idt_ptr; 11 | 12 | /** 13 | * fill entries of IDT 14 | */ 15 | void idt_set_entry(int index, uint32 base, uint16 seg_sel, uint8 flags) { 16 | IDT *this = &g_idt[index]; 17 | 18 | this->base_low = base & 0xFFFF; 19 | this->segment_selector = seg_sel; 20 | this->zero = 0; 21 | this->type = flags | 0x60; 22 | this->base_high = (base >> 16) & 0xFFFF; 23 | } 24 | 25 | void idt_init() { 26 | g_idt_ptr.base_address = (uint32)g_idt; 27 | g_idt_ptr.limit = sizeof(g_idt) - 1; 28 | pic8259_init(); 29 | 30 | idt_set_entry(0, (uint32)exception_0, 0x08, 0x8E); 31 | idt_set_entry(1, (uint32)exception_1, 0x08, 0x8E); 32 | idt_set_entry(2, (uint32)exception_2, 0x08, 0x8E); 33 | idt_set_entry(3, (uint32)exception_3, 0x08, 0x8E); 34 | idt_set_entry(4, (uint32)exception_4, 0x08, 0x8E); 35 | idt_set_entry(5, (uint32)exception_5, 0x08, 0x8E); 36 | idt_set_entry(6, (uint32)exception_6, 0x08, 0x8E); 37 | idt_set_entry(7, (uint32)exception_7, 0x08, 0x8E); 38 | idt_set_entry(8, (uint32)exception_8, 0x08, 0x8E); 39 | idt_set_entry(9, (uint32)exception_9, 0x08, 0x8E); 40 | idt_set_entry(10, (uint32)exception_10, 0x08, 0x8E); 41 | idt_set_entry(11, (uint32)exception_11, 0x08, 0x8E); 42 | idt_set_entry(12, (uint32)exception_12, 0x08, 0x8E); 43 | idt_set_entry(13, (uint32)exception_13, 0x08, 0x8E); 44 | idt_set_entry(14, (uint32)exception_14, 0x08, 0x8E); 45 | idt_set_entry(15, (uint32)exception_15, 0x08, 0x8E); 46 | idt_set_entry(16, (uint32)exception_16, 0x08, 0x8E); 47 | idt_set_entry(17, (uint32)exception_17, 0x08, 0x8E); 48 | idt_set_entry(18, (uint32)exception_18, 0x08, 0x8E); 49 | idt_set_entry(19, (uint32)exception_19, 0x08, 0x8E); 50 | idt_set_entry(20, (uint32)exception_20, 0x08, 0x8E); 51 | idt_set_entry(21, (uint32)exception_21, 0x08, 0x8E); 52 | idt_set_entry(22, (uint32)exception_22, 0x08, 0x8E); 53 | idt_set_entry(23, (uint32)exception_23, 0x08, 0x8E); 54 | idt_set_entry(24, (uint32)exception_24, 0x08, 0x8E); 55 | idt_set_entry(25, (uint32)exception_25, 0x08, 0x8E); 56 | idt_set_entry(26, (uint32)exception_26, 0x08, 0x8E); 57 | idt_set_entry(27, (uint32)exception_27, 0x08, 0x8E); 58 | idt_set_entry(28, (uint32)exception_28, 0x08, 0x8E); 59 | idt_set_entry(29, (uint32)exception_29, 0x08, 0x8E); 60 | idt_set_entry(30, (uint32)exception_30, 0x08, 0x8E); 61 | idt_set_entry(31, (uint32)exception_31, 0x08, 0x8E); 62 | idt_set_entry(32, (uint32)irq_0, 0x08, 0x8E); 63 | idt_set_entry(33, (uint32)irq_1, 0x08, 0x8E); 64 | idt_set_entry(34, (uint32)irq_2, 0x08, 0x8E); 65 | idt_set_entry(35, (uint32)irq_3, 0x08, 0x8E); 66 | idt_set_entry(36, (uint32)irq_4, 0x08, 0x8E); 67 | idt_set_entry(37, (uint32)irq_5, 0x08, 0x8E); 68 | idt_set_entry(38, (uint32)irq_6, 0x08, 0x8E); 69 | idt_set_entry(39, (uint32)irq_7, 0x08, 0x8E); 70 | idt_set_entry(40, (uint32)irq_8, 0x08, 0x8E); 71 | idt_set_entry(41, (uint32)irq_9, 0x08, 0x8E); 72 | idt_set_entry(42, (uint32)irq_10, 0x08, 0x8E); 73 | idt_set_entry(43, (uint32)irq_11, 0x08, 0x8E); 74 | idt_set_entry(44, (uint32)irq_12, 0x08, 0x8E); 75 | idt_set_entry(45, (uint32)irq_13, 0x08, 0x8E); 76 | idt_set_entry(46, (uint32)irq_14, 0x08, 0x8E); 77 | idt_set_entry(47, (uint32)irq_15, 0x08, 0x8E); 78 | idt_set_entry(128, (uint32)exception_128, 0x08, 0x8E); 79 | 80 | load_idt((uint32)&g_idt_ptr); 81 | asm volatile("sti"); 82 | } 83 | 84 | -------------------------------------------------------------------------------- /src/io_ports.c: -------------------------------------------------------------------------------- 1 | #include "io_ports.h" 2 | 3 | /** 4 | * read a byte from given port number 5 | */ 6 | uint8 inportb(uint16 port) { 7 | uint8 ret; 8 | asm volatile("inb %1, %0" : "=a"(ret) : "Nd"(port)); 9 | return ret; 10 | } 11 | 12 | /** 13 | * write a given byte to given port number 14 | */ 15 | void outportb(uint16 port, uint8 val) { 16 | asm volatile("outb %1, %0" :: "dN"(port), "a"(val)); 17 | } 18 | 19 | /** 20 | * read 2 bytes(short) from given port number 21 | */ 22 | uint16 inports(uint16 port) { 23 | uint16 rv; 24 | asm volatile ("inw %1, %0" : "=a" (rv) : "dN" (port)); 25 | return rv; 26 | } 27 | 28 | /** 29 | * write given 2 bytes(short) to given port number 30 | */ 31 | void outports(uint16 port, uint16 data) { 32 | asm volatile ("outw %1, %0" : : "dN" (port), "a" (data)); 33 | } 34 | 35 | /** 36 | * read 4 bytes(long) from given port number 37 | */ 38 | uint32 inportl(uint16 port) { 39 | uint32 rv; 40 | asm volatile ("inl %%dx, %%eax" : "=a" (rv) : "dN" (port)); 41 | return rv; 42 | } 43 | 44 | /** 45 | * write given 4 bytes(long) to given port number 46 | */ 47 | void outportl(uint16 port, uint32 data) { 48 | asm volatile ("outl %%eax, %%dx" : : "dN" (port), "a" (data)); 49 | } 50 | 51 | -------------------------------------------------------------------------------- /src/isr.c: -------------------------------------------------------------------------------- 1 | #include "isr.h" 2 | #include "idt.h" 3 | #include "8259_pic.h" 4 | #include "console.h" 5 | 6 | // For both exceptions and irq interrupt 7 | ISR g_interrupt_handlers[NO_INTERRUPT_HANDLERS]; 8 | 9 | // for more details, see Intel manual -> Interrupt & Exception Handling 10 | char *exception_messages[32] = { 11 | "Division By Zero", 12 | "Debug", 13 | "Non Maskable Interrupt", 14 | "Breakpoint", 15 | "Overflow", 16 | "BOUND Range Exceeded", 17 | "Invalid Opcode", 18 | "Device Not Available (No Math Coprocessor)", 19 | "Double Fault", 20 | "Coprocessor Segment Overrun", 21 | "Invalid TSS", 22 | "Segment Not Present", 23 | "Stack-Segment Fault", 24 | "General Protection", 25 | "Page Fault", 26 | "Unknown Interrupt (intel reserved)", 27 | "x87 FPU Floating-Point Error (Math Fault)", 28 | "Alignment Check", 29 | "Machine Check", 30 | "SIMD Floating-Point Exception", 31 | "Virtualization Exception", 32 | "Reserved", 33 | "Reserved", 34 | "Reserved", 35 | "Reserved", 36 | "Reserved", 37 | "Reserved", 38 | "Reserved", 39 | "Reserved", 40 | "Reserved", 41 | "Reserved", 42 | "Reserved" 43 | }; 44 | 45 | /** 46 | * register given handler to interrupt handlers at given num 47 | */ 48 | void isr_register_interrupt_handler(int num, ISR handler) { 49 | printf("IRQ %d registered\n", num); 50 | if (num < NO_INTERRUPT_HANDLERS) 51 | g_interrupt_handlers[num] = handler; 52 | } 53 | 54 | /* 55 | * turn off current interrupt 56 | */ 57 | void isr_end_interrupt(int num) { 58 | pic8259_eoi(num); 59 | } 60 | 61 | /** 62 | * invoke isr routine and send eoi to pic, 63 | * being called in irq.asm 64 | */ 65 | void isr_irq_handler(REGISTERS *reg) { 66 | if (g_interrupt_handlers[reg->int_no] != NULL) { 67 | ISR handler = g_interrupt_handlers[reg->int_no]; 68 | handler(reg); 69 | } 70 | pic8259_eoi(reg->int_no); 71 | } 72 | 73 | static void print_registers(REGISTERS *reg) { 74 | printf("REGISTERS:\n"); 75 | printf("err_code=%d\n", reg->err_code); 76 | printf("eax=0x%x, ebx=0x%x, ecx=0x%x, edx=0x%x\n", reg->eax, reg->ebx, reg->ecx, reg->edx); 77 | printf("edi=0x%x, esi=0x%x, ebp=0x%x, esp=0x%x\n", reg->edi, reg->esi, reg->ebp, reg->esp); 78 | printf("eip=0x%x, cs=0x%x, ss=0x%x, eflags=0x%x, useresp=0x%x\n", reg->eip, reg->ss, reg->eflags, reg->useresp); 79 | } 80 | 81 | /** 82 | * invoke exception routine, 83 | * being called in exception.asm 84 | */ 85 | void isr_exception_handler(REGISTERS reg) { 86 | if (reg.int_no < 32) { 87 | printf("EXCEPTION: %s\n", exception_messages[reg.int_no]); 88 | print_registers(®); 89 | for (;;) 90 | ; 91 | } 92 | if (g_interrupt_handlers[reg.int_no] != NULL) { 93 | ISR handler = g_interrupt_handlers[reg.int_no]; 94 | handler(®); 95 | } 96 | } -------------------------------------------------------------------------------- /src/kernel.c: -------------------------------------------------------------------------------- 1 | #include "kernel.h" 2 | #include "console.h" 3 | #include "string.h" 4 | #include "gdt.h" 5 | #include "idt.h" 6 | #include "keyboard.h" 7 | #include "io_ports.h" 8 | #include "framebuffer.h" 9 | #include "multiboot.h" 10 | #include "stdint-gcc.h" 11 | #include "ctypes.h" 12 | #include "qemu.h" 13 | #include "romfont.h" 14 | 15 | 16 | #include 17 | #include 18 | #include 19 | 20 | 21 | #define BRAND_QEMU 1 22 | #define BRAND_VBOX 2 23 | 24 | #define MAX_FILENAME_LENGTH 20 25 | #define MAX_FILE_COUNT 100 26 | #define MAX_FILE_CONTENT_LENGTH 10000 27 | 28 | typedef struct { 29 | char name[MAX_FILENAME_LENGTH]; 30 | int size; 31 | char content[MAX_FILE_CONTENT_LENGTH]; 32 | } File; 33 | 34 | typedef struct { 35 | char name[MAX_FILENAME_LENGTH]; 36 | int file_count; 37 | File files[MAX_FILE_COUNT]; 38 | } Directory; 39 | 40 | Directory root_directory; 41 | 42 | void scan(const char *shell, bool init_all){ 43 | char new_buffer [255]; 44 | printf(shell); 45 | memset(new_buffer, 0, sizeof(new_buffer)); 46 | getstr_bound(new_buffer, strlen(shell)); 47 | } 48 | 49 | 50 | void custom_strcpy(char *dest, const char *src) { 51 | while (*src != '\0') { 52 | *dest = *src; 53 | src++; 54 | dest++; 55 | } 56 | *dest = '\0'; // Null-terminate the destination string 57 | } 58 | 59 | void initFileSystem() { 60 | custom_strcpy(root_directory.name, "root"); 61 | root_directory.file_count = 0; 62 | } 63 | 64 | void createFile(char *name, char *content) { 65 | if (root_directory.file_count < MAX_FILE_COUNT) { 66 | File newFile; 67 | custom_strcpy(newFile.name, name); 68 | newFile.size = strlen(content); 69 | custom_strcpy(newFile.content, content); 70 | newFile.content[MAX_FILE_CONTENT_LENGTH - 1] = '\0'; 71 | 72 | root_directory.files[root_directory.file_count++] = newFile; 73 | printf("File '%s' created successfully.\n", name); 74 | } else { 75 | printf("File system full. Cannot create more files.\n"); 76 | } 77 | } 78 | 79 | 80 | 81 | void listFiles() { 82 | printf("Files in root directory:\n"); 83 | for (int i = 0; i < root_directory.file_count; ++i) { 84 | printf("- FILE NAME: %s, FILE CONTENT: %s\n", root_directory.files[i].name, root_directory.files[i].content); 85 | } 86 | } 87 | 88 | 89 | void __cpuid(uint32 type, uint32 *eax, uint32 *ebx, uint32 *ecx, uint32 *edx) { 90 | asm volatile("cpuid" 91 | : "=a"(*eax), "=b"(*ebx), "=c"(*ecx), "=d"(*edx) 92 | : "0"(type)); // put the type into eax 93 | } 94 | 95 | int cpuid_info(int print) { 96 | uint32 brand[12]; 97 | uint32 eax, ebx, ecx, edx; 98 | uint32 type; 99 | 100 | memset(brand, 0, sizeof(brand)); 101 | __cpuid(0x80000002, (uint32 *)brand+0x0, (uint32 *)brand+0x1, (uint32 *)brand+0x2, (uint32 *)brand+0x3); 102 | __cpuid(0x80000003, (uint32 *)brand+0x4, (uint32 *)brand+0x5, (uint32 *)brand+0x6, (uint32 *)brand+0x7); 103 | __cpuid(0x80000004, (uint32 *)brand+0x8, (uint32 *)brand+0x9, (uint32 *)brand+0xa, (uint32 *)brand+0xb); 104 | 105 | if (print) { 106 | printf("Brand: %s\n", brand); 107 | for(type = 0; type < 4; type++) { 108 | __cpuid(type, &eax, &ebx, &ecx, &edx); 109 | printf("type:0x%x, eax:0x%x, ebx:0x%x, ecx:0x%x, edx:0x%x\n", type, eax, ebx, ecx, edx); 110 | } 111 | } 112 | 113 | if (strstr(brand, "QEMU") != NULL) 114 | return BRAND_QEMU; 115 | 116 | return BRAND_VBOX; 117 | } 118 | 119 | 120 | BOOL is_echo(char *b) { 121 | if((b[0]=='e')&&(b[1]=='c')&&(b[2]=='h')&&(b[3]=='o')) 122 | if(b[4]==' '||b[4]=='\0') 123 | return TRUE; 124 | return FALSE; 125 | } 126 | 127 | void shutdown() { 128 | int brand = cpuid_info(0); 129 | // QEMU 130 | if (brand == BRAND_QEMU) 131 | outports(0x604, 0x2000); 132 | else 133 | // VirtualBox 134 | outports(0x4004, 0x3400); 135 | } 136 | 137 | void new_kernel_instance(char *cmd_to_run){ 138 | //INIT KERNEL CODE 139 | //RUN THE MKFILE CMD AS A KERNEL INSTANCE 140 | //RETURN OUTPUT TO MAIN FUNCTION 141 | printf("\nRunning Command/Program '%s' in Quantum instance...\n\n", cmd_to_run); 142 | if(cmd_to_run = "mkfile") { 143 | char name [255]; 144 | const char *shell_file = "File Name> "; 145 | printf(shell_file); 146 | memset(name, 0, sizeof(name)); 147 | getstr_bound(name, strlen(shell_file)); 148 | 149 | char file_content [255]; 150 | const char *shell_file_content = "File Content> "; 151 | printf(shell_file_content); 152 | memset(file_content, 0, sizeof(file_content)); 153 | getstr_bound(file_content, strlen(shell_file_content)); 154 | 155 | //CREATE THE FILE BASED ON THE FILE NAME AND IT'S CONTENT 156 | createFile(name, file_content); 157 | } else if(cmd_to_run = "clear"){ 158 | printf("\nThe 'clear' command should not be run in a Quantum Instance.\n"); 159 | printf("Just run 'clear' in the Terminal.\n"); 160 | }else { 161 | printf("Command '%s' not found!!\n", cmd_to_run); 162 | } 163 | } 164 | 165 | void non_terminal(){ 166 | //init the terminal but when enter is pressed dont add the terminal text. 167 | } 168 | 169 | void magix(){ 170 | 171 | 172 | char name [255]; 173 | const char *shell_file = "File Name> "; 174 | printf(shell_file); 175 | memset(name, 0, sizeof(name)); 176 | getstr_bound(name, strlen(shell_file)); 177 | printf("___________________________________ \n"); 178 | printf("Welcome To The Magix Editor!!\n\n"); 179 | printf_color(COLOR_GREEN, "EXIT(.out magix)\n"); 180 | 181 | char file_content [255]; 182 | const char *shell_file_content = "> "; 183 | 184 | while(1){ 185 | if(strcmp(file_content, ".out magix") == 0){ 186 | main_loop(); 187 | } 188 | else { 189 | printf(shell_file_content); 190 | memset(file_content, 0, sizeof(file_content)); 191 | getstr_bound(file_content, strlen(shell_file_content)); 192 | } 193 | } 194 | 195 | //CREATE THE FILE BASED ON THE FILE NAME AND IT'S CONTENT 196 | createFile(name, file_content); 197 | } 198 | 199 | 200 | 201 | 202 | void login_and_run() { 203 | char buffer[255]; 204 | const char *shell = "Password> "; 205 | gdt_init(); 206 | idt_init(); 207 | 208 | console_init(COLOR_WHITE, COLOR_BLUE); 209 | keyboard_init(); 210 | 211 | printf("Login Needed To Continue...\n"); 212 | printf("Default Password: 'root'.\n"); 213 | 214 | while(1) { 215 | printf(shell); 216 | memset(buffer, 0, sizeof(buffer)); 217 | getstr_bound(buffer, strlen(shell)); 218 | 219 | if (strlen(buffer) == 0) 220 | continue; 221 | if(strcmp(buffer, "root") == 0) { 222 | main_loop(); 223 | console_clear(COLOR_WHITE, COLOR_BLACK); 224 | } 225 | else if(strcmp(buffer, "shutdown") == 0) { 226 | shutdown(); 227 | } 228 | else { 229 | printf("invalid command: %s\n", buffer); 230 | } 231 | 232 | } 233 | } 234 | 235 | void main_loop() { 236 | char buffer[255]; 237 | const char *shell = "[root@Quantix]$ "; 238 | gdt_init(); 239 | idt_init(); 240 | initFileSystem(); 241 | 242 | console_init(COLOR_WHITE, COLOR_BLACK); 243 | keyboard_init(); 244 | 245 | printf("starting terminal...\n"); 246 | printf("INIT Quantix.....\n"); 247 | printf("Kernel Ready (Type 'help' to see list of supported commands)\n"); 248 | printf("Important Info: 'MAX FILES: 100', 'MAX FILE CONTENT: 10,000'\n\n"); 249 | 250 | while(1) { 251 | printf_color(COLOR_RED, shell); 252 | printf(""); 253 | memset(buffer, 0, sizeof(buffer)); 254 | getstr_bound(buffer, strlen(shell)); 255 | // Draw the box using framebuffer functions 256 | // Draw the box using framebuffer functions 257 | 258 | if (strlen(buffer) == 0) 259 | continue; 260 | if(strcmp(buffer, "cpuid") == 0) { 261 | cpuid_info(1); 262 | } 263 | else if(strcmp(buffer, "help") == 0) { 264 | printf("Quantix Operating System & Tiny OS Terminal\n"); 265 | printf("Commands:\n\n help\n cpuid\n clear\n mkfile(Create a basic file, like touch command)\n ls(List all files and their contents in DIR)\n whoami\n echo\n exec(Execute a file/program)\n qexec(Execute program in Quantum instance)\n shutdown\n\n"); 266 | } 267 | else if(strcmp(buffer, "mkfile") == 0) { 268 | char name [255]; 269 | const char *shell_file = "File Name> "; 270 | printf(shell_file); 271 | memset(name, 0, sizeof(name)); 272 | getstr_bound(name, strlen(shell_file)); 273 | 274 | char file_content [255]; 275 | const char *shell_file_content = "File Content> "; 276 | printf(shell_file_content); 277 | memset(file_content, 0, sizeof(file_content)); 278 | getstr_bound(file_content, strlen(shell_file_content)); 279 | 280 | //CREATE THE FILE BASED ON THE FILE NAME AND IT'S CONTENT 281 | createFile(name, file_content); 282 | } 283 | else if(strcmp(buffer, "rm") == 0){ 284 | scan("File to remove> ", TRUE); 285 | printf("'rm' command isn't ready for use yet.\n"); 286 | } 287 | else if(strcmp(buffer, "ls") == 0) { 288 | listFiles(); 289 | } 290 | else if(strcmp(buffer, "qexec") == 0){ 291 | char program_name [255]; 292 | const char *prompt = "Program To Run In Quantum Instance> "; 293 | printf(prompt); 294 | memset(program_name, 0, sizeof(program_name)); 295 | getstr_bound(program_name, strlen(prompt)); 296 | new_kernel_instance(program_name); 297 | } 298 | else if(strcmp(buffer, "exec") == 0){ 299 | char program_name [255]; 300 | const char *prompt = "Program To Run In Kernel> "; 301 | printf("Available Programs/Commands to execute:\n"); 302 | printf_color(COLOR_GREEN, " - Magix(CLI Text Editor)\n - calc(CLI Calculator)\n - mani(Quantix OS Manifesto)\n - guide(List of all sys cmds and what they do)\n\n"); 303 | 304 | printf(prompt); 305 | memset(program_name, 0, sizeof(program_name)); 306 | getstr_bound(program_name, strlen(prompt)); 307 | if(strcmp(program_name, "calc") == 0){ 308 | printf("Running basic calculator app...\n"); 309 | } else if(strcmp(program_name, "magix") == 0){ 310 | magix(); 311 | }else { 312 | printf("ERROR: Command '%s' not found :(\n\n"); 313 | } 314 | } 315 | else if(strcmp(buffer, "whoami") == 0) { 316 | printf("Quantix Operating System User:\n"); 317 | printf("User: ROOT; (Sudo Privileges: TRUE)\n"); 318 | printf("CPUID INFO: \n\n"); 319 | cpuid_info(1); 320 | } 321 | else if(strcmp(buffer, "clear") == 0) { 322 | console_clear(COLOR_WHITE, COLOR_BLACK); 323 | } 324 | else if(is_echo(buffer)) { 325 | printf("%s\n", buffer + 5); 326 | } 327 | else if(strcmp(buffer, "shutdown") == 0) { 328 | shutdown(); 329 | } else { 330 | printf("Invalid command: %s\n", buffer); 331 | } 332 | } 333 | } 334 | 335 | void kmain(){ 336 | //FUNCTION THAT RUNS THE OS 337 | login_and_run(); 338 | } 339 | -------------------------------------------------------------------------------- /src/keyboard.c: -------------------------------------------------------------------------------- 1 | #include "keyboard.h" 2 | 3 | #include "console.h" 4 | #include "idt.h" 5 | #include "io_ports.h" 6 | #include "isr.h" 7 | #include "types.h" 8 | #include "string.h" 9 | 10 | static BOOL g_caps_lock = FALSE; 11 | static BOOL g_shift_pressed = FALSE; 12 | char g_ch = 0, g_scan_code = 0; 13 | 14 | // see scan codes defined in keyboard.h for index 15 | char g_scan_code_chars[128] = { 16 | 0, 27, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', '\b', 17 | '\t', 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', '\n', 18 | 0, 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'', '`', 0, 19 | '\\', 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/', 0, '*', 0, ' ', 20 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '-', 0, 0, 0, '+', 0, 0, 21 | 0, 0, 0, 0, 0, 0, 0, 0, 0 22 | }; 23 | 24 | 25 | static int get_scancode() { 26 | int i, scancode = 0; 27 | 28 | // get scancode until status is on(key pressed) 29 | for (i = 1000; i > 0; i++) { 30 | // Check if scan code is ready 31 | if ((inportb(KEYBOARD_STATUS_PORT) & 1) == 0) continue; 32 | // Get the scan code 33 | scancode = inportb(KEYBOARD_DATA_PORT); 34 | break; 35 | } 36 | if (i > 0) 37 | return scancode; 38 | return 0; 39 | } 40 | 41 | char alternate_chars(char ch) { 42 | switch(ch) { 43 | case '`': return '~'; 44 | case '1': return '!'; 45 | case '2': return '@'; 46 | case '3': return '#'; 47 | case '4': return '$'; 48 | case '5': return '%'; 49 | case '6': return '^'; 50 | case '7': return '&'; 51 | case '8': return '*'; 52 | case '9': return '('; 53 | case '0': return ')'; 54 | case '-': return '_'; 55 | case '=': return '+'; 56 | case '[': return '{'; 57 | case ']': return '}'; 58 | case '\\': return '|'; 59 | case ';': return ':'; 60 | case '\'': return '\"'; 61 | case ',': return '<'; 62 | case '.': return '>'; 63 | case '/': return '?'; 64 | default: return ch; 65 | } 66 | } 67 | 68 | void keyboard_handler(REGISTERS *r) { 69 | int scancode; 70 | 71 | g_ch = 0; 72 | scancode = get_scancode(); 73 | g_scan_code = scancode; 74 | if (scancode & 0x80) { 75 | // key release 76 | } else { 77 | // key down 78 | switch(scancode) { 79 | case SCAN_CODE_KEY_CAPS_LOCK: 80 | if (g_caps_lock == FALSE) 81 | g_caps_lock = TRUE; 82 | else 83 | g_caps_lock = FALSE; 84 | break; 85 | 86 | case SCAN_CODE_KEY_ENTER: 87 | g_ch = '\n'; 88 | break; 89 | 90 | case SCAN_CODE_KEY_TAB: 91 | g_ch = '\t'; 92 | break; 93 | 94 | case SCAN_CODE_KEY_LEFT_SHIFT: 95 | g_shift_pressed = TRUE; 96 | break; 97 | 98 | default: 99 | g_ch = g_scan_code_chars[scancode]; 100 | // if caps in on, covert to upper 101 | if (g_caps_lock) { 102 | // if shift is pressed before 103 | if (g_shift_pressed) { 104 | // replace alternate chars 105 | g_ch = alternate_chars(g_ch); 106 | } else 107 | g_ch = upper(g_ch); 108 | } else { 109 | if (g_shift_pressed) { 110 | if (isalpha(g_ch)) 111 | g_ch = upper(g_ch); 112 | else 113 | // replace alternate chars 114 | g_ch = alternate_chars(g_ch); 115 | } else 116 | g_ch = g_scan_code_chars[scancode]; 117 | g_shift_pressed = FALSE; 118 | } 119 | break; 120 | } 121 | } 122 | } 123 | 124 | void keyboard_init() { 125 | isr_register_interrupt_handler(IRQ_BASE + 1, keyboard_handler); 126 | } 127 | 128 | // a blocking character read 129 | char kb_getchar() { 130 | char c; 131 | 132 | while(g_ch <= 0); 133 | c = g_ch; 134 | g_ch = 0; 135 | g_scan_code = 0; 136 | return c; 137 | } 138 | 139 | char kb_get_scancode() { 140 | char code; 141 | 142 | while(g_scan_code <= 0); 143 | code = g_scan_code; 144 | g_ch = 0; 145 | g_scan_code = 0; 146 | return code; 147 | } 148 | 149 | 150 | 151 | -------------------------------------------------------------------------------- /src/multiboot.h: -------------------------------------------------------------------------------- 1 | /* multiboot.h - Multiboot header file. */ 2 | /* Copyright (C) 1999,2003,2007,2008,2009,2010 Free Software Foundation, Inc. 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to 6 | * deal in the Software without restriction, including without limitation the 7 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 8 | * sell copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ANY 17 | * DEVELOPER OR DISTRIBUTOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 18 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR 19 | * IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 20 | */ 21 | 22 | #ifndef MULTIBOOT_HEADER 23 | #define MULTIBOOT_HEADER 1 24 | 25 | /* How many bytes from the start of the file we search for the header. */ 26 | #define MULTIBOOT_SEARCH 8192 27 | #define MULTIBOOT_HEADER_ALIGN 4 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 | /* Alignment of multiboot modules. */ 36 | #define MULTIBOOT_MOD_ALIGN 0x00001000 37 | 38 | /* Alignment of the multiboot info structure. */ 39 | #define MULTIBOOT_INFO_ALIGN 0x00000004 40 | 41 | /* Flags set in the ’flags’ member of the multiboot header. */ 42 | 43 | /* Align all boot modules on i386 page (4KB) boundaries. */ 44 | #define MULTIBOOT_PAGE_ALIGN 0x00000001 45 | 46 | /* Must pass memory information to OS. */ 47 | #define MULTIBOOT_MEMORY_INFO 0x00000002 48 | 49 | /* Must pass video information to OS. */ 50 | #define MULTIBOOT_VIDEO_MODE 0x00000004 51 | 52 | /* This flag indicates the use of the address fields in the header. */ 53 | #define MULTIBOOT_AOUT_KLUDGE 0x00010000 54 | 55 | /* Flags to be set in the ’flags’ member of the multiboot info structure. */ 56 | 57 | /* is there basic lower/upper memory information? */ 58 | #define MULTIBOOT_INFO_MEMORY 0x00000001 59 | /* is there a boot device set? */ 60 | #define MULTIBOOT_INFO_BOOTDEV 0x00000002 61 | /* is the command-line defined? */ 62 | #define MULTIBOOT_INFO_CMDLINE 0x00000004 63 | /* are there modules to do something with? */ 64 | #define MULTIBOOT_INFO_MODS 0x00000008 65 | 66 | /* These next two are mutually exclusive */ 67 | 68 | /* is there a symbol table loaded? */ 69 | #define MULTIBOOT_INFO_AOUT_SYMS 0x00000010 70 | /* is there an ELF section header table? */ 71 | #define MULTIBOOT_INFO_ELF_SHDR 0X00000020 72 | 73 | /* is there a full memory map? */ 74 | #define MULTIBOOT_INFO_MEM_MAP 0x00000040 75 | 76 | /* Is there drive info? */ 77 | #define MULTIBOOT_INFO_DRIVE_INFO 0x00000080 78 | 79 | /* Is there a config table? */ 80 | #define MULTIBOOT_INFO_CONFIG_TABLE 0x00000100 81 | 82 | /* Is there a boot loader name? */ 83 | #define MULTIBOOT_INFO_BOOT_LOADER_NAME 0x00000200 84 | 85 | /* Is there a APM table? */ 86 | #define MULTIBOOT_INFO_APM_TABLE 0x00000400 87 | 88 | /* Is there video information? */ 89 | #define MULTIBOOT_INFO_VBE_INFO 0x00000800 90 | #define MULTIBOOT_INFO_FRAMEBUFFER_INFO 0x00001000 91 | 92 | #ifndef ASM_FILE 93 | 94 | typedef unsigned char multiboot_uint8_t; 95 | typedef unsigned short multiboot_uint16_t; 96 | typedef unsigned int multiboot_uint32_t; 97 | typedef unsigned long long multiboot_uint64_t; 98 | 99 | struct multiboot_header 100 | { 101 | /* Must be MULTIBOOT_MAGIC - see above. */ 102 | multiboot_uint32_t magic; 103 | 104 | /* Feature flags. */ 105 | multiboot_uint32_t flags; 106 | 107 | /* The above fields plus this one must equal 0 mod 2^32. */ 108 | multiboot_uint32_t checksum; 109 | 110 | /* These are only valid if MULTIBOOT_AOUT_KLUDGE is set. */ 111 | multiboot_uint32_t header_addr; 112 | multiboot_uint32_t load_addr; 113 | multiboot_uint32_t load_end_addr; 114 | multiboot_uint32_t bss_end_addr; 115 | multiboot_uint32_t entry_addr; 116 | 117 | /* These are only valid if MULTIBOOT_VIDEO_MODE is set. */ 118 | multiboot_uint32_t mode_type; 119 | multiboot_uint32_t width; 120 | multiboot_uint32_t height; 121 | multiboot_uint32_t depth; 122 | }; 123 | 124 | /* The symbol table for a.out. */ 125 | struct multiboot_aout_symbol_table 126 | { 127 | multiboot_uint32_t tabsize; 128 | multiboot_uint32_t strsize; 129 | multiboot_uint32_t addr; 130 | multiboot_uint32_t reserved; 131 | }; 132 | typedef struct multiboot_aout_symbol_table multiboot_aout_symbol_table_t; 133 | 134 | /* The section header table for ELF. */ 135 | struct multiboot_elf_section_header_table 136 | { 137 | multiboot_uint32_t num; 138 | multiboot_uint32_t size; 139 | multiboot_uint32_t addr; 140 | multiboot_uint32_t shndx; 141 | }; 142 | typedef struct multiboot_elf_section_header_table multiboot_elf_section_header_table_t; 143 | 144 | struct multiboot_info 145 | { 146 | /* Multiboot info version number */ 147 | multiboot_uint32_t flags; 148 | 149 | /* Available memory from BIOS */ 150 | multiboot_uint32_t mem_lower; 151 | multiboot_uint32_t mem_upper; 152 | 153 | /* "root" partition */ 154 | multiboot_uint32_t boot_device; 155 | 156 | /* Kernel command line */ 157 | multiboot_uint32_t cmdline; 158 | 159 | /* Boot-Module list */ 160 | multiboot_uint32_t mods_count; 161 | multiboot_uint32_t mods_addr; 162 | 163 | union 164 | { 165 | multiboot_aout_symbol_table_t aout_sym; 166 | multiboot_elf_section_header_table_t elf_sec; 167 | } u; 168 | 169 | /* Memory Mapping buffer */ 170 | multiboot_uint32_t mmap_length; 171 | multiboot_uint32_t mmap_addr; 172 | 173 | /* Drive Info buffer */ 174 | multiboot_uint32_t drives_length; 175 | multiboot_uint32_t drives_addr; 176 | 177 | /* ROM configuration table */ 178 | multiboot_uint32_t config_table; 179 | 180 | /* Boot Loader Name */ 181 | multiboot_uint32_t boot_loader_name; 182 | 183 | /* APM table */ 184 | multiboot_uint32_t apm_table; 185 | 186 | /* Video */ 187 | multiboot_uint32_t vbe_control_info; 188 | multiboot_uint32_t vbe_mode_info; 189 | multiboot_uint16_t vbe_mode; 190 | multiboot_uint16_t vbe_interface_seg; 191 | multiboot_uint16_t vbe_interface_off; 192 | multiboot_uint16_t vbe_interface_len; 193 | 194 | multiboot_uint64_t framebuffer_addr; 195 | multiboot_uint32_t framebuffer_pitch; 196 | multiboot_uint32_t framebuffer_width; 197 | multiboot_uint32_t framebuffer_height; 198 | multiboot_uint8_t framebuffer_bpp; 199 | #define MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED 0 200 | #define MULTIBOOT_FRAMEBUFFER_TYPE_RGB 1 201 | #define MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT 2 202 | multiboot_uint8_t framebuffer_type; 203 | union 204 | { 205 | struct 206 | { 207 | multiboot_uint32_t framebuffer_palette_addr; 208 | multiboot_uint16_t framebuffer_palette_num_colors; 209 | }; 210 | struct 211 | { 212 | multiboot_uint8_t framebuffer_red_field_position; 213 | multiboot_uint8_t framebuffer_red_mask_size; 214 | multiboot_uint8_t framebuffer_green_field_position; 215 | multiboot_uint8_t framebuffer_green_mask_size; 216 | multiboot_uint8_t framebuffer_blue_field_position; 217 | multiboot_uint8_t framebuffer_blue_mask_size; 218 | }; 219 | }; 220 | }; 221 | typedef struct multiboot_info multiboot_info_t; 222 | 223 | struct multiboot_color 224 | { 225 | multiboot_uint8_t red; 226 | multiboot_uint8_t green; 227 | multiboot_uint8_t blue; 228 | }; 229 | 230 | struct multiboot_mmap_entry 231 | { 232 | multiboot_uint32_t size; 233 | multiboot_uint64_t addr; 234 | multiboot_uint64_t len; 235 | #define MULTIBOOT_MEMORY_AVAILABLE 1 236 | #define MULTIBOOT_MEMORY_RESERVED 2 237 | #define MULTIBOOT_MEMORY_ACPI_RECLAIMABLE 3 238 | #define MULTIBOOT_MEMORY_NVS 4 239 | #define MULTIBOOT_MEMORY_BADRAM 5 240 | multiboot_uint32_t type; 241 | } __attribute__((packed)); 242 | typedef struct multiboot_mmap_entry multiboot_memory_map_t; 243 | 244 | struct multiboot_mod_list 245 | { 246 | /* the memory used goes from bytes ’mod_start’ to ’mod_end-1’ inclusive */ 247 | multiboot_uint32_t mod_start; 248 | multiboot_uint32_t mod_end; 249 | 250 | /* Module command line */ 251 | multiboot_uint32_t cmdline; 252 | 253 | /* padding to take it to 16 bytes (must be zero) */ 254 | multiboot_uint32_t pad; 255 | }; 256 | typedef struct multiboot_mod_list multiboot_module_t; 257 | 258 | /* APM BIOS info. */ 259 | struct multiboot_apm_info 260 | { 261 | multiboot_uint16_t version; 262 | multiboot_uint16_t cseg; 263 | multiboot_uint32_t offset; 264 | multiboot_uint16_t cseg_16; 265 | multiboot_uint16_t dseg; 266 | multiboot_uint16_t flags; 267 | multiboot_uint16_t cseg_len; 268 | multiboot_uint16_t cseg_16_len; 269 | multiboot_uint16_t dseg_len; 270 | }; 271 | 272 | #endif /* ! ASM_FILE */ 273 | 274 | #endif /* ! MULTIBOOT_HEADER */ -------------------------------------------------------------------------------- /src/qemu.h: -------------------------------------------------------------------------------- 1 | #ifndef _QEMU_H 2 | #define _QEMU_H 3 | 4 | #define QEMU_SERIAL_PORT 0x3f8 5 | 6 | uint32 qemu_init_debug(); 7 | void qemu_printf_string(char *msg); 8 | void qemu_printc(char); 9 | 10 | #endif -------------------------------------------------------------------------------- /src/quantum_funcs.c: -------------------------------------------------------------------------------- 1 | //CODE FOR ALL OS QUANTUM COMPUTER-LIKE FUNCTIONALITY 2 | 3 | //HEADER FILES 4 | #include "kernel.h" 5 | #include "console.h" 6 | #include "string.h" 7 | #include "gdt.h" 8 | #include "idt.h" 9 | #include "keyboard.h" 10 | #include "io_ports.h" 11 | #include "framebuffer.h" 12 | #include "multiboot.h" 13 | #include "stdint-gcc.h" 14 | #include "ctypes.h" 15 | #include "qemu.h" 16 | #include "romfont.h" 17 | //END HEADER FILES 18 | 19 | //MAIN CODE 20 | 21 | void new_kernel_instance(){ 22 | 23 | } 24 | -------------------------------------------------------------------------------- /src/romfont.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MrGilli/Quantix-OS/c228b3a2e03fa2c12f383b902be0df91b3182fdb/src/romfont.h -------------------------------------------------------------------------------- /src/stdint-gcc.h: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2008-2020 Free Software Foundation, Inc. 2 | 3 | This file is part of GCC. 4 | 5 | GCC is free software; you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation; either version 3, or (at your option) 8 | any later version. 9 | 10 | GCC is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | Under Section 7 of GPL version 3, you are granted additional 16 | permissions described in the GCC Runtime Library Exception, version 17 | 3.1, as published by the Free Software Foundation. 18 | 19 | You should have received a copy of the GNU General Public License and 20 | a copy of the GCC Runtime Library Exception along with this program; 21 | see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 22 | . */ 23 | 24 | /* 25 | * ISO C Standard: 7.18 Integer types 26 | */ 27 | 28 | #ifndef _GCC_STDINT_H 29 | #define _GCC_STDINT_H 30 | 31 | /* 7.8.1.1 Exact-width integer types */ 32 | 33 | #ifdef __INT8_TYPE__ 34 | typedef __INT8_TYPE__ int8_t; 35 | #endif 36 | #ifdef __INT16_TYPE__ 37 | typedef __INT16_TYPE__ int16_t; 38 | #endif 39 | #ifdef __INT32_TYPE__ 40 | typedef __INT32_TYPE__ int32_t; 41 | #endif 42 | #ifdef __INT64_TYPE__ 43 | typedef __INT64_TYPE__ int64_t; 44 | #endif 45 | #ifdef __UINT8_TYPE__ 46 | typedef __UINT8_TYPE__ uint8_t; 47 | #endif 48 | #ifdef __UINT16_TYPE__ 49 | typedef __UINT16_TYPE__ uint16_t; 50 | #endif 51 | #ifdef __UINT32_TYPE__ 52 | typedef __UINT32_TYPE__ uint32_t; 53 | #endif 54 | #ifdef __UINT64_TYPE__ 55 | typedef __UINT64_TYPE__ uint64_t; 56 | #endif 57 | 58 | /* 7.8.1.2 Minimum-width integer types */ 59 | 60 | typedef __INT_LEAST8_TYPE__ int_least8_t; 61 | typedef __INT_LEAST16_TYPE__ int_least16_t; 62 | typedef __INT_LEAST32_TYPE__ int_least32_t; 63 | typedef __INT_LEAST64_TYPE__ int_least64_t; 64 | typedef __UINT_LEAST8_TYPE__ uint_least8_t; 65 | typedef __UINT_LEAST16_TYPE__ uint_least16_t; 66 | typedef __UINT_LEAST32_TYPE__ uint_least32_t; 67 | typedef __UINT_LEAST64_TYPE__ uint_least64_t; 68 | 69 | /* 7.8.1.3 Fastest minimum-width integer types */ 70 | 71 | typedef __INT_FAST8_TYPE__ int_fast8_t; 72 | typedef __INT_FAST16_TYPE__ int_fast16_t; 73 | typedef __INT_FAST32_TYPE__ int_fast32_t; 74 | typedef __INT_FAST64_TYPE__ int_fast64_t; 75 | typedef __UINT_FAST8_TYPE__ uint_fast8_t; 76 | typedef __UINT_FAST16_TYPE__ uint_fast16_t; 77 | typedef __UINT_FAST32_TYPE__ uint_fast32_t; 78 | typedef __UINT_FAST64_TYPE__ uint_fast64_t; 79 | 80 | /* 7.8.1.4 Integer types capable of holding object pointers */ 81 | 82 | #ifdef __INTPTR_TYPE__ 83 | typedef __INTPTR_TYPE__ intptr_t; 84 | #endif 85 | #ifdef __UINTPTR_TYPE__ 86 | typedef __UINTPTR_TYPE__ uintptr_t; 87 | #endif 88 | 89 | /* 7.8.1.5 Greatest-width integer types */ 90 | 91 | typedef __INTMAX_TYPE__ intmax_t; 92 | typedef __UINTMAX_TYPE__ uintmax_t; 93 | 94 | #if (!defined __cplusplus || __cplusplus >= 201103L \ 95 | || defined __STDC_LIMIT_MACROS) 96 | 97 | /* 7.18.2 Limits of specified-width integer types */ 98 | 99 | #ifdef __INT8_MAX__ 100 | # undef INT8_MAX 101 | # define INT8_MAX __INT8_MAX__ 102 | # undef INT8_MIN 103 | # define INT8_MIN (-INT8_MAX - 1) 104 | #endif 105 | #ifdef __UINT8_MAX__ 106 | # undef UINT8_MAX 107 | # define UINT8_MAX __UINT8_MAX__ 108 | #endif 109 | #ifdef __INT16_MAX__ 110 | # undef INT16_MAX 111 | # define INT16_MAX __INT16_MAX__ 112 | # undef INT16_MIN 113 | # define INT16_MIN (-INT16_MAX - 1) 114 | #endif 115 | #ifdef __UINT16_MAX__ 116 | # undef UINT16_MAX 117 | # define UINT16_MAX __UINT16_MAX__ 118 | #endif 119 | #ifdef __INT32_MAX__ 120 | # undef INT32_MAX 121 | # define INT32_MAX __INT32_MAX__ 122 | # undef INT32_MIN 123 | # define INT32_MIN (-INT32_MAX - 1) 124 | #endif 125 | #ifdef __UINT32_MAX__ 126 | # undef UINT32_MAX 127 | # define UINT32_MAX __UINT32_MAX__ 128 | #endif 129 | #ifdef __INT64_MAX__ 130 | # undef INT64_MAX 131 | # define INT64_MAX __INT64_MAX__ 132 | # undef INT64_MIN 133 | # define INT64_MIN (-INT64_MAX - 1) 134 | #endif 135 | #ifdef __UINT64_MAX__ 136 | # undef UINT64_MAX 137 | # define UINT64_MAX __UINT64_MAX__ 138 | #endif 139 | 140 | #undef INT_LEAST8_MAX 141 | #define INT_LEAST8_MAX __INT_LEAST8_MAX__ 142 | #undef INT_LEAST8_MIN 143 | #define INT_LEAST8_MIN (-INT_LEAST8_MAX - 1) 144 | #undef UINT_LEAST8_MAX 145 | #define UINT_LEAST8_MAX __UINT_LEAST8_MAX__ 146 | #undef INT_LEAST16_MAX 147 | #define INT_LEAST16_MAX __INT_LEAST16_MAX__ 148 | #undef INT_LEAST16_MIN 149 | #define INT_LEAST16_MIN (-INT_LEAST16_MAX - 1) 150 | #undef UINT_LEAST16_MAX 151 | #define UINT_LEAST16_MAX __UINT_LEAST16_MAX__ 152 | #undef INT_LEAST32_MAX 153 | #define INT_LEAST32_MAX __INT_LEAST32_MAX__ 154 | #undef INT_LEAST32_MIN 155 | #define INT_LEAST32_MIN (-INT_LEAST32_MAX - 1) 156 | #undef UINT_LEAST32_MAX 157 | #define UINT_LEAST32_MAX __UINT_LEAST32_MAX__ 158 | #undef INT_LEAST64_MAX 159 | #define INT_LEAST64_MAX __INT_LEAST64_MAX__ 160 | #undef INT_LEAST64_MIN 161 | #define INT_LEAST64_MIN (-INT_LEAST64_MAX - 1) 162 | #undef UINT_LEAST64_MAX 163 | #define UINT_LEAST64_MAX __UINT_LEAST64_MAX__ 164 | 165 | #undef INT_FAST8_MAX 166 | #define INT_FAST8_MAX __INT_FAST8_MAX__ 167 | #undef INT_FAST8_MIN 168 | #define INT_FAST8_MIN (-INT_FAST8_MAX - 1) 169 | #undef UINT_FAST8_MAX 170 | #define UINT_FAST8_MAX __UINT_FAST8_MAX__ 171 | #undef INT_FAST16_MAX 172 | #define INT_FAST16_MAX __INT_FAST16_MAX__ 173 | #undef INT_FAST16_MIN 174 | #define INT_FAST16_MIN (-INT_FAST16_MAX - 1) 175 | #undef UINT_FAST16_MAX 176 | #define UINT_FAST16_MAX __UINT_FAST16_MAX__ 177 | #undef INT_FAST32_MAX 178 | #define INT_FAST32_MAX __INT_FAST32_MAX__ 179 | #undef INT_FAST32_MIN 180 | #define INT_FAST32_MIN (-INT_FAST32_MAX - 1) 181 | #undef UINT_FAST32_MAX 182 | #define UINT_FAST32_MAX __UINT_FAST32_MAX__ 183 | #undef INT_FAST64_MAX 184 | #define INT_FAST64_MAX __INT_FAST64_MAX__ 185 | #undef INT_FAST64_MIN 186 | #define INT_FAST64_MIN (-INT_FAST64_MAX - 1) 187 | #undef UINT_FAST64_MAX 188 | #define UINT_FAST64_MAX __UINT_FAST64_MAX__ 189 | 190 | #ifdef __INTPTR_MAX__ 191 | # undef INTPTR_MAX 192 | # define INTPTR_MAX __INTPTR_MAX__ 193 | # undef INTPTR_MIN 194 | # define INTPTR_MIN (-INTPTR_MAX - 1) 195 | #endif 196 | #ifdef __UINTPTR_MAX__ 197 | # undef UINTPTR_MAX 198 | # define UINTPTR_MAX __UINTPTR_MAX__ 199 | #endif 200 | 201 | #undef INTMAX_MAX 202 | #define INTMAX_MAX __INTMAX_MAX__ 203 | #undef INTMAX_MIN 204 | #define INTMAX_MIN (-INTMAX_MAX - 1) 205 | #undef UINTMAX_MAX 206 | #define UINTMAX_MAX __UINTMAX_MAX__ 207 | 208 | /* 7.18.3 Limits of other integer types */ 209 | 210 | #undef PTRDIFF_MAX 211 | #define PTRDIFF_MAX __PTRDIFF_MAX__ 212 | #undef PTRDIFF_MIN 213 | #define PTRDIFF_MIN (-PTRDIFF_MAX - 1) 214 | 215 | #undef SIG_ATOMIC_MAX 216 | #define SIG_ATOMIC_MAX __SIG_ATOMIC_MAX__ 217 | #undef SIG_ATOMIC_MIN 218 | #define SIG_ATOMIC_MIN __SIG_ATOMIC_MIN__ 219 | 220 | #undef SIZE_MAX 221 | #define SIZE_MAX __SIZE_MAX__ 222 | 223 | #undef WCHAR_MAX 224 | #define WCHAR_MAX __WCHAR_MAX__ 225 | #undef WCHAR_MIN 226 | #define WCHAR_MIN __WCHAR_MIN__ 227 | 228 | #undef WINT_MAX 229 | #define WINT_MAX __WINT_MAX__ 230 | #undef WINT_MIN 231 | #define WINT_MIN __WINT_MIN__ 232 | 233 | #endif /* (!defined __cplusplus || __cplusplus >= 201103L 234 | || defined __STDC_LIMIT_MACROS) */ 235 | 236 | #if (!defined __cplusplus || __cplusplus >= 201103L \ 237 | || defined __STDC_CONSTANT_MACROS) 238 | 239 | #undef INT8_C 240 | #define INT8_C(c) __INT8_C(c) 241 | #undef INT16_C 242 | #define INT16_C(c) __INT16_C(c) 243 | #undef INT32_C 244 | #define INT32_C(c) __INT32_C(c) 245 | #undef INT64_C 246 | #define INT64_C(c) __INT64_C(c) 247 | #undef UINT8_C 248 | #define UINT8_C(c) __UINT8_C(c) 249 | #undef UINT16_C 250 | #define UINT16_C(c) __UINT16_C(c) 251 | #undef UINT32_C 252 | #define UINT32_C(c) __UINT32_C(c) 253 | #undef UINT64_C 254 | #define UINT64_C(c) __UINT64_C(c) 255 | #undef INTMAX_C 256 | #define INTMAX_C(c) __INTMAX_C(c) 257 | #undef UINTMAX_C 258 | #define UINTMAX_C(c) __UINTMAX_C(c) 259 | 260 | #endif /* (!defined __cplusplus || __cplusplus >= 201103L 261 | || defined __STDC_CONSTANT_MACROS) */ 262 | 263 | #if (defined __STDC_WANT_IEC_60559_BFP_EXT__ \ 264 | || (defined (__STDC_VERSION__) && __STDC_VERSION__ > 201710L)) 265 | /* TS 18661-1 / C2X widths of integer types. */ 266 | 267 | #ifdef __INT8_TYPE__ 268 | # undef INT8_WIDTH 269 | # define INT8_WIDTH 8 270 | #endif 271 | #ifdef __UINT8_TYPE__ 272 | # undef UINT8_WIDTH 273 | # define UINT8_WIDTH 8 274 | #endif 275 | #ifdef __INT16_TYPE__ 276 | # undef INT16_WIDTH 277 | # define INT16_WIDTH 16 278 | #endif 279 | #ifdef __UINT16_TYPE__ 280 | # undef UINT16_WIDTH 281 | # define UINT16_WIDTH 16 282 | #endif 283 | #ifdef __INT32_TYPE__ 284 | # undef INT32_WIDTH 285 | # define INT32_WIDTH 32 286 | #endif 287 | #ifdef __UINT32_TYPE__ 288 | # undef UINT32_WIDTH 289 | # define UINT32_WIDTH 32 290 | #endif 291 | #ifdef __INT64_TYPE__ 292 | # undef INT64_WIDTH 293 | # define INT64_WIDTH 64 294 | #endif 295 | #ifdef __UINT64_TYPE__ 296 | # undef UINT64_WIDTH 297 | # define UINT64_WIDTH 64 298 | #endif 299 | 300 | #undef INT_LEAST8_WIDTH 301 | #define INT_LEAST8_WIDTH __INT_LEAST8_WIDTH__ 302 | #undef UINT_LEAST8_WIDTH 303 | #define UINT_LEAST8_WIDTH __INT_LEAST8_WIDTH__ 304 | #undef INT_LEAST16_WIDTH 305 | #define INT_LEAST16_WIDTH __INT_LEAST16_WIDTH__ 306 | #undef UINT_LEAST16_WIDTH 307 | #define UINT_LEAST16_WIDTH __INT_LEAST16_WIDTH__ 308 | #undef INT_LEAST32_WIDTH 309 | #define INT_LEAST32_WIDTH __INT_LEAST32_WIDTH__ 310 | #undef UINT_LEAST32_WIDTH 311 | #define UINT_LEAST32_WIDTH __INT_LEAST32_WIDTH__ 312 | #undef INT_LEAST64_WIDTH 313 | #define INT_LEAST64_WIDTH __INT_LEAST64_WIDTH__ 314 | #undef UINT_LEAST64_WIDTH 315 | #define UINT_LEAST64_WIDTH __INT_LEAST64_WIDTH__ 316 | 317 | #undef INT_FAST8_WIDTH 318 | #define INT_FAST8_WIDTH __INT_FAST8_WIDTH__ 319 | #undef UINT_FAST8_WIDTH 320 | #define UINT_FAST8_WIDTH __INT_FAST8_WIDTH__ 321 | #undef INT_FAST16_WIDTH 322 | #define INT_FAST16_WIDTH __INT_FAST16_WIDTH__ 323 | #undef UINT_FAST16_WIDTH 324 | #define UINT_FAST16_WIDTH __INT_FAST16_WIDTH__ 325 | #undef INT_FAST32_WIDTH 326 | #define INT_FAST32_WIDTH __INT_FAST32_WIDTH__ 327 | #undef UINT_FAST32_WIDTH 328 | #define UINT_FAST32_WIDTH __INT_FAST32_WIDTH__ 329 | #undef INT_FAST64_WIDTH 330 | #define INT_FAST64_WIDTH __INT_FAST64_WIDTH__ 331 | #undef UINT_FAST64_WIDTH 332 | #define UINT_FAST64_WIDTH __INT_FAST64_WIDTH__ 333 | 334 | #ifdef __INTPTR_TYPE__ 335 | # undef INTPTR_WIDTH 336 | # define INTPTR_WIDTH __INTPTR_WIDTH__ 337 | #endif 338 | #ifdef __UINTPTR_TYPE__ 339 | # undef UINTPTR_WIDTH 340 | # define UINTPTR_WIDTH __INTPTR_WIDTH__ 341 | #endif 342 | 343 | #undef INTMAX_WIDTH 344 | #define INTMAX_WIDTH __INTMAX_WIDTH__ 345 | #undef UINTMAX_WIDTH 346 | #define UINTMAX_WIDTH __INTMAX_WIDTH__ 347 | 348 | #undef PTRDIFF_WIDTH 349 | #define PTRDIFF_WIDTH __PTRDIFF_WIDTH__ 350 | 351 | #undef SIG_ATOMIC_WIDTH 352 | #define SIG_ATOMIC_WIDTH __SIG_ATOMIC_WIDTH__ 353 | 354 | #undef SIZE_WIDTH 355 | #define SIZE_WIDTH __SIZE_WIDTH__ 356 | 357 | #undef WCHAR_WIDTH 358 | #define WCHAR_WIDTH __WCHAR_WIDTH__ 359 | 360 | #undef WINT_WIDTH 361 | #define WINT_WIDTH __WINT_WIDTH__ 362 | 363 | #endif 364 | 365 | #endif /* _GCC_STDINT_H */ -------------------------------------------------------------------------------- /src/string.c: -------------------------------------------------------------------------------- 1 | #include "string.h" 2 | 3 | #include "types.h" 4 | 5 | void *memset(void *dst, char c, uint32 n) { 6 | char *temp = dst; 7 | for (; n != 0; n--) *temp++ = c; 8 | return dst; 9 | } 10 | 11 | void *memcpy(void *dst, const void *src, uint32 n) { 12 | char *ret = dst; 13 | char *p = dst; 14 | const char *q = src; 15 | while (n--) 16 | *p++ = *q++; 17 | return ret; 18 | } 19 | 20 | int memcmp(uint8 *s1, uint8 *s2, uint32 n) { 21 | while (n--) { 22 | if (*s1 != *s2) 23 | return 0; 24 | s1++; 25 | s2++; 26 | } 27 | return 1; 28 | } 29 | 30 | int strlen(const char *s) { 31 | int len = 0; 32 | while (*s++) 33 | len++; 34 | return len; 35 | } 36 | 37 | int strcmp(const char *s1, char *s2) { 38 | int i = 0; 39 | 40 | while ((s1[i] == s2[i])) { 41 | if (s2[i++] == 0) 42 | return 0; 43 | } 44 | return 1; 45 | } 46 | 47 | int strncmp(const char *s1, const char *s2, int c) { 48 | int result = 0; 49 | 50 | while (c) { 51 | result = *s1 - *s2++; 52 | if ((result != 0) || (*s1++ == 0)) { 53 | break; 54 | } 55 | c--; 56 | } 57 | return result; 58 | } 59 | 60 | int strcpy(char *dst, const char *src) { 61 | int i = 0; 62 | while ((*dst++ = *src++) != 0) 63 | i++; 64 | return i; 65 | } 66 | 67 | void strcat(char *dest, const char *src) { 68 | char *end = (char *)dest + strlen(dest); 69 | memcpy((void *)end, (void *)src, strlen(src)); 70 | end = end + strlen(src); 71 | *end = '\0'; 72 | } 73 | 74 | int isspace(char c) { 75 | return c == ' ' || c == '\t' || c == '\n' || c == '\v' || c == '\f' || c == '\r'; 76 | } 77 | 78 | int isalpha(char c) { 79 | return (((c >= 'A') && (c <= 'Z')) || ((c >= 'a') && (c <= 'z'))); 80 | } 81 | 82 | char upper(char c) { 83 | if ((c >= 'a') && (c <= 'z')) 84 | return (c - 32); 85 | return c; 86 | } 87 | 88 | char lower(char c) { 89 | if ((c >= 'A') && (c <= 'Z')) 90 | return (c + 32); 91 | return c; 92 | } 93 | 94 | void itoa(char *buf, int base, int d) { 95 | char *p = buf; 96 | char *p1, *p2; 97 | unsigned long ud = d; 98 | int divisor = 10; 99 | 100 | /* If %d is specified and D is minus, put ‘-’ in the head. */ 101 | if (base == 'd' && d < 0) { 102 | *p++ = '-'; 103 | buf++; 104 | ud = -d; 105 | } else if (base == 'x') 106 | divisor = 16; 107 | 108 | /* Divide UD by DIVISOR until UD == 0. */ 109 | do { 110 | int remainder = ud % divisor; 111 | *p++ = (remainder < 10) ? remainder + '0' : remainder + 'a' - 10; 112 | } while (ud /= divisor); 113 | 114 | /* Terminate BUF. */ 115 | *p = 0; 116 | 117 | /* Reverse BUF. */ 118 | p1 = buf; 119 | p2 = p - 1; 120 | while (p1 < p2) { 121 | char tmp = *p1; 122 | *p1 = *p2; 123 | *p2 = tmp; 124 | p1++; 125 | p2--; 126 | } 127 | } 128 | 129 | char *strstr(const char *in, const char *str) { 130 | char c; 131 | uint32 len; 132 | 133 | c = *str++; 134 | if (!c) 135 | return (char *)in; 136 | 137 | len = strlen(str); 138 | do { 139 | char sc; 140 | do { 141 | sc = *in++; 142 | if (!sc) 143 | return (char *)0; 144 | } while (sc != c); 145 | } while (strncmp(in, str, len) != 0); 146 | 147 | return (char *)(in - 1); 148 | } 149 | 150 | -------------------------------------------------------------------------------- /src/todo.txt: -------------------------------------------------------------------------------- 1 | TODO: 2 | - Seperate file for File System code. 3 | 4 | - Token user input so multiple words can be in a command. 5 | * Instead of mkfile to create a file the usr can type mkfile hello to create a unique file called hello.txt 6 | -------------------------------------------------------------------------------- /src/vga.c: -------------------------------------------------------------------------------- 1 | #include "vga.h" 2 | #include "io_ports.h" 3 | #include "types.h" 4 | 5 | /** 6 | * 16 bit video buffer elements(register ax) 7 | * 8 bits(ah) higher : 8 | * lower 4 bits - forec olor 9 | * higher 4 bits - back color 10 | 11 | * 8 bits(al) lower : 12 | * 8 bits : ASCII character to print 13 | * 14 | * returns complete item with fore & back color to be placed at VGA address 15 | */ 16 | uint16 vga_item_entry(uint8 ch, VGA_COLOR_TYPE fore_color, VGA_COLOR_TYPE back_color) { 17 | uint16 ax = 0; 18 | uint8 ah = 0, al = 0; 19 | 20 | ah = back_color; 21 | ah <<= 4; 22 | ah |= fore_color; 23 | ax = ah; 24 | ax <<= 8; 25 | al = ch; 26 | ax |= al; 27 | 28 | return ax; 29 | } 30 | 31 | /** 32 | * set cursor position to given (x, y) 33 | * by writing to CRT controller registers 34 | */ 35 | void vga_set_cursor_pos(uint8 x, uint8 y) { 36 | // The screen is 80 characters wide... 37 | uint16 cursorLocation = y * VGA_WIDTH + x; 38 | outportb(0x3D4, 14); 39 | outportb(0x3D5, cursorLocation >> 8); 40 | outportb(0x3D4, 15); 41 | outportb(0x3D5, cursorLocation); 42 | } 43 | 44 | /** 45 | * disable blinking top-left cursor 46 | * by writing to CRT controller registers 47 | */ 48 | void vga_disable_cursor() { 49 | outportb(0x3D4, 10); 50 | outportb(0x3D5, 32); 51 | } 52 | 53 | --------------------------------------------------------------------------------