]> git.dujemihanovic.xyz Git - nameless-os.git/blob - boot/x86/protected.s
kprint can accept a const string
[nameless-os.git] / boot / x86 / protected.s
1 ; Everything between real mode and the C kernel
2
3 bits 16
4
5 switch_to_pm
6 mov bx, 0B800h
7 mov es, bx ; set extra segment to starting address of video RAM
8 mov byte [es:0], 'L' ; print an L to screen, to let us know that we actually got here
9
10 cli ; disable interrupts
11 xor ax, ax ; clear accumulator
12 mov ds, ax ; clear data segment, this makes sure the next instruction reads from the right place
13 lgdt [gdt_desc] ; load the Global Descriptor Table
14
15 mov eax, cr0 ; move Control Register 0 to accumulator
16 or eax, 1 ; flip the bit which controls memory protection
17 mov cr0, eax ; move the accumulator back to CR0
18 jmp CODE_SEG:protected ; not quite there yet, need to do a far jump to clean the pipeline from any 16-bit instructions
19 ; note that the jump does not have to be physically far away, it just needs to use a segmented address
20
21 bits 32 ; we are finally in 32-bit mode
22 protected
23 mov ax, DATA_SEG ; put the selector for the data segment in the accumulator
24 ; in real mode, segmentation works by taking one of these segment registers, shifting it right by 4 bits or 1 hex digit
25 ; and then adding a 16-bit offset to form a 20-bit address
26 ; example: 1234h:5678h
27 ; 1234h is shifted to 12340h, 12340h + 5678h is 179B8h
28 ; in 32-bit protected mode, these segment registers do not hold the segment address itself, but a selector in the GDT
29 ; so we have to update the segment registers accordingly
30 mov ds, ax
31 mov ss, ax
32 mov es, ax
33 mov fs, ax
34 mov gs, ax
35
36 ; reinitialize the stack at a safe location
37 mov ebp, 090000h
38 mov esp, ebp
39
40 ; print a string to let us know that we survived the switch
41 mov ebx, pm_success
42 call pmprint
43
44 ; transfer control to the kernel
45 call KERNEL_OFFSET
46
47 ; above call should not return in normal circumstances, but if it does hang forever
48 jmp $
49
50 pmprint
51 pusha ; save registers to stack
52 mov edx, video_memory ; initialize dx with location of VRAM
53
54 .loop
55 mov al, [ebx] ; read next char and put it in al
56 mov ah, 00000111b ; puts the VGA text mode color white on black into ah
57
58 cmp al, 0 ; if the next character is null, we reached end of string
59 je .done ; so return the instruction
60
61 mov [edx], al ; otherwise put the next character in the video memory
62 mov [edx+1], ah ; do the same for its color
63
64 inc ebx ; point to next character in string
65 add edx, 2 ; point to next character in VRAM
66
67 jmp .loop ; go back to the loop
68
69 .done
70 popa ; restore registers from stack
71 ret ; return
72
73 pm_success db "Now in protected mode", 0
74 video_memory equ 0B8000h
75
76 ; the actual Global Descriptor Table
77 ; refer to Volume 3, Chapter 2, 2.1.1 of Intel's 64 and IA-32 Software Developer's Manual for more info
78 gdt_start
79 null_seg
80 dq 0
81 code_seg
82 dw 0FFFFh
83 dw 0
84 db 0
85 db 10011010b
86 db 11001111b
87 db 0
88 data_seg
89 dw 0FFFFh
90 dw 0
91 db 0
92 db 10010010b
93 db 11001111b
94 db 0
95 gdt_end
96 gdt_desc
97 dw gdt_end - gdt_start - 1
98 dd gdt_start
99 CODE_SEG equ code_seg - gdt_start
100 DATA_SEG equ data_seg - gdt_start
101