flat assembler
Message board for the users of flat assembler.
Index
> OS Construction > Understand GetMemoryMap function Goto page 1, 2 Next |
Author |
|
Feryno 19 Nov 2020, 20:38
how does you binary look like?
Code: sub rsp,8*(4+1) ;... lea rax,[DescriptorVersion] mov [rsp+8*(4+0)],rax lea r9,[DescriptorSize] lea r8,[MapKey] lea rdx,[MemoryMap] lea rcx,[MemoryMapSize] and qword [rcx],0 ; set MemoryMapSize initially to 0 to force the function to fail and to return necessary buffer size for the second call mov rax,[...] call rax ; If the MemoryMap buffer is too small, the EFI_BUFFER_TOO_SMALL error code is returned and the MemoryMapSize value contains the size of the buffer needed to contain the current memory map. The actual size of the buffer allocated for the consequent call to GetMemoryMap() should be bigger than the value returned in MemoryMapSize, since allocation of the new buffer may potentially increase memory map size. mov rcx,error_EFI_BUFFER_TOO_SMALL cmp rcx,rax jnz fail ; second round lea rax,[DescriptorVersion] mov [rsp+8*(4+0)],rax lea r9,[DescriptorSize] lea r8,[MapKey] lea rdx,[MemoryMap] lea rcx,[MemoryMapSize] ; now it contains buffer size required for the memory map ; you can also slightly increase the buffer size, e.g. add qword [rcx],100h but most of times it is not necessary mov rax,[...] call rax if EFI_SUCCESS = 0 test rax,rax else cmp rax,EFI_SUCCESS end if jnz fail ; ... add rsp,8*(4+1) |
|||
19 Nov 2020, 20:38 |
|
Fulgurance 20 Nov 2020, 19:07
What do you need to see ? Some implementations ?
And i have the same problem if I try to use AllocatePages or AllocatePool : Code: format pe64 efi entry Main section '.text' code readable executable include "UEFI/UEFI.fasm" Main: mov [UEFIHandle],rcx mov [UEFISystemTable],rdx push rbp mov rdx,[UEFISystemTable] UEFI ConOut,SimpleTextOutputProtocol,ClearScreen,[rdx+SystemTable.ConOut] mov rdx,[UEFISystemTable] UEFI ConOut,SimpleTextOutputProtocol,EnableCursor,[rdx+SystemTable.ConOut],0 mov rdx,[UEFISystemTable] UEFI ConOut,SimpleTextOutputProtocol,SetAttribute,[rdx+SystemTable.ConOut],0x02 mov rdx,[UEFISystemTable] UEFI ConOut,SimpleTextOutputProtocol,OutputString,[rdx+SystemTable.ConOut],SystemText mov rdx,[UEFISystemTable] UEFI ConOut,SimpleTextOutputProtocol,SetAttribute,[rdx+SystemTable.ConOut],0x0F mov rdx,[UEFISystemTable] UEFI ConOut,SimpleTextOutputProtocol,OutputString,[rdx+SystemTable.ConOut],Text ;mov rdx,[UEFISystemTable] ;UEFI BootServices,BootServices,AllocatePool,MemoryType.ConventionalMemory,5294967296,MemoryMapBufferAddress mov rdx,[UEFISystemTable] UEFI BootServices,BootServices,AllocatePages,0,7,1,PhysicalAddress cmp rax,0 je Success cmp rax,1 je OutOfResources cmp rax,2 je OutOfResources cmp rax,3 je OutOfResources cmp rax,4 je OutOfResources cmp rax,5 je OutOfResources cmp rax,6 je OutOfResources jmp $ Success: mov rdx,[UEFISystemTable] UEFI ConOut,SimpleTextOutputProtocol,OutputString,[rdx+SystemTable.ConOut],TestText jmp $ OutOfResources: mov rdx,[UEFISystemTable] UEFI ConOut,SimpleTextOutputProtocol,OutputString,[rdx+SystemTable.ConOut],Test1Text jmp $ ;mov rdx,[UEFISystemTable] ;UEFI BootServices,BootServices.GetMemoryMap,MemoryMapSize,MemoryMap,MapKey,DescriptorSize,DescriptorVersion section '.data' data readable writable include "UEFI/GUID.fasm" include "UEFI/Interface.fasm" include "UEFI/DataTypes.fasm" include "UEFI/TableHeader.fasm" include "UEFI/AllocateType.fasm" include "UEFI/BootServices.fasm" include "UEFI/GetMemoryMapStatusCodes.fasm" include "UEFI/GraphicsOutputBltOperation.fasm" include "UEFI/GraphicsOutputProtocol.fasm" include "UEFI/LocateSearchType.fasm" include "UEFI/MemoryDescriptor.fasm" include "UEFI/MemoryType.fasm" include "UEFI/SimpleTextOutputProtocol.fasm" include "UEFI/SystemTable.fasm" UEFIHandle: dq ? UEFISystemTable: dq ? SystemText: du '* ',0 Text: du 'Starting AllocatePool test',0 TestText: du 'Test OK',0 Test1Text: du 'Impossible to allocate',0 PhysicalAddress: dq ? MemoryMapBufferAddress: dq 0 ;MemoryMapSize: dq 4096 ;MemoryMap: rb 4096 ;MapKey: dq 0 ;DescriptorSize: dq 48 ;DescriptorVersion: dq 0 ConOut functions works, I think something is bad with my argument, but what ? Don't see error message, it's just to return something. |
|||
20 Nov 2020, 19:07 |
|
Feryno 20 Nov 2020, 20:41
Fulgurance wrote: What do you need to see ? your binary |
|||
20 Nov 2020, 20:41 |
|
Fulgurance 20 Nov 2020, 21:05
I attached him. You have sources and assembled file
|
|||||||||||
20 Nov 2020, 21:05 |
|
Fulgurance 21 Nov 2020, 15:19
Do you found the problem ?
|
|||
21 Nov 2020, 15:19 |
|
Feryno 21 Nov 2020, 17:28
Code: mov rdx,[UEFISystemTable] UEFI BootServices,BootServices,AllocatePages,0,7,1,PhysicalAddress cmp rax,0 je Success cmp rax,1 je OutOfResources cmp rax,2 je OutOfResources cmp rax,3 je OutOfResources cmp rax,4 je OutOfResources cmp rax,5 je OutOfResources cmp rax,6 je OutOfResources jmp $ the above assembles into this: Code: .text:00000000004010E0 mov rdx, cs:qword_402020 .text:00000000004010E7 sub rsp, 20h .text:00000000004010EB mov rbx, [rdx+60h] .text:00000000004010EF mov rax, [rbx+28h] .text:00000000004010F3 mov rcx, 0 .text:00000000004010FA mov rdx, 7 .text:0000000000401101 mov r8, 1 .text:0000000000401108 mov r9, 4020A2h .text:000000000040110F call rax .text:0000000000401111 add rsp, 20h .text:0000000000401115 cmp rax, 0 .text:0000000000401119 jz short loc_401141 .text:000000000040111B cmp rax, 1 .text:000000000040111F jz short loc_401167 .text:0000000000401121 cmp rax, 2 .text:0000000000401125 jz short loc_401167 .text:0000000000401127 cmp rax, 3 .text:000000000040112B jz short loc_401167 .text:000000000040112D cmp rax, 4 .text:0000000000401131 jz short loc_401167 .text:0000000000401133 cmp rax, 5 .text:0000000000401137 jz short loc_401167 .text:0000000000401139 cmp rax, 6 .text:000000000040113D jz short loc_401167 .text:000000000040113F .text:000000000040113F loc_40113F: ; CODE XREF: _ModuleEntryPoint:loc_40113F↓j .text:000000000040113F jmp short loc_40113F see the line .text:0000000000401108 mov r9, 4020A2h this is meant to be pointer to qword holding physical address it should be aligned on its size boundary for performance reasons (this shouldn't be the case of your function returning with error) but what if uefi must allocate you program to different virtual address so binary header is not at 400000h, code does not start at 401000? reloc section could fix that or it is possible to generate position independent code so instead of mov r9,address do it this way: lea r9,[address] this translates into RIP-relative addressing mode which is position independent and you do not need reloc section how do you know what the values 0, 7 mean? why don't you create header file where you define AllocateAnyPages = 0 EfiConventionalMemory = 7 and use this so your source code is easier to understand? but this is still not the reason why alloc failed using debugger and stepping you code I got this: https://pasteboard.co/JBpLMTd.png AllocatePages returned 8000000000000002h = EFI_INVALID_PARAMETER UEFI spec.pdf In general, UEFI OS loaders and UEFI applications should allocate memory (and pool) of type EfiLoaderData. UEFI boot service drivers must allocate memory (and pool) of type EfiBootServicesData. UEFI runtime drivers should allocate memory (and pool) of type EfiRuntimeServicesData (although such allocation can only be made during boot services time). you set the second param to 7 = EfiConventionalMemory that's why alloc failed when I set MemoryType = EfiLoaderData then the alloc succeded and returned rax=0 |
|||
21 Nov 2020, 17:28 |
|
Fulgurance 21 Nov 2020, 19:21
Oh I love your explanation !
How do you have log like with hexadecimal and code ? Is it possible to have the same log with Virtualbox ? And I have already implemented for Types (AllocateAnyPages, EfiConventionalMemory ...etc), it's just because I check where is the problem) I don't understand very good something, the difference between LEA and MOV, MOV can't put address into register ? And what is reloc section ? |
|||
21 Nov 2020, 19:21 |
|
Feryno 22 Nov 2020, 08:04
using MOV you need reloc section
using LEA no need reloc, it generates position independent code as it translates into: lea r9,[rip+imm32] I recommend LEA and forget using mov for any address the static analysis was done using IDA the debugger is available to download here in FASM forum in the projects and ideas section here with qemu (2 MB) http://fdbg.x86asm.net/fdbg.uefi.0002.qemu.zip you need an utility to read/write 1,44 MB floppy images and copy your binary into the floppy image, then run the bat file and also look at the included pictures and read the txt file in the floppy image for help |
|||
22 Nov 2020, 08:04 |
|
Fulgurance 22 Nov 2020, 11:54
Okay, thanks for your advice. I return to you if I have any others questions,
Oh yes I know already Qemu, I just ask if I can debug like Qemu with virtualbox. But it's more simple for me to install, I use Linux! I just thinking about something, I think it's more complicated to implement that for my macro now, I need to check if my argument is an address or value, but difficult to do that I think.... (to check if I use mov or lea instruction) I have just question, if I want to load address with stack, I have an error, because lea can't affect value to stack, I need before to work with register and after put value into stack ? For example, I try to apply your advices with GetMemoryMap, but this don't work, why now ? Code: format pe64 efi entry Main section '.text' code readable executable Main: mov [UEFIHandle],rcx mov [UEFISystemTable],rdx push rbp ;-------------------------------------------- mov rdx,[UEFISystemTable] push rbp sub rsp,0x20 mov rcx,[rdx+SystemTable.ConOut] mov rax,[rcx+SimpleTextOutputProtocol.ClearScreen] call rax add rsp,0x20 ;-------------------------------------------- mov rdx,[UEFISystemTable] push rbp sub rsp,5*8 mov rcx,[rdx+SystemTable.BootServices] mov rax,[rcx+BootServices.GetMemoryMap] lea rcx,[MemoryMapSize] lea rdx,[MemoryMap] lea r8,[MapKey] lea r9,[DescriptorSize] lea r10,[DescriptorVersion] mov qword[rsp + 8*4],r10 call rax add rsp,5*8 ;-------------------------------------------- cmp rax,0 ;jne Fail ;-------------------------------------------- Success: mov rdx,[UEFISystemTable] push rbp sub rsp,0x20 mov rcx,[rdx+SystemTable.ConOut] mov rax,[rcx+SimpleTextOutputProtocol.OutputString] mov rdx,TestText call rax add rsp,0x20 ;-------------------------------------------- Fail: jmp $ section '.data' data readable writable include "UEFI/GUID.fasm" include "UEFI/Interface.fasm" include "UEFI/DataTypes.fasm" include "UEFI/TableHeader.fasm" include "UEFI/AllocateType.fasm" include "UEFI/BootServices.fasm" include "UEFI/GetMemoryMapStatusCodes.fasm" include "UEFI/GraphicsOutputBltOperation.fasm" include "UEFI/GraphicsOutputProtocol.fasm" include "UEFI/LocateSearchType.fasm" include "UEFI/MemoryDescriptor.fasm" include "UEFI/MemoryType.fasm" include "UEFI/SimpleTextOutputProtocol.fasm" include "UEFI/SystemTable.fasm" UEFIHandle: dq ? UEFISystemTable: dq ? SystemText: du '* ',0 Text: du 'Starting AllocatePool test',0 TestText: du 'Test OK',0 Test1Text: du 'Impossible to allocate',0 PhysicalAddress: dq ? MemoryMapBufferAddress: dq 0 MemoryMapSize: dq 8 MemoryMap: dq ? MapKey: dq ? DescriptorSize: dq ? DescriptorVersion: dd ? |
|||
22 Nov 2020, 11:54 |
|
Feryno 22 Nov 2020, 21:44
lea r10,[...]
mov [rsp+...],r10 You did it well, that's the right way to go I do not know whether in FASM there is such a way (maybe already implemented, maybe creating a new macro?) but in C using something like &address translates into lea reg,[address] while without & it translates into mov reg,[address] / mov [address],reg of course you can define it to be an address and then no need to use & then you have to use *address to obtain the value stored at the address like mov reg,[address] but I believe it is solvable in FASM to tell it whether to use lea (input param is a pointer) or whether to use mov (input is some value like dword or qword) |
|||
22 Nov 2020, 21:44 |
|
Fulgurance 22 Nov 2020, 22:18
Okay. I progress good x)
And for the code, what is the problem now? |
|||
22 Nov 2020, 22:18 |
|
Feryno 23 Nov 2020, 14:17
the problem is explained in one of my previous posts where I showed how to call GetMemoryMap (you need to call it twice, the first one always returning an error but filled the size of buffer necessary for the next call)
|
|||
23 Nov 2020, 14:17 |
|
Fulgurance 23 Nov 2020, 15:34
Oh yes, but I try to understand something, the first time when you call him, you have an error yes (normal),bbut how can I check if it's error by me, or the good error?
Because the handbook say : Quote: If the MemoryMap buffer is too small, the EFI_BUFFER_TOO_SMALL error code is returned and the Normally I have error code (into rax I think), but now,I don't have any code error when I test rax How can I test if I have EFI_BUFFER_TOO_SMALL,or if its just coding error? |
|||
23 Nov 2020, 15:34 |
|
Feryno 23 Nov 2020, 20:14
Code: EFI_SUCCESS = 0 EFIERR = 8000000000000000h EFI_LOAD_ERROR = EFIERR or 1 EFI_INVALID_PARAMETER = EFIERR or 2 EFI_UNSUPPORTED = EFIERR or 3 EFI_BAD_BUFFER_SIZE = EFIERR or 4 EFI_BUFFER_TOO_SMALL = EFIERR or 5 EFI_NOT_READY = EFIERR or 6 EFI_DEVICE_ERROR = EFIERR or 7 EFI_WRITE_PROTECTED = EFIERR or 8 EFI_OUT_OF_RESOURCES = EFIERR or 9 EFI_VOLUME_CORRUPTED = EFIERR or 10 EFI_VOLUME_FULL = EFIERR or 11 EFI_NO_MEDIA = EFIERR or 12 EFI_MEDIA_CHANGED = EFIERR or 13 EFI_NOT_FOUND = EFIERR or 14 EFI_ACCESS_DENIED = EFIERR or 15 EFI_NO_RESPONSE = EFIERR or 16 EFI_NO_MAPPING = EFIERR or 17 EFI_TIMEOUT = EFIERR or 18 EFI_NOT_STARTED = EFIERR or 19 EFI_ALREADY_STARTED = EFIERR or 20 EFI_ABORTED = EFIERR or 21 EFI_ICMP_ERROR = EFIERR or 22 EFI_TFTP_ERROR = EFIERR or 23 EFI_PROTOCOL_ERROR = EFIERR or 24 mov rcx,EFI_BUFFER_TOO_SMALL cmp rax,rcx don't forget to set MemoryMapSize to 0 before the first call of GetMemoryMap, this forces the GetMemoryMap to return the above error code and fill the value at MemoryMapSize: Code: lea rcx,[MemoryMapSize] and qword [rcx],0 call ... mov rcx,... cmp rax,rcx |
|||
23 Nov 2020, 20:14 |
|
Fulgurance 25 Nov 2020, 15:30
And I have question about reloc, is it "org directive" like? If I use reloc section, I can save instructions no?
|
|||
25 Nov 2020, 15:30 |
|
Feryno 25 Nov 2020, 16:23
no need to use reloc if you generate RIP-relative addressing mode everywhere (using LEA reg,[address] instead of mov reg,address)
I found few firmwares where uefi refused to load executable if reloc missing... in that case add reloc section and one dummy referrence so the reloc is not empty org directive is used for something else |
|||
25 Nov 2020, 16:23 |
|
Fulgurance 01 Dec 2020, 22:55
I already applied your advice with LEA instruction, but when I call GetMemoryMap, this don't work.
What is the problem ? (Text don't appear because GetMemoryMap always fail Code: format pe64 efi entry Main section '.text' code readable executable Main: mov [UEFIHandle],rcx mov [UEFISystemTable],rdx push rbp ;-------------------------------------------- mov rdx,[UEFISystemTable] push rbp sub rsp,0x20 mov rcx,[rdx+SystemTable.ConOut] mov rax,[rcx+SimpleTextOutputProtocol.ClearScreen] call rax add rsp,0x20 ;-------------------------------------------- mov rdx,[UEFISystemTable] push rbp sub rsp,5*8 mov rcx,[rdx+SystemTable.BootServices] mov rax,[rcx+BootServices.GetMemoryMap] lea rcx,[MemoryMapSize] lea rdx,[MemoryMap] lea r8,[MapKey] lea r9,[DescriptorSize] lea r10,[DescriptorVersion] mov qword[rsp + 8*4],r10 call rax add rsp,5*8 ;-------------------------------------------- cmp rax,1 jne Fail ;-------------------------------------------- Success: mov rdx,[UEFISystemTable] push rbp sub rsp,0x20 mov rcx,[rdx+SystemTable.ConOut] mov rax,[rcx+SimpleTextOutputProtocol.OutputString] mov rdx,TestText call rax add rsp,0x20 ;-------------------------------------------- Fail: jmp $ section '.data' data readable writable include "UEFI/GUID.fasm" include "UEFI/Interface.fasm" include "UEFI/DataTypes.fasm" include "UEFI/TableHeader.fasm" include "UEFI/AllocateType.fasm" include "UEFI/BootServices.fasm" include "UEFI/GetMemoryMapStatusCodes.fasm" include "UEFI/GraphicsOutputBltOperation.fasm" include "UEFI/GraphicsOutputProtocol.fasm" include "UEFI/LocateSearchType.fasm" include "UEFI/MemoryDescriptor.fasm" include "UEFI/MemoryType.fasm" include "UEFI/SimpleTextOutputProtocol.fasm" include "UEFI/SystemTable.fasm" UEFIHandle: dq ? UEFISystemTable: dq ? SystemText: du '* ',0 Text: du 'Starting GetMemoryMap test',0 TestText: du 'Test OK',0 MemoryMapSize: dq 0 MemoryMap: dq ? MapKey: dq ? DescriptorSize: dq ? DescriptorVersion: dd ? |
|||
01 Dec 2020, 22:55 |
|
Feryno 02 Dec 2020, 19:16
Fulgurance, I wrote it twice (19 Nov 2020, 21:38, 23 Nov 2020, 15:17) so I had to repeat it for the third time - please call it twice:
[0] on the first call, you must erase the value at MemoryMapSize, like: Code: ... lea rcx,[MemoryMapSize] and qword [rcx],0 call rax mov rcx,EFI_BUFFER_TOO_SMALL cmp rax,rcx it must fail with rax=EFI_BUFFER_TOO_SMALL but it fills the qword at MemoryMapSize with the desired size of the buffer [1] then you call it for the second time (now without erasing the MemoryMapSize value as it already contains the necessary buffer size) and it should return success Code: ... lea rcx,[MemoryMapSize] call rax if EFI_SUCCESS = 0 test rax,rax else mov rcx,EFI_SUCCESS cmp rax,rcx end if your code failed very likely due to insufficient value at MemoryMapSize (you didn't initialize it, you do not know how big buffer is necessary, but UEFI knows and returns the size on the first call which returns the necessary error code but fills the buffer size) Code: cmp rax,1 jne Fail this is a mistake, I posted you EFI return codes (23 Nov 2020, 21:14) and EFI_SUCCESS is 0, so do not compare the return value with 1... You are on the right way, improving, I believe you will now have success. |
|||
02 Dec 2020, 19:16 |
|
Fulgurance 02 Dec 2020, 22:40
Sorry Feryno, I try to understand. I sure after it's good.
But I don't understand one thing: Code: and qword [rcx],0 When you do that, the variable is set to 0,but I already set MemoryMapSize to 0 before no ? And I already copied the part of your example with Code: lea rcx,[MemoryMapSize] and qword [rcx],0 Now I'm not on my laptop, but later I paste you my code. |
|||
02 Dec 2020, 22:40 |
|
Goto page 1, 2 Next < Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.