]> git.dujemihanovic.xyz Git - nameless-os.git/blob - boot/x86/protected.s
966390af1a8dad8101595cfa6ed045159dc82636
[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 ; transfer control to the kernel
41 call KERNEL_OFFSET
42
43 ; above call should not return in normal circumstances, but if it does hang forever
44 jmp $
45
46 pmprint
47 pusha ; save registers to stack
48 mov edx, video_memory ; initialize dx with location of VRAM
49
50 .loop
51 mov al, [ebx] ; read next char and put it in al
52 mov ah, 00000111b ; puts the VGA text mode color white on black into ah
53
54 cmp al, 0 ; if the next character is null, we reached end of string
55 je .done ; so return the instruction
56
57 mov [edx], al ; otherwise put the next character in the video memory
58 mov [edx+1], ah ; do the same for its color
59
60 inc ebx ; point to next character in string
61 add edx, 2 ; point to next character in VRAM
62
63 jmp .loop ; go back to the loop
64
65 .done
66 popa ; restore registers from stack
67 ret ; return
68
69 video_memory equ 0B8000h
70
71 ; the actual Global Descriptor Table
72 ; refer to Volume 3, Chapter 2, 2.1.1 of Intel's 64 and IA-32 Software Developer's Manual for more info
73 gdt_start
74 null_seg
75 dq 0
76 code_seg
77 dw 0FFFFh
78 dw 0
79 db 0
80 db 10011010b
81 db 11001111b
82 db 0
83 data_seg
84 dw 0FFFFh
85 dw 0
86 db 0
87 db 10010010b
88 db 11001111b
89 db 0
90 gdt_end
91 gdt_desc
92 dw gdt_end - gdt_start - 1
93 dd gdt_start
94 CODE_SEG equ code_seg - gdt_start
95 DATA_SEG equ data_seg - gdt_start
96