summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md21
-rw-r--r--boot.asm162
-rw-r--r--kernel.asm23
-rw-r--r--package.nix12
4 files changed, 197 insertions, 21 deletions
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..74acca9
--- /dev/null
+++ b/README.md
@@ -0,0 +1,21 @@
+# bootler
+
+hobby bootloader written in asm. It's just for playing around... for now :p
+
+### memory map
+
++------ 0x00100000 ------+
+| hardware, bios stuff |
++------ 0x00080000 ------+
+| pm stack (esp) | from boot.asm
++------ 0x00010200 ------+
+| kernel (kernel.asm) |
++------ 0x00010000 ------+
+| free |
++------ 0x00007E00 ------+
+| bootloader (boot.asm) |
++------ 0x00007C00 ------+
+| real mode stack (sp) | from boot.asm
++------ 0x00000500 ------+
+| bios stuff |
++------ 0x00000000 ------+
diff --git a/boot.asm b/boot.asm
index b5c50cb..bb852ef 100644
--- a/boot.asm
+++ b/boot.asm
@@ -1,28 +1,158 @@
-; yoinked from osdev.org
-mov ax, 0x07C0
+; 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
-mov si, msg
-cld
+; 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
-ch_loop:
- lodsb
- ; hang if at null terminator
- or al, al
- jz hang
+; load gdt
+lgdt [gdt_descriptor]
- ; BIOS interrupt prints al
- mov ah, 0x0E
- mov bh, 0
+; 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]
- jmp ch_loop
+; 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
-hang:
- jmp hang
+ ; 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
-msg db 'Hello World', 0
+ 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
diff --git a/kernel.asm b/kernel.asm
new file mode 100644
index 0000000..23c0d5d
--- /dev/null
+++ b/kernel.asm
@@ -0,0 +1,23 @@
+[bits 32]
+
+mov al, 'K'
+out dx, al
+mov al, 'e'
+out dx, al
+mov al, 'r'
+out dx, al
+mov al, 'n'
+out dx, al
+mov al, 'e'
+out dx, al
+mov al, 'l'
+out dx, al
+mov al, 0x0D
+out dx, al
+mov al, 0x0A
+out dx, al
+mov al, 0x00
+out dx, al
+jmp $
+
+times 512-($-$$) db 0
diff --git a/package.nix b/package.nix
index 150b46b..1cef31a 100644
--- a/package.nix
+++ b/package.nix
@@ -11,7 +11,12 @@ in
version = "0.1.0";
src = ./.;
buildPhase = ''
- ${nasm}/bin/nasm boot.asm -o ${bootImg}
+ ${nasm}/bin/nasm boot.asm -o boot.bin
+ ${nasm}/bin/nasm kernel.asm -o kernel.bin
+
+ dd if=/dev/zero of=${bootImg} bs=512 count=2
+ dd if=boot.bin of=${bootImg} conv=notrunc
+ dd if=kernel.bin of=${bootImg} bs=512 seek=1 conv=notrunc
'';
installPhase = ''
mkdir -p $out/bin
@@ -26,13 +31,10 @@ in
cp $(echo $out)/bin/${bootImg} ./.bootler/${bootImg}
chmod a+w ./.bootler/${bootImg}
- echo "press any key to continue. Qemu will clear the screen..."
- read -s -n 1
-
# run image
${qemu}/bin/qemu-system-x86_64 \
-nographic \
- -hda ./.bootler/${bootImg}
+ -drive file=./.bootler/${bootImg},format=raw,index=0,media=disk
# clean up
rm ./.bootler -r