summaryrefslogtreecommitdiff
path: root/src/boot/bootloader.asm
blob: fc17af879457d9b2695e04abea6fd226e4465ec0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
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

; 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 0 with label step2 as its beginning offset
	jmp 0:step2

step2:
	; Setup segments

	cli		; Disable interrupts
	mov ax, 0
	mov ds, ax
	mov es, ax
	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

.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


[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

	; Enable A20 line
	in al, 0x92
	or al, 2
	out 0x92, al

	jmp $

; Fill in to the end and add bootloader signature
	times 510 - ($ - $$) db 0
	dw 0xAA55