Сборка - Как установить графический режим в UEFI (без VGA, без BIOS, ничего не рекомендуется) - PullRequest
0 голосов
/ 23 октября 2018

Инструменты, которые я использую: nasm, qemu-system-x86_64.

Операционная система, на которой я работаю: Windows 10.

Поэтому я проверил «Предупреждение ОС реального режима»в https://wiki.osdev.org/Real_Mode_OS_Warning

То, что статья, кажется, подразумевает, - то, что все может быть сделано без использования прерываний BIOS вообще.Я знаю, как загрузить Long Mode, и поэтому я сделал это, но теперь я застрял, потому что прерывания BIOS были все, что я знал до сих пор.Я хочу сделать что-то вроде установки графического режима в режим полного доступа к памяти (может показаться знакомым, если вы видели int 10h / AX = 4F02h / BX = 81FFh), но так как я не хочу использовать что-то, что устарело (BIOS), у меня естьУ меня возникли проблемы с поиском в Интернете того, как установить графический режим и затем получить доступ к отдельным пикселям только в длинном режиме.

Надеемся, что удастся ответить на этот вопрос в StackOverflow.Я очень верю, что «это слишком сложно» не появится в качестве ответа, тем более что OSDev только что сказал мне НЕ использовать устаревшие вещи.Говорить кому-то, что это слишком сложно, предполагает то, что они знают и чему они могут научиться, даже не зная, кто они.Мне просто нужна отправная точка, чтобы узнать, как это сделать.

Чтобы дать разъяснение, вещи, которые не работали для меня:

Вход в графический режим без прерываний в сборке

Это не сработало для меня, потому что в ответе содержится ссылка на VGA, которая мне не нужна.

Графический режим в сборке 8086

Это не сработало для меня, потому что вопрос не о длинном режиме, а о VGA-графике в реальном режиме.

Как записать данные на видеокарту без использования BIOS?

Это не сработало для меня, потому что ответ был по сути "слишком сложен, используйте устаревшие вещи", что противоположно тому, что я пытаюсь сделать, и совершенно противоречит тому, чтоМне только что сказали об OSDev.

Рисование непосредственно графической картой на Intel 8086

Это не сработало для меня, потому что ответ не имеет ничего общего с настройкойграфический режим.

Несколько сборок x86y language questions

Это не сработало для меня, потому что в ответах не говорится, как установить графический режим в UEFI.Они говорят только об устаревших вещах.

1 Ответ

0 голосов
/ 30 октября 2018

Вот пример кода, который использует 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, и выполняет запись в ConOut с использованием EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.
  • Она опирается на код запуска, хранящий указатель на таблицу служб загрузки EFI в глобальной переменной с именем efi_boot_services.
  • Это написано для газа, а не для насм.

Вот пример вывода:

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