summaryrefslogtreecommitdiff
path: root/bootloader.asm
diff options
context:
space:
mode:
Diffstat (limited to 'bootloader.asm')
-rw-r--r--bootloader.asm111
1 files changed, 111 insertions, 0 deletions
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: