组装 - 如何在 UEFI 中设置图形模式(无 VGA、无 BIOS、没有弃用) [英] Assembly - How to set graphics mode in UEFI (No VGA, No BIOS, Nothing deprecated)

查看:41
本文介绍了组装 - 如何在 UEFI 中设置图形模式(无 VGA、无 BIOS、没有弃用)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用的工具:nasm、qemu-system-x86_64.

Tools I'm using: nasm, qemu-system-x86_64.

我使用的操作系统:Windows 10.

Operating System I'm on: Windows 10.

所以我在 https://wiki.osdev.org/Real_Mode_OS_Warning 查看了实模式操作系统警告"

这篇文章似乎暗示着一切都可以在不使用 BIOS 中断的情况下完成.我知道如何加载长模式,所以我已经这样做了,但现在我被卡住了,因为直到现在我只知道 BIOS 中断.我想做一些事情,比如将图形模​​式设置为全内存访问模式(如果你看过 int 10h/AX = 4F02h/BX = 81FFh,可能听起来很熟悉),但因为我不不想使用已弃用的东西 (BIOS),我一直在网上搜索如何设置图形模式,然后仅在长模式下访问单个像素时遇到问题.

What the article seems to imply is that everything can be done without using BIOS interrupts whatsoever. I know how to load Long Mode, and so I've done this, but now I am stuck because BIOS interrupts were all I knew until now. I want to do something like set the graphics mode to full-memory-access-mode (might sound familiar if you've seen int 10h / AX = 4F02h / BX = 81FFh), but since I don't want to use something that's deprecated (BIOS), I have been having trouble searching the web for how to set the graphics mode and then access individual pixels in Long Mode only.

希望可以在 StackOverflow 上回答这个问题.我非常相信它太复杂了"不会作为答案出现,尤其是因为 OSDev 刚刚告诉我不要使用已弃用的东西.告诉某人太难了,假设他们知道什么以及他们能够学习什么,甚至不知道他们是谁.我只需要一个起点来找出如何做到这一点.

Hopefully it turns out to be possible to answer this question on StackOverflow. I have much faith that "it's too complicated" won't show up as an answer, especially since I was just told by OSDev NOT to use deprecated things. Telling someone it's too difficult assumes what they know and what they're able to learn without even knowing who they are. I just need a starting point to find out how to do this.

澄清一下,对我不起作用的事情:

To give clarification, things that didn't work for me:

进入图形模式而不在汇编中中断

这对我不起作用,因为答案提供了我不想要的 VGA 链接.

This didn't work for me because the answer gives a link to VGA, which I don't want.

程序集 8086 中的图形模式

这对我不起作用,因为问题不是关于长模式,而是关于实模式下的 VGA 图形.

This didn't work for me because the question does not ask about Long Mode, but rather about VGA graphics in Real Mode.

如何将数据写入图形不使用BIOS的卡?

这对我不起作用,因为答案本质上是它太复杂了,使用已弃用的东西",这与我正在尝试做的相反,并且与我刚刚在 OSDev 上被告知的内容完全矛盾.

This didn't work for me because the answer was essentially "it's too complicated, use the deprecated stuff", which is the opposite of what i'm trying to do and quite contradictory to what I was just told on OSDev.

在 Intel 8086 上直接通过显卡绘图

这对我不起作用,因为答案与设置图形模式无关.

This didn't work for me because the answer has nothing to do with setting the graphics mode.

一些 x86 汇编语言问题

这对我不起作用,因为答案没有说明如何在 UEFI 中设置图形模式.他们只谈论过时的东西.

This didn't work for me because the answers do not say how to set the graphics mode in UEFI. They only talk about deprecated things.

推荐答案

这是使用 UEFI 获取和打印第一个图形设备上可用的图形模式并可选择设置模式的示例代码.

Here is sample code that uses UEFI to get and print the available graphics modes on the first graphics device and optionally sets the mode.

我使用了这个参考: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 引导服务表的指针存储在名为 efi_boot_services 的全局变量中的启动代码.
  • 它是为 gas 而不是 nasm 编写的.

这是示例输出:

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,所以我没有解释一切是如何工作的,如果您需要更多解释,请告诉我.

I assume you are familiar with UEFI, so I haven't explained how everything works, so let me know if you need more explanation.

            .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
"
    trace2: .asciz  "mode %d: size %d, ver %d, hor res %d, ver res %d, pixel format %d
"
    trace3: .asciz  "frame buffer: %p, frame buffer size: %llx
"

            .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

这篇关于组装 - 如何在 UEFI 中设置图形模式(无 VGA、无 BIOS、没有弃用)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆