作为我正在编写的UEFI应用程序的一部分,我希望我的应用程序在与此应用程序相同的文件夹中加载第二个应用程序。然而,要做到这一点,我需要知道当前运行文件的完整文件路径,并且我可以访问的固件中没有一个包含SIMPLE_FILE_SYSTEM_PROTOCOL示例(使用locateHandleBuffer)。
我的解决方案是获取正在运行的应用程序的LOADED_IMAGE_PROTOCOL,从那里获取设备路径(希望它是一个文件路径媒体设备路径),然后从那里开始。
问题是,我的应用程序的每次运行都会给出不同的设备路径。在某些固件上,只有设备路径的长度会改变,但在其他固件上,设备路径类型会改变。此外,在我尝试过的所有固件中,没有一个设备类型是有效的设备类型。
**我如何获得我试图加载的文件的设备路径?**是这段代码被破坏了,还是我做错了,或者两者兼而有之?
下面是来自应用程序的消息的一些截图。第一个是QEMU,第二个是来自我的笔记本电脑:
100d1x
的字符串
下面是执行设备路径打印的主程序流部分:
;Get the loaded image protocol for this handle
mov rcx, [EFI_HANDLE]
mov rdx, GUID_EFI_LOADED_IMAGE_PROTOCOL
call getProtocolFromHandle
;If getting the protocol failed, exit
cmp rax, [RETURN_SUCCESS]
je print
cmp rax, [RETURN_UNSUPPORTED]
jne error
mov rcx, [CONERR]
mov rdx, protocolNotFound
call printString
jmp printFinalString
print:
;If we have a loaded image protocol, then print information about the device path
add rcx, [OFFSET_LOADED_IMAGE_DEVICE_PATH_PROTOCOL]
mov r8, [rcx]
mov r9, [rcx]
mov r10, [rcx]
and r8, [MASK_FIRST_BYTE]
shr r8, 56
and r9, [MASK_SECOND_BYTE]
shr r9, 48
and r10, [MASK_THIRD_FOURTH_BYTES]
shr r10, 32
mov rcx, [CONOUT]
mov rdx, devicePathOne
call printString
mov rdx, r8
call printNumber
mov rdx, devicePathTwo
call printString
mov rdx, r9
call printNumber
mov rdx, devicePathThree
call printString
mov rdx, r10
call printNumber
mov rdx, newLine
call printString
字符串
下面是从给定句柄获取协议的代码部分:
;****************************************************
;*** getProtocolFromHandle [BOOT FUNCTION ONLY] ***
;*** Definition: Gets the address of the protocol ***
;*** of the specified GUID from the image handle ***
;*** Input: rcx is the image handle ***
;*** rdx is the protocol's GUID ***
;*** Output: rcx is a pointer to the protocol ***
;*** interface installed on that handle ***
;*****************************************************
getProtocolFromHandle:
;Save registers
push rdx
push r8
push r9
push r10
push r11
;Call the function
mov r8, ADDRESS_OPEN_PROTOCOL
mov r9, [EFI_HANDLE]
mov r10, 0
mov r11, [CONSTANT_OPEN_PROTOCOL_GET_PROTOCOL]
push r11 ;Arguments to the stack must be pushed in reverse order
push r10
sub rsp, 0x20
call [BOOT_SERVICES_OPEN_PROTOCOL]
;Restore registers
add rsp, 0x20
pop r10
pop r11
pop r11
pop r10
pop r9
pop r8
pop rdx
;Prepare return values and return
mov rcx, [ADDRESS_OPEN_PROTOCOL]
ret
型
下面是我认为对理解代码有用的数据的副本:
OFFSET_LOADED_IMAGE_DEVICE_PATH_PROTOCOL dq 28
ADDRESS_OPEN_PROTOCOL dq 0
MASK_FIRST_BYTE dq 0xff00000000000000
MASK_SECOND_BYTE dq 0x00ff000000000000
MASK_THIRD_FOURTH_BYTES dq 0x0000ffff00000000
型
**编辑:**今天运行这个应用程序的一个示例,在尝试获取值时崩溃了。这表明我的地址完全错误,但我不知道它是如何错误的:
1条答案
按热度按时间2ekbmq321#
我已经发现了这个问题。这里的主要问题是加载的图像设备路径的偏移量需要是32而不是28。即使协议以UINT 32(4字节)开始,它似乎在64位系统上填充了零以占用8字节。
另外,上面的代码的其余部分将无法工作,因为它有很多错误,需要大量的更改,但至少现在你可以得到指向设备路径协议的指针!
这样的东西会起作用:
字符串
这些函数看起来像这样(我使用的是tab宽度8,所以SO中的星号对齐可能看起来很奇怪,因为它的tab宽度是4):
型