summaryrefslogtreecommitdiffstats
path: root/pmgdt.s
blob: f71cb361264eedcb444e8d10b47a2974b0c4668d (plain) (blame)
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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
global _main
global _pm_bootstrap
global gdt_start
global gdt_null
global gdt_code
global gdt_data
global gdt_user_code
global gdt_user_data
global gdt_end
global gdt_descriptor

[bits 16]

_main:
_pm_bootstrap:
    mov     dx, msg_title
    call    putstr
    mov     dx, msg_ldgdt
    call    putstr

    cli
    lgdt    [gdt_descriptor]

    in      al, 0x92
    or      al, 2
    out     0x92, al

    mov     eax, cr0
    or      eax, 0x1
    mov     cr0, eax

    jmp     dword CODE_SEGMENT:pmkernel

msg_title: db 13, 10, 'YOTOS protected mode loader', 13, 10, 0
msg_ldgdt: db 'Loading Global Descriptor Table (GDT)... ', 0

putstr:             ; dx=argument
    mov     cx, bx  ; we must preserve bx
putstr_start:
    mov     bx, dx  ; [dx] is not a effective address
    mov     al, byte [bx]
    test    al, al
    jz      putstr_end
    mov     ah, 0x0e
    mov     bx, 0x0007
    int     0x10
    inc     dx
    jmp     putstr_start
putstr_end:
    mov     bx, cx
    ret



; GDT entry


gdt_start:

gdt_null:   ; null descriptor
    dd  0x00
    dd  0x00

gdt_code:   ; code segment descriptor
    dw  0xffff      ; segment limit (bits 0-15)
    dw  0x0         ; base (bits 0-15)
    db  0x0         ; base (bits 16-23)

    db  10011010b   ; (present) 1,
                    ; (privilege) 00,
                    ; (descriptor type) 1,
                    ; type = 
                    ; (code) 1, 
                    ; (conforming) 0, 
                    ; (readable) 1,
                    ; (accessed) 0

    db  11001111b   ; (granularity) 1,
                    ; (32-bit default) 1,
                    ; (64-bit segment) 0, 
                    ; (AVL) 0,
                    ; segment limit (bits 16-19)
    
    db  0x0         ; base (bits 24-31)

gdt_data:   ; data segment descriptor
    dw  0xffff      ; segment limit (bits 0-15)
    dw  0x0         ; base (bits 0-15)
    db  0x0         ; base (bits 16-23)

    db  10010010b   ; (present) 1,
                    ; (privilege) 00,
                    ; (descriptor type) 1,
                    ; type = 
                    ; (code) 0, 
                    ; (expand down) 0, 
                    ; (writable) 1,
                    ; (accessed) 0

    db  11001111b   ; (granularity) 1,
                    ; (32-bit default) 1,
                    ; (64-bit segment) 0, 
                    ; (AVL) 0,
                    ; segment limit (bits 16-19)
    
    db  0x0         ; base (bits 24-31)

gdt_user_code:  ; user mode code segment descriptor
    dw  0xffff      
    dw  0x0         
    db  0x0         
    db  11111010b   
    db  11001111b   
    db  0x0         

gdt_user_data:  ; user mode data segment descriptor
    dw  0xffff
    dw  0x0
    db  0x0
    db  11110010b
    db  11001111b  
    db  0x0  

gdt_end:

gdt_descriptor:
    dw  gdt_end - gdt_start - 1
    dd  load_offset + gdt_start

CODE_SEGMENT    equ     gdt_code - gdt_start
DATA_SEGMENT    equ     gdt_data - gdt_start