diff options
| -rw-r--r-- | Makefile | 9 | ||||
| -rw-r--r-- | boot.txt | 1 | ||||
| -rw-r--r-- | bootloader.asm | 111 |
3 files changed, 121 insertions, 0 deletions
diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..f44f839 --- /dev/null +++ b/Makefile @@ -0,0 +1,9 @@ +BOOTLOADER=./bootloader.asm +TARGET=./boot.img + +all: + nasm -f bin $(BOOTLOADER) -o $(TARGET) + dd if=./boot.txt >> $(TARGET) + dd if=/dev/zero bs=512 count=1 >> $(TARGET) +clean: + rm -f $(TARGET) diff --git a/boot.txt b/boot.txt new file mode 100644 index 0000000..ebf67aa --- /dev/null +++ b/boot.txt @@ -0,0 +1 @@ +Initializing CemOS... diff --git a/bootloader.asm b/bootloader.asm new file mode 100644 index 0000000..99627d5 --- /dev/null +++ b/bootloader.asm @@ -0,0 +1,111 @@ +ORG 0x0 +BITS 16 + +_start: + jmp short start + nop + +; Setup dummy BIOS Parameter block so a dumb BIOS does not corrupt us +; if it starts messing up with the parameter block + times 33 db 0 + +start: + ; Set CS to 0x07c0 with label step2 as its beginning offset + jmp 0x07c0:step2 + +step2: + ; Setup segments + + cli ; Disable interrupts + mov ax, 0x07c0 + mov ds, ax + mov es, ax + mov ax, 0x00 + mov ss, ax + mov sp, 0x7c00 ; Stack segment starts right before ds + ; and grows down to 0x0. This works because + ; Intel implements a full descending stack + + ; Setup and test interrupt vector table and interrupts + mov word[ss:0x00], handle_zerodiv_intr ; first 2 bytes, mem offset for int + ; 0 location + ; Use SS here because it already starts + ; at 0x0 + + mov word[ss:0x02], 0x7c0 ; Data segment our interrupt is + + sti ; Enable interrupts + + + ; Test interrupts +; mov ax, 0x00 +; div ax + + mov si, load_msg + call print + + ; Load sector from disk + + mov ah, 2 ; Read sector into memory + mov al, 1 ; Read 1 sector + + mov ch, 0 ; Cylinder number + mov cl, 2 ; Sector number to start reading from + + mov dh, 0 ; Head number + ;DL ; Drive number (Already set by bios) + + ; Sector will be loaded at ES:BX. We already have ES set, + ; just set the BX to an address after the end of the bootloader. This + ; avoids the risk of corrupting any data from our bootloader. + mov bx, kbuf_sector + int 0x13 + + ; Jump if CF is set + jc kload_failure ; On I/O error, CF is set + + ; Kernel loaded succesfully (hopefully) + mov si, kbuf_sector + call print + jmp $ + +kload_failure: + mov si, err_msg + call print + jmp $ + +print: + mov bx, 0 +.loop + lodsb + cmp al, 0 + je .done + call print_char + jmp .loop +.done: + ret + +print_char: + mov ah, 0x0e + int 0x10 + ret + + +; Interrupt handlers +handle_zerodiv_intr: + mov si, divzero_msg + call print + iret + +; Static data + load_msg: db 'Starting bootloader...', 0x0A, 0x0D, 0 + divzero_msg: db 'Interrupts working properly...', 0x0A, 0x0D, 0 + err_msg: db 'Failed to load kernel...', 0x0A, 0x0D, 0 + +; Fill in to the end and add bootloader signature + times 510 - ($ - $$) db 0 + dw 0xAA55 + +; This just labels an address after the bootloader. Just makes it easier +; to refer to the loaded sector from int 0x13. +kbuf_sector: |
