Summarization on using ADLO to bring up VGA

Gerald Chiu snow2moutain at hotmail.com
Tue Sep 7 04:26:01 CEST 2004


>perhaps it would make sense to summarize "lessons learned" and send them
>to list, so that whoever will play with ADLO next can benefit from the
>knowledge


  Ok,after Richard Smith's help ,I succeded in booting linux with VGA 
supported.

  Mainboard: intel 440bx
  Video Card: S3 Trio64V+  (PCI card)
  And Richard said that he made Assiliant 65550 and 69000 PCI cards work 
and some S3 based cards work on 440bx mainboard.  
  I had tried to use a ATI PCI card,but failed when the program run into 
VGA Bios ,and never return back.I also having problem on bringing up AGP 
video card,although I had set some registers about AGP enabling(maybe I 
hadn't set correctly,anyway, I don't care AGP too much now).
  
  Prepare pirq,vga bios(get them from a running os),then use ADLO to copy 
them to proper address,maybe you need to modify loader.s about setting up 
shadowing.

  Attached  loader.s which was modified by Richard Smith sets up the 
shadowing correctly. 
I used it and succeeded,too.Thanks.


 
;*****************************************************
; $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

; Outputs a value to PCI config space
; put the bus,dev,function,offset in eax
; and the byte value in dl then call this macro

MACRO PCI_CONFIG_WRITE_BYTE
   shl edx, #8
   mov dl,  al
   and dl,  #3
   shl edx, #16
   or  eax, #0x80000000
   and eax, #0xfffffffc
   mov dx,  #0x0cf8
   out dx,  eax
   shr edx, #16
   mov al,  dh
   mov dh,  #0
   add edx, #0x0cfc
   out dx,  al
MEND

;*****************************************************
; B) shadow - ON (enable/read/write)

; This is orginal shadowing setup code
; Works on the Matsonic 7308e mainboard
;mov eax, #0x80000070
;mov dx,  #0x0cf8
;out dx,  eax

;mov eax, #0xFFFFFFFF
;mov dx,  #0x0cfc
;out dx,  eax

; This enables shadowing for the 0x0f0000 -
; 0x0fffff range and the 0x0C0000 - 0x0cffff range
; for the 440bx chipset.  

mov eax, #0x59
mov edx, #0x20
PCI_CONFIG_WRITE_BYTE
mov eax, #0x5A
mov edx, #0x22
PCI_CONFIG_WRITE_BYTE
mov eax, #0x5b
mov edx, #0x22
PCI_CONFIG_WRITE_BYTE

;*****************************************************
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 - 0xF0000
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
;*****************************************************
; D) copy -- video bios

; on my system video bios is just 48KB (0x0C000)
; but just for paranoida we copy  64kb (0X10000)

; counter - 64kb
mov ecx, #0x10000

; source - 0x18000  ( 0x8000+0x10000 = 0x18000 ) 
mov ax,  #0x10         ; src-segment - 2nd entry in GDT
mov ds,  ax
mov eax, #0x18000      ; src-offset  - 0x18000
mov esi, eax

; destination - 0xC0000
mov ax,  #0x10         ; dst-segment - 2nd entry in GDT
mov es,  ax
mov eax, #0xC0000      ; dst-offset  - 0xC0000
mov edi, eax

; clear direction flag
cld

; the copy
rep
  movsb



;*****************************************************
nop
nop
;*****************************************************
; E) copy -- pirq table

; on my system video bios is just 48KB (0x0C000)
; but just for paranoida we copy  64kb (0X10000)

; counter - 256kb -- 0x100
mov ecx, #0x100

; source - 0x7F00  ( 0x7C00+0x300 = 0x7F00 ) 
mov ax,  #0x10        ; src-segment - 2nd entry in GDT
mov ds,  ax
mov eax, #0x7F00      ; src-offset  - 0x7F00
mov esi, eax

; destination - 0xFFD00
mov ax,  #0x10         ; dst-segment - 2nd entry in GDT
mov es,  ax
mov eax, #0xFFD00      ; dst-offset  - 0xFD00
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, #0x59
mov edx, #0x30
PCI_CONFIG_WRITE_BYTE
mov eax, #0x5A
mov edx, #0x33
PCI_CONFIG_WRITE_BYTE
mov eax, #0x5b
mov edx, #0x33
PCI_CONFIG_WRITE_BYTE

;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.

; -0x100 b/c we put $PIR table here.

.org 0x400-1-0x100
; dd 0xdeadbeef			
db 0x0

;*****************************************************

_________________________________________________________________
享用世界上最大的电子邮件系统― MSN Hotmail。  http://www.hotmail.com  




More information about the coreboot mailing list