diff --git a/bin/shade.bin b/bin/shade.bin new file mode 100755 index 0000000..fe77f8c Binary files /dev/null and b/bin/shade.bin differ diff --git a/bin/shade.iso b/bin/shade.iso new file mode 100644 index 0000000..43a4f47 Binary files /dev/null and b/bin/shade.iso differ diff --git a/old/Makefile b/old/Makefile new file mode 100644 index 0000000..825ff4d --- /dev/null +++ b/old/Makefile @@ -0,0 +1,56 @@ +# $@ = target file +# $< = first dependency +# $^ = all dependencies + +GDB = gdb + +C_FILES = $(shell find src/ -type f -name '*.c') +CO_FILES = $(patsubst src/%.c, obj/%.o, $(C_FILES)) +ASM_FILES = $(shell find src/kernel/ -type f -name '*.asm') +AO_FILES = $(patsubst src/kernel/%.asm, obj/kernel/%.o, $(ASM_FILES)) +ABIN_FILES = $(patsubst src/%.asm, bin/%.bin, $(ASM_FILES)) + +os-image.bin: bin/boot.bin bin/kernel.bin + cat $^ > $@ + +bin/boot.bin: src/boot/boot.asm bin/kernel.bin .FORCE + sed -i.orig "s@CH_REPLACE_BOOTSECTORCOUNT@$(shell ./getinblocks.py $(shell du -b "bin/kernel.bin" | cut -f 1))@g" src/boot/kernel.asm + nasm -Isrc/boot/ $< -f bin -o $@ + mv src/boot/kernel.asm.orig src/boot/kernel.asm + +.FORCE: + +bin/kernel.bin: obj/kernel/entry.o ${CO_FILES} ${AO_FILES} + i386-elf-ld -o $@ -Ttext 0x1000 $^ --oformat binary + +kernel.elf: obj/kernel/entry.o ${CO_FILES} ${AO_FILES} + i386-elf-ld -o $@ -Ttext 0x1000 $^ + +run: clean os-image.bin + qemu-system-x86_64 -hdd os-image.bin -d int + +debug: clean os-image.bin kernel.elf + qemu-system-x86_64 -s -S -hdd os-image.bin & + ${GDB} os-image.bin -ex "symbol-file kernel.elf" -ex "target remote localhost:1234" + + + +obj/%.o: src/%.c + mkdir -p "$(@D)" + i386-elf-gcc -g -ffreestanding -c $< -o $@ + +obj/%.o: src/%.asm + mkdir -p "$(@D)" + nasm -f elf $< -o $@ + +bin/%.bin: src/%.asm + mkdir -p "$(@D)" + nasm -f bin $< -o $@ + +clean: + find obj -type f -name '*.o' -exec rm {} + + find obj -type f -name '*.bin' -exec rm {} + + find bin -type f -name '*.o' -exec rm {} + + find bin -type f -name '*.bin' -exec rm {} + + find . -type f -name '*.dis' -exec rm {} + + rm -f kernel.elf \ No newline at end of file diff --git a/old/bin/boot.bin b/old/bin/boot.bin new file mode 100644 index 0000000..1a008f3 Binary files /dev/null and b/old/bin/boot.bin differ diff --git a/old/bin/kernel.bin b/old/bin/kernel.bin new file mode 100755 index 0000000..959dbee Binary files /dev/null and b/old/bin/kernel.bin differ diff --git a/old/getinblocks.py b/old/getinblocks.py new file mode 100755 index 0000000..d269dec --- /dev/null +++ b/old/getinblocks.py @@ -0,0 +1,4 @@ +#!/usr/bin/python3 +import sys, math +intg = int(sys.argv[1]) +print(int(math.ceil(intg/512)), end='') diff --git a/old/obj/kernel/entry.o b/old/obj/kernel/entry.o new file mode 100644 index 0000000..fa6bc54 Binary files /dev/null and b/old/obj/kernel/entry.o differ diff --git a/old/obj/kernel/kernel.o b/old/obj/kernel/kernel.o new file mode 100644 index 0000000..8ed7c05 Binary files /dev/null and b/old/obj/kernel/kernel.o differ diff --git a/old/obj/kernel/platform/drivers/ports.o b/old/obj/kernel/platform/drivers/ports.o new file mode 100644 index 0000000..1b53202 Binary files /dev/null and b/old/obj/kernel/platform/drivers/ports.o differ diff --git a/old/obj/kernel/platform/interrupts/int.o b/old/obj/kernel/platform/interrupts/int.o new file mode 100644 index 0000000..dab89eb Binary files /dev/null and b/old/obj/kernel/platform/interrupts/int.o differ diff --git a/old/obj/kernel/platform/interrupts/int_lowlevel.o b/old/obj/kernel/platform/interrupts/int_lowlevel.o new file mode 100644 index 0000000..c3f6326 Binary files /dev/null and b/old/obj/kernel/platform/interrupts/int_lowlevel.o differ diff --git a/old/obj/kernel/print.o b/old/obj/kernel/print.o new file mode 100644 index 0000000..6a393f3 Binary files /dev/null and b/old/obj/kernel/print.o differ diff --git a/old/obj/kernel/strings.o b/old/obj/kernel/strings.o new file mode 100644 index 0000000..107b607 Binary files /dev/null and b/old/obj/kernel/strings.o differ diff --git a/old/obj/kernel/util.o b/old/obj/kernel/util.o new file mode 100644 index 0000000..5e77ddb Binary files /dev/null and b/old/obj/kernel/util.o differ diff --git a/old/os-image.bin b/old/os-image.bin new file mode 100644 index 0000000..4683e53 Binary files /dev/null and b/old/os-image.bin differ diff --git a/old/src/boot/boot.asm b/old/src/boot/boot.asm new file mode 100644 index 0000000..4a4d793 --- /dev/null +++ b/old/src/boot/boot.asm @@ -0,0 +1,39 @@ +[org 0x7c00] + KERNEL_OFFSET equ 0x1000 ; Same one used while linking! + + mov [BOOT_DRIVE], dl ; BIOS sets boot drive to 'dl' for us + mov bp, 0x9000 + mov sp, bp + + mov bx, MSG_REAL_MODE + call print + call print_nl + + call load_kernel + call enable_protected + + jmp $ ; never executed + +%include "output/print.asm" +%include "output/print_hex.asm" +%include "disk/disk.asm" +%include "protected/gdt.asm" +%include "output/vga-print.asm" +%include "protected/protected-switch.asm" +%include "kernel.asm" + +[bits 32] +BEGIN_PROTECTED: + mov ebx, MSG_PROT_MODE + call print_string_pm + + call KERNEL_OFFSET ; give control to kernel + jmp $ ; infinite loop if kernel returns control to us + +BOOT_DRIVE db 0 +MSG_REAL_MODE db "llb: started, preparing protected mode initialization", 0 +MSG_PROT_MODE db "llb: loaded protected mode successfully, jumping to llb2", 0 +MSG_LOAD_KERNEL db "llb: loading kernel into memory at 0x1000", 0 + +times 510 - ($-$$) db 0 +dw 0xaa55 \ No newline at end of file diff --git a/old/src/boot/disk/disk.asm b/old/src/boot/disk/disk.asm new file mode 100644 index 0000000..4102835 --- /dev/null +++ b/old/src/boot/disk/disk.asm @@ -0,0 +1,40 @@ +; load 'dh' sectors from drive 'dl' into ES:BX +disk_load: + pusha + push dx ; save dx to stack for later use, as it needs to be overwritten + + mov ah, 0x02 ; ah: int 0x13 function. 0x02 = 'read' + mov al, dh ; al: number of sectors to read (0x01 .. 0x80) + mov cl, 0x02 ; cl: sector (0x01 .. 0x11). 0x01 is boot sector, 0x02 is first 'avaliable' sector + mov ch, 0x00 ; ch: cylinder (0x0 .. 0x3FF, upper 2 bits in 'cl') + ; dl: drive number. caller sets it as param and gets it from bios + ; 0 = floppy, 1 = floppy2, 0x80 = hdd, 0x81 = hdd2 + mov dh, 0x00 ; dh: head number (0x0 .. 0xF) + + ; [es:bx] pointer to buf where data is stored + ; caller sets it up, and is standard location for int 13h + int 13h + jc disk_error ; if error (in carry) + + pop dx + cmp al, dh ; al is # of sectors read. compare it + jne sectors_error + popa + ret + +disk_error: + mov bx, DISK_ERROR + call print + call print_nl + mov dh, ah ; ah = error code, dl = disk drive that caused error + call print_hex + +sectors_error: + mov bx, SECTORS_ERROR + call print + +disk_loop: + jmp $ + +DISK_ERROR: db "Disk read error", 0 +SECTORS_ERROR: db "Incorrect number of sectors read", 0 \ No newline at end of file diff --git a/old/src/boot/kernel.asm b/old/src/boot/kernel.asm new file mode 100644 index 0000000..47749af --- /dev/null +++ b/old/src/boot/kernel.asm @@ -0,0 +1,11 @@ +[bits 16] +load_kernel: + mov bx, MSG_LOAD_KERNEL + call print + call print_nl + + mov bx, KERNEL_OFFSET ; Read from disk and store at 0x1000 + mov dh, CH_REPLACE_BOOTSECTORCOUNT ; Populated with kernel sector count at build (see makefile) + mov dl, [BOOT_DRIVE] + call disk_load + ret \ No newline at end of file diff --git a/old/src/boot/output/print.asm b/old/src/boot/output/print.asm new file mode 100644 index 0000000..5fd8309 --- /dev/null +++ b/old/src/boot/output/print.asm @@ -0,0 +1,33 @@ +print: + pusha + +; logic being implemented here: +; while ( string[i] != 0 ) { print string[i]; i++ } + +start: + mov al, [bx] + cmp al, 0 ; check if al (byte we are printing) is a 0 (null byte) + je done ; if so, jump to done + + ; print with BIOS help + mov ah, 0x0e + int 0x10 ; char already in al + + add bx, 1 ; increment pointer + jmp start ; repeat + +done: + popa + ret + +print_nl: + pusha + + mov ah, 0x0e + mov al, 0x0a ; newline char + int 0x10 + mov al, 0x0d ; carriage return + int 0x10 + + popa + ret \ No newline at end of file diff --git a/old/src/boot/output/print_hex.asm b/old/src/boot/output/print_hex.asm new file mode 100644 index 0000000..e6df82b --- /dev/null +++ b/old/src/boot/output/print_hex.asm @@ -0,0 +1,38 @@ +; data in dx +print_hex: + pusha + + mov cx, 0 ; index var + +hex_loop: + cmp cx, 4 ; loop 4 times + je end + + ; 1) convert last char of 'dx' to ascii + mov ax, dx ; ax is working register + and ax, 0x000f ; 0x1234 -> 0x0004 + add al, 0x30 ; add 0x30 to N to convert it to ascii "n" + cmp al, 0x39 ; if > 9, add extra 8 to represent a-f + jle step2 + add al, 7 ; A is ascii 64 instead of 58, 65-58 = 7 + +step2: + ; 2) get correct pos of string to place char + ; bx <- base address + string length - index + mov bx, HEX_OUT + 5 + sub bx, cx ; cx: index + mov [bx], al ; copy ascii char on al to pos pointed by bx + ror dx, 4 ; 1234 - 4123 - 3412 - 2341 - 1234 + + add cx, 1 + jmp hex_loop + +end: + mov bx, HEX_OUT + call print + + popa + ret + +HEX_OUT: + db '0x0000', 0 ; reserve memory for string \ No newline at end of file diff --git a/old/src/boot/output/vga-print.asm b/old/src/boot/output/vga-print.asm new file mode 100644 index 0000000..a9055e3 --- /dev/null +++ b/old/src/boot/output/vga-print.asm @@ -0,0 +1,26 @@ +[bits 32] + +; defining constants +VIDEO_MEMORY equ 0xb8000 +WHITE_ON_BLACK equ 0x0f ; color byte + +print_string_pm: + pusha + mov edx, VIDEO_MEMORY + +print_string_pm_loop: + mov al, [ebx] ; [ebx] is address of char + mov ah, WHITE_ON_BLACK + + cmp al, 0 ; is end of string? + je print_string_pm_done + + mov [edx], ax ; store char + attribute in video memory + add ebx, 1 ; next char + add edx, 2 ; next video memory position + + jmp print_string_pm_loop + +print_string_pm_done: + popa + ret \ No newline at end of file diff --git a/old/src/boot/protected/gdt.asm b/old/src/boot/protected/gdt.asm new file mode 100644 index 0000000..df7bfe2 --- /dev/null +++ b/old/src/boot/protected/gdt.asm @@ -0,0 +1,32 @@ + +gdt_start: ; use labels to compute sizes and jumps + ; gdt starts with 8 byte null + dd 0x0 + dd 0x0 + +; GDT for code segment, base = 0x00000000, length = 0xfffff +gdt_code: + dw 0xffff ; segment length + dw 0x0 ; segment base + db 0x0 ; segment base + db 10011010b ; flags + db 11001111b ; flags + segment length + db 0x0 ; segment base + +; GDT for data segment +gdt_data: + dw 0xffff ; segment length + dw 0x0 ; segment base + db 0x0 ; segment base + db 10010010b ; flags + db 11001111b ; flags + segment length + db 0x0 ; segment base + +gdt_end: + +gdt_descriptor: + dw gdt_end - gdt_start - 1 ; size, always 1 less than what it actually is + dd gdt_start ; address + +CODE_SEG equ gdt_code - gdt_start +DATA_SEG equ gdt_data - gdt_start \ No newline at end of file diff --git a/old/src/boot/protected/protected-switch.asm b/old/src/boot/protected/protected-switch.asm new file mode 100644 index 0000000..53708d7 --- /dev/null +++ b/old/src/boot/protected/protected-switch.asm @@ -0,0 +1,24 @@ +[bits 16] +enable_protected: + cli ; Disable interrupts + lgdt [gdt_descriptor] ; load the GDT + mov eax, cr0 + or eax, 0x1 ; set 32-bit mode bit + mov cr0, eax + jmp CODE_SEG:init_protected ; far jump into a different segment + +[bits 32] +init_protected: ; now in 32bit + mov ax, DATA_SEG ; update segment registers + mov ds, ax + mov ss, ax + mov es, ax + mov fs, ax + mov gs, ax + + ; wipe registers clean + + mov ebp, 0x90000 ; update stack to top of free space + mov esp, ebp + + call BEGIN_PROTECTED ; call known label with useful code \ No newline at end of file diff --git a/old/src/kernel/entry.asm b/old/src/kernel/entry.asm new file mode 100644 index 0000000..a8d38ec --- /dev/null +++ b/old/src/kernel/entry.asm @@ -0,0 +1,4 @@ +[bits 32] +[extern main] ; define callpoint, must have same name as kernel.c entrypoint +call main ; jump to fun, linker will figure out where it is +jmp $ \ No newline at end of file diff --git a/old/src/kernel/kernel.c b/old/src/kernel/kernel.c new file mode 100644 index 0000000..a3f295a --- /dev/null +++ b/old/src/kernel/kernel.c @@ -0,0 +1,54 @@ +#include "./platform/drivers/ports.h" +#include "print.h" +#include "./platform/types.h" +#include "./platform/interrupts/int.h" + +void dummy_test_entrypoint() {} + +void kernel_welcome() { + print_str("Welcome to "); + print_set_color(PRINT_COLOR_CYAN, PRINT_COLOR_BLACK); + print_str("Shade"); + print_set_color(PRINT_COLOR_WHITE, PRINT_COLOR_BLACK); + print_str("!\n"); + + print_str("shadeOS kernel version "); + + print_set_color(PRINT_COLOR_YELLOW, PRINT_COLOR_BLACK); + print_str("0.2.2"); + + print_set_color(PRINT_COLOR_WHITE, PRINT_COLOR_BLACK); + print_newline(); + + print_str("Running on "); + + print_set_color(PRINT_COLOR_YELLOW, PRINT_COLOR_BLACK); + print_str("shade-development"); + + print_set_color(PRINT_COLOR_WHITE, PRINT_COLOR_BLACK); + + print_newline(); +} + +// kMain +void main() { + // Initialize screen buffer + struct Char* buffer = (struct Char*) 0xb8000; + + clear_all(); // Clear screen + set_cursor_pos(0, 0); // Set cursor position + print_set_color(PRINT_COLOR_WHITE, PRINT_COLOR_BLACK); // Set print color + + // welcome messages + kernel_msg_ok("Initialized display successfully\n"); + kernel_welcome(); + + print_str("Copyright (c) e3team 2022. All rights reserved.\n"); + print_str("This program is provided \"as-is\" and no express or implied warranty is provided.\n"); + print_str("The full license can be found at /sys/LICENCE on this system or ./LICENCE in the source tree.\n"); + + idt_init(); + kernel_msg_ok("Interrupts initialized"); + + __asm__ __volatile__("int $2"); +} \ No newline at end of file diff --git a/old/src/kernel/platform/drivers/ports.c b/old/src/kernel/platform/drivers/ports.c new file mode 100644 index 0000000..34a48db --- /dev/null +++ b/old/src/kernel/platform/drivers/ports.c @@ -0,0 +1,26 @@ +/* + * Read 1 byte from specified port + */ +unsigned char port_byte_in(unsigned short port) { + unsigned char result; + // source and dest are backwards. + // "=a (result)" set the C variable to the value of register e'a'x + // '"d" (port) map the C variable port into e'd'x register + __asm__("in %%dx, %%al" : "=a" (result) : "d" (port)); +} + +void port_byte_out(unsigned short port, unsigned char data) { + // both regs are C vars, nothing is returned, so no '=' in asm syntax + // comma because two vars in input area and none in return area + __asm__("out %%al, %%dx" : : "a" (data), "d" (port)); +} + +unsigned short port_word_in(unsigned short port) { + unsigned short result; + __asm__("in %%dx, %%ax" : "=a" (result) : "d" (port)); + return result; +} + +void port_word_out(unsigned short port, unsigned short data) { + __asm__("out %%ax, %%dx" : : "a" (data), "d" (port)); +} \ No newline at end of file diff --git a/old/src/kernel/platform/drivers/ports.h b/old/src/kernel/platform/drivers/ports.h new file mode 100644 index 0000000..d616f0e --- /dev/null +++ b/old/src/kernel/platform/drivers/ports.h @@ -0,0 +1,4 @@ +unsigned char port_byte_in(unsigned short port); +void port_byte_out(unsigned short port, unsigned char data); +unsigned short port_word_in(unsigned short port); +void port_word_out(unsigned short port, unsigned short data); \ No newline at end of file diff --git a/old/src/kernel/platform/gdt.h b/old/src/kernel/platform/gdt.h new file mode 100644 index 0000000..5545747 --- /dev/null +++ b/old/src/kernel/platform/gdt.h @@ -0,0 +1,28 @@ +#ifndef GDT_H +#define GDT_H + +#include + +// the GDT descriptor format makes literally no sense, who came up with this +typedef struct { + uint16_t limit_low16; // Low 16 bits of limit + uint16_t base_low16; // Low 16 bits of base + uint8_t base_mid8; // Middle 8 bits of base + uint8_t access; // 7: present, 6-5: priv level, 4: type, 3: executable, 2: dc, 1: rw, 0: accessed (zero) + uint8_t limit_flags; // High 4 bits of limit AND flags (?? why). flags: 3: granularity, 2: size, 1: long, 0: reserved + uint8_t base_high8; // High 8 bits of base +} __attribute__((packed)) gdt_entry_t; + +typedef struct { + uint16_t size; // GDT size (bytes) - 1 + uint32_t offset; // Address of element 0 of the GDT +} __attribute__((packed)) gdt_ptr_t; + +static gdt_entry_t gdt[8192]; +static gdt_ptr_t gdtr; + +void init_gdt(); +void gdt_set_segment(int limit, int base, int access); +void load_gdt(); + +#endif \ No newline at end of file diff --git a/old/src/kernel/platform/interrupts/int.c b/old/src/kernel/platform/interrupts/int.c new file mode 100644 index 0000000..4b77162 --- /dev/null +++ b/old/src/kernel/platform/interrupts/int.c @@ -0,0 +1,35 @@ +#include "int.h" +#include "../../print.h" + +int count = 0; + +void exception_handler(registers_t r) { + print_str("I"); + count++; + if (count > 4) { + __asm__ __volatile__("cli; hlt"); + } +} + +void idt_set_descriptor(u8 vector, void* isr, u8 flags) { + idt_entry_t* descriptor = &idt[vector]; + + descriptor->isr_low = (u32)isr & 0xFFFF; + descriptor->kernel_cs = 0x08; // this value can be whatever offset your kernel code selector is in your GDT + descriptor->attributes = flags; + descriptor->isr_high = (u32)isr >> 16; + descriptor->reserved = 0; +} + +void idt_init() { + idtr.base = (u32)&idt[0]; + idtr.limit = (u16)sizeof(idt_entry_t) * 256 - 1; + + for (u8 vector = 0; vector < 32; vector++) { + idt_set_descriptor(vector, isr_stub_table[vector], 0x8E); + isr_stub_table[vector] = TRUE; + } + + __asm__ volatile ("lidt %0" : : "m"(idtr)); // load the new IDT + __asm__ volatile ("sti"); // set the interrupt flag +} \ No newline at end of file diff --git a/old/src/kernel/platform/interrupts/int.h b/old/src/kernel/platform/interrupts/int.h new file mode 100644 index 0000000..3f36fc9 --- /dev/null +++ b/old/src/kernel/platform/interrupts/int.h @@ -0,0 +1,40 @@ +#ifndef INT_H +#define INT_H + +#include "../types.h" + +typedef struct { + u16 isr_low; // The lower 16 bits of the ISR's address + u16 kernel_cs; // The GDT segment selector that the CPU will load into CS before calling the ISR + u8 reserved; // Set to zero + u8 attributes; // Type and attributes; see the IDT page + u16 isr_high; // The higher 16 bits of the ISR's address +} __attribute__((packed)) idt_entry_t; + +__attribute__((aligned(0x10))) +static idt_entry_t idt[256]; // Create an array of IDT entries; aligned for performance + +typedef struct { + u16 limit; + u32 base; +} __attribute__((packed)) idtr_t; + +static idtr_t idtr; + +typedef struct { + u32 ds; /* Data segment selector */ + u32 edi, esi, ebp, esp, ebx, edx, ecx, eax; /* Pushed by pusha. */ + u32 int_no, err_code; /* Interrupt number and error code (if applicable) */ + u32 eip, cs, eflags, useresp, ss; /* Pushed by the processor automatically */ +} registers_t; + +__attribute__((noreturn)) +void exception_handler(registers_t r); + +void idt_set_descriptor(u8 vector, void* isr, u8 flags); + +extern void* isr_stub_table[]; + +void idt_init(void); + +#endif \ No newline at end of file diff --git a/old/src/kernel/platform/interrupts/int_lowlevel.asm b/old/src/kernel/platform/interrupts/int_lowlevel.asm new file mode 100644 index 0000000..0d2f397 --- /dev/null +++ b/old/src/kernel/platform/interrupts/int_lowlevel.asm @@ -0,0 +1,102 @@ +%macro isr_err_stub 1 +isr_stub_%+%1: + push byte %1 ; Push interrupt no to stack + + ; 1. Save CPU state + pusha ; Pushes edi,esi,ebp,esp,ebx,edx,ecx,eax + mov ax, ds ; Lower 16-bits of eax = ds. + push eax ; save the data segment descriptor + mov ax, 0x10 ; kernel data segment descriptor + mov ds, ax + mov es, ax + mov fs, ax + mov gs, ax + + ; 2. Call C handler + call exception_handler + + ; 3. Restore state + pop eax + mov ds, ax + mov es, ax + mov fs, ax + mov gs, ax + popa + add esp, 8 ; Cleans up the pushed error code and pushed ISR number + sti + iret ; pops 5 things at once: CS, EIP, EFLAGS, SS, and ESP +%endmacro +; if writing for 64-bit, use iretq instead +%macro isr_no_err_stub 1 +isr_stub_%+%1: + push byte 0 ; No error occured + push byte %1 ; Push interrupt no to stack + + ; 1. Save CPU state + pusha ; Pushes edi,esi,ebp,esp,ebx,edx,ecx,eax + mov ax, ds ; Lower 16-bits of eax = ds. + push eax ; save the data segment descriptor + mov ax, 0x10 ; kernel data segment descriptor + mov ds, ax + mov es, ax + mov fs, ax + mov gs, ax + + ; 2. Call C handler + call exception_handler + + ; 3. Restore state + pop eax + mov ds, ax + mov es, ax + mov fs, ax + mov gs, ax + popa + add esp, 8 ; Cleans up the pushed error code and pushed ISR number + sti + iret ; pops 5 things at once: CS, EIP, EFLAGS, SS, and ESP +%endmacro + +extern exception_handler + +isr_no_err_stub 0 +isr_no_err_stub 1 +isr_no_err_stub 2 +isr_no_err_stub 3 +isr_no_err_stub 4 +isr_no_err_stub 5 +isr_no_err_stub 6 +isr_no_err_stub 7 +isr_err_stub 8 +isr_no_err_stub 9 +isr_err_stub 10 +isr_err_stub 11 +isr_err_stub 12 +isr_err_stub 13 +isr_err_stub 14 +isr_no_err_stub 15 +isr_no_err_stub 16 +isr_err_stub 17 +isr_no_err_stub 18 +isr_no_err_stub 19 +isr_no_err_stub 20 +isr_no_err_stub 21 +isr_no_err_stub 22 +isr_no_err_stub 23 +isr_no_err_stub 24 +isr_no_err_stub 25 +isr_no_err_stub 26 +isr_no_err_stub 27 +isr_no_err_stub 28 +isr_no_err_stub 29 +isr_err_stub 30 +isr_no_err_stub 31 + +global isr_stub_table +isr_stub_table: +%assign i 0 +%rep 32 + dd isr_stub_%+i ; use DQ instead if targeting 64-bit +%assign i i+1 +%endrep + diff --git a/old/src/kernel/platform/types.h b/old/src/kernel/platform/types.h new file mode 100644 index 0000000..e18f414 --- /dev/null +++ b/old/src/kernel/platform/types.h @@ -0,0 +1,18 @@ +#ifndef TYPES_H +#define TYPES_H + +typedef unsigned int u32; +typedef int i32; +typedef unsigned short u16; +typedef short i16; +typedef unsigned char u8; +typedef char i8; + +#define high16(i32) (i32 & 0xffff) +#define low16(i32) ((i32>>16) & 0xffff) + +#define TRUE 1 +#define FALSE 0 +#define NULL 0 + +#endif \ No newline at end of file diff --git a/old/src/kernel/print.c b/old/src/kernel/print.c new file mode 100644 index 0000000..014de03 --- /dev/null +++ b/old/src/kernel/print.c @@ -0,0 +1,110 @@ +#include "print.h" +#include "./platform/drivers/ports.h" + +int row = 0; +int col = 0; +char color = PRINT_COLOR_WHITE | PRINT_COLOR_BLACK << 4; + +void clear_row(int row) { + struct Char* buffer = (struct Char*) 0xb8000; + + struct Char empty = (struct Char) { + character: ' ', + color: color, + }; + + for (int x = 0; x < NUM_COLS; x++) { + buffer[x + NUM_COLS * row] = empty; + } + set_cursor_pos(col, row); +} + +void clear_all() { + for (int i = 0; i < NUM_ROWS; i++) { + clear_row(i); + } + set_cursor_pos(col, row); +} + +void print_newline() { + struct Char* buffer = (struct Char*) 0xb8000; + + col = 0; + + if (row < NUM_ROWS - 1) { + row++; + return; + } + + for (int row = 1; row < NUM_ROWS; row++) { + for (int col = 0; col < NUM_COLS; col++) { + struct Char character = buffer[col + NUM_COLS * row]; + buffer[col + NUM_COLS * (row - 1)] = character; + } + } + + clear_row(NUM_COLS - 1); + set_cursor_pos(col, row); +} + +void print_char(char character) { + struct Char* buffer = (struct Char*) 0xb8000; + + if (character == '\n') { + print_newline(); + return; + } + + if (col > NUM_COLS) { + print_newline(); + } + + struct Char cr = (struct Char) { + character: character, + color: color, + }; + buffer[col + NUM_COLS * row] = cr; + + col++; + set_cursor_pos(col, row); +} + +void print_str(char* str) { + for (int i = 0; 1; i++) { + char character = (char) str[i]; + + if (character == '\0') { + return; + } + + print_char(character); + } +} + +void print_set_color(char foreground, char background) { + color = foreground + (background << 4); +} + +void set_cursor_pos(int col, int row) { + int offset = col + NUM_COLS * row; + port_byte_out(REG_SCREEN_CTRL, 14); + port_byte_out(REG_SCREEN_DATA, (unsigned char)(offset >> 8)); + port_byte_out(REG_SCREEN_CTRL, 15); + port_byte_out(REG_SCREEN_DATA, (unsigned char)(offset & 0xff)); +} + +void kernel_msg_ok(char* msg) { + char ok_p1[] = "[ "; + char ok_p2[] = "OK "; + char ok_p3[] = "] "; + + print_set_color(PRINT_COLOR_WHITE, PRINT_COLOR_BLACK); + print_str(ok_p1); + + print_set_color(PRINT_COLOR_GREEN, PRINT_COLOR_BLACK); + print_str(ok_p2); + + print_set_color(PRINT_COLOR_WHITE, PRINT_COLOR_BLACK); + print_str(ok_p3); + print_str(msg); +} \ No newline at end of file diff --git a/old/src/kernel/print.h b/old/src/kernel/print.h new file mode 100644 index 0000000..edd8a9e --- /dev/null +++ b/old/src/kernel/print.h @@ -0,0 +1,44 @@ +#ifndef PRINT_H +#define PRINT_H +#define REG_SCREEN_CTRL 0x3d4 +#define REG_SCREEN_DATA 0x3d5 + +enum { + PRINT_COLOR_BLACK = 0, + PRINT_COLOR_BLUE = 1, + PRINT_COLOR_GREEN = 2, + PRINT_COLOR_CYAN = 3, + PRINT_COLOR_RED = 4, + PRINT_COLOR_MAGENTA = 5, + PRINT_COLOR_BROWN = 6, + PRINT_COLOR_LIGHT_GRAY = 7, + PRINT_COLOR_DARK_GRAY = 8, + PRINT_COLOR_LIGHT_BLUE = 9, + PRINT_COLOR_LIGHT_GREEN = 10, + PRINT_COLOR_LIGHT_CYAN = 11, + PRINT_COLOR_LIGHT_RED = 12, + PRINT_COLOR_PINK = 13, + PRINT_COLOR_YELLOW = 14, + PRINT_COLOR_WHITE = 15, +}; + +const static int NUM_COLS = 80; +const static int NUM_ROWS = 25; + +struct Char { + char character; + char color; +}; + +void clear_row(int row); +void clear_all(); + +void print_newline(); +void print_char(char character); +void print_set_color(char foreground, char background); +void print_str(char* str); + +void set_cursor_pos(int col, int row); + +void kernel_msg_ok(char* msg); +#endif \ No newline at end of file diff --git a/old/src/kernel/strings.c b/old/src/kernel/strings.c new file mode 100644 index 0000000..d148672 --- /dev/null +++ b/old/src/kernel/strings.c @@ -0,0 +1,48 @@ +#include +#include + +void itoa(int n, char str[]) { + int i, sign; + if ((sign = n) < 0) n = -n; + i = 0; + do { + str[i++] = n % 10 + '0'; + } while ((n /= 10) > 0); + + if (sign < 0) str[i++] = '-'; + str[i] = '\0'; + + strrev(str); +} + +/* K&R */ +void strrev(char s[]) { + int c, i, j; + for (i = 0, j = strlen(s)-1; i < j; i++, j--) { + c = s[i]; + s[i] = s[j]; + s[j] = c; + } +} + +/* K&R */ +int strlen(char s[]) { + int i = 0; + while (s[i] != '\0') ++i; + return i; +} + +char* strcpy(char* strDest, const char* strSrc) { + if ( (strDest == NULL) || (strSrc == NULL) ) { + return NULL; + } + char* strDestCopy = strDest; + while ((*strDest++=*strSrc++)!='\0'); + return strDestCopy; +} + +char* strcnc(char* str1, char* str2) { + char* str_dest; + strcpy(str_dest, str1); + strcpy(str_dest, str2); +} \ No newline at end of file diff --git a/old/src/kernel/strings.h b/old/src/kernel/strings.h new file mode 100644 index 0000000..ee4402a --- /dev/null +++ b/old/src/kernel/strings.h @@ -0,0 +1,10 @@ +#ifndef STRINGS_H +#define STRINGS_H + +void itoa(int n, char str[]); +void strrev(char s[]); +int strlen(char s[]); +char* strcpy(char* strDest, const char* strSrc); +char* strcnc(char* str1, char* str2); + +#endif \ No newline at end of file diff --git a/old/src/kernel/util.c b/old/src/kernel/util.c new file mode 100644 index 0000000..e945d94 --- /dev/null +++ b/old/src/kernel/util.c @@ -0,0 +1,25 @@ +#include "util.h" + +void memcpy(char *source, char *dest, int nbytes) { + int i; + for (i = 0; i < nbytes; i++) { + *(dest + i) = *(source + i); + } +} + +void memset(char *dest, char val, int len) { + char *temp = (char *)dest; + for(; len !=0; len--) *temp++ = val; +} + +void int_to_ascii(int n, char str[]) { + int i, sign; + if ((sign = n) < 0) n = -n; + i = 0; + do { + str[i++] = n % 10 + '0'; + } while ((n /= 10) > 0); + + if (sign < 0) str[i++] = '-'; + str[i] = '\0'; +} \ No newline at end of file diff --git a/old/src/kernel/util.h b/old/src/kernel/util.h new file mode 100644 index 0000000..889ccb0 --- /dev/null +++ b/old/src/kernel/util.h @@ -0,0 +1,8 @@ +#ifndef UTIL_H +#define UTIL_H + +void memcpy(char *source, char *dest, int nbytes); +void memset(char *dest, char val, int len); +void int_to_ascii(int n, char str[]); + +#endif \ No newline at end of file diff --git a/src/boot/entry.asm b/src/boot/entry.asm index 6c1af37..dce2d91 100644 --- a/src/boot/entry.asm +++ b/src/boot/entry.asm @@ -48,10 +48,17 @@ check_cpuid: jmp error check_x64_supported: +<<<<<<< HEAD mov eax, 0x80000000 cpuid cmp eax, 0x80000001 jb .x64_unsupported ; CPUID extended feature set isnt even supported, def no x64 +======= + mov eax, 0x80000000 ; Magic code that i dont understand + cpuid ; Magic code that i dont understand + cmp eax, 0x80000001 ; Magic code that i dont undetstand + jb .x64_unsupported ; Something went wrong so x64 isnt supported +>>>>>>> a6f98cddb6e41c517b2f8129624d0ad8965ee0f9 mov eax, 0x80000001 ; Set magic value 0x80000001 into EAX for cpuid cpuid ; Get "extended features list" from CPU info @@ -131,6 +138,7 @@ stack_bottom: stack_top: section .rodata +<<<<<<< HEAD ; Access bits PRESENT equ 1 << 7 NOT_SYS equ 1 << 4 @@ -176,6 +184,13 @@ gdt64: db PRESENT | RING3 | NOT_SYS | RW ; access: 0b11110010 db GRAN_4K | SZ_32 | 0xf ; flags and limit (high, bits 16-19) db 0 ; base (high, bits 24-31) +======= +gdt64: + dd 0 ; zero entry + dd 0 +.code_segment: equ $ - gdt64 + dq (1 << 43) | (1 << 44) | (1 << 47) | (1 << 53) ; code segment +>>>>>>> a6f98cddb6e41c517b2f8129624d0ad8965ee0f9 .pointer: dw $ - gdt64 - 1 ; length dq gdt64 ; address \ No newline at end of file