commit 343f0cfd439fdeefc96923da7cf6b2b9c7c14146 Author: shibedrill Date: Sat Mar 29 20:31:35 2025 -0400 Project assignment 2 work complete diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json new file mode 100644 index 0000000..c2098a2 --- /dev/null +++ b/.vscode/c_cpp_properties.json @@ -0,0 +1,18 @@ +{ + "configurations": [ + { + "name": "linux-gcc-x64", + "includePath": [ + "${workspaceFolder}/**" + ], + "compilerPath": "/usr/bin/gcc", + "cStandard": "${default}", + "cppStandard": "${default}", + "intelliSenseMode": "linux-gcc-x64", + "compilerArgs": [ + "" + ] + } + ], + "version": 4 +} \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..c604297 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,24 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "name": "C/C++ Runner: Debug Session", + "type": "cppdbg", + "request": "launch", + "args": [], + "stopAtEntry": false, + "externalConsole": false, + "cwd": "/home/river/Documents/School/2024-2025/2024-2025 Semester 2/Op Sys/myos", + "program": "/home/river/Documents/School/2024-2025/2024-2025 Semester 2/Op Sys/myos/build/Debug/outDebug", + "MIMode": "gdb", + "miDebuggerPath": "gdb", + "setupCommands": [ + { + "description": "Enable pretty-printing for gdb", + "text": "-enable-pretty-printing", + "ignoreFailures": true + } + ] + } + ] +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..a94c29c --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,60 @@ +{ + "C_Cpp_Runner.cCompilerPath": "gcc", + "C_Cpp_Runner.cppCompilerPath": "g++", + "C_Cpp_Runner.debuggerPath": "gdb", + "C_Cpp_Runner.cStandard": "", + "C_Cpp_Runner.cppStandard": "", + "C_Cpp_Runner.msvcBatchPath": "", + "C_Cpp_Runner.useMsvc": false, + "C_Cpp_Runner.warnings": [ + "-Wall", + "-Wextra", + "-Wpedantic", + "-Wshadow", + "-Wformat=2", + "-Wcast-align", + "-Wconversion", + "-Wsign-conversion", + "-Wnull-dereference" + ], + "C_Cpp_Runner.msvcWarnings": [ + "/W4", + "/permissive-", + "/w14242", + "/w14287", + "/w14296", + "/w14311", + "/w14826", + "/w44062", + "/w44242", + "/w14905", + "/w14906", + "/w14263", + "/w44265", + "/w14928" + ], + "C_Cpp_Runner.enableWarnings": true, + "C_Cpp_Runner.warningsAsError": false, + "C_Cpp_Runner.compilerArgs": [], + "C_Cpp_Runner.linkerArgs": [], + "C_Cpp_Runner.includePaths": [], + "C_Cpp_Runner.includeSearch": [ + "*", + "**/*" + ], + "C_Cpp_Runner.excludeSearch": [ + "**/build", + "**/build/**", + "**/.*", + "**/.*/**", + "**/.vscode", + "**/.vscode/**" + ], + "C_Cpp_Runner.useAddressSanitizer": false, + "C_Cpp_Runner.useUndefinedSanitizer": false, + "C_Cpp_Runner.useLeakSanitizer": false, + "C_Cpp_Runner.showCompilationTime": false, + "C_Cpp_Runner.useLinkTimeOptimization": false, + "C_Cpp_Runner.msvcSecureNoWarnings": false, + "makefile.configureOnOpen": false +} \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..848af57 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,6 @@ +FROM alpine:3.21 +RUN mkdir -p /usr/src/myos +COPY ./* /usr/src/myos +RUN apk add bash nasm make gcc qemu-system-i386 git vim +CMD ["/bin/bash"] + diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..9f86a67 --- /dev/null +++ b/Makefile @@ -0,0 +1,19 @@ +C_FILES=./kernel.c ./console/console.c +O_FILES=$(C_FILES:.c=.o) + +all: qemu_launch + +qemu_launch: os.bin + qemu-system-i386 -drive format=raw,file=$<,index=0,if=floppy +os.bin: boot.bin kernel.bin + cat $^ > $@ +boot.bin: boot.asm + nasm $< -f bin -o $@ +kernel.bin: kernel-entry.o $(O_FILES) + ld -m elf_i386 -s -o $@ -Ttext 0x1000 $^ --oformat binary +kernel-entry.o: kernel-entry.elf + nasm $< -f elf -o $@ +$(O_FILES): + gcc -Iinclude -fno-pie -m32 -ffreestanding -c ${@:.o=.c} -o $@ +clean: + find . -name \*.o | xargs --no-run-if-empty rm diff --git a/boot.asm b/boot.asm new file mode 100644 index 0000000..017baba --- /dev/null +++ b/boot.asm @@ -0,0 +1,87 @@ +[bits 16] +[org 0x7c00] + +KERNEL_ADDRESS equ 0x1000 +mov [BOOT_DRIVE], DL +mov bp, 0x9000 +mov sp, bp + +call kernel_load +mov BX, DISK_SUCCESS_MESSAGE +call print_string +jmp switch_to_32bit +jmp done + +%include "gdt.asm" + +kernel_load: + pusha + mov AH, 0x02 + mov AL, [NUM_SECTORS] + mov BX, KERNEL_ADDRESS + mov CH, 0x00 + mov CL, 0x02 + mov DH, 0x00 + mov DL, [BOOT_DRIVE] + int 13h + jc disk_read_error + cmp AL, [NUM_SECTORS] + jne disk_sector_error + popa + ret +disk_read_error: + mov BX, DISK_READ_ERROR_MESSAGE + call print_string + jmp done +disk_sector_error: + mov BX, DISK_SECTOR_ERROR_MESSAGE + call print_string + jmp done + + +print_string: + pusha + mov AH, 0x0e +print_loop: + mov AL, [BX] + cmp AL, 0x00 + je done_print + int 10h + add BX, 1 + jmp print_loop +done_print: + popa + ret + +done: + jmp $ + + +switch_to_32bit: + cli + lgdt [gdt] + mov EAX, CR0 + or eax, 0x01 + mov CR0, EAX + jmp 0x08:begin_32bit + +[bits 32] +begin_32bit: + mov AX, 0x10 + mov SS, AX + mov DS, AX + mov ES, AX + mov FS, AX + mov GS, AX + mov ebp, 0x90000 + mov esp, ebp + jmp KERNEL_ADDRESS + + +NUM_SECTORS db 0x09 +DISK_SUCCESS_MESSAGE db "Read succeeded, continuing", 0 +DISK_READ_ERROR_MESSAGE db "Problem with disk read", 0 +DISK_SECTOR_ERROR_MESSAGE db "Read and requested sectors differ", 0 +BOOT_DRIVE db 0 +times 510 - ($-$$) db 0 +dw 0xaa55 diff --git a/console/console.c b/console/console.c new file mode 100644 index 0000000..e047ca4 --- /dev/null +++ b/console/console.c @@ -0,0 +1,44 @@ + +const int VGA_WIDTH = 80; +const int VGA_HEIGHT = 25; +const int VGA_BYTES_PER_CHARACTER = 2; + +char* const VGA_BUFFER = (char*) 0xb8000; + +static int terminal_position = 0; + +void clear_terminal() { + + for (int i=0; i<(VGA_WIDTH * VGA_HEIGHT); i++) { + // Text byte gets nulled + VGA_BUFFER[i*2] = '\0'; + // Style byte gets 0x07 for white text on a black background? + VGA_BUFFER[i*2 + 1] = 0x07; + } + +} + +void print_character(char c) { + if (c == '\n') { + terminal_position = (terminal_position + (VGA_BYTES_PER_CHARACTER * VGA_WIDTH)) - (terminal_position % (VGA_BYTES_PER_CHARACTER * VGA_WIDTH)); + } else { + VGA_BUFFER[(terminal_position * VGA_BYTES_PER_CHARACTER)] = c; + VGA_BUFFER[(terminal_position * VGA_BYTES_PER_CHARACTER) + 1] = 0x07; + terminal_position++; + } +} + +void print_string(char* string) { + + for (int i=0; string[i] != '\0'; i++) { + print_character(string[i]); + } + +} + +void print_line(char* string) { + + print_string(string); + print_character('\n'); + +} \ No newline at end of file diff --git a/gdt.asm b/gdt.asm new file mode 100644 index 0000000..ac0d1c8 --- /dev/null +++ b/gdt.asm @@ -0,0 +1,21 @@ +gdt_null_segment: + dq 0x0 +gdt_code_segment: + dw 0xffff + dw 0x0 + db 0x0 + db 10011010b + db 11001111b + db 0x0 +gdt_data_segment: + dw 0xffff + dw 0x0 + db 0x0 + db 10010010b + db 11001111b + db 0x0 +gdt_end: + +gdt: + dw gdt_end - gdt_null_segment - 1 + dd gdt_null_segment diff --git a/include/console.h b/include/console.h new file mode 100644 index 0000000..10e3aab --- /dev/null +++ b/include/console.h @@ -0,0 +1,19 @@ +#ifndef MYOS_INCLUDE_CONSOLE_H + + #define MYOS_INCLUDE_CONSOLE_H + + extern const int VGA_WIDTH; + + extern const int VGA_HEIGHT; + + extern const int VGA_BYTES_PER_CHARACTER; + + void clear_terminal(); + + void print_character(char c); + + void print_string(char* str); + + void print_line(char* str); + +#endif \ No newline at end of file diff --git a/kernel-entry.elf b/kernel-entry.elf new file mode 100644 index 0000000..4908e43 --- /dev/null +++ b/kernel-entry.elf @@ -0,0 +1,8 @@ +global _start + +[bits 32] + +_start: + [extern main] + call main + jmp $ diff --git a/kernel.c b/kernel.c new file mode 100644 index 0000000..3d3e4d0 --- /dev/null +++ b/kernel.c @@ -0,0 +1,11 @@ +#include "console.h" + +void main() { + + clear_terminal(); + print_string("HELLO"); + print_line("WORLD"); + print_string("TODAY"); + + return; +}