]> git.dujemihanovic.xyz Git - nameless-os.git/blob - boot/x86/stage3/loader.s
Load ELF kernel instead of flat binary
[nameless-os.git] / boot / x86 / stage3 / loader.s
1 bits 16
2 cpu 686
3
4 extern run_kernel
5
6 section .text
7 %include "../fat32/fat32-structs.s"
8
9 %macro print 1
10 push si
11 mov si, %1
12 call print_str
13 pop si
14 %endmacro
15
16 extern __STACK_BOTTOM__
17
18 global _start
19 _start:
20 mov sp, __STACK_BOTTOM__
21 mov [BOOT_DRIVE], dl
22 call enable_unreal
23 print begin
24 call check_a20
25 jc .a20_enabled
26 call enable_a20
27 jnc .a20_enable_fail
28 .a20_enabled:
29 print a20_enabled
30 call get_1st_data_sec
31 mov ax, 0x1000
32 mov es, ax
33 mov eax, BPB_RootClus
34 xor di, di
35 call read_cluster_chain
36 jc critical_error
37
38 push cx
39 push si
40 .find_kernel:
41 mov si, kernel_name
42 cmp byte [es:di], 0 ; end of root directory
43 je .kernel_missing
44 cmp byte [es:di], 0xe5 ; unused entry
45 je .increment
46 mov cx, 11
47 push si
48 push di
49 repe cmpsb
50 pop di
51 pop si
52 je .kernel_found
53 .increment:
54 add di, 32
55 jno .find_kernel
56 mov bx, es
57 add bx, 0x1000
58 mov es, bx
59 jmp .find_kernel
60 .kernel_found:
61 pop si
62 pop cx
63 print kernel_found
64 mov eax, [es:di+dir_entry.filesize]
65 mov [KERNEL_SIZE], eax
66 mov ax, [es:di+dir_entry.firstclushi]
67 shl eax, 16
68 mov ax, [es:di+dir_entry.firstcluslo]
69 call print_dword
70 mov edi, 0x100000
71 print kernel_loading
72 call read_clus_chain_unreal ; load kernel
73 print kernel_loaded
74
75 call get_e820_map
76 mov ebx, ecx
77 mov eax, 24
78 mul ecx
79 add eax, 20
80 sub sp, ax
81
82 cli
83 lgdt [gdt]
84 mov eax, cr0
85 or al, 1
86 mov cr0, eax
87 jmp 0x8:in_protected
88 .kernel_missing:
89 print missing_kernel
90 jmp .halt
91
92 .a20_enable_fail:
93 print a20_fail
94 .halt:
95 hlt
96 jmp $-1
97
98 ; eax - start cluster
99 ; edi - address to load to
100 read_clus_chain_unreal:
101 push eax
102 push edi
103 .loop:
104 push di
105 push es
106 push ax
107 xor di, di
108 mov ax, 0x1000
109 mov es, ax
110 pop ax
111 call read_cluster
112 pop es
113 pop di
114 jc .done
115 push esi
116 push eax
117 push ebx
118 push ecx
119 mov esi, 0x10000
120 xor ebx, ebx
121 movzx eax, word BPB_BytsPerSec
122 movzx bx, byte BPB_SecPerClus
123 mul ebx
124 mov ecx, eax
125 call memcpy
126 add edi, ecx
127 pop ecx
128 pop ebx
129 pop eax
130 pop esi
131 cmp eax, 0xffffff7
132 jl .loop
133 .done:
134 pop edi
135 pop eax
136 ret
137
138 ; esi - copy from
139 ; edi - copy to
140 ; ecx - bytes to copy
141 memcpy:
142 push esi
143 push edi
144 push ecx
145 push dx
146
147 .loop:
148 mov dl, [esi]
149 mov [edi], dl
150 dec ecx
151 cmp ecx, 0
152 je .done
153 inc esi
154 inc edi
155 jmp .loop
156 .done:
157 pop dx
158 pop ecx
159 pop edi
160 pop esi
161 ret
162
163 %include "unreal.s"
164 %include "a20.s"
165 %include "../fat32/fat32.s"
166 %include "gdt.s"
167 %include "print.s"
168 %include "e820.s"
169
170 bits 32
171 section .text
172 in_protected:
173 mov ax, 0x10
174 mov ds, ax
175 mov es, ax
176 mov ss, ax
177 mov fs, ax
178 mov gs, ax
179
180 push dword [KERNEL_SIZE]
181 push 0x100000
182 push ebx
183 push edi
184 call run_kernel
185
186 section .bss
187 KERNEL_SIZE: resd 1
188
189 section .rodata
190
191 kernel_name: db "KERNEL ELF"
192 begin: db "Nameless Bootloader revision ", GIT_REVISION, 0xd, 0xa, 0
193 a20_enabled: db "A20 has been enabled", 0xd, 0xa, "Searching for kernel...", 0xd, 0xa, 0
194 a20_fail: db "Failed to enable A20, giving up!", 0xd, 0xa, 0
195 crit_err: db "A critical error occurred, dumping registers now: ", 0xd, 0xa, 0
196 kernel_found: db "Found kernel at cluster ", 0
197 kernel_loading: db 0xd, 0xa, "Loading kernel...", 0xd, 0xa, 0
198 kernel_loaded: db "Kernel successfully loaded.", 0xd, 0xa, "Setting up kernel environment and running kernel...", 0xd, 0xa, 0
199 missing_kernel: db "Could not find KERNEL.ELF", 0xd, 0xa, 0
200 eax_s: db "EAX: ", 0
201 ebx_s: db "EBX: ", 0
202 ecx_s: db "ECX: ", 0
203 edx_s: db "EDX: ", 0
204 esi_s: db "ESI: ", 0
205 edi_s: db "EDI: ", 0
206 cs_s: db "CS: ", 0
207 ds_s: db "DS: ", 0
208 es_s: db "ES: ", 0
209 ss_s: db "SS: ", 0
210 space: db " ", 0
211 hex_delm: db "0x", 0
212 newline: db 0xd, 0xa, 0