From 8062dc98afe22942796ab0a1d5fb61cab2ad2282 Mon Sep 17 00:00:00 2001 From: Tom-on64 Date: Fri, 8 Mar 2024 19:30:37 +0100 Subject: [PATCH] After C Switch --- build.sh | 37 ++-- src/boot.asm | 187 ++++++++++------ src/filetable.asm | 22 -- src/fs/calc.asm | 32 --- src/fs/edit.asm | 312 -------------------------- src/kernel.asm | 503 ------------------------------------------ src/kernel/entry.asm | 9 + src/kernel/main.c | 6 + src/kernel/screen.c | 21 ++ src/kernel/screen.h | 9 + src/lib/disk.asm | 334 ---------------------------- src/lib/print.asm | 129 ----------- src/lib/screen.asm | 24 -- src/testing/hello | Bin 44 -> 0 bytes src/testing/hello.asm | 25 --- 15 files changed, 180 insertions(+), 1470 deletions(-) delete mode 100644 src/filetable.asm delete mode 100644 src/fs/calc.asm delete mode 100644 src/fs/edit.asm delete mode 100644 src/kernel.asm create mode 100644 src/kernel/entry.asm create mode 100644 src/kernel/main.c create mode 100644 src/kernel/screen.c create mode 100644 src/kernel/screen.h delete mode 100644 src/lib/disk.asm delete mode 100644 src/lib/print.asm delete mode 100644 src/lib/screen.asm delete mode 100644 src/testing/hello delete mode 100644 src/testing/hello.asm diff --git a/build.sh b/build.sh index eb530a9..d39d11c 100644 --- a/build.sh +++ b/build.sh @@ -1,32 +1,27 @@ #!/bin/bash -# Create ./build dir if it doesn't exist -if !(test -d ./build); then - mkdir ./build - echo "Created ./build/ directory!" -fi +[[ -d ./build ]] || mkdir build + +rm -rf ./build/** # Bootloader -nasm -fbin src/boot.asm -o ./build/boot.bin -nasm -fbin src/filetable.asm -o ./build/filetable.bin +nasm -fbin ./src/boot.asm -o ./build/boot.bin # Kernel -nasm -fbin src/kernel.asm -o ./build/kernel.bin +nasm -felf32 ./src/kernel/entry.asm -o ./build/entry.o -# Programs -nasm -fbin src/fs/calc.asm -o ./build/calc.bin -nasm -fbin src/fs/edit.asm -o ./build/edit.bin +for file in ./src/kernel/**.c; do + filename=$(basename "$file" .c) + i386-elf-gcc -ffreestanding -Wall -Wextra -m32 -c $file -o ./build/$filename.o +done -cat ./build/calc.bin ./build/edit.bin > ./build/files.bin +i386-elf-ld -o ./build/kernel.bin -Ttext 0x1000 --oformat binary ./build/**.o -# Final binary -cat ./build/boot.bin ./build/filetable.bin ./build/kernel.bin ./build/files.bin > ./build/temp.bin -dd if=/dev/zero of=./build/kern.iso bs=512 count=2880 -dd if=./build/temp.bin of=./build/kern.iso conv=notrunc -rm -rf ./build/**.bin - -echo "Built kern.iso!" +# OS Image +cat build/boot.bin build/kernel.bin > build/os.bin +dd if=/dev/zero of=./kern.iso bs=512 count=2880 +dd if=./build/os.bin of=./kern.iso conv=notrunc # Run QEMU -echo "Running QEMU..." -qemu-system-x86_64 -drive format=raw,file="./build/kern.iso",index=0,media=disk -m 256M +qemu-system-x86_64 -drive format=raw,file="./kern.iso",index=0,media=disk -m 256M -accel tcg + diff --git a/src/boot.asm b/src/boot.asm index efeec90..52c8c7d 100644 --- a/src/boot.asm +++ b/src/boot.asm @@ -1,98 +1,149 @@ -[org 0x7c00] [bits 16] +[org 0x7c00] [global start] +%define KERNEL_LOC 0x1000 +%define KERNEL_SIZE 20 ; 20 Sectors -> 10kB +%define ENDL 0x0a, 0x0d +%define VIDMEM 0xb800 + start: - ; Setup + mov [driveNum], dl ; Store the drive number + + ; Set up the stack xor ax, ax mov es, ax mov ds, ax mov bp, 0x7c00 mov sp, bp - ; Save drive number - mov byte [driveNumber], dl + ; Setup screen + mov ax, 3 ; 80x25 Text mode + int 0x10 + mov ah, 1 ; Hide cursor + mov cx, 0x2607 + int 0x10 - ; Print boot message - mov si, bootMsg - call print - mov dl, byte [driveNumber] - call printHex - mov si, newline - call print + mov byte [0xb800], 'A' +.read: + ; Location + mov bx, KERNEL_LOC - ; Read filetable from disk - mov bx, FILETAB_LOC ; Filetable location in memory - mov es, bx - xor bx, bx + ; CHS Location + mov al, KERNEL_SIZE + mov ch, 0 ; Cylinder + mov dh, 0 ; Head + mov cl, 2 ; Sector + mov dl, [driveNum] - mov ah, 2 ; Read from disk - mov al, 1 ; Read 1 sector (512B) + mov ah, 2 ; Read from disk + int 0x13 ; Read interrupt - mov dl, byte [driveNumber] ; Drive number - mov ch, 0 ; Cylinder - mov dh, 0 ; Head - mov cl, 2 ; Sector - int 0x13 ; INT 0x13 - Disk operations + jc .diskErr - jc readFail ; CF will be set if the read fails + cli + lgdt [GDT_Descriptor] + ; Enable protected mode + mov eax, cr0 + or eax, 1 + mov cr0, eax - ; Read filetable from disk - mov bx, KERNEL_LOC ; Filetable location in memory - mov es, bx - xor bx, bx + ; Far jump to 32 bit mode!! + jmp CODE_SEG:protected_start - mov ah, 2 ; Read from disk - mov al, 4 ; Read 4 sectors (2kB) +.diskErr: + dec byte [counter] + jnz .read - mov dl, byte [driveNumber] ; Drive number - mov ch, 0 ; Cylinder - mov dh, 0 ; Head - mov cl, 3 ; Sector - int 0x13 ; INT 0x13 - Disk operations + mov si, diskErrMsg + mov bl, 0x04 + call puts - jc readFail ; CF will be set if the read fails + cli + hlt - ; Setup segmentation - mov ax, KERNEL_LOC - mov ds, ax +; +; Prints a string +; si: char* - String to print +; bl: byte - Color attribute +; +puts: + push ax + push es + + mov ax, VIDMEM + mov es, ax + mov word di, [cursor] + + mov ah, bl +.loop: + lodsb ; mov al, [si]; inc si + cmp al, 0 + je .done + mov [es:di], ax ; Really smart thing + add di, 2 + jmp .loop +.done: + mov [cursor], di + pop es + pop ax + ret + +;; Data +driveNum: db 3 +counter: db 0 +cursor: dw 0 + +; Strings +msg: db "Booting...", 0 +diskErrMsg: db "Failed while reading from disk!", 0 + +;; 32 Bit entry code +[bits 32] +protected_start: + ; Set up data and stack segments + mov ax, DATA_SEG + mov ds, ax + mov ss, ax mov es, ax mov fs, ax mov gs, ax - ; Setup stack - mov bp, 0xffff - mov sp, bp - mov ax, 0x9000 - mov ss, ax + ; Set up the stack pointer in protected mode + mov ebp, 0x90000 + mov esp, ebp - mov bl, byte [driveNumber] + ; Perform the far jump + jmp KERNEL_LOC + +;; GDT +GDT_Start: + null_descriptor: ; No clue why this exists + dd 0 + dd 0 + code_descriptor: ; Memory for code + dw 0xffff ; First 16 bits of limit + dw 0 ; 16 bits + + db 0 ; + 8 bits = 24 bits + db 0b10011010 ; p, dpl, s, type flags + db 0b11001111 ; Other flags, last 4 bits of limit + db 0 ; Base + data_descriptor: ; Memory for data + dw 0xffff ; First 16 bits of limit + dw 0 ; 16 bits + + db 0 ; + 8 bits = 24 bits + db 0b10010010 ; p, dpl, s, type flags + db 0b11001111 ; Other flags, last 4 bits of limit + db 0 ; Base +GDT_End: - ; Setup video mode - mov ax, 0x0003 - int 0x10 - mov ah, 0x0b - mov bx, 0x0001 - int 0x10 +GDT_Descriptor: + dw GDT_End - GDT_Start - 1 ; Size + dd GDT_Start ; GDT Pointer - ; Far jump to the kernel (never returns) - jmp KERNEL_LOC:0x0000 - -readFail: - mov si, diskErrorMsg - call print - cli - hlt - -%include "./src/lib/print.asm" - -driveNumber: db 0 - -bootMsg: db ENDL, "Booting kern.", ENDL, "Booting from drive ", 0 -diskErrorMsg: db "Disk Error!", ENDL, 0 - -FILETAB_LOC equ 0x1000 -KERNEL_LOC equ 0x2000 +CODE_SEG equ code_descriptor - GDT_Start +DATA_SEG equ data_descriptor - GDT_Start times 510-($-$$) db 0 dw 0xaa55 + diff --git a/src/filetable.asm b/src/filetable.asm deleted file mode 100644 index 800cd3a..0000000 --- a/src/filetable.asm +++ /dev/null @@ -1,22 +0,0 @@ -; ------------------ -; Simple Filetable -; ------------------ -; -; 16 Byte entries -; 0-9 - Filename -; 10-12 - File extension (type) -; 13 - Number of filetable entries -; 14 - Starting Sector -; 15 - Filesize in sectors (n * 512) -; -; ------------------ - -filetable: - ; db 'all',0,0,0,0,0,0,0,'txt',0,1,7 ; all - start: 1, size: 7 - db 'boot',0,0,0,0,0,0, 'bin',0,1,1 ; boot.bin - start: 1, size: 1 - db 'filetable',0, 'txt',0,2,1 ; filetable.txt - start: 2, size: 1 - db 'kernel',0,0,0,0, 'bin',0,3,4 ; kernel.bin - start: 3, size: 4 - db 'calc',0,0,0,0,0,0, 'bin',0,7,1 ; calc.bin - start: 7, size: 1 - db 'edit',0,0,0,0,0,0, 'bin',0,8,4 ; edit.bin - start: 8, size: 2 - -times 512-($-$$) db 0 diff --git a/src/fs/calc.asm b/src/fs/calc.asm deleted file mode 100644 index 9713e03..0000000 --- a/src/fs/calc.asm +++ /dev/null @@ -1,32 +0,0 @@ -[bits 16] - -start: - pusha - - mov si, msg - call print - - xor ax, ax - int 0x16 - - mov dl, ah - call printHexByte - - xor ax, ax - int 0x16 - - popa -.return: - mov ax, 0x2000 - mov ds, ax - mov es, ax - mov fs, ax - mov gs, ax - - jmp 0x2000:0x0000 - -%include "./src/lib/print.asm" - -msg: db "Hello!", ENDL, 0 - -times 512-($-$$) db 0 diff --git a/src/fs/edit.asm b/src/fs/edit.asm deleted file mode 100644 index 0637402..0000000 --- a/src/fs/edit.asm +++ /dev/null @@ -1,312 +0,0 @@ -[bits 16] - -start: - pusha - mov byte [driveNum], dl - -hexEditor: - call clearText - - mov di, 0x0e60 ; Offset in vidmem (2nd to last line) - mov si, hexModeMsg - call drawString - mov di, 0x0f00 ; Last line - mov si, controlsMsg - call drawString - - mov di, hexCode - xor cx, cx ; Clear counter - - mov dx, [codeLen] - call printHexByte - mov si, bytesMsg - call print - mov si, newline - call print - - cmp word [codeLen], 0 - je getHexCh - - mov cx, [codeLen] -.printCode: - mov dl, [di] - call printHexByte - mov ah, 0x0e - mov al, ' ' - int 0x10 - inc di - dec cx - jnz .printCode - - mov cx, [codeLen] -getHexCh: - xor ax, ax - int 0x16 - cmp al, RUN_CODE - je .runInput - cmp al, QUIT_EDIT - je return - cmp al, SAVE_FILE - je save - cmp al, OPEN_FILE - je open - cmp al, 0x08 ; Backspace - je .backspace - - xor ah, ah - call asciiToHex ; Get the hex digit into bx - - cmp ax, 15 ; Check if it's a hex character - jg getHexCh ; If not, ignore it - - inc cx - cmp cx, 2 ; Check if we've gotten a whole byte (2 hex digits/nibbles) - je .putByte - mov [hexByte], al - jmp getHexCh -.putByte: - cmp di, hexCode+510 - jge getHexCh ; Max length reached - rol byte [hexByte], 4 - or byte [hexByte], al - mov al, [hexByte] - stosb - mov dx, [hexByte] - call printHexByte - inc word [codeLen] - xor cx, cx - mov al, ' ' - mov ah, 0x0e - int 0x10 - jmp getHexCh -.backspace: - cmp word [codeLen], 0 ; Check if there's anything to delete - je getHexCh ; If not, ignore - mov byte [hexByte], 0 - dec word [codeLen] - xor cx, cx - mov byte [di], 0 - dec di - mov si, hexBackspace - call print - jmp getHexCh -.runInput: - mov si, runMsg - call print - - pusha - push es - call hexCode ;! Runs arbitrary code (may break everything) - pop es - popa - - mov si, ranMsg - call print - xor ax, ax - int 0x16 - jmp hexEditor -return: - popa - - mov ax, 0x2000 - mov es, ax - xor bx, bx - - mov ds, ax - mov fs, ax - mov gs, ax - jmp 0x2000:0x0000 - -; Saves a file -save: - mov dl, 9 - mov si, saveFileMsg - call getInput - mov byte al, [filename] - cmp byte al, 0 - je getHexCh - - ; Call saveFile - mov byte dl, [driveNum] - push word filename - push word binFile ; Filetype, TODO: More filetypes other than .bin - push word 1 ; TODO: Dynamic filesize - push word 0x8000 ; Program location (this segment) - push word savedData ; Offset (hex code location) - call saveFile ; Returns exit code in al - add sp, 10 ; Stack bs - - mov ax, 0x8000 - mov es, ax - mov fs, ax - - cmp al, 0 ; Won't be 1 (File not found) so must be disk error - jne .error - - jmp getHexCh -.error: - mov si, diskErrMsg - mov di, 0x0f00 ; Last line - call drawString - - jmp getHexCh - -; Opens a file -open: - mov dl, 11 - mov si, openFileMsg - call getInput - mov byte al, [filename] - cmp byte al, 0 - je getHexCh - - ; Call loadFile - mov byte dl, [driveNum] - push word filename - push word 0x8000 - push word hexCode - call loadFile - - mov ax, 0x8000 - mov es, ax - mov fs, ax - - cmp al, 1 - je .notFound - cmp al, 2 - je .diskErr - - ; Success - jmp hexEditor -.notFound: - mov si, notFoundMsg - jmp .err -.diskErr: - mov si, diskErrMsg -.err: - mov di, 0x0f00 - call drawString - xor ax, ax - int 0x16 - jmp hexEditor - -; -; Gets a filename (10 chars, If less, padded with Nulls) -; Outputs the filename in the filename buffer -; si - Prompt string (Null terminated) -; dl - String offset -; -getInput: - pusha - push es - - mov di, 0x0f00 ; Last line - call drawString ; si should contain the string - - mov ah, 2 ; Move cursor to input position - mov dh, 24 ; Last line - int 0x10 - - mov di, filename - xor cx, cx ; Entered filename length -.loop: - xor ax, ax - int 0x16 - - cmp al, 0xD ; User pressed enter - je .done - cmp al, 8 ; Backspace - je .backspace - cmp al, 27 ; Escape - je .escape - cmp cx, 10 ; Filename too long - je .loop - - mov ah, 0x0e - int 0x10 - mov [di], al - inc di - inc cx - jmp .loop -.backspace: - cmp cx, 0 - je .loop - dec cx - dec di - mov si, textBackspace - call print - jmp .loop -.escape: - xor cx, cx - mov si, filename -.done: - cmp cx, 10 - je .after - mov byte [di], 0 - inc cx - inc di -.after: - mov ah, 2 ; Move cursor - xor dx, dx ; 0,0 - int 0x10 - - pop es - popa - ret - -; Expects al to contain an ASCII character, will set bx to it's hex equivalent -asciiToHex: - cmp al, 'F' - jle .upperCase - sub al, 32 -.upperCase: - cmp al, '9' - jle .getHex - sub al, 7 -.getHex: - sub al, '0' - ret - -;; Includes -%include "./src/lib/print.asm" -%include "./src/lib/disk.asm" - -;; Variables -hexModeMsg: db " -- HEX -- ", 0 -textModeMsg: db " -- Text -- ", 0 -controlsMsg: db "'$' Execute; ^Q Quit; ^S Save; ^O Open", 0 -saveFileMsg: db "Save as: ", 0 ; Make sure to erase the controls -openFileMsg: db "Open file: ", 0 -bytesMsg: db " Bytes", 0 -; savedMsg: db "Saved file as '", 0 -; openedMsg: db "Editing file '", 0 -runMsg: db ENDL, ENDL, 0 -ranMsg: db ENDL, ENDL, " - Finished Execution - ", ENDL, 0 -notFoundMsg: db "File not found! ", 0 ; Erase the user input -diskErrMsg: db "Disk Error! ", 0 - -; Filetypes -binFile: db "bin" -txtFile: db "txt" - -hexBackspace: db 8,8,8,' ',8,8,0 -textBackspace: db 8,' ',8,0 - -driveNum: db 0 -hexByte: db 0 - -filenameLen: db 0 -filename: times 10 db 0 - -;; Constants -RUN_CODE equ '$' -QUIT_EDIT equ 'q' -NEW_FILE equ 'n' -SAVE_FILE equ 's' -OPEN_FILE equ 'o' - -times 3*512-($-$$) db 0 - -savedData: - hexCode: times 510 db 0 ; Code buffer - codeLen: dw 0 ; Hopefully we don't overflow :) diff --git a/src/kernel.asm b/src/kernel.asm deleted file mode 100644 index fd6a2d8..0000000 --- a/src/kernel.asm +++ /dev/null @@ -1,503 +0,0 @@ -[bits 16] - -start: - ; Save the drive number from stack - mov byte [driveNum], dl - - mov bx, 0x2000 - mov es, bx - xor bx, bx - - call resetTextMode - call clearText - - ; Print start message - mov si, startMsg - call print - -; Runs prompt -input: - mov si, prompt - call print - mov ax, 0x2000 - mov ds, ax - mov es, ax - mov si, userInput - xor cx, cx -.loop: - xor ax, ax ; Clear ax - int 0x16 ; Get a character - - cmp al, 0x0d ; Compare with CR - je .enter - cmp al, 0x08 ; Compare with BS - je .backspace - - mov ah, 0x0e ; Echo back input - mov bh, 0 - int 0x10 - - mov [si], al ; Add the input to userInput - inc cx - inc si - jmp .loop -.backspace: - cmp cx, 0 ; Check if we can backspace - je .loop - mov byte [si], 0 - dec si - dec cx - mov al, 0x08 - int 0x10 - mov al, ' ' - int 0x10 - mov al, 0x08 - int 0x10 - jmp .loop -.enter: - push si - mov si, newline - call print - pop si - mov byte [si], 0 ; NULL terminate userInput (Replaces CR) - mov byte [inputLen], cl - - cmp byte [inputLen], 0 ; Check if user input something - je input - -tokenize: ; Tokenize - mov si, userInput -.loop: - inc si - cmp byte [si], 0 - je .done - cmp byte [si], ' ' - jne .loop - mov byte [si], 0 - jmp .loop -.done: - -; Runs a command in userInput -; Expects tokenized input -runCommand: - mov di, lsCmd - call .cmp - je fileList - - mov di, gfxCmd - call .cmp - je graphicsTest - - mov di, helpCmd - call .cmp - je help - - mov di, rebootCmd - call .cmp - je reboot - - mov di, clearCmd - call .cmp - je clear - - mov di, exitCmd - call .cmp - je shutdown - - mov di, rmCmd - call .cmp - je rmFile - - jmp .end -.cmp: - push cx - mov si, userInput - repe cmpsb - pop cx - ret -.end: - -; -; Load Program - Takes userInput and tries to run that file -; -loadProgram: - mov di, userInput - mov bx, FILETAB_LOC - mov es, bx - xor bx, bx ; Get [es:bx] to be start of filetable -.nextCh: - mov al, [es:bx] - cmp al, 0 ; Check for end of filetable - je .notFound - - cmp al, [di] ; Check for starting character - je .beginSearch - - add bx, 16 ; Move to the next entry - jmp .nextCh -.beginSearch: - push bx ; Save position, if it doesn't equal - mov byte cl, [inputLen] -.searchLoop: - mov al, [es:bx] - inc bx - cmp al, [di] - jne .restartSearch - - dec cl - jz .match - inc di - jmp .searchLoop -.match: - mov al, [es:bx] - cmp al, 0 ; Check if we are at the end of a filename - je foundProgram -.restartSearch: - mov di, userInput - pop bx - inc bx - jmp .nextCh -.notFound: - mov si, fileNotFoundMsg - call print - jmp input - -foundProgram: - mov al, [es:bx] - cmp al, 0 ; Loop until we find the extension - jne .getMetadata - inc bx - jmp foundProgram -.getMetadata: - mov al, [es:bx] - mov [fileExt], al - inc bx - mov al, [es:bx] - mov [fileExt+1], al - inc bx - mov al, [es:bx] - mov [fileExt+2], al - inc bx - - inc bx ; Ignore Number of FT entries for now - - ; mov cl, [es:bx] ; Starting sector - ; inc bx - ; mov al, [es:bx] ; Number of sectors to read - ; push ax ; Save file size - - ; mov ah, 0 ; Reset disk system - ; mov dl, byte [driveNum] - ; int 0x13 - - ; mov bx, PROGRAM_LOC - ; mov es, bx - ; xor bx, bx ; [es:bx] - Place to load out program - - ; mov ah, 2 ; Read sectors into memory - ; mov dl, byte [driveNum] - ; mov ch, 0 ; Cylinder - ; mov dh, 0 ; Head - ; int 0x13 - - mov byte dl, [driveNum] ; Drive number - push word userInput ; Filename - push word PROGRAM_LOC ; Dest. segment - push word 0x0000 ; Dest. offset - call loadFile - - cmp byte al, 0 - je .loaded ; Loaded file successfully - - mov si, programLoadFailMsg - call print - - jmp input -.loaded: - ; Check file extension. If 'bin', then run, if 'txt', print - pop ax ; Restore file size - - mov cx, 3 ; Check file extension - mov si, fileExt - mov ax, 0x2000 - mov es, ax - mov di, binExt - repe cmpsb - jne .printText ; TODO: Check for more file extensions - - mov dl, [driveNum] - - mov ax, PROGRAM_LOC - mov ds, ax - mov es, ax - mov fs, ax - mov gs, ax - - jmp PROGRAM_LOC:0x0000 -.printText: - mov bx, PROGRAM_LOC - mov es, bx - xor bx, bx - mov cx, 512 - mul cx - mov cx, ax - mov ah, 0x0e -.textLoop: - mov al, [es:bx] - cmp al, 0 - je .rep - int 0x10 -.rep: - inc bx - dec cx - jnz .textLoop - - mov si, newline - call print - jmp input - -; -; Help - Prints the help message (helpMsg) -; -help: - mov si, helpMsg - call print - jmp input - -; -; Clears the screen -; -clear: - call clearText - jmp input - -; -; Shuts the system down -; Only works for QEMU -; -shutdown: - mov ax, 0x2000 - mov dx, 0x0604 - out dx, ax - -; -; Remove file (rm) -; -rmFile: - call removeFile - jmp input - -; -; File list (ls) -; -fileList: - mov bx, FILETAB_LOC - mov es, bx - xor bx, bx - - mov al, 2 ; Read from disk - mov byte dl, [driveNum] - mov ch, 0 ; Cylinder - mov dh, 0 ; Head - mov cl, 2 ; Sector - mov al, 1 ; Read 1 sector - int 0x13 ; Move filetable to es:bx - - mov si, fileListMsg - call print - -; Prints the filetable -printFiletable: - mov bx, FILETAB_LOC - mov es, bx - xor bx, bx - xor cx, cx ; Entry byte couter - mov ah, 0x0e ; Prepare for printing -.filenameLoop: - mov al, [es:bx] ; Get filename character - cmp al, 0 ; Check if it's NULL - je .filenameEnd ; If so, end the filename reading - cmp cx, 9 ; Check if we already read 10 Bytes - je .filenameEnd - int 0x10 ; Else print the character - inc cx ; Increment byte counter - inc bx - jmp .filenameLoop -.filenameEnd: - push cx -.skipNull: - cmp cx, 0 - je .done - cmp cx, 10 ; Check if we're at the end of filename - je .fileExt ; If so, print extension - inc cx - inc bx - jmp .skipNull -.fileExt: - ; push cx ; Save the counter - mov al, '.' ; Print a "." to separate filename from extension - int 0x10 -.fileExtLoop: - mov al, [es:bx] - cmp cx, 13 ; Check if we printed 3 characters - je .fileExtEnd - cmp al, 0 - je .fileExtEnd - int 0x10 - inc cx - inc bx - jmp .fileExtLoop -.fileExtEnd: - cmp cx, 13 - je .whitespace - inc cx - inc bx - mov al, ' ' ; Print whitespace - int 0x10 - jmp .fileExtEnd -.whitespace: - pop cx -.wsLoop: - cmp cx, 11 ; Max filename length + 1 for spacing - je .fileInfo - mov al, ' ' - int 0x10 - inc cx - jmp .wsLoop -.fileInfo: - ; Entry number - mov dl, [es:bx] - call printHexByte - inc bx - mov al, ' ' - int 0x10 - ; Start sector - mov dl, [es:bx] - call printHexByte - inc bx - mov al, ' ' - int 0x10 - int 0x10 - int 0x10 - ; File size - mov al, [es:bx] - inc bx - cmp al, 1 - je .oneSector ; Only print 512B - shr al, 1 ; Divide by 2 - jc .oneHalf ; We had an odd number of sectors - add al, '0' - int 0x10 - mov si, kilobyteText - call print - jmp .repeat -.oneHalf: - add al, '0' - int 0x10 - mov si, oneHalfText - call print - jmp .repeat -.oneSector: - mov si, sectorLenText - call print -.repeat: - mov si, newline - call print - xor cx, cx - jmp .filenameLoop -.done: - jmp input - -; -; Graphics Mode Test -; -graphicsTest: - call resetGraphicsMode - - ; Test square - mov ah, 0x0c ; Write gfx pixel - mov al, 0x02 ; Green - mov bh, 0 ; Page number - - mov cx, 100 ; Column number - mov dx, 100 ; Row number - int 0x10 -.colLoop: - inc cx - int 0x10 - cmp cx, 150 - jne .colLoop - - inc dx - int 0x10 - mov cx, 99 - cmp dx, 150 - jne .colLoop -.done: - mov si, startMsg - call print - - xor ax, ax - int 0x16 - - call resetTextMode - jmp input - -; -; Reboots the OS -; -reboot: jmp 0xffff:0x0000 - -;; Includes -%include "./src/lib/print.asm" -%include "./src/lib/screen.asm" -%include "./src/lib/disk.asm" - -;; Variables -driveNum: db 0 - -startMsg: db "kern.", ENDL, ENDL, 0 ; The bootup message -prompt: db "> ", 0 ; Prompt for input -fileNotFoundMsg: db "File not found!", ENDL, 0 ; User tries to load nonexistent file -programLoadFailMsg: db "Couldn't load file!", ENDL, 0 ; File load fail -sectorLenText: db "512B", 0 -kilobyteText: db "kB", 0 -oneHalfText: db ".5kB", 0 - -fileListMsg: db " Filename E# St Size ", ENDL, \ - "---------- ------- ------", ENDL, 0 - -helpMsg: db "Available Commands:", ENDL, \ - " clear | Clears the screen", ENDL, \ - " edit | Opens the code editor", ENDL, \ - " exit | Shuts the system down", ENDL, \ - " gfx | Graphics mode test", ENDL, \ - " help | Prints this message", ENDL, \ - " ls | List all files", ENDL, \ - " reboot | Reboots the system", ENDL, \ - " rm | Removes a file", ENDL, ENDL, 0 - -; Commands -; TODO: Put these into a file or something -clearCmd: db "clear", 0 -exitCmd: db "exit" -gfxCmd: db "gfx", 0 -helpCmd: db "help", 0 -lsCmd: db "ls", 0 -rebootCmd: db "reboot", 0 -rmCmd: db "rm", 0 - -; Files -fileExt: db " ", 0 -binExt: db "bin", 0 -txtExt: db "txt", 0 - -inputLen: db 0 -tokenCount: db 0 -userInput: times 80 db 0 - -;; Constants -FILETAB_LOC equ 0x1000 -PROGRAM_LOC equ 0x8000 - -times 4*512-($-$$) db 0 diff --git a/src/kernel/entry.asm b/src/kernel/entry.asm new file mode 100644 index 0000000..737e646 --- /dev/null +++ b/src/kernel/entry.asm @@ -0,0 +1,9 @@ +[bits 32] +[global _start] + +[extern main] + +_start: + call main + cli + hlt diff --git a/src/kernel/main.c b/src/kernel/main.c new file mode 100644 index 0000000..f23560e --- /dev/null +++ b/src/kernel/main.c @@ -0,0 +1,6 @@ +#include "screen.h" + +void main() { + print("Hello, World!", 0x0f); +} + diff --git a/src/kernel/screen.c b/src/kernel/screen.c new file mode 100644 index 0000000..08d72c6 --- /dev/null +++ b/src/kernel/screen.c @@ -0,0 +1,21 @@ +#include "screen.h" + +unsigned int cursor = 0; + +void putc(char c, char attr) { + int mem = VIDMEM + cursor * 2; + *(char*)(mem) = c; + *(char*)(mem+1) = attr; + + cursor++; +} + +void print(char* s, char attr) { + int i = 0; + char c = *s; + while (c != '\0') { + putc(c, attr); + c = *(s + ++i); + } +} + diff --git a/src/kernel/screen.h b/src/kernel/screen.h new file mode 100644 index 0000000..04ba67d --- /dev/null +++ b/src/kernel/screen.h @@ -0,0 +1,9 @@ +#ifndef SCREEN_H +#define SCREEN_H + +#define VIDMEM 0xb8000 + +void putc(char c, char attr); +void print(char* s, char attr); + +#endif diff --git a/src/lib/disk.asm b/src/lib/disk.asm deleted file mode 100644 index 59a11e7..0000000 --- a/src/lib/disk.asm +++ /dev/null @@ -1,334 +0,0 @@ -; -; Loads a file from the filetable into a memory location -; Params: -; dl - Disk number (byte) -; Filename (Null terminated) -; Destination location segment -; Destination location offset -; -; Returns: -; al - Exit code : 0 - Success; 1 - File not found; 2 - Disk error -; -loadFile: - ; Func prologue - push bp - mov bp, sp - push bx - push fs - push cx - push dx - push si - push es - - mov byte [diskNum], dl - mov bx, [bp+4] ; src Offset - mov fs, [bp+6] ; src Segment - mov si, [bp+8] ; Filename - - push bx - - mov cx, 10 - mov di, fileName -.getFilename: - lodsb ; mov byte al, [si]; inc si - cmp al, 0 ; End of fileName - je .filenamePad - stosb - loop .getFilename - jmp .filenameDone -.filenamePad: - dec si ; Fill the rest with Null -.filenamePadLoop: - stosb - loop .filenamePadLoop -.filenameDone: - mov si, fileName - call print - - mov ax, FILETAB_LOC - mov es, ax - xor di, di ; es:di - Filetable location - mov si, fileName -.fileNameCheck: - mov al, [es:di] - cmp al, 0 ; End of filetable - je .notFound - - cmp al, [si] - je .beginCmp - - add di, 16 - jmp .fileNameCheck -.beginCmp: - push di - mov cl, 10 -.cmpLoop: - mov al, [es:di] - inc di - cmp al, [si] - jne .redoCheck - - dec cl - jz .found - inc si - jmp .cmpLoop -.redoCheck: - mov si, fileName - pop di - add di, 16 - jmp .fileNameCheck -.notFound: - mov byte [exitCode], NOT_FOUND - jmp .done -.found: - add di, 3 ; Skip extension - inc di ; Skip Number of entries - - xor ax, ax ; Reset disk - mov dl, [diskNum] - int 0x13 - - mov ch, 0 ; Cylinder - mov dh, 0 ; Head - mov cl, [es:di] ; Sector - inc di - mov al, [es:di] ; Length in sectors - mov bx, fs - mov es, bx - pop bx - mov dx, bx - call printHexByte - mov ah, 2 ; Read from disk - int 0x13 - - jnc .done - - mov byte [exitCode], DISK_ERROR -.done: - ; Func epilogue - pop es - pop si - pop dx - pop cx - pop fs - pop bx - mov sp, bp - pop bp - mov byte al, [exitCode] - ret - -; -; Saves a file to the disk and updates filetable -; dl - Disk number -; Params: -; Filename (Null terminated) -; Filetype (Null terminated) -; Filesize (Byte) -; Source location segment -; Source location offset -; -; Returns: -; al - Exit code : 0 - Success; 1 - File not found; 2 - Disk error -; -saveFile: - ; Func prologue - push bp - mov bp, sp - push bx - push fs - push cx - push dx - push si - push es - - mov byte [diskNum], dl - mov bx, [bp+4] ; src Offset - mov fs, [bp+6] ; src Segment - mov cx, [bp+8] ; Filesize - mov ax, [bp+10] ; Filetype - - push bx - - mov byte [filesize], cl - - mov si, ax - mov di, filetype - mov cx, 3 - rep movsb - - mov si, [bp+12] ; Filename - mov cx, 10 - mov di, fileName -.getFilename: - lodsb ; mov byte al, [si]; inc si - cmp al, 0 ; End of fileName - je .filenamePad - stosb - loop .getFilename - jmp .filenameDone -.filenamePad: - dec si ; Fill the rest with Null -.filenamePadLoop: - stosb - loop .filenamePadLoop -.filenameDone: - mov ax, FILETAB_LOC - mov es, ax - xor di, di ; es:di - Filetable location - mov si, fileName -.fileNameCheck: - mov byte al, [es:di+14] ; Starting sector - cmp al, 0 ; No file, create one - je createFile - - add byte al, [es:di+15] ; Filesize - mov byte [availableSector], al - - mov al, [es:di] - cmp al, 0 ; End of filetable - je createFile ; File doesn't exist, create new one - - cmp al, [si] - je .beginCmp - - add di, 16 - jmp .fileNameCheck -.beginCmp: - push di - mov cl, 10 -.cmpLoop: - mov al, [es:di] - inc di - cmp al, [si] - jne .redoCheck - - dec cl - jz .found - inc si - jmp .cmpLoop -.redoCheck: - mov si, fileName - pop di - add di, 16 - jmp .fileNameCheck -.found: ; File already exists (override) - ; TODO: Ask user if they want to override file - add di, 3 ; Skip extension - inc di ; Skip Number of entries - - xor ax, ax ; Reset disk - mov dl, [diskNum] - int 0x13 - - ; TODO: Override current file - ; push fs - ; mov ch, 0 ; Cylinder - ; mov dh, 0 ; Head - ; mov cl, [es:di] ; Sector - ; inc di - ; mov al, [es:di] ; Length in sectors - ; mov ah, 3 ; Write to disk - ; pop es ; es:bx - Destination - ; int 0x13 - - ; jnc returnToCaller - - mov byte [exitCode], DISK_ERROR - jmp returnToCaller ; TODO: Fix this - -createFile: ; Appends a file to the filetable. - mov di, FILETAB_LOC - mov es, di - xor di, di - -.filetabEnd: ; Move to the end of filetable - cmp byte [es:di], 0 - je .filetabEndDone - add di, 16 - jmp .filetabEnd -.filetabEndDone: - mov cx, 10 - mov si, fileName - rep movsb ; Append the fileName - mov cx, 3 - mov si, filetype - rep movsb ; Append the extension - mov byte [es:di], 0 ; Number of entries - inc di - mov byte al, [availableSector] - stosb ; Starting sector - mov byte al, [filesize] - stosb ; File length in sectors - - ; Write changed filetable to disk - ;! If filetable size changes, this will have to change (probably) - mov bx, FILETAB_LOC - mov es, bx - xor bx, bx ; es:bx - Filetable location - mov dl, [diskNum] - mov ah, 3 ; Write to disk - mov al, 1 ; Write 1 sector - mov ch, 0 ; Cylinder - mov dh, 0 ; Head - mov cl, 2 ; Sector - int 0x13 - - jnc writeFileData - - mov byte [exitCode], DISK_ERROR - jmp returnToCaller - -writeFileData: ; Writes file data to the disk - mov ax, 0x8000 ; Source segment - mov es, ax - pop bx ; es:bx - Source - mov ah, 3 ; Write to disk - mov byte al, [filesize] - mov dl, [diskNum] - mov ch, 0 ; Cylinder - mov dh, 0 ; Head - mov byte cl, [availableSector] - int 0x13 - - jnc returnToCaller - - mov byte [exitCode], DISK_ERROR ; Exit code - Disk Error - -returnToCaller: - ; Func epilogue - pop es - pop si - pop dx - pop cx - pop fs - pop bx - mov sp, bp - pop bp - mov byte al, [exitCode] - ret - -; -; Removes a file from the disk/filetable -; -; Params: -; Filename -; -removeFile: - ret - -;; Variables -availableSector: db 0 -exitCode: db 0 - -diskNum: db 0 -filesize: db 0 -filetype: times 3 db 0 -fileName: times 10 db 0 - -;; Constants -FILETAB_LOC equ 0x1000 - -; Exit codes -SUCCESS equ 0 -NOT_FOUND equ 1 -DISK_ERROR equ 2 diff --git a/src/lib/print.asm b/src/lib/print.asm deleted file mode 100644 index e32255f..0000000 --- a/src/lib/print.asm +++ /dev/null @@ -1,129 +0,0 @@ -; -; Prints a string -; si - Pointer to NULL terminated string -; -print: - pusha - mov ah, 0x0e - mov bl, 0x1f - mov bh, 0 -.loop: - lodsb ; Load [si] into al; Increment si - or al, al - jz .done - int 0x10 - jmp .loop -.done: - popa - ret - -; -; Prints a hex value -; dx - Value to print in Hex -; -printHex: - pusha - xor cx, cx ; Init counter -.loop: - cmp cx, 4 ; Check for loop end - je .done - mov ax, dx ; Copy dx to ax - and ax, 0x000f ; Get last nibble (4 bits) of ax - add ax, '0' ; Convert number to an ASCII number (0-9) - cmp ax, '9' ; Check if number was less than 9, meaning we can use it - jle .addChar - add ax, 0x07 ; Convert to letter (A-F) -.addChar: - mov bx, hexString + 5 - sub bx, cx ; Get position of current hex character - mov [bx], al - ror dx, 4 ; Rotate bits of dx (0x1a2b -> 0xb1a2) - inc cx ; Increment the counter - jmp .loop -.done: - mov si, hexString - call print - popa - ret - -; -; Prints a hex byte -; dl - Hex byte -; -printHexByte: - pusha - xor cx, cx - mov bh, 0 - mov bl, 0x1f ; White on blue -.loop: - mov al, dl - and al, 0xF0 - ror al, 4 - add al, '0' - cmp al, '9' - jle .hexNum - add al, 7 -.hexNum: - mov ah, 0x0e - int 0x10 - inc cx - cmp cx, 2 - je .done - ror dl, 4 - jmp .loop -.done: - popa - ret - -hexString: db "0x0000", 0 - -; -; Clears the screen in text mode -; Assumes VGA text 3 - 80x25, 16 color -; -clearText: - pusha - push es - mov ax, 0x0b800 - mov es, ax - xor di, di ; es:di - b800:0000 - - mov al, ' ' ; Fill with spaces - mov ah, 0x17 ; White on blue - mov cx, 80*25 - rep stosw - - mov ah, 2 - xor dx, dx ; Set cursor to 0,0 - int 0x10 - - pop es - popa - ret - -; -; Writes a string into video memory -; di - Video memory offset -; si - string -; -drawString: - pusha - push es ; For some reason doesn't get stored in pusha - mov ax, VIDMEM - mov es, ax -.loop: - cmp byte [si], 0 - je .after - movsb - mov byte [es:di], 0x1f ; White on blue - inc di - jmp .loop -.after: - pop es - popa - ret - -; Usefull definitions -%define ENDL 0x0a, 0x0d -VIDMEM equ 0x0b800 -newline: db ENDL, 0 ; CRLF diff --git a/src/lib/screen.asm b/src/lib/screen.asm deleted file mode 100644 index 14f2c9d..0000000 --- a/src/lib/screen.asm +++ /dev/null @@ -1,24 +0,0 @@ -resetTextMode: - pusha - - mov ah, 0 ; Set mode - mov al, 0x03 ; 25x80, Text mode - int 0x10 - - mov ah, 0x0b ; Change color/palette - mov bh, 0x00 ; Change BG color - mov bl, 0x01 ; Blue BG - int 0x10 - - popa - ret - -resetGraphicsMode: - pusha - - mov ah, 0 ; Set mode - mov al, 0x13 ; 320x200, 256 color graphics mode - int 0x10 - - popa - ret diff --git a/src/testing/hello b/src/testing/hello deleted file mode 100644 index a710842ec906930dd23fb4ade3952dce1dca254e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 44 wcmdnOx54AAz=l*H&N(XpB=dn-@vMO1fwN*e7!>+$^d0DX(D&jM0|SEs0MfP;SO5S3 diff --git a/src/testing/hello.asm b/src/testing/hello.asm deleted file mode 100644 index 7c638ea..0000000 --- a/src/testing/hello.asm +++ /dev/null @@ -1,25 +0,0 @@ -[bits 16] - -start: - mov ah, 0x0e - mov al, 'H' - int 0x10 - mov al, 'e' - int 0x10 - mov al, 'l' - int 0x10 - int 0x10 - mov al, 'o' - int 0x10 - mov al, '!' - int 0x10 - - xor ax, ax - int 0x16 - - mov ax, 0x2000 - mov ds, ax - mov es, ax - mov fs, ax - mov gs, ax - jmp 0x2000:0x0000