diff options
Diffstat (limited to 'util/ADLO/loader.s')
-rw-r--r-- | util/ADLO/loader.s | 461 |
1 files changed, 461 insertions, 0 deletions
diff --git a/util/ADLO/loader.s b/util/ADLO/loader.s new file mode 100644 index 0000000000..48b6ec3299 --- /dev/null +++ b/util/ADLO/loader.s @@ -0,0 +1,461 @@ +;***************************************************** +; $Id: loader.s,v 1.1 2002/11/25 02:07:53 rminnich Exp $ +;***************************************************** +USE32 +; code it is loaded into memory at 0x7C00 +;***************************************************** +nop +nop +;***************************************************** +; A) setup GDT, so that we do not depend on program +; that loaded us for GDT. +; Ex: LinuxBIOS and EtherBOOT use different GDT's. + +;----------------------------------------------------- +; 0) + +cli + +;----------------------------------------------------- +; I) + +lgdt [0x7C00+protected_gdt] + +;----------------------------------------------------- +; II) setup CS + +jmp 0x08:0x7C00+newpgdt + +newpgdt: nop + +;----------------------------------------------------- +; III) setup all other segments + +mov ax, #0x10 +mov ss, ax +mov ds, ax +mov es, ax +mov fs, ax +mov gs, ax + +;----------------------------------------------------- +; IV) + +; not now +;sti + +;***************************************************** +nop +nop +;***************************************************** +; B) shadow - ON (enable/read/write) + +mov eax, #0x80000070 +mov dx, #0x0cf8 +out dx, eax + +mov eax, #0xFFFFFFFF +mov dx, #0x0cfc +out dx, eax + +;***************************************************** +nop +nop +;***************************************************** +; C) copy -- boch bios + +; counter - 64kb. +mov ecx, #0x10000 + +; source - 0x8000 ( 0x7C00+0x400 = 0x8000 ) +mov ax, #0x10 ; src-segment - 2nd entry in GDT +mov ds, ax +mov eax, #0x8000 ; src-offset - 0x8000 +mov esi, eax + +; destination - 0xE0000 +mov ax, #0x10 ; dst-segment - 2nd entry in GDT +mov es, ax +mov eax, #0xF0000 ; dst-offset - 0xF0000 +mov edi, eax + +; clear direction flag +cld + +; the copy +rep + movsb + +;***************************************************** +nop +nop +;***************************************************** +; X) copy -- LinuxBIOS table into safe place. + + ;; TODO. + ;; Q1 : what is the size of table. + ;; Q2 : where to copy? + +;***************************************************** +nop +nop +;***************************************************** +; E) shadow - OFF (write) + +mov eax, #0x80000070 +mov dx, #0x0cf8 +out dx, eax + +;mov eax, #0xFFFFFFFF +mov eax, #0x0000FFFF +mov dx, #0x0cfc +out dx, eax + +;***************************************************** +nop +nop +;***************************************************** +; F) do a little prep work. + +;----------------------------------------------------- +; I) disable cache + +; if you disable cache, GRUB's GFX mode will be VERY slow. +; so DO NOT DISABLE + +;mov eax, cr0 +;or eax, #0x60000000 +;wbinvd +;mov cr0, eax +;wbinvd + +;----------------------------------------------------- +; II) disable MTRR +; clear the "E" (0x800) and "FE" (0x400) flags in +; IA32_MTRRdefType register (0x2FF) + +;----------------------- + +;mov ECX,#0x2FF + +; select either of the two below +; depending on if your compiler suports +; {RD,WR}MSR or not +;rdmsr +; .byte 0x0F, 0x32 + +;xor edx, edx +; xor eax, eax +;and eax, #0xFFFFF3FF + +; select either of the two below +; depending on if your compiler suports +; {RD,WR}MSR or not +;wrmsr +; .byte 0x0F, 0x30 + +;----------------------- +;; This is what PC BIOS is setting. -- P6STMT. +; add VIDEO BIOS cacheable!!!! +;----------------------- +; Fixed Range C0--C8 +;mov ECX,#0x268 +;mov EDX,#0x05050505 +;mov EAX,#0x05050505 +;wrmsr +;----------------------- +; Fixed Range C8--CF +;mov ECX,#0x269 +;mov EDX,#0x0 +;mov EAX,#0x05050505 +;wrmsr +;----------------------- + +;----------------------------------------------------- +; III) tell BOCHS' BIOS we want to boot from hdd. +; 0x00 - floppy +; 0x02 - hdd +; In future there will be 'fd failover'option in bochs. + +mov al, #0x3d ;; cmos_reg +out 0x70, al +mov al, #0x02 ;; val (hdd) +out 0x71, al + +;----------------------------------------------------- +; IV) tell BOCHS' BIOS length of our mem block @ 1mb. +; This is for Int 15 / EAX=E820 +; 119mb = 0x77 00 00 00 +; (this is for 128mb of ram) +; (FIXME: this value is currently hard coded) +; (it should be being passed from LinuxBIOS ) + +; for WinFast 6300 +; 07 70 = 0770 +; 06 80 = 0770 - 00F0 << ALT (for unpatched bochs) + +; for P6STMT - 10kb less ram +; 077F - 10 = 07 6F +; 07 6F - 00 F0 = 06 7F + +mov al, #0x35 ;; cmos_reg +out 0x70, al +mov al, #0x06 ;; val +out 0x71, al + +mov al, #0x34 ;; cmos_reg +out 0x70, al +mov al, #0x7F ;; val +out 0x71, al + +mov al, #0x31 ;; cmos_reg +out 0x70, al +mov al, #0x00 ;; val +out 0x71, al + +mov al, #0x30 ;; cmos_reg +out 0x70, al +mov al, #0x00 ;; val +out 0x71, al + +;----------------------------------------------------- +; V) tell BOCHS' BIOS we want to have LBA translation. +; 0x00 - NONE +; 0x01 - LBA <<<< +; 0x02 - LARGE +; 0x03 - R-CHS +; In future there will be 'fd failover'option in bochs. + +mov al, #0x39 ;; cmos_reg +out 0x70, al +mov al, #0x01 ;; val (LBA) +out 0x71, al + +;***************************************************** +nop +nop +;***************************************************** +; G) the switch -- protected to real mode + +; IASDM, Vol 3 +; (8-14) 8.8.2 Switching Back to Real-Address Mode + +;===================================================== +; 1) disable interrupts + +cli + +;===================================================== +nop +;===================================================== +; 2) paging + +;not enabled, so not applicable. + +;===================================================== +; 3) setup CS segment limit (64kb) +; I) + +lgdt [0x7C00+new_gdt] + +;----------------------------------------------------- +; II) + +jmp 0x08:0x7C00+new64lim + +new64lim: nop + +;===================================================== +nop +;===================================================== +; 4) setup all other segments + +mov ax, #0x10 +mov ss, ax +mov ds, ax +mov es, ax +mov fs, ax +mov gs, ax + +;===================================================== +nop +;===================================================== +; 5) LIDT +; I) + +; set up Real Mode IDT table (0...3FF) + +; for BOCH's BIOS the address 0xF000:0xFF53 +; cantains value 0xCF which is IRET opcode. + +; counter +mov cx, #0xFF ;1024 bytes(255 interrupts)(4*255=0x3FF) + +; destination - 0x00000 = ES:EDI +mov ax, #0x10 ; dst-segment - 2nd entry in GDT +mov es, ax +mov eax, #0x00000 ; dst-offset - 0x00000 +mov edi, eax + +; data to store -- 0xF000:FF53 +mov eax, #0xF000FF53 + +; clear direction flag +cld + +; the store +rep + stosd + +;----------------------------------------------------- +; II) +; load interrupt descriptor table + +lidt [0x7C00+new_idt] + +;===================================================== +nop +nop +;===================================================== +; 6) clear the PE flag in CR0 register. +; I) + +; switch to 16 bit segments +mov ax, #0x20 +mov ss, ax +mov ds, ax +mov es, ax +mov fs, ax +mov gs, ax + +;----------------------------------------------------- +; II) + +; switch to 16 bit CS + +jmp 0x018:0x7C00+new16bit + +USE16 + +new16bit: nop + +;----------------------------------------------------- +; III) +; the switch + +;xor eax, eax + +mov eax, cr0 +and eax, #0xFFFFFFFE +mov cr0, eax ;switch to RM + +;===================================================== +nop +nop +;===================================================== +; 7) far jump -- (to real mode address) + +jmp 0x0:0x7C00+realcs + +realcs: nop + +;===================================================== +; 8) set all segment registers to 0's + +mov ax, #0x0 +mov ss, ax +mov ds, ax +mov es, ax +mov fs, ax +mov gs, ax + +;===================================================== +; 9) re-enable interrupts + +sti + +;***************************************************** +nop +nop +;***************************************************** +; G) jump to BIOS. + +jmp 0xFFFF:0x0000 +;jmp 0xF000:0xFFF0 + +;***************************************************** +;***************************************************** +nop +nop +nop +nop +;***************************************************** +;***************************************************** + +USE32 + +new_idt: +dw 0x03ff ;; limit 15:00 +dw 0x0000 ;; base 15:00 +dw 0x0000 ;; base 23:16 + +new_gdt: +dw 0x0028 ;; limit 15:00 +dw 0x7C00+new_gdt_table ;; base 15:00 +dw 0x0000 ;; base 23:16 + +protected_gdt: +dw 0x0018 ;; limit 15:00 +dw 0x7C00+pmode_gdt_table ;; base 15:00 +dw 0x0000 ;; base 23:16 + +;----------------------------------------------------- + +new_gdt_table: +;// 1 2 3 4 +;//0 +dd 0x00000000 +dd 0x00000000 + +;//8 +dd 0x0000ffff +dd 0x00409E00 + +;//10 +dd 0x0000ffff +dd 0x00409200 + +;//18 +dd 0x0000ffff +dd 0x00009a00 + +;//20 +dd 0x0000ffff +dd 0x00009200 + +;------------------------- + +pmode_gdt_table: +;// 1 2 3 4 +;//0 +dd 0x00000000 +dd 0x00000000 + +;//8 +dd 0x0000ffff +dd 0x00CF9E00 + +;//10 +dd 0x0000ffff +dd 0x00CF9200 + +;***************************************************** +;***************************************************** +; the file size must be 1024 bytes. + + +.org 0x400-1 +; dd 0xdeadbeef +db 0x0 + +;***************************************************** |