为什么OpenVolume在QEMU中引起#GD错误?
我正在研究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.
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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论