summaryrefslogtreecommitdiff
path: root/asm/boot.asm
diff options
context:
space:
mode:
authorandromeda <andromeda@lenovo>2026-03-03 18:18:57 +0100
committerandromeda <andromeda@lenovo>2026-03-03 18:18:57 +0100
commitd879df630f68bb56f291ac285f951ca2ba6764e7 (patch)
treebaf7f8f71dfdef788e1cbc032268c58d1dd9e8b1 /asm/boot.asm
parentab30c236003a8dafd148d821dbe559202446b0d7 (diff)
reorganise
Diffstat (limited to 'asm/boot.asm')
-rw-r--r--asm/boot.asm158
1 files changed, 158 insertions, 0 deletions
diff --git a/asm/boot.asm b/asm/boot.asm
new file mode 100644
index 0000000..bb852ef
--- /dev/null
+++ b/asm/boot.asm
@@ -0,0 +1,158 @@
+; bootler
+; legacy bootloader in nasm-flavoured asm
+; 2026 Andromeda
+; GPL licensed
+
+[bits 16]
+[org 0x7C00] ; address where bootloader is loaded
+
+xor ax, ax
+mov ds, ax
+mov es, ax
+mov ss, ax
+mov sp, 0x7C00
+
+mov ah, 0x0E
+mov al, 'R'
+int 0x10
+mov al, 'e'
+int 0x10
+mov al, 'a'
+int 0x10
+mov al, 'l'
+int 0x10
+mov al, 0x0D
+int 0x10
+mov al, 0x0A
+int 0x10
+mov al, 0x00 ; stops serial and bios output from overlapping in qemu -nographic
+int 0x10 ; output
+
+; activate a20
+mov ax, 0x2401
+int 0x15
+jc error
+
+; load kernel
+; 'docs' from https://www.ctyme.com/intr/rb-0607.htm
+mov ah, 0x02
+mov al, 1 ; number of sectors to read (must be nonzero)
+mov ch, 0 ; low eight bits of cylinder number
+mov cl, 2 ; sector number 1-63 (bits 0-5); high two bits of cylinder (bits 6-7,
+ ; hard disk only)
+mov dh, 0 ; head number
+; dl is already set by bios
+mov bx, 0x1000 ; data buffer
+mov es, bx
+xor bx, bx
+int 0x13 ; read disk
+jc error
+
+; load gdt
+lgdt [gdt_descriptor]
+
+; jump to pm
+cli
+mov eax, cr0
+or eax, 1
+mov cr0, eax
+jmp 0x08:pm_start
+
+error:
+ mov al, 'e'
+ int 0x10
+ mov al, 'r'
+ int 0x10
+ mov al, 'r'
+ int 0x10
+ mov al, 'o'
+ int 0x10
+ mov al, 'r'
+ int 0x10
+ jmp $
+
+gdt_data:
+ ; null segment
+ dq 0x0000000000000000
+ ; code segment
+ dw 0xFFFF
+ dw 0x0000
+
+ db 0x00
+ db 10011010b ; 32-bit code segment, present, ring 0
+ db 11001111b ; limit bits 16-19
+ db 0x00
+
+ ; data segment
+ dw 0xFFFF
+ dw 0x0000
+
+ db 0x00
+ db 10010010b ; 32-bit data segment, present, ring 0
+ db 11001111b ; limit bits 16-19
+ db 0x00
+
+gdt_descriptor:
+ dw $ - gdt_data - 1 ; size
+ dd gdt_data ; start
+
+[bits 32]
+
+; entry point
+pm_start:
+ ; data segment registers
+ mov ax, 0x10
+ mov ds, ax
+ mov es, ax
+ mov fs, ax
+ mov gs, ax
+ mov ss, ax
+ mov esp, 0x80000
+
+ ; TODO actually configure COM1
+ mov dx, 0x3F8 ; COM1
+ mov al, 'P'
+ out dx, al
+ mov al, 'r'
+ out dx, al
+ mov al, 'o'
+ out dx, al
+ mov al, 't'
+ out dx, al
+ mov al, 'e'
+ out dx, al
+ mov al, 'c'
+ out dx, al
+ mov al, 't'
+ out dx, al
+ mov al, 'e'
+ out dx, al
+ mov al, 'd'
+ out dx, al
+ mov al, 0x0D
+ out dx, al
+ mov al, 0x0A
+ out dx, al
+
+ jmp 0x08:0x10000
+
+pm_error:
+ mov al, 'p'
+ out dx, al
+ mov al, 'm'
+ out dx, al
+ mov al, 'e'
+ out dx, al
+ mov al, 'r'
+ out dx, al
+ mov al, 'r'
+ out dx, al
+ mov al, 'o'
+ out dx, al
+ mov al, 'r'
+ out dx, al
+ jmp $
+
+times 510-($-$$) db 0 ; 2 bytes less now
+db 0x55
+db 0xAA