summaryrefslogtreecommitdiff
path: root/bootloader.asm
diff options
context:
space:
mode:
authorCarlos Maiolino <[email protected]>2025-07-17 19:20:25 +0200
committerCarlos Maiolino <[email protected]>2025-07-17 19:20:25 +0200
commitc91590e59f6f41b7316edd8587542ed24d0fdb22 (patch)
tree08e44bc42edfde59f69edc8bd96b4daaa848bb26 /bootloader.asm
parent92ee05c13b207c953e7d2fb0217caa3344318467 (diff)
Setup GDT and load protected mode
Create a GDT table and use it to switch CPU into protected mode. This also gets rid of the print routines. Giving we won't have access to the BIOS interrupts once we switch the CPU to protected mode, they are pointless. Signed-off-by: Carlos Maiolino <[email protected]>
Diffstat (limited to 'bootloader.asm')
-rw-r--r--bootloader.asm86
1 files changed, 64 insertions, 22 deletions
diff --git a/bootloader.asm b/bootloader.asm
index bf3afb4..f42e702 100644
--- a/bootloader.asm
+++ b/bootloader.asm
@@ -1,6 +1,8 @@
-ORG 0x0
+ORG 0x7c00
BITS 16
+CODE_SEG equ gdt_code - gdt_start ; 0x8
+DATA_SEG equ gdt_data - gdt_start ; 0x10
_start:
jmp short start
nop
@@ -10,42 +12,82 @@ _start:
times 33 db 0
start:
- ; Set CS to 0x07c0 with label step2 as its beginning offset
- jmp 0x07c0:step2
+ ; Set CS to 0 with label step2 as its beginning offset
+ jmp 0:step2
step2:
; Setup segments
cli ; Disable interrupts
- mov ax, 0x07c0
+ mov ax, 0
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
sti ; Enable interrupts
- jmp $
+.load_protected:
+ cli
+ lgdt[gdt_table]
+ mov eax, cr0
+ or eax, 0x1
+ mov cr0, eax
+ jmp CODE_SEG:start_32
+
+; GDT table description
+gdt_start:
+gdt_null: ; First segment Descriptor is always 0
+ dd 0x0
+ dd 0x0
+
+;Second segment descriptor... Code segment - 0x8
+gdt_code:
+ dw 0xffff ; Segment limit 0-15
+ dw 0 ; Base address 0-15
+ db 0 ; Base 16-23
+ db 0x9a ; Access byte field 0b10011010
+
+ ; We don't have a 4 bits type, so use a byte type
+ ; to set both Segment limit high bits and flags
+
+ db 11001111b ; Segment limit 16-19
+ ; Flags 0-3
+ db 0 ; Base address high bits 24-31
+
+;Second segment descriptor... Data segment - 0x10
+gdt_data:
+ dw 0xffff ; Segment limit 0-15
+ dw 0 ; Base address 0-15
+ db 0 ; Base 16-23
+ db 0x92 ; Access byte field 0b10010010
+ db 11001111b ; Segment limit 16-19
+ ; Flags 0-3
+ db 0 ; Base address high bits 24-31
+gdt_end:
+
+gdt_table:
+ dw gdt_end - gdt_start - 1
+ dd gdt_start
-; Message Print routines
-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
+[BITS 32]
+
+; No access to BIOS from now on....
+start_32:
+ ; Set all segments to the same as the DATA_SEG
+ mov ax, DATA_SEG
+ mov ds, ax
+ mov es, ax
+ mov fs, ax
+ mov gs, ax
+ mov ss, ax
+
+ ; Set the stack pointer and base pointer further in mem
+ mov ebp, 0x00200000
+ mov esp, ebp
+ jmp $
; Fill in to the end and add bootloader signature
times 510 - ($ - $$) db 0