summaryrefslogtreecommitdiff
path: root/boot1/boot1.asm
blob: 59c0dd0d72ab532caee08ff4f503d6c22bef9f57 (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
101
102
103
104
105
106
107
108
109
110
111
112
113
[BITS 16]
[ORG 0]

START:
        ;; initialize segments
        mov	ax, BOOT1SEG
        mov	ds, ax
        mov es, ax
        mov ss, ax

        ;; make sure we are running on a 386+

        ;; while we're still in real mode, detect system hardware via BIOS
        call PROBE_VIDEO
        call GET_EQUIPMENT_LIST
        call GET_MEMORY_SIZE
        call GET_TIME
        
        ;; switch the processor into protected mode, keep ints disabled
        cli
        lidt [IDT_Pointer]
        lgdt [GDT_Pointer]
        call ENABLE_A20
        mov ax, 0x01
        lmsw ax

        ;; Jump to 32 bit code, this completes the transition to protected mode
        db 0x66			; operand size override prefix
        db 0xea			; jmp opcode
        dd (BOOT1SEG<<4) + setup_32 ; want to jump here
        dw (1<<3)		; ...in the kernel code segment

[BITS 32]
setup_32:
        ;; set up data segment registers
        mov	ax, (2<<3)
        mov	ds, ax
        mov	es, ax
        mov	fs, ax
        mov	gs, ax
        mov	ss, ax

        ;; create an initial stack
        mov esp, KERN_STACK + 4096
        mov ebp, esp

        ;; create a stack frame, pass ptr to hardware block as param
        mov eax, (BOOT1SEG<<4)+BIOS_HARDWARE_BLOCK
        push eax
        push (BOOT1SEG<<4)+.HANG
        jmp (1<<3):0x00010000     ; entry point of kernel

.HANG:  
        nop
        jmp .HANG


; Setup data
; ----------------------------------------------------------------------

BIOS_HARDWARE_BLOCK:
bDisplayType            db      0x00
bFontSize               db      0x00
wEquipmentBitvector     dw      0x0000
wMemorySize             dw      0x0000
wSystemClock            dw      0x0000        
        
NUM_GDT_ENTRIES equ 3           ; number of entries in GDT
GDT_ENTRY_SZ equ 8              ; size of a single GDT entry

align 8, db 0
GDT:
	; Descriptor 0 is not used
	dw 0
	dw 0
	dw 0
	dw 0

	; Descriptor 1: kernel code segment
	dw 0xFFFF	; bytes 0 and 1 of segment size
	dw 0x0000	; bytes 0 and 1 of segment base address
	db 0x00		; byte 2 of segment base address
	db 0x9A		; present, DPL=0, non-system, code, non-conforming,
			;   readable, not accessed
	db 0xCF		; granularity=page, 32 bit code, upper nibble of size
	db 0x00		; byte 3 of segment base address

	; Descriptor 2: kernel data and stack segment
	; NOTE: what Intel calls an "expand-up" segment
	; actually means that the stack will grow DOWN,
	; towards lower memory.  So, we can use this descriptor
	; for both data and stack references.
	dw 0xFFFF	; bytes 0 and 1 of segment size
	dw 0x0000	; bytes 0 and 1 of segment base address
	db 0x00		; byte 2 of segment base address
	db 0x92		; present, DPL=0, non-system, data, expand-up,
			;   writable, not accessed
	db 0xCF		; granularity=page, big, upper nibble of size
	db 0x00		; byte 3 of segment base address

GDT_Pointer:
	dw NUM_GDT_ENTRIES*GDT_ENTRY_SZ	; limit
	dd (BOOT1SEG<<4) + GDT		; base address

IDT_Pointer:
	dw 0
	dd 00

%include "defs.asm"
%include "hardware.asm"
%include "video.asm"