1 ;*****************************************************
2 ; $Id: loader.s,v 1.1 2002/11/25 02:07:53 rminnich Exp $
3 ;*****************************************************
5 ; code it is loaded into memory at 0x7C00
6 ;*****************************************************
9 ;*****************************************************
10 ; A) setup GDT, so that we do not depend on program
11 ; that loaded us for GDT.
12 ; Ex: LinuxBIOS and EtherBOOT use different GDT's.
14 ;-----------------------------------------------------
19 ;-----------------------------------------------------
22 lgdt [0x7C00+protected_gdt]
24 ;-----------------------------------------------------
27 jmp 0x08:0x7C00+newpgdt
31 ;-----------------------------------------------------
32 ; III) setup all other segments
41 ;-----------------------------------------------------
47 ;*****************************************************
50 ;*****************************************************
51 ; B) shadow - ON (enable/read/write)
61 ;*****************************************************
64 ;*****************************************************
65 ; C) copy -- boch bios
70 ; source - 0x8000 ( 0x7C00+0x400 = 0x8000 )
71 mov ax, #0x10 ; src-segment - 2nd entry in GDT
73 mov eax, #0x8000 ; src-offset - 0x8000
76 ; destination - 0xE0000
77 mov ax, #0x10 ; dst-segment - 2nd entry in GDT
79 mov eax, #0xF0000 ; dst-offset - 0xF0000
82 ; clear direction flag
89 ;*****************************************************
92 ;*****************************************************
93 ; X) copy -- LinuxBIOS table into safe place.
96 ;; Q1 : what is the size of table.
97 ;; Q2 : where to copy?
99 ;*****************************************************
102 ;*****************************************************
103 ; E) shadow - OFF (write)
109 ;mov eax, #0xFFFFFFFF
114 ;*****************************************************
117 ;*****************************************************
118 ; F) do a little prep work.
120 ;-----------------------------------------------------
123 ; if you disable cache, GRUB's GFX mode will be VERY slow.
132 ;-----------------------------------------------------
134 ; clear the "E" (0x800) and "FE" (0x400) flags in
135 ; IA32_MTRRdefType register (0x2FF)
137 ;-----------------------
141 ; select either of the two below
142 ; depending on if your compiler suports
149 ;and eax, #0xFFFFF3FF
151 ; select either of the two below
152 ; depending on if your compiler suports
157 ;-----------------------
158 ;; This is what PC BIOS is setting. -- P6STMT.
159 ; add VIDEO BIOS cacheable!!!!
160 ;-----------------------
166 ;-----------------------
172 ;-----------------------
174 ;-----------------------------------------------------
175 ; III) tell BOCHS' BIOS we want to boot from hdd.
178 ; In future there will be 'fd failover'option in bochs.
180 mov al, #0x3d ;; cmos_reg
182 mov al, #0x02 ;; val (hdd)
185 ;-----------------------------------------------------
186 ; IV) tell BOCHS' BIOS length of our mem block @ 1mb.
187 ; This is for Int 15 / EAX=E820
188 ; 119mb = 0x77 00 00 00
189 ; (this is for 128mb of ram)
190 ; (FIXME: this value is currently hard coded)
191 ; (it should be being passed from LinuxBIOS )
195 ; 06 80 = 0770 - 00F0 << ALT (for unpatched bochs)
197 ; for P6STMT - 10kb less ram
199 ; 07 6F - 00 F0 = 06 7F
201 mov al, #0x35 ;; cmos_reg
206 mov al, #0x34 ;; cmos_reg
211 mov al, #0x31 ;; cmos_reg
216 mov al, #0x30 ;; cmos_reg
221 ;-----------------------------------------------------
222 ; V) tell BOCHS' BIOS we want to have LBA translation.
227 ; In future there will be 'fd failover'option in bochs.
229 mov al, #0x39 ;; cmos_reg
231 mov al, #0x01 ;; val (LBA)
234 ;*****************************************************
237 ;*****************************************************
238 ; G) the switch -- protected to real mode
241 ; (8-14) 8.8.2 Switching Back to Real-Address Mode
243 ;=====================================================
244 ; 1) disable interrupts
248 ;=====================================================
250 ;=====================================================
253 ;not enabled, so not applicable.
255 ;=====================================================
256 ; 3) setup CS segment limit (64kb)
259 lgdt [0x7C00+new_gdt]
261 ;-----------------------------------------------------
264 jmp 0x08:0x7C00+new64lim
268 ;=====================================================
270 ;=====================================================
271 ; 4) setup all other segments
280 ;=====================================================
282 ;=====================================================
286 ; set up Real Mode IDT table (0...3FF)
288 ; for BOCH's BIOS the address 0xF000:0xFF53
289 ; cantains value 0xCF which is IRET opcode.
292 mov cx, #0xFF ;1024 bytes(255 interrupts)(4*255=0x3FF)
294 ; destination - 0x00000 = ES:EDI
295 mov ax, #0x10 ; dst-segment - 2nd entry in GDT
297 mov eax, #0x00000 ; dst-offset - 0x00000
300 ; data to store -- 0xF000:FF53
303 ; clear direction flag
310 ;-----------------------------------------------------
312 ; load interrupt descriptor table
314 lidt [0x7C00+new_idt]
316 ;=====================================================
319 ;=====================================================
320 ; 6) clear the PE flag in CR0 register.
323 ; switch to 16 bit segments
331 ;-----------------------------------------------------
334 ; switch to 16 bit CS
336 jmp 0x018:0x7C00+new16bit
342 ;-----------------------------------------------------
350 mov cr0, eax ;switch to RM
352 ;=====================================================
355 ;=====================================================
356 ; 7) far jump -- (to real mode address)
358 jmp 0x0:0x7C00+realcs
362 ;=====================================================
363 ; 8) set all segment registers to 0's
372 ;=====================================================
373 ; 9) re-enable interrupts
377 ;*****************************************************
380 ;*****************************************************
386 ;*****************************************************
387 ;*****************************************************
392 ;*****************************************************
393 ;*****************************************************
398 dw 0x03ff ;; limit 15:00
399 dw 0x0000 ;; base 15:00
400 dw 0x0000 ;; base 23:16
403 dw 0x0028 ;; limit 15:00
404 dw 0x7C00+new_gdt_table ;; base 15:00
405 dw 0x0000 ;; base 23:16
408 dw 0x0018 ;; limit 15:00
409 dw 0x7C00+pmode_gdt_table ;; base 15:00
410 dw 0x0000 ;; base 23:16
412 ;-----------------------------------------------------
436 ;-------------------------
452 ;*****************************************************
453 ;*****************************************************
454 ; the file size must be 1024 bytes.
461 ;*****************************************************