From 3c90dd8b3d3ae54ad1243ca1ac9b523b53b5dff5 Mon Sep 17 00:00:00 2001 From: Paul Mathieu Date: Wed, 24 Sep 2025 00:49:54 +0200 Subject: [PATCH] Add a fat12-enabled boot sector --- Makefile | 35 ++++++++++++++++++++++++------- bootsect.S | 29 ++++++++++++++++++++++++++ bootsect.ld | 20 ++++++++++++++++++ fat12boot.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 136 insertions(+), 7 deletions(-) create mode 100644 bootsect.S create mode 100644 bootsect.ld create mode 100644 fat12boot.c diff --git a/Makefile b/Makefile index b6f2a88..fdf8895 100644 --- a/Makefile +++ b/Makefile @@ -9,17 +9,37 @@ crc16.s: crc16.c crc16.bin: crc16.s crt0.c ia16-elf-gcc -o crc16.bin -Os -nostdlib crc16.s crt0.c -wozmon.s: wozmon.cc - ia16-elf-gcc -S -Os -o wozmon.s wozmon.cc +CC = ia16-elf-gcc +CXX = ia16-elf-gcc +LD = ia16-elf-gcc +CXXFLAGS = -mregparmcall -ffunction-sections -Os -flto +CFLAGS = -mregparmcall -ffunction-sections -Os -flto +LDFLAGS = -mregparmcall -Wl,--gc-sections -Os -nostdlib -flto -wozmon.bin: wozmon.s crt0.c - ia16-elf-gcc -o wozmon.bin -Os -nostdlib wozmon.s crt0.c - truncate -s 510 wozmon.bin - printf "\125\252" >> wozmon.bin +%.elf: + $(LD) $(LDFLAGS) $(CPPFLAGS) -o $@ $^ + +bootsectors = fat12boot.bin wozmon.bin + +$(bootsectors): + ia16-elf-objcopy -O binary $? $@ + truncate -s 510 $@ + printf "\125\252" >> $@ + +fat12boot.elf: fat12boot.o fat12.o bootsect.S +fat12boot.elf: LDFLAGS += -T bootsect.ld + +fat12boot.bin: fat12boot.elf + +wozmon.elf: wozmon.o bootsect.S +wozmon.elf: LDFLAGS += -T bootsect.ld +wozmon.elf: CPPFLAGS += -DNOBPB + +wozmon.bin: wozmon.elf .PHONY: clean clean: ## Remove generated files - rm -rf wozmon.bin crc16.bin readfloppy.bin writefloppy.bin + rm -rf wozmon.bin crc16.bin readfloppy.bin writefloppy.bin fat12boot.bin .PHONY: dev-image dev-image: @@ -42,6 +62,7 @@ binaries: ## Build all binaries docker build --build-arg TARGET=debug.bin -o . --target=export . docker build --build-arg TARGET=dosdbt.bin -o . --target=export . docker build --build-arg TARGET=format.bin -o . --target=export . + docker build --build-arg TARGET=fat12boot.bin -o . --target=export . .PHONY: help diff --git a/bootsect.S b/bootsect.S new file mode 100644 index 0000000..233e7f2 --- /dev/null +++ b/bootsect.S @@ -0,0 +1,29 @@ + .arch i8086,jumps + .code16 + +.section .init +.global _start +_start: +#ifndef NOBPB + jmp l0 + nop + +.ascii "IBM 3.1" +bpb_bytespersect: .word 512 +bpb_sectspercluster: .byte 2 +bpb_reservedsects: .word 1 +bbp_fats: .byte 2 +bpb_rootentries: .word 112 +bpb_localsectors: .word 720 +bpb_mediadescr: .byte 0xfd +bpb_sectsperfat: .word 2 + +l0: +#endif // NOBPB + cli + xor %ax, %ax + mov %ax, %ds + mov %ax, %ss + mov $0x7c00, %sp + sti + jmp main diff --git a/bootsect.ld b/bootsect.ld new file mode 100644 index 0000000..d9546fd --- /dev/null +++ b/bootsect.ld @@ -0,0 +1,20 @@ +SECTIONS { + . = 0x7c00; + + .text : { + KEEP(*(.init)) + *(.text*) + } + + .rodata : { + *(.rodata*) + } + + .bss (NOLOAD) : { + * (.bss) + } + + .data : { + *(.data) + } +} diff --git a/fat12boot.c b/fat12boot.c new file mode 100644 index 0000000..633da70 --- /dev/null +++ b/fat12boot.c @@ -0,0 +1,59 @@ +#include +#include + +#include "fat12.h" + +#define kPolmonAddress ((void*)0x0600) +#define kFatAddress ((void*)0x1000) +#define kRootDirAddress ((void*)0x1200) + + +static int putchar(int c) { + register uint8_t khar asm ("al") = c; + register uint8_t func asm ("ah") = 0x0e; + register uint8_t page asm ("bh") = 0; + + asm volatile ("int $0x10" + :: "r" (khar), "r" (func), "r" (page) + : "bp"); + + return c; +} + +static int puts(const char* msg) { + while (*msg) { + putchar(*msg++); + } + return 0; +} + +__attribute__((noreturn)) +static void die(const char* msg) { + puts(msg); + while (1) { + } + __builtin_unreachable(); +} + +__attribute__((noreturn)) +static void jump(void* addr) { + asm volatile ("ljmp $0,%0" :: "i"(addr)); + __builtin_unreachable(); +} + +__attribute__((noreturn)) +static void loadpolmon() { + if (fat12_init(kFatAddress, kRootDirAddress)) { + die("fi"); + } + + if (fat12_readfile("POLMON COM", kPolmonAddress)) { + die("pnf"); + } + + jump(kPolmonAddress); +} + +int main() { + loadpolmon(); +}