繁体   English   中英

如何在 vmware 或 Virtualbox 中使用 VESA 模式?

[英]How to use VESA mode in vmware or Virtualbox?

我正在从头开始构建自己的操作系统。 我阅读了 VESA 教程并编写了一个程序来切换到 VESA 模式,然后将屏幕变白。 (Stage1.asm 是一个简单地加载和执行 kernel 的程序。)

Stage2.asm

[BITS 16]
MOV AX, 800
MOV BX, 600
MOV CL, 32
CALL vbe_set_mode
JMP Fill

vbe_set_mode:
    mov [.width], ax
    mov [.height], bx
    mov [.bpp], cl
 
    sti
 
    push es
    mov ax, 0x4F00
    mov di, vbe_info
    int 0x10
    pop es
 
    cmp ax, 0x4F
    jne .error
 
    mov ax, word[vbe_info.video_modes]
    mov [.offset], ax
    mov ax, word[vbe_info.video_modes+2]
    mov [.segment], ax
 
    mov ax, [.segment]
    mov fs, ax
    mov si, [.offset]
 
.find_mode:
    mov dx, [fs:si]
    add si, 2
    mov [.offset], si
    mov [.mode], dx
    mov ax, 0
    mov fs, ax
    
    push dx
    mov dx, 0xFFFF
    cmp [.mode], dx
    pop dx
    je .error
 
    push es
    mov ax, 0x4F01
    mov cx, [.mode]
    mov di, vbe_mode_info
    int 0x10
    pop es
 
    cmp ax, 0x4F
    jne .error
 
    mov ax, [.width]
    cmp ax, [vbe_mode_info.width]
    jne .next_mode
 
    mov ax, [.height]
    cmp ax, [vbe_mode_info.height]
    jne .next_mode
 
    mov al, [.bpp]
    cmp al, [vbe_mode_info.bpp]
    jne .next_mode
 
    mov ax, [.width]
    mov word[vbe_screen.width], ax
    mov ax, [.height]
    mov word[vbe_screen.height], ax
    mov eax, [vbe_mode_info.framebuffer]
    mov dword[vbe_screen.physical_buffer], eax
    mov ax, [vbe_mode_info.pitch]
    mov word[vbe_screen.bytes_per_line], ax
    mov eax, 0
    mov al, [.bpp]
    mov byte[vbe_screen.bpp], al
    shr eax, 3
    mov dword[vbe_screen.bytes_per_pixel], eax
 
    mov ax, [.width]
    shr ax, 3
    dec ax
    mov word[vbe_screen.x_cur_max], ax
 
    mov ax, [.height]
    shr ax, 4
    dec ax
    mov word[vbe_screen.y_cur_max], ax
 
    ; Set the mode
    push es
    mov ax, 0x4F02
    mov bx, [.mode]
    or bx, 0x4000           ; enable LFB
    mov di, 0           ; not sure if some BIOSes need this... anyway it doesn't hurt
    int 0x10
    pop es
 
    cmp ax, 0x4F
    jne .error
 
    clc
    ret
 
.next_mode:
    mov ax, [.segment]
    mov fs, ax
    mov si, [.offset]
    jmp .find_mode
 
.error:
    LEA SI, MsgNoVESA
    CALL Print
    jmp $
 
.width              dw 0
.height             dw 0
.bpp                db 0
.segment            dw 0
.offset             dw 0
.mode               dw 0

vbe_screen:
.width dw 0
.height dw 0
.bpp dw 0
.physical_buffer db 0
.bytes_per_pixel dw 0
.bytes_per_line dw 0
.x_cur_max dw 0
.y_cur_max dw 0


vbe_info:
.signature db "VESA"
.version dw 0
.oem dd 0
.capabilities dd 0
.video_modes dd 0
.video_memory dw 0
.software_rev dw 0
.vendor dd 0
.product_name dd 0
.product_rev dd 0
.reserved db 222 dup 0
.oem_data db 256 dup 0

vbe_mode_info:
.attributes dw 0
.window_a db 0
.window_b db 0
.granularity dw 0
.window_size dw 0
.segment_a dw 0
.segment_b dw 0
.win_func_ptr dd 0
.pitch dw 0
.width dw 0
.height dw 0
.w_char db 0
.y_char db 0
.planes db 0
.bpp db 0
.banks db 0
.memory_model db 0
.bank_size db 0
.image_pages db 0
.reserved0 db 0
.red_mask db 0
.red_position db 0
.green_mask db 0
.green_position db 0
.blue_mask db 0
.blue_position db 0
.reserved_mask db 0
.reserved_position db 0
.direct_color_attributes db 0
.framebuffer dd 0
.off_screen_mem_off dd 0
.off_screen_mem_size dw 0
.reserved1 db 206 dup 0

Fill:
    MOV EBX, [vbe_mode_info.framebuffer]
    MOV EAX, [vbe_mode_info.framebuffer]
    ADD EAX, 800 * 600 * 4
    MOV ECX, 0x00FFFFFF
    MOV EDX, 0

FillLoop:
    MOV [EBX], ECX
    ADD EBX, 4
    CMP EBX, EAX
    JA EndFunc
    JMP FillLoop

EndFunc:
    CLI
    HLT

MsgNoVESA: db "This PC is not support VESA.", 0x00

该程序适用于 QEMU,但不适用于 vmware 或 Virtualbox。 为什么这个程序只能在 QEMU 上运行?

我在代码中发现了几个错误:

 mov eax, [vbe_mode_info.framebuffer] mov dword[vbe_screen.physical_buffer], eax

字节大小的变量.physical_buffer db 0中写入dword

 mov eax, 0 mov al, [.bpp] mov byte[vbe_screen.bpp], al shr eax, 3 mov dword[vbe_screen.bytes_per_pixel], eax

字大小的变量.bytes_per_pixel dw 0中写入一个dword 这会破坏指向线性帧缓冲区的指针,这会在写入 memory 时产生灾难性的结果


您永远不会检查 VESA 版本。 尽管如此,您还是应该这样做,因为您需要的帧缓冲区指针PhysBasePtr仅包含在 VESA 2.0 版及更高版本的 ModeInformation 块中。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM