commit e2567d25bafe0e052fd5e0e2dcdfeddfceea1662 Author: Wes R Date: Mon Aug 21 10:09:02 2023 -0400 first commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4941711 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +*~ +build/* \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..bcbc84f --- /dev/null +++ b/Makefile @@ -0,0 +1,50 @@ +ASM=nasm + +SRC_DIR=src +BUILD_DIR=build + +.PHONY: all floppy_image kernel bootloader clean always + +# +# Floppy image +# * use dd to create 1.44MB blank image file +# * apply FAT12 filesystem to image +# * copy 512 byte bootloader binary to image using dd (overwriting first sector) +# * copy kernel binary to filesystem +# + this step wtill fail if bootloader binary does not contain proper FAT12 headers +# +floppy_image: $(BUILD_DIR)/main_floppy.img + +$(BUILD_DIR)/main_floppy.img: bootloader kernel + dd if=/dev/zero of=$(BUILD_DIR)/main_floppy.img bs=512 count=2880 + mkfs.fat -F 12 -n "WEESLOS" $(BUILD_DIR)/main_floppy.img + dd if=$(BUILD_DIR)/bootloader.bin of=$(BUILD_DIR)/main_floppy.img conv=notrunc + mcopy -i $(BUILD_DIR)/main_floppy.img $(BUILD_DIR)/kernel.bin "::kernel.bin" + +# +# Bootloader +# +bootloader: $(BUILD_DIR)/bootloader.bin + +$(BUILD_DIR)/bootloader.bin: always + $(ASM) $(SRC_DIR)/bootloader/boot.asm -f bin -o $(BUILD_DIR)/bootloader.bin + +# +# Kernel +# +kernel: $(BUILD_DIR)/kernel.bin + +$(BUILD_DIR)/kernel.bin: always + $(ASM) $(SRC_DIR)/kernel/main.asm -f bin -o $(BUILD_DIR)/kernel.bin + +# +# Always +# +always: + mkdir -p $(BUILD_DIR) + +# +# Clean +# +clean: + rm -rf $(BUILD_DIR)/* diff --git a/REAMDE.MD b/REAMDE.MD new file mode 100644 index 0000000..e69de29 diff --git a/src/bootloader/boot.asm b/src/bootloader/boot.asm new file mode 100644 index 0000000..7d13b2e --- /dev/null +++ b/src/bootloader/boot.asm @@ -0,0 +1,86 @@ + org 0x7c00 + bits 16 + +%define ENDL 0x0d, 0x0a + +;; FAT12 header start + jmp short start + nop + +bdb_oem: db 'MSWIN4.1' ;8 bytes +bdb_bytes_per_sector: dw 512 +bdb_sectors_per_cluster: db 1 +bdb_reserved_sctors: dw 1 +bdb_fat_count: db 2 +bdb_dir_entries_count: dw 0E0h +bdb_total_sectors: dw 2880 ; 2880 * 512 = 1.44MB +bdb_media_descriptor_type: db 0F0h ; F0 = 3.5" floppy +bdb_sectors_per_fat: dw 9 ; 9 sectors/FAT +bdb_sectors_per_track: dw 18 +bdb_heads: dw 2 +bdb_hidden_sector_count: dd 0 +bdb_large_sector_count: dd 0 + +;; Extended boot record +ebr_drive_number: db 0 ; 0x00 = floppy, 0x80 hdd + db 0 ; reserved byte +ebr_signature: db 29h ; magic number? +ebr_volume_id: db 69h, 69h, 69h, 69h ; serial number +ebr_volume_label: db 'WEESLOS ' ; must be 11 bytes, pad with spaces +ebr_system_id: db 'FAT12 ' ; must be 8 bytes, pad with spaces + +;; FAT12 header end + +start: + jmp main + +;; Prints a string to the screen. +;; Params: +;; - ds;si points to string +;; +puts: + ;; push crap to stack that can/will be modified + push si + push ax + push bx +.loop: + lodsb ; loads next character into al + or al, al ; verify if next character is null + jz .done ; conditonal jump ifeq zero (if result of OR instruction above is zero) + + mov ah, 0x0e ; 0x0e "Teletype Output" subfunction of BIOS interrupt 0x10 + mov bh, 0 ; set page number to 0 + int 0x10 ; Call BIOS interrupt + + jmp .loop +.done: + ;; retrieve crap and return + pop bx + pop ax + pop si + ret + + +main: + ;; Data segment setup + mov ax, 0 ; canot write to ds/es directly + mov ds, ax + mov es, ax + + ;; Stack initalization + mov ss, ax + mov sp, 0x7c00 ; stack will grow downwards in memory as it is filled + + ;; print message + mov si, msg_hello + call puts + + hlt ; stop executing + +.halt: + jmp .halt ; really make sure we're not executing random shit + +msg_hello: db 'Hello Shitass!', ENDL, 0 ; named constant + +times 510-($-$$) db 0 ; pad program with zeros up to byte 510 +dw 0AA55h ; BIOS requires last two bytes of first sector to be AA55 diff --git a/src/kernel/main.asm b/src/kernel/main.asm new file mode 100644 index 0000000..678cb7b --- /dev/null +++ b/src/kernel/main.asm @@ -0,0 +1,58 @@ + org 0x7c00 + bits 16 + +%define ENDL 0x0d, 0x0a + +start: + jmp main + +;; Prints a string to the screen. +;; Params: +;; - ds;si points to string +;; +puts: + ;; push crap to stack that can/will be modified + push si + push ax + push bx +.loop: + lodsb ; loads next character into al + or al, al ; verify if next character is null + jz .done ; conditonal jump ifeq zero (if result of OR instruction above is zero) + + mov ah, 0x0e ; 0x0e "Teletype Output" subfunction of BIOS interrupt 0x10 + mov bh, 0 ; set page number to 0 + int 0x10 ; Call BIOS interrupt + + jmp .loop +.done: + ;; retrieve crap and return + pop bx + pop ax + pop si + ret + + +main: + ;; Data segment setup + mov ax, 0 ; canot write to ds/es directly + mov ds, ax + mov es, ax + + ;; Stack initalization + mov ss, ax + mov sp, 0x7c00 ; stack will grow downwards in memory as it is filled + + ;; print message + mov si, msg_hello + call puts + + hlt ; stop executing + +.halt: + jmp .halt ; really make sure we're not executing random shit + +msg_hello: db 'Hello Shitass!', ENDL, 0 ; named constant + +times 510-($-$$) db 0 ; pad program with zeros up to byte 510 +dw 0AA55h ; BIOS requires last two bytes of first sector to be AA55