簡體   English   中英

裝配 - 如何在UEFI中設置圖形模式(無VGA,無BIOS,無需棄用)

[英]Assembly - How to set graphics mode in UEFI (No VGA, No BIOS, Nothing deprecated)

我正在使用的工具:nasm,qemu-system-x86_64。

操作系統我在:Windows 10。

所以我在https://wiki.osdev.org/Real_Mode_OS_Warning上查看了“實模式操作系統警告”

這篇文章似乎暗示的是,一切都可以在不使用BIOS中斷的情況下完成。 我知道如何加載長模式,所以我已經完成了這個,但現在我被卡住了,因為直到現在我才知道BIOS中斷。 我想做一些事情,比如將圖形模​​式設置為全內存訪問模式(如果你看到int 10h / AX = 4F02h / BX = 81FFh ,可能聽起來很熟悉),但是因為我不想使用的東西是不推薦使用(BIOS),我一直無法在網上搜索如何設置圖形模式,然后只能在長模式下訪問各個像素。

希望事實證明可以在StackOverflow上回答這個問題。 我非常相信“它太復雜”不會出現作為答案,特別是因為OSDev告訴我不要使用棄用的東西。 告訴某人,如果不知道他們是誰,他們就會知道他們所知道的以及他們能夠學到什么。 我只需要一個起點來了解如何做到這一點。

為了澄清,那些對我不起作用的事情:

在裝配中進入圖形模式而不中斷

這對我不起作用,因為答案提供了VGA的鏈接,我不想要。

程序集8086中的圖形模式

這對我不起作用,因為問題不是詢問長模式,而是關於實模式下的VGA圖形。

如何在不使用BIOS的情況下將數據寫入顯卡?

這對我來說不起作用,因為答案基本上是“它太復雜了,使用了被棄用的東西”,這與我正在嘗試做的完全相反,而且與我在OSDev上被告知的相反。

在Intel 8086上直接通過顯卡繪圖

這對我不起作用,因為答案與設置圖形模式無關。

一些x86匯編語言問題

這對我不起作用,因為答案沒有說明如何在UEFI中設置圖形模式。 他們只談論棄用的東西。

以下是使用UEFI在第一個圖形設備上獲取和打印可用圖形模式並可選擇設置模式的示例代碼。

我使用了這個參考: http//wiki.phoenix.com/wiki/index.php/EFI_GRAPHICS_OUTPUT_PROTOCOL

實施說明:

  • 它調用LocateProtocol來獲取圖形輸出協議。 我嘗試使用LocateHandle來獲取支持圖形輸出協議的所有句柄。 它返回了兩個句柄,但OpenProtocol失敗了。 我沒有機會使用LocateHandle調試版本。 這個版本使用LocateProtocol工作。
  • 它打印可用模式的數量,當前模式以及每種模式的特征。
  • 該功能的參數是要設置的模式。 如果為-1,則不更改模式。 否則它必須介於0和N-1之間,其中N是支持的圖形模式數。 該函數不檢查該參數,但SetMode函數會檢查它。
  • 它使用Sys V x86-64函數調用約定,但使用UEFI約定的UEFI函數調用除外。
  • 它使用一個名為efi_printf的函數,它就像printf一樣,使用EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL寫入ConOut。
  • 它依賴於在名為efi_boot_services的全局變量中存儲指向EFI引導服務表的指針的啟動代碼。
  • 它是為氣體而不是鼻子而寫的。

這是示例輸出:

max mode: 5
mode 1: size 36, ver 0, hor res 800, ver res 600, pixel format 1
frame buffer: b1000000, frame buffer size: 1d4c00
mode 0: size 36, ver 0, hor res 640, ver res 480, pixel format 1
mode 1: size 36, ver 0, hor res 800, ver res 600, pixel format 1
mode 2: size 36, ver 0, hor res 1024, ver res 768, pixel format 1
mode 3: size 36, ver 0, hor res 1280, ver res 1024, pixel format 1
mode 4: size 36, ver 0, hor res 1600, ver res 1200, pixel format 1

我假設您熟悉UEFI,所以我沒有解釋一切是如何工作的,所以如果您需要更多解釋,請告訴我。

            .intel_syntax noprefix

            .section .text
            .align  16
            .globl  gfxmode
    gfxmode:
            push    rbx
            push    rbp
            push    r14
            push    r15
            sub     rsp, 0x38

            mov     ebp, edi                // desired mode

            lea     rcx, EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID[rip]
            xor     edx, edx                // arg 2: unused
            lea     r8, 0x20[rsp]           // arg 3: address of protocol
            mov     rax, efi_boot_services[rip]
            call    0x140[rax]              // locate protocol
            test    rax, rax
            js      2f

            mov     r15, 0x20[rsp]          // graphics output protocol
            mov     r14, 0x18[r15]          // mode

            lea     rdi, trace1[rip]
            mov     esi, [r14]              // max mode
            call    efi_printf

            mov     rdi, 8[r14]             // current mode info
            mov     esi, 4[r14]             // current mode number
            mov     edx, 16[r14]            // current mode info size
            call    print_mode

            lea     rdi, trace3[rip]
            mov     rsi, 24[r14]            // frame buffer addr
            mov     rdx, 32[r14]            // frame buffer size
            call    efi_printf

            xor     ebx, ebx
    1:
            mov     rcx, r15                // arg 1: graphics output protocol
            mov     edx, ebx                // arg 2: mode number
            lea     r8, 0x30[rsp]           // arg 3: &info size
            lea     r9, 0x28[rsp]           // arg 4: &info
            call    0x00[rcx]               // query mode
            test    rax, rax
            js      2f

            mov     rdi, 0x28[rsp]          // mode info
            mov     esi, ebx                // mode number
            mov     edx, 0x30[rsp]          // mode info size
            call    print_mode

            mov     rax, efi_boot_services[rip]
            mov     rcx, 0x28[rsp]          // mode info
            call    0x48[rax]               // free pool

            inc     ebx
            cmp     ebx, [r14]              // max mode
            jb      1b

            xor     eax, eax
            test    ebp, ebp                // new mode
            js      2f
            mov     rcx, r15                // arg 1: graphics output protocol
            mov     edx, ebp                // arg 2: mode number
            call    0x08[rcx]               // set mode

    2:
            add     rsp, 0x38
            pop     r15
            pop     r14
            pop     rbp
            pop     rbx
            ret

            .align  16
    print_mode:
            // rdi: mode info
            // esi: mode number
            // edx: mode size
            mov     ecx, [rdi]              // mode version
            mov     r8d, 4[rdi]             // hor res
            mov     r9d, 8[rdi]             // ver res
            mov     eax, 12[rdi]            // pixel format
            push    rax
            lea     rdi, trace2[rip]
            call    efi_printf
            add     rsp, 8
            ret

    trace1: .asciz  "max mode: %d\n"
    trace2: .asciz  "mode %d: size %d, ver %d, hor res %d, ver res %d, pixel format %d\n"
    trace3: .asciz  "frame buffer: %p, frame buffer size: %llx\n"

            .align  16
    EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID:
            .byte   0xde,0xa9,0x42,0x90,0xdc,0x23,0x38,0x4a
            .byte   0x96,0xfb,0x7a,0xde,0xd0,0x80,0x51,0x6a

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM