diff options
| -rw-r--r-- | .gitignore | 2 | ||||
| -rw-r--r-- | Makefile | 27 | ||||
| -rw-r--r-- | link.ld | 21 | ||||
| -rw-r--r-- | mbr/stage1.asm | 79 | ||||
| -rw-r--r-- | src/entry.c | 5 |
5 files changed, 134 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..98f5968 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +*.bin +*.o diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..cf4e41d --- /dev/null +++ b/Makefile @@ -0,0 +1,27 @@ +AS = nasm +CC = clang +CFILES = $(shell find src/ -name "*.c") +OFILES = $(CFILES:.c=.o) + +LDFLAGS = -nostdlib -Tlink.ld -no-pie +CFLAGS = -ffreestanding -nostdinc -fno-pic -mno-sse -mno-sse2 \ + -mno-mmx -mno-80387 -fno-stack-protector + +.PHONY: all +all: $(OFILES) stage1.bin stage2.bin + cat stage1.bin stage2.bin >boot.bin + +.PHONY: stage1.bin +stage1.bin: + $(AS) -fbin mbr/stage1.asm -o $@ + +.PHONY: stage2.bin +stage2.bin: + $(CC) $(LDFLAGS) $(OFILES) -o $@ + +%.o: %.c + $(CC) -c $(CFLAGS) $< -o $@ + +.PHONY: test +test: + qemu-system-i386 -hda boot.bin --enable-kvm @@ -0,0 +1,21 @@ +OUTPUT_FORMAT(binary) +ENTRY(main) + +SECTIONS { + . = 0x8000; + + .text : { + *(.text) + } + + .data : { + *(.data) + } + + .bss : { + __bss_start = .; + *(COMMON) + *(.bss) + __bss_end = .; + } +} diff --git a/mbr/stage1.asm b/mbr/stage1.asm new file mode 100644 index 0000000..ea51f22 --- /dev/null +++ b/mbr/stage1.asm @@ -0,0 +1,79 @@ +[org 0x7C00] + +_start: + xor ax, ax + mov ds, ax + mov es, ax + mov ss, ax + mov fs, ax + mov gs, ax + + cli ;; Disable all interrupts + cld ;; Strings shall increment + mov [boot_drive], dl ;; Save the boot drive + + mov si, boot_sig + call print_str + call enable_a20 + call disk_load + + jmp 0x0000:0x8000 + hlt + jmp $ + +;; +;; Write a string to the screen +;; +;; [SI]: Base address of string +;; +print_str: + lodsb ;; Load *(SI++) -> AL + or al, al ;; Null byte? + jz .done ;; Yup, finish + mov ah, 0x0E ;; Print char + int 0x10 ;; BIOS call + jmp print_str ;; Loop again until NUL +.done: + ret + +;; +;; Enable the A20 gate to access the full +;; 16 megs +;; +enable_a20: + in al, 0x92 ;; Check the state + test al, 2 ;; is it already set? + jnz .done ;; Yes, no need to re-enable + or al, 2 ;; No, enable it + out 0x92, al ;; Write the new value back +.done: + ret + +DAP: + .size: db 0x10 + .reserved: db 0x00 + .count: dw 1 + .buffer: dw 0x8000 + .segment: dw 0 + .lba_lo: dd 1 + .lba_hi: dd 0 +disk_load: + mov si, DAP + mov ah, 0x42 + mov dl, [boot_drive] + int 0x13 + jc .disk_err + ret +.disk_err: + mov si, disk_errmsg + call print_str +.hang: + hlt + jmp .hang + +boot_sig: db "* beepboot stage0", 0x0A, 0x0D, 0x00 +disk_errmsg: db "[!] failed to read disk", 0x0A, 0x0D, 0x00 +boot_drive: db 0 + +times 510 - ($ - $$) db 0 +dw 0xAA55 diff --git a/src/entry.c b/src/entry.c new file mode 100644 index 0000000..45698fd --- /dev/null +++ b/src/entry.c @@ -0,0 +1,5 @@ +int +main(void) +{ + for (;;); +} |
