Home arrow Forums
OSDEV Forums  


hehongjie
User

Fresh Osdever
Posts: 1
graphgraph
Karma: 0  
VBE Function issue - 2007/10/11 00:13 I call the VBE AX=0X4f00 function,computer always reboot.

My VGA card hardware is Intel845G,below code write in nasm compiler.



Thank.



; 按照.exe文件的建构来构建
org 0x100000 ; 指定代码开始位置
bits 32


exehead times 0x100 db 0x0

main:

jmp main_variable_end
main_eip dd 0x0 ; 临时保存的堆栈数据

main_parametersize dd 0x03 ; 参数个数
main_returnvalueaddress dd 0X03 ; 返回值地址
main_gdtbase dd 0X03 ; GDT表基址


mian_diskbuffer times 4096 db 0x0
mian_vesabiosimg times 65536 db 0x0
main_srcmempoint dd 0x0
main_destmempoint dd 0x0
mian_i dd 0x0
main_diskpoint dd 0x20000 ; 将显卡信息写入磁盘的位置(扇区号),写入位置为文件之外,测试用。

mian_addrpminfoblock dd 0x0 ; pminfoblock的位置指针
mian_vbestack times 1024 db 0x0 ; pminfoblock的位置指针

main_ldt dw 0x0 ; ldt内容
main_biosdatasel times 0x0600 db 0x0 ; vbe3的缓冲区

mian_farcall times 6 db 0x0; 段间调用地址

; ss esp的保存位置
main_ss dw 0x0
main_esp dd 0x0
main_es dw 0x0

ldt_start:
dw 0
dw 0
dw 0
dw 0

dw 0
dw 0
dw 0
dw 0

dw 0
dw 0
dw 0
dw 0

dw 0
dw 0
dw 0
dw 0

dw 0
dw 0
dw 0
dw 0

dw 0
dw 0
dw 0
dw 0

dw 0
dw 0
dw 0
dw 0

dw 0
dw 0
dw 0
dw 0

dw 0 ; 测试用ldt
dw 0
dw 0
dw 0

ldt_end:

; VBE 变量
vbereturnstatus dw 0x0000
vbecontrollerinfomation times 512 db 0x0

main_variable_end:

; 通过堆栈传递n个参数,每个参数固定4字节,栈底为参数个数(包括“参数个 ”参数)和返回值地址(如果返回值地址为0表示不需要返回置),即“参 个数”参数最少为2)
; 参数压栈顺序从右到左,弹出顺序从左到右

pop dword [main_eip]


pop dword [main_parametersize]
pop dword [main_returnvalueaddress]
pop dword [main_gdtbase]

push dword [main_eip]



mov dword [main_srcmempoint],0xC0000
mov dword [main_destmempoint],mian_vesabiosimg
mov dword [mian_i],0x0

cld
main_for_1:

mov ecx,1024
mov esi,dword [main_srcmempoint]
mov edi,dword [main_destmempoint]
rep movsd


; 保存到磁盘
;push dword [main_srcmempoint]
;push dword [main_diskpoint]
;push 0x00
;push 0x04
;call writedisk
;add dword [main_diskpoint],0x08


add dword [main_srcmempoint],0x1000
add dword [main_destmempoint],0x1000

inc dword [mian_i]
cmp dword [mian_i],16
jnz main_for_1




; 定位 mian_addrpminfoblock
mov dword [mian_addrpminfoblock],mian_vesabiosimg + 0x00004F70

; 设置ldt在gdt中的描述符
mov ebx,dword [main_gdtbase]
mov word [ebx + 0x18 + 0],ldt_end - ldt_start - 1
mov edx,ldt_start
mov word [ebx + 0x18 + 2],dx
shr edx,16
mov byte [ebx + 0x18 + 4],dl
mov byte [ebx + 0x18 + 5],0x82 ; 8X 为系统描述符
mov byte [ebx + 0x18 + 6],0x40
mov byte [ebx + 0x18 + 7],dh

; 设置ldt的内容(biosdatasel)
mov ebx,ldt_start
mov word [ebx + 0x0 + 0],0x0600 - 1
mov edx,main_biosdatasel
mov word [ebx + 0x0 + 2],dx
shr edx,16
mov byte [ebx + 0x0 + 4],dl
mov byte [ebx + 0x0 + 5],0x92
mov byte [ebx + 0x0 + 6],0x00
mov byte [ebx + 0x0 + 7],dh

; 设置ldt的内容(A0000H)
mov ebx,ldt_start
mov word [ebx + 0x08 + 0],0xFFFF
mov edx,0x000A0000
mov word [ebx + 0x08 + 2],dx
shr edx,16
mov byte [ebx + 0x08 + 4],dl
mov byte [ebx + 0x08 + 5],0x92
mov byte [ebx + 0x08 + 6],0x00
mov byte [ebx + 0x08 + 7],dh

; 设置ldt的内容(B0000H)
mov ebx,ldt_start
mov word [ebx + 0x10 + 0],0xFFFF
mov edx,0x000B0000
mov word [ebx + 0x10 + 2],dx
shr edx,16
mov byte [ebx + 0x10 + 4],dl
mov byte [ebx + 0x10 + 5],0x92
mov byte [ebx + 0x10 + 6],0x00
mov byte [ebx + 0x10 + 7],dh

; 设置ldt的内容(B8000H)
mov ebx,ldt_start
mov word [ebx + 0x18 + 0],0x7FFF
mov edx,0x000B8000
mov word [ebx + 0x18 + 2],dx
shr edx,16
mov byte [ebx + 0x18 + 4],dl
mov byte [ebx + 0x18 + 5],0x92
mov byte [ebx + 0x18 + 6],0x00
mov byte [ebx + 0x18 + 7],dh

; 设置ldt的内容(CodeSegSel)
mov ebx,ldt_start
mov word [ebx + 0x20 + 0],0xFFFF
mov edx,mian_vesabiosimg
mov word [ebx + 0x20 + 2],dx
shr edx,16
mov byte [ebx + 0x20 + 4],dl
mov byte [ebx + 0x20 + 5],0x92
mov byte [ebx + 0x20 + 6],0x00
mov byte [ebx + 0x20 + 7],dh

; 设置保护模式标记
mov ebx,dword [mian_addrpminfoblock]
add ebx,18
mov byte [ebx],0x01


; 设置ldt的内容(保护模式BIOS缓冲,可执行的)
mov ebx,ldt_start
mov word [ebx + 0x28 + 0],0xFFFF
mov edx,mian_vesabiosimg
mov word [ebx + 0x28 + 2],dx
shr edx,16
mov byte [ebx + 0x28 + 4],dl
mov byte [ebx + 0x28 + 5],0x9A
mov byte [ebx + 0x28 + 6],0x00
mov byte [ebx + 0x28 + 7],dh

; 设置ldt的内容(VBE 16Bit Stack)
mov ebx,ldt_start
mov word [ebx + 0x30 + 0],1024 - 1
mov edx,mian_vbestack
mov word [ebx + 0x30 + 2],dx
shr edx,16
mov byte [ebx + 0x30 + 4],dl
mov byte [ebx + 0x30 + 5],0x92
mov byte [ebx + 0x30 + 6],0x00
mov byte [ebx + 0x30 + 7],dh

; 设置ldt的内容(512字节的VBE Info缓冲区)
mov ebx,ldt_start
mov word [ebx + 0x38 + 0],0x01FF
mov edx,vbecontrollerinfomation
mov word [ebx + 0x38 + 2],dx
shr edx,16
mov byte [ebx + 0x38 + 4],dl
mov byte [ebx + 0x38 + 5],0x92
mov byte [ebx + 0x38 + 6],0x00
mov byte [ebx + 0x38 + 7],dh

; 设置ldt的内容(测试段1M,起始地址0x100000内容为core.asm,可执行的)
mov ebx,ldt_start
mov word [ebx + 0x40 + 0],0xFFFF
mov edx,0x100000
mov word [ebx + 0x40 + 2],dx
shr edx,16
mov byte [ebx + 0x40 + 4],dl
mov byte [ebx + 0x40 + 5],0x9A
mov byte [ebx + 0x40 + 6],0x0F ; 0x4F
mov byte [ebx + 0x40 + 7],dh


; 设置 VBE Bios 缓冲
mov ebx,dword [mian_addrpminfoblock]
mov word [ebx + 8],0x0004
mov word [ebx + 10],0x000C
mov word [ebx + 12],0x0014
mov word [ebx + 14],0x001C
mov word [ebx + 16],0x0024

; 设置 check sum
mov ebx,dword [mian_addrpminfoblock]
mov al,0x00
add al,byte [ebx + 0]
add al,byte [ebx + 1]
add al,byte [ebx + 2]
add al,byte [ebx + 3]
add al,byte [ebx + 4]
add al,byte [ebx + 5]
add al,byte [ebx + 6]
add al,byte [ebx + 7]
add al,byte [ebx + 8]
add al,byte [ebx + 9]
add al,byte [ebx + 10]
add al,byte [ebx + 11]
add al,byte [ebx + 12]
add al,byte [ebx + 13]
add al,byte [ebx + 14]
add al,byte [ebx + 15]
add al,byte [ebx + 16]
add al,byte [ebx + 17]
add al,byte [ebx + 18]
mov ah,255
sub ah,al
inc ah
mov byte [ebx + 19],ah

; 设置 装载ldt main_ldt
mov word [main_ldt],0x0018
lldt word [main_ldt]


mov word [main_ss],ss ; 保存堆栈寄存器
mov dword [main_esp],esp
mov word [main_es],es

mov dx,0x0034
mov ss,dx
mov esp,1024

mov ax,0x4F00
mov dx,0x003C
mov es,dx
mov di,0x00

mov ebx,testcall
sub ebx,0x100000
mov dword [mian_farcall + 0],ebx
mov word [mian_farcall + 4],0x0044
call dword far [mian_farcall]




mov dx,word [main_ss]
mov ss,dx
mov edx,dword [main_esp]
mov esp,edx
mov dx,word [main_es]
mov es,dx ; 恢复堆栈寄存器

push mian_diskbuffer
push 0x08
push 0x00
push 0x04
call writedisk


ret

; 调用VBE初始化入口
mov word [main_ss],ss ; 保存堆栈寄存器
mov dword [main_esp],esp
mov word [main_es],es

mov dx,0x0034
mov ss,dx
mov esp,1024

mov ax,0x4F00
mov dx,0x003C
mov es,dx
mov di,0x00

mov edx,dword [mian_addrpminfoblock]
add edx,6
mov ebx,0x0
mov bx,word [edx]
mov dword [mian_farcall + 0],ebx
mov word [mian_farcall + 4],0x002C
call dword far [mian_farcall]


mov dx,word [main_ss]
mov ss,dx
mov edx,dword [main_esp]
mov esp,edx
mov dx,word [main_es]
mov es,dx ; 恢复堆栈寄存器

;mov dword[mian_diskbuffer],0x88664444

;push mian_diskbuffer
;push 0x08
;push 0x00
;push 0x04
;call writedisk





; 调用一个VBE函数
mov word [main_ss],ss ; 保存堆栈寄存器
mov dword [main_esp],esp
mov word [main_es],es

mov dx,0x0034
mov ss,dx
mov esp,1024

mov ax,0x4F00
mov dx,0x003C
mov es,dx
mov di,0x00

mov edx,dword [mian_addrpminfoblock]
add edx,4
mov ebx,0x0
mov bx,word [edx]
mov dword [mian_farcall + 0],ebx
mov word [mian_farcall + 4],0x002C
call dword far [mian_farcall]

mov dx,word [main_ss]
mov ss,dx
mov edx,dword [main_esp]
mov esp,edx
mov dx,word [main_es]
mov es,dx ; 恢复堆栈寄存器

;mov ecx,128
;mov esi,vbecontrollerinfomation
;mov edi,mian_diskbuffer
;rep movsd



;mov ebx,dword [mian_addrpminfoblock]
;mov edx,dword [ebx + 0]
;mov dword [mian_diskbuffer + 0],edx
;mov edx,dword [ebx + 4]
;mov dword [mian_diskbuffer + 4],edx
;mov edx,dword [ebx + 8]
;mov dword [mian_diskbuffer + 8],edx
;mov edx,dword [ebx + 12]
;mov dword [mian_diskbuffer + 12],edx
;mov edx,dword [ebx + 16]
;mov dword [mian_diskbuffer + 16],edx

mov dword [mian_diskbuffer + 512 + 8],0xAABBEEF1
mov dword [mian_diskbuffer + 512 + 12],0xCCDDAAB2

push mian_diskbuffer
push 0x08
push 0x00
push 0x04
call writedisk


ret




; 读磁盘(4K字节)
; 返回值 int returnvalue ,1表示操作成功,0表示操作失败
; 输入参数 int clusternum ,要读取的扇区号,8的整数倍
; 输入参数 int* mempoint ,读取内容的存放位置(占用4K字节)
readdisk:
jmp readdisk_variable_end
readdisk_eip dd 0x0 ; 临时保存的堆栈数据

readdisk_parametersize dd 0X0
readdisk_returnvalueaddress dd 0X0
readdisk_clusternum dd 0X08
readdisk_mempoint dd 0X0
readdisk_variable_end:

pop dword [readdisk_eip]

pop dword [readdisk_parametersize]
pop dword [readdisk_returnvalueaddress]
pop dword [readdisk_clusternum]
pop dword [readdisk_mempoint]

push dword [readdisk_eip]


cmp dword [readdisk_returnvalueaddress],0x0
je readdisk_retuen_none
mov ebx,dword [readdisk_returnvalueaddress]
mov dword [ebx],0X01
readdisk_retuen_none:


MOV DX, 1F7h ;status register
readdisk_LOOP1:
IN AL,DX ;sets AL to status register (which is 8 bits)
AND AL, 10000000B
JNE readdisk_LOOP1

MOV DX, 1F7h ;status register again
readdisk_LOOP2:
IN AL, DX ;sets AL to status register again
AND AL, 01000000B
JE readdisk_LOOP2


; 设置不使用中断
;3F6 (Read): Alternate Status Register
;3F6 (Write): Device Control Register
mov dx,3F6H
mov al,02H
out dx,al


; 设置扇区数 8扇区 4KBytes
mov dx,1F2H
mov al,08H
out dx,al

; 设置lba地址数据
;1F3H (Read and Write): LBA Low Register
;1F4H (Read and Write): LBA Mid Register
;1F5H (Read and Write): LBA High Register



mov dx,1F3H
mov al,byte [readdisk_clusternum + 0]
out dx,al

mov dx,1F4H
mov al,byte [readdisk_clusternum + 1]
out dx,al

mov dx,1F5H
mov al,byte [readdisk_clusternum + 2]
out dx,al

; 设置磁盘和模式
MOV DX, 1F6H ;device/head register
MOV AL, 40H ;0 selects device 0 (master). 10h would select device 1 (slave). 40表示lba模式
OUT DX, AL ;selects master device


MOV DX, 1F7H ;command register
MOV AL, 20H ; OPCODE - 20h (with retries) or 21h (without retries)
OUT DX, AL ; sends the command!


MOV DX, 1F7H ;status register
readdisk_LOOP3:
IN AL, DX
AND AL, 00001000B ;if DRQ is not high, the device doesn't have data for us
JE readdisk_LOOP3 ;yet, so keep looking until it does!



MOV DX, 1F0H ;data register
MOV edi, dword [readdisk_mempoint] ;points DI to the buffer we're using
MOV ecx, 2048 ; 2048 decimal. This controls the REP command. 4K Bytes writeing.
CLD ;clear the direction flag so INSW increments DI (not decrements it)
REP insw



ret

; 写磁盘(4K字节)
; 返回值 int returnvalue ,1表示操作成功,0表示操作失败
; 输入参数 int clusternum ,要写入的扇区号,8的整数倍
; 输入参数 int* mempoint ,写入内容的存放位置(占用4K字节)
writedisk:
jmp writedisk_variable_end
writedisk_eip dd 0x0 ; 临时保存的堆栈数据

writedisk_parametersize dd 0X0
writedisk_returnvalueaddress dd 0X0
writedisk_clusternum dd 0X08
writedisk_mempoint dd 0X0
writedisk_variable_end:

pop dword [writedisk_eip]

pop dword [writedisk_parametersize]
pop dword [writedisk_returnvalueaddress]
pop dword [writedisk_clusternum]
pop dword [writedisk_mempoint]

push dword [writedisk_eip]



cmp dword [writedisk_returnvalueaddress],0x0
je writedisk_retuen_none
mov ebx,dword [writedisk_returnvalueaddress]
mov dword [ebx],0X01
writedisk_retuen_none:


MOV DX, 1F7h ;status register
writedisk_LOOP1:
IN AL,DX ;sets AL to status register (which is 8 bits)
AND AL, 10000000B
JNE writedisk_LOOP1

MOV DX, 1F7h ;status register again
writedisk_LOOP2:
IN AL, DX ;sets AL to status register again
AND AL, 01000000B
JE writedisk_LOOP2


; 设置不使用中断
;3F6 (Read): Alternate Status Register
;3F6 (Write): Device Control Register
mov dx,3F6H
mov al,02H
out dx,al


; 设置扇区数 8扇区 4KBytes
mov dx,1F2H
mov al,08H
out dx,al

; 设置lba地址数据
;1F3H (Read and Write): LBA Low Register
;1F4H (Read and Write): LBA Mid Register
;1F5H (Read and Write): LBA High Register

mov dx,1F3H
mov al,byte [writedisk_clusternum + 0]
out dx,al

mov dx,1F4H
mov al,byte [writedisk_clusternum + 1]
out dx,al

mov dx,1F5H
mov al,byte [writedisk_clusternum + 2]
out dx,al

; 设置磁盘和模式
MOV DX, 1F6H ;device/head register
MOV AL, 40H ;0 selects device 0 (master). 10h would select device 1 (slave). 40表示lba模式
OUT DX, AL ;selects master device


MOV DX, 1F7H ;command register
MOV AL, 30H ; OPCODE - 30h (with retries) or 31h (without retries)
OUT DX, AL ; sends the command!



MOV DX, 1F7H ;status register
writedisk_LOOP3:
IN AL, DX
AND AL, 00001000B ;if DRQ is not high, the device doesn't have data for us
JE writedisk_LOOP3 ;yet, so keep looking until it does!



MOV DX, 1F0H ;data register
MOV esi, dword [writedisk_mempoint] ;points DI to the buffer we're using
MOV ecx, 2048 ; 2048 decimal. This controls the REP command. 4K Bytes writeing.
CLD ;clear the direction flag so INSW increments DI (not decrements it)
REP outsw



ret



testcall:

;push ax

;mov dword [es:di],0x1236

;pop ax

retf
  | | The administrator has disabled public write access.
OSDEV
Community
Advertisement
   

A WebArticles site. Sponsored by Evoleto. Motorola V525 / Business Directory / Delaware Incorporation / Home Made Bazaar