为什么OpenVolume在QEMU中引起#GD错误?

发布于 2025-01-24 01:26:25 字数 5741 浏览 0 评论 0原文

我正在研究UEFI应用程序的NASM实施。我需要做的一件事是在其“文件系统”上读取文件。为此,我使用的是EFI_SIMPLE_FILE_SYSTEM协议和OpenVolume方法。

但是,当我在QEMU中运行UEFI应用程序时,我会在错误0中获得一般保护故障。根据Osdev的说法,这给出了三个选择。

我不太了解如何测试这一点,因为该错误发生在OpenVolume Call中。我已经使用了UEFI OpenVolume的任何一侧的无限循环来确保在该功能调用中发生错误(uefi固件内)。

因为这是一个大文件,所以我将在下面放置我的代码的相关部分。完整文件可在 https://github.com/jd9999/project-turtle

请请请如果您需要更多信息,请发表评论。

错误屏幕

主要功能

mov rcx, GUID_EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
call locateHandlesByProtocol

;;We'll just open the first one, as a test
mov rdx, rcx
mov rcx, [rcx]
call openFileSystem ;TODO fix the #GP error!
mov rcx, rdx
call freeBuffer

rocateHandlesByByprotocol方法

;**************************************************************************************************
;*** locateHandlesByProtocol [BOOT FUNCTION ONLY]                                               ***
;*** Definition: provides a list and count of every handle that supports the requested protocol ***
;*** Input: rcx is the address of the protocol GUID                                             ***
;*** Output: rcx holds address to the buffer containing the array of handles found              ***
;***         rdx holds the number of handles with that protocol                                 ***
;**************************************************************************************************
locateHandlesByProtocol:
    ;Call the function
    push r8
    push r9
    push r10
    push r11
    mov rdx, rcx
    mov rcx, [LOCATE_PROTOCOL_SEARCH_PROTOCOL]
    mov r8, 0 ;null
    mov r9, LOCATE_PROTOCOL_HANDLE_COUNT
    mov r10, LOCATE_PROTOCOL_BUFFER_ADDRESS

    ;TODO - Should there be this many push/pop operations?
    push r8
    push r9
    push r10
    sub rsp, 0x20
    call [BOOT_SERVICES_LOCATE_HANDLE_BUFFER]

    ;Check for errors
    cmp rax, [EFI_SUCCESS]
    je LHBPend

    cmp rax, [EFI_INVALID_PARAMETER]
    jne LHBP1
    mov rcx, invalidParameterError
    jmp LHBPerrExit

    LHBP1:
    cmp rax, [EFI_OUT_OF_RESOURCES]
    jne LHBP2
    mov rcx, outOfResourcesError
    jmp LHBPerrExit

    LHBP2:
    cmp rax, [EFI_NOT_FOUND]
    jne LHBP3
    mov rcx, notFoundError
    jmp LHBPerr

    LHBP3:
    ;Unknown error, let's just end the program here...
    mov rcx, unknownError
    jmp LHBPerrExit

    LHBPerr:
    call printErrorString

    ;Return
    LHBPend:
    ;TODO - Should there be this many push/pop operations?
    add rsp, 0x20
    pop r10
    pop r9
    pop r8
    mov rcx, [LOCATE_PROTOCOL_BUFFER_ADDRESS]
    mov rdx, [LOCATE_PROTOCOL_HANDLE_COUNT]
    pop r11
    pop r10
    pop r9
    pop r8
    ret

    LHBPerrExit:
    call printErrorString
    mov rcx, rax
    call exit

OpenFileSystem方法

;*****************************************************************************
;*** openFileSystem                                                        ***
;*** Definition: opens a file system for various operations                ***
;*** Input: rcx is a pointer to a EFI_SYSTEM_FILE_SYSTEM_PROTOCOL object   ***
;*** Output: rcx is a pointer to an EFI_FILE_PROTOCOL for that file system ***
;*****************************************************************************
openFileSystem:
    ;Call the function
    push rdx
    push r8
    push r9
    push r10
    push r11

    mov r8, rcx
    mov rdx, OPEN_VOLUME_FILE_PROTOCOL_HANDLE_ADDRESS
    add r8, [OFFSET_SIMPLE_FILE_SYSTEM_OPEN_VOLUME]
    sub rsp, 0x20
    call r8

    ;Check for errors
    cmp rax, [EFI_SUCCESS]
    je OFSend

    cmp rax, [EFI_UNSUPPORTED]
    jne OFS1
    mov rcx, unsupportedError
    jmp OFSerrExit

    OFS1:
    cmp rax, [EFI_NO_MEDIA]
    jne OFS2
    mov rcx, noMediaError
    jmp OFSerr

    OFS2:
    cmp rax, [EFI_DEVICE_ERROR]
    jne OFS3
    mov rcx, deviceError
    jmp OFSerr

    OFS3:
    cmp rax, [EFI_VOLUME_CORRUPTED]
    jne OFS4
    mov rcx, volumeCorruptedError
    jmp OFSerr

    OFS4:
    cmp rax, [EFI_ACCESS_DENIED]
    jne OFS5
    mov rcx, accessDeniedError
    jmp OFSerr

    OFS5:
    cmp rax, [EFI_OUT_OF_RESOURCES]
    jne OFS2
    mov rcx, outOfResourcesError
    jmp OFSerrExit

    OFS6:
    cmp rax, [EFI_MEDIA_CHANGED]
    jne OFS7
    mov rcx, mediaChangedError
    jmp OFSerr

    OFS7:
    ;Unknown error, let's just end the program here...
    mov rcx, unknownError
    jmp OFSerrExit

    OFSerr:
    call printErrorString

    ;Return
    OFSend:
    add rsp, 0x20
    mov rcx, [OPEN_VOLUME_FILE_PROTOCOL_HANDLE_ADDRESS]
    pop r11
    pop r10
    pop r9
    pop r8
    pop rdx
    ret

    OFSerrExit:
    call printErrorString
    mov rcx, rax
    call exit

相关数据成员

GUID_EFI_SIMPLE_FILE_SYSTEM_PROTOCOL    dd 0x964e5b22
                    dw 0x6459, 0x11d2
                    db 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b

;****************************************
;*** Stores values related to the     ***
;*** UEFI LocateHandleBuffer function ***
;****************************************
LOCATE_PROTOCOL_SEARCH_PROTOCOL dq 2
LOCATE_PROTOCOL_HANDLE_COUNT dq 0
LOCATE_PROTOCOL_BUFFER_ADDRESS dq 0

;**********************************************
;*** Stores values related to the UEFI      ***
;*** Simple File System openVolume function ***
;**********************************************
OPEN_VOLUME_FILE_PROTOCOL_HANDLE_ADDRESS dq 0

I am working on a NASM implementation of a UEFI application. One of the things I need it to do is to read files on its' file system. To do that, I am using the EFI_SIMPLE_FILE_SYSTEM protocol and the openVolume method.

However, when I run my UEFI application in QEMU, I get a general protection fault with error 0. According to OSDev, that leaves three options as to what it could be.

I don't know too well how to test that, since the error happens within the openVolume call. I have used infinite loops either side of the UEFI openVolume to make sure the error occurs within that function call (which is within the UEFI firmware).

Because it's a big file, I'll just put relevant parts of my code below. The full file is available on https://github.com/JD9999/Project-Turtle

Please comment if you need any more information.

Error screen
Qemu error

Main function

mov rcx, GUID_EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
call locateHandlesByProtocol

;;We'll just open the first one, as a test
mov rdx, rcx
mov rcx, [rcx]
call openFileSystem ;TODO fix the #GP error!
mov rcx, rdx
call freeBuffer

locateHandlesByProtocol method

;**************************************************************************************************
;*** locateHandlesByProtocol [BOOT FUNCTION ONLY]                                               ***
;*** Definition: provides a list and count of every handle that supports the requested protocol ***
;*** Input: rcx is the address of the protocol GUID                                             ***
;*** Output: rcx holds address to the buffer containing the array of handles found              ***
;***         rdx holds the number of handles with that protocol                                 ***
;**************************************************************************************************
locateHandlesByProtocol:
    ;Call the function
    push r8
    push r9
    push r10
    push r11
    mov rdx, rcx
    mov rcx, [LOCATE_PROTOCOL_SEARCH_PROTOCOL]
    mov r8, 0 ;null
    mov r9, LOCATE_PROTOCOL_HANDLE_COUNT
    mov r10, LOCATE_PROTOCOL_BUFFER_ADDRESS

    ;TODO - Should there be this many push/pop operations?
    push r8
    push r9
    push r10
    sub rsp, 0x20
    call [BOOT_SERVICES_LOCATE_HANDLE_BUFFER]

    ;Check for errors
    cmp rax, [EFI_SUCCESS]
    je LHBPend

    cmp rax, [EFI_INVALID_PARAMETER]
    jne LHBP1
    mov rcx, invalidParameterError
    jmp LHBPerrExit

    LHBP1:
    cmp rax, [EFI_OUT_OF_RESOURCES]
    jne LHBP2
    mov rcx, outOfResourcesError
    jmp LHBPerrExit

    LHBP2:
    cmp rax, [EFI_NOT_FOUND]
    jne LHBP3
    mov rcx, notFoundError
    jmp LHBPerr

    LHBP3:
    ;Unknown error, let's just end the program here...
    mov rcx, unknownError
    jmp LHBPerrExit

    LHBPerr:
    call printErrorString

    ;Return
    LHBPend:
    ;TODO - Should there be this many push/pop operations?
    add rsp, 0x20
    pop r10
    pop r9
    pop r8
    mov rcx, [LOCATE_PROTOCOL_BUFFER_ADDRESS]
    mov rdx, [LOCATE_PROTOCOL_HANDLE_COUNT]
    pop r11
    pop r10
    pop r9
    pop r8
    ret

    LHBPerrExit:
    call printErrorString
    mov rcx, rax
    call exit

openFileSystem method

;*****************************************************************************
;*** openFileSystem                                                        ***
;*** Definition: opens a file system for various operations                ***
;*** Input: rcx is a pointer to a EFI_SYSTEM_FILE_SYSTEM_PROTOCOL object   ***
;*** Output: rcx is a pointer to an EFI_FILE_PROTOCOL for that file system ***
;*****************************************************************************
openFileSystem:
    ;Call the function
    push rdx
    push r8
    push r9
    push r10
    push r11

    mov r8, rcx
    mov rdx, OPEN_VOLUME_FILE_PROTOCOL_HANDLE_ADDRESS
    add r8, [OFFSET_SIMPLE_FILE_SYSTEM_OPEN_VOLUME]
    sub rsp, 0x20
    call r8

    ;Check for errors
    cmp rax, [EFI_SUCCESS]
    je OFSend

    cmp rax, [EFI_UNSUPPORTED]
    jne OFS1
    mov rcx, unsupportedError
    jmp OFSerrExit

    OFS1:
    cmp rax, [EFI_NO_MEDIA]
    jne OFS2
    mov rcx, noMediaError
    jmp OFSerr

    OFS2:
    cmp rax, [EFI_DEVICE_ERROR]
    jne OFS3
    mov rcx, deviceError
    jmp OFSerr

    OFS3:
    cmp rax, [EFI_VOLUME_CORRUPTED]
    jne OFS4
    mov rcx, volumeCorruptedError
    jmp OFSerr

    OFS4:
    cmp rax, [EFI_ACCESS_DENIED]
    jne OFS5
    mov rcx, accessDeniedError
    jmp OFSerr

    OFS5:
    cmp rax, [EFI_OUT_OF_RESOURCES]
    jne OFS2
    mov rcx, outOfResourcesError
    jmp OFSerrExit

    OFS6:
    cmp rax, [EFI_MEDIA_CHANGED]
    jne OFS7
    mov rcx, mediaChangedError
    jmp OFSerr

    OFS7:
    ;Unknown error, let's just end the program here...
    mov rcx, unknownError
    jmp OFSerrExit

    OFSerr:
    call printErrorString

    ;Return
    OFSend:
    add rsp, 0x20
    mov rcx, [OPEN_VOLUME_FILE_PROTOCOL_HANDLE_ADDRESS]
    pop r11
    pop r10
    pop r9
    pop r8
    pop rdx
    ret

    OFSerrExit:
    call printErrorString
    mov rcx, rax
    call exit

Relevant data members

GUID_EFI_SIMPLE_FILE_SYSTEM_PROTOCOL    dd 0x964e5b22
                    dw 0x6459, 0x11d2
                    db 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b

;****************************************
;*** Stores values related to the     ***
;*** UEFI LocateHandleBuffer function ***
;****************************************
LOCATE_PROTOCOL_SEARCH_PROTOCOL dq 2
LOCATE_PROTOCOL_HANDLE_COUNT dq 0
LOCATE_PROTOCOL_BUFFER_ADDRESS dq 0

;**********************************************
;*** Stores values related to the UEFI      ***
;*** Simple File System openVolume function ***
;**********************************************
OPEN_VOLUME_FILE_PROTOCOL_HANDLE_ADDRESS dq 0

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文