From c75d8ab7912b75d0dbacc180b903ec6bd410258e Mon Sep 17 00:00:00 2001 From: Robert Date: Sat, 2 Sep 2023 19:40:46 +0200 Subject: [PATCH] create test bootloader --- Makefile | 37 +++++++ README.md | 5 + bochs_config | 8 ++ src/boot/boot.asm | 217 ++++++++++++++++++++++++++++++++++++++++++ src/kernel/kernel.asm | 0 5 files changed, 267 insertions(+) create mode 100644 Makefile create mode 100644 README.md create mode 100644 bochs_config create mode 100644 src/boot/boot.asm create mode 100644 src/kernel/kernel.asm diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..9302292 --- /dev/null +++ b/Makefile @@ -0,0 +1,37 @@ +ASM=nasm + +SRC_DIR=src +BUILD_DIR=build + +BOOT_FILES = $(shell find $(SRC_DIR)/boot/ -type f -name "*.asm") +KERN_ASM_FILES = $(shell find $(SRC_DIR)/kernel/ -type f -name "*.asm") + +BOOT_BIN_FILES = $(patsubst src/%.asm, $(BUILD_DIR)/%.bin, $(BOOT_FILES)) +KERN_BIN_FILES = $(patsubst src/%.asm, $(BUILD_DIR)/%.bin, $(KERN_ASM_FILES)) + +BOOTLOADER = $(BUILD_DIR)/boot.bin +KERNEL = $(BUILD_DIR)/kernel.bin +IMAGE = $(BUILD_DIR)/clipper.img + +.PHONY: all clipper kernel bootloader clean always + +clipper: $(IMAGE) + +$(IMAGE): bootloader kernel + dd if=/dev/zero of=$(IMAGE) bs=512 count=2880 + mkfs.fat -F 12 -n "CLPR" $(IMAGE) + dd if=$(BOOTLOADER) of=$(IMAGE) conv=notrunc + mcopy -i $(IMAGE) $(KERNEL) "::kernel.bin" + +bootloader: $(BOOT_BIN_FILES) + cp $(BUILD_DIR)/boot/boot.bin $(BOOTLOADER) + +kernel: $(KERN_BIN_FILES) + cp $(BUILD_DIR)/kernel/kernel.bin $(KERNEL) + +$(BUILD_DIR)/%.bin: $(SRC_DIR)/%.asm + @mkdir -p "$(@D)" + $(ASM) $< -f bin -o $@ + +clean: + rm -rf $(BUILD_DIR)/* diff --git a/README.md b/README.md new file mode 100644 index 0000000..790d71f --- /dev/null +++ b/README.md @@ -0,0 +1,5 @@ +# Clipper + +Clipper is an operating system kernel I write to learn about kernel development. As of right now, it is more or less following [nanobyte's](https://www.youtube.com/@nanobyte-dev) OS development tutorial. + +My ultimate goal is to create a simple, bootable POSIX-compliant operating system. diff --git a/bochs_config b/bochs_config new file mode 100644 index 0000000..f7f10cd --- /dev/null +++ b/bochs_config @@ -0,0 +1,8 @@ +megs: 128 +romimage: file=/usr/share/bochs/BIOS-bochs-latest, address=0xfffe0000 +vgaromimage: file=/usr/share/bochs/VGABIOS-lgpl-latest +floppya: 1_44=build/clipper.img, status=inserted +boot: floppy +mouse: enabled=0 +display_library: sdl, options="gui_debug" + diff --git a/src/boot/boot.asm b/src/boot/boot.asm new file mode 100644 index 0000000..d71a580 --- /dev/null +++ b/src/boot/boot.asm @@ -0,0 +1,217 @@ +org 0x7C00 +bits 16 + +%define ENDL 0x0D, 0x0A + +; FAT 12 BIOS PARAMETER BLOCK +jmp short start +nop +bpb_oem: db "CLPROS01" +bpb_bytes_per_sector: dw 512 +bpb_sectors_per_cluster: db 1 +bpb_reserved_sectors: dw 1 +bpb_fat_count: db 2 +bpb_dir_entries_count: dw 0E0h +bpb_total_sectors: dw 2880 +bpb_media_descriptor_type: db 0F0h +bpb_sectors_per_fat: dw 9 +bpb_sectors_per_track: dw 18 +bpb_heads: dw 2 +bpb_hidden_sectors: dd 0 +bpb_large_sector_count: dd 0 + +; EXTENDED BOOT RECORD +ebr_drive_number: db 0 + db 0 +ebr_signature: db 28h +ebr_volume_id: db 63h, 6Ch, 70h, 72h +ebr_volume_label: db "Clipper " +ebr_system_identifier: db "FAT12 " + +start: + jmp main + +; +; Prints a string to the screen +; Params: +; - ds:si points to string +puts: + push si + push ax + + mov ah, 0Eh + +.loop: + lodsb ; load byte at ds:si into al + or al, al ; is null? + jz .done + + int 10h + jmp .loop + +.done: + pop si + pop ax + ret + + +main: + ; setup data segment + mov ax, 0 + mov ds, ax + mov es, ax + + ; setup stack + mov ss, ax + mov sp, 0x7C00 + + ; print message + mov si, msg_hello + call puts + + ; read something from disk + mov [ebr_drive_number], dl + mov ax, 1 + mov cl, 1 + mov bx, 0x7E00 + call disk_read + + mov di, 0 + mov cl, [ebr_drive_number] +.loop: + xor ch, ch + shl cx, 4 + add ch, 30h + test cx, 9 + jle .write_disk_number + add ch, 11h + +.write_disk_number: + mov byte [msg_drive_number_value + di], ch + inc di + cmp di, 2 + jne .loop + + mov si, msg_drive_number + call puts + + hlt + jmp halt + +floppy_error: + mov si, msg_read_failed + call puts + jmp wait_key_and_reboot + +wait_key_and_reboot: + mov ah, 0 + int 16h + jmp 0FFFFh:0 + hlt + +halt: + cli + hlt + +; +; Convert LBA address to CHS +; Parameters: +; - ax: LBA address +; Returns: +; - cx [bits 0-5]: sector +; - cx [bits 6-15]: cylinder +; - dh: head +; +lba_to_chs: + push ax + push dx + + xor dx, dx + div word [bpb_sectors_per_track] + + inc dx + mov cx, dx + + xor dx, dx + div word [bpb_heads] + + mov dh, dl + mov ch, al + shl ah, 6 + or cl, ah + + pop ax + mov dl, al + pop ax + ret + +; +; Reads from disk +; Parameters: +; - ax: LBA address +; - cl: number of sectors to read (max 128) +; - dl: drive number +; - es:bx: memory address where to store data +; +disk_read: + push ax + push bx + push cx + push dx + push di + + push cx + call lba_to_chs + pop ax + + mov ah, 02h + mov di, 3 + +.retry: + pusha + stc + int 13h + jnc .done + + popa + call disk_reset + + dec di + jnz .retry + +.fail: + jmp floppy_error + +.done: + popa + + pop di + pop dx + pop cx + pop bx + pop ax + ret + +; +; Resets a disk controller +; Parameters: +; dl: drive number +; +disk_reset: + pusha + mov ah, 0 + stc + int 13h + jc floppy_error + popa + ret + + +msg_hello: db "Hello, Clipper!", ENDL, 0 +msg_read_failed: db "Failed to read from disk.", ENDL, 0 +msg_drive_number: db "Disk number: " +msg_drive_number_value: dw 0 +msg_drive_number_end: db ENDL, 0 + +times 510-($-$$) db 0 +dw 0AA55h diff --git a/src/kernel/kernel.asm b/src/kernel/kernel.asm new file mode 100644 index 0000000..e69de29