Compiling an assembly file to .efi, in edk2 environment #4778
Ravi969696
started this conversation in
General
Replies: 7 comments 10 replies
-
Please post the actual build failure output. Not some fragment of an error. We don’t see what you see. The tools throw lots of context about the error. If you want to get your problem resolved you need to make it easy for the experts to look at your error. Don’t make me grep the code base and try to reverse engineer what error you hit and then tell you all the information you did not send me. I’ve got other stuff I’d rather work on. It is you job reporting an error to make it an easy button for us to figure out. When I file a bug for a compiler error I don’t tell them to build the edk2, I make a simple at desk command line example that reproduces the error. And like magic it gets fixed right away. The person fixing the compiler can’t figure out how to install, run, and debug 100 Radom projects a day. You kind of have a limited chance to ask the experts. You should really try to maximize you chances. This is not criticism, this is really good career advice…. Think about how you would process the bug report you wrote, they will get much better.Sent from my iPhoneOn Aug 31, 2023, at 10:42 PM, Ravi969696 ***@***.***> wrote:
Hi All
The issue is, i am trying to execute an old .efi file (an assembly file, compiled in fasm)
when i execute this file in slimboot(+ uefi payload), at lines where some of the uefi functions are called(protocalhandler()), a general protection exception is thrown.
But same file executes perfectly in AMI BIOS
what i am trying to do is(any other suggestions are appreciated), is to compile this assembly file in edk2 environment (in PldPlatform/PldCommonPkg/Application/) i took the example of GPIO dump present in the same path and made the inf file, but i am getting error saying that "Recipe to make assembly file is missing"
Thanks
—Reply to this email directly, view it on GitHub, or unsubscribe.You are receiving this because you are subscribed to this thread.Message ID: ***@***.***>
|
Beta Was this translation helpful? Give feedback.
2 replies
-
Ravi,
This is the link error:
Build/EhlPlatformPkgX64/DEBUG_GCC5/X64/PldPlatform/PldCommonPkg/Application/fasm/fasm/DEBUG/AutoGen.c:718: undefined reference to `main’
OK so here is some background of “how it works” TM to help you debug
The entry point for edk2 images is _ModuleEntryPoint. You don’t generally have to code this as it lives in a library. You pulled in UefiApplicationEntryPoint lib so this is your entry point [1]. This entry point calls some build auto generated code that glues things together. For example the entry point is called from ProcessModuleEntryPointList*[2]. This is why your failing AutoGen.c file lives in the build output since it is generated from parsing the INF file.
Your farm.inf is parsed to generate the AutoGen.c. Your line:
ENTRY_POINT = main
Tells the build to make ProcessModuleEntryPointList() [2] call main(). You can look in Build/EhlPlatformPkgX64/DEBUG_GCC5/X64/PldPlatform/PldCommonPkg/Application/fasm/fasm/DEBUG/AutoGen.c and see the code that got generated.
So your issue is main() is missing from fast.asm. I’m not clear what your fast.asm file actually is? I’ll assume some kind of assembler? Side note the edk2 tends to use NASM for assembly as it supports a lot of different toolchains, and if we can’t use NASM there can always be an *.S unix assembler files.
OK so now I need guess what you are trying to do since I don’t have access to fast.asm …. But at least you attached enough info to make it easy for me to help you so thanks for that.
1) fast.asm is just an assembler file and you want it to run. It does not call C code.
OK os you just need to add this line to your assembler. The ASM_FUNC makes it global so the linker can see it and adds an extra “_” if your complier adds “_” in front of C symbols (the compilers we use are mixed on if they do this, so the macro abstracts that).
ASM_FUNC (_ModuleEntryPoint)
If you need to access the arguments they will be passed in registers. I see from the build output you are using X64 so that would be [3]:
Rcx - EFI_HANDLE
Rdx - EFI_SYSTEM_TABLE *
You need to remove UefiApplicationEntryPoint and all the other libs.
2) Your crazy and you are trying to write a UEFI Shell command in assembler.
3) You some how lost the source to something and you only have he reveersed engineered assembler from a C app?
Same answer for these 2…
You need to add in the missing ASM_FUNC (_ModuleEntryPoint) entry point and get the arguments in the register.
You require UefiApplicationEntryPoint, but you only need to list the libs you actually call into from your assembly code.
If you trim the [LibrayClasses] section down to UefiApplicationEntryPoint you will get link failures for the missing libs and you can then only add back the ones you actually need. This is not perfect as one of the libraries you include may include other libraries. But it will get ride of the any less common library.
[1] https://github.com/tianocore/edk2/blob/master/MdePkg/Library/UefiApplicationEntryPoint/ApplicationEntryPoint.c#L34
<https://github.com/tianocore/edk2/blob/master/MdePkg/Library/UefiApplicationEntryPoint/ApplicationEntryPoint.c#L34>[2] https://github.com/tianocore/edk2/blob/master/MdePkg/Library/UefiApplicationEntryPoint/ApplicationEntryPoint.c#L58C12-L58C12
[3] https://uefi.org/specs/UEFI/2.10/02_Overview.html#x64-platforms
On a side note you have the libraries listed under the INF file in your DSC. This is not the default way to do things, this is usually the override for making one driver do something different. There are more general sections that do global library picking for all drivers.
Thanks,
Andrew Fish
PS Sorry for the long answer but I sometimes turn these answers into mini blog posts as I’ve gotten feedback people other than the person debugging the issue find them useful to enhance their general understanding, and make it easier to debug if they hit a related issue in the future.
… On Sep 1, 2023, at 11:40 AM, Ravi969696 ***@***.***> wrote:
sorry its fasm.inf not fasm.inc
—
Reply to this email directly, view it on GitHub <#4778 (reply in thread)>, or unsubscribe <https://github.com/notifications/unsubscribe-auth/AD4ZCO6MYGVP7CORH5N2MITXYIT2TANCNFSM6AAAAAA4HBVWVY>.
You are receiving this because you commented.
|
Beta Was this translation helpful? Give feedback.
2 replies
-
On Sep 11, 2023, at 7:42 AM, Ravi969696 ***@***.***> wrote:
Hello Andrew
i tried the solution provided by you, but did not work, it seems that the assembler is not even trying to open fasm.asm(even if i deliberately make syntax errors, i see no errors), i think somehow the build system is not aware of this assembly file.
You are using GCC5 tools so .asm file are not supported [1]. You have to use .s (.S) for gnu assembler. Note GNU assembler is not the same as MASM (.asm) you you have to port the assembly code to GNU assembler.
Our default assembler for x86 is NASM not MASM (.asm). The reason is MASM (.asm) is for VC++ is not compatible with GNU assembler (.s) and we had to have 2 copies of all the assembly files. By using NASM we got to an assembly file that could be shared between toolchains.
Random Google (or maybe Bing since it is MASM) shows [2]
[1] https://github.com/tianocore/edk2/blob/master/BaseTools/Conf/build_rule.template#L158
[2] https://left404.com/2011/01/04/converting-x86-assembly-from-masm-to-nasm-3/
… —
Reply to this email directly, view it on GitHub <#4778 (reply in thread)>, or unsubscribe <https://github.com/notifications/unsubscribe-auth/AD4ZCO2CA3L3R3OPQXCFI5DXZ4PMPANCNFSM6AAAAAA4HBVWVY>.
You are receiving this because you commented.
|
Beta Was this translation helpful? Give feedback.
1 reply
-
I forgot to mention the NASM files have a *.nasm extension. There are 450+ in the edk2 code base you can use as reference.
/Volumes/Case/edk2(master)>find . -iname '*.nasm' | wc -l
458
Thanks,
Andrew Fish
… On Sep 12, 2023, at 7:13 AM, Ravi969696 ***@***.***> wrote:
Andrew,
Thank you for the information
—
Reply to this email directly, view it on GitHub <#4778 (reply in thread)>, or unsubscribe <https://github.com/notifications/unsubscribe-auth/AD4ZCO5CSQW5JQV7X3S5CFTX2BU2DANCNFSM6AAAAAA4HBVWVY>.
You are receiving this because you commented.
|
Beta Was this translation helpful? Give feedback.
1 reply
-
There are a lot of random sources of General Protection faults. It is usually good to look at the assembly instruction that faulted to get some clues as to what might have happened? Do figure out what instruction is located at RIP: 00000000772877B8
Thanks,
Andrew Fish
… On Sep 12, 2023, at 9:30 AM, Ravi969696 ***@***.***> wrote:
Before we jump in to port entire code
i would like to ask you: as per your opinion. why calling a funtion EFI_BOOT_SERVICES.HandleProtocol, results in the following exception in a slimboot + uefi environment, but work perfectly fine in AMI BIOS
!!!! X64 Exception Type - 0D(#GP - General Protection) CPU Apic ID - 00000000 ! !!!
ExceptionData - 0000000000000000
RIP - 00000000772877B8, CS - 0000000000000038, RFLAGS - 0000000000010246
RAX - 00000000769D2000, RCX - 00000000773DFCA0, RDX - 00000000769D1408
RBX - 8000000000000003, RSP - 00000000791B9FA8, RBP - 0000000077387E98
RSI - 0000000000000009, RDI - 00000000769D12F5
R8 - 00000000791B9EC2, R9 - 000000008101E000, R10 - 0000000000000001
R11 - 00000000791B9EC3, R12 - 00000000791BA2B8, R13 - 00000000791BA2C8
R14 - 00000000791BA438, R15 - 0000000000000000
DS - 0000000000000030, ES - 0000000000000030, FS - 0000000000000030
GS - 0000000000000030, SS - 0000000000000030
CR0 - 0000000080010033, CR2 - 0000000000000000, CR3 - 0000000078C01000
CR4 - 0000000000000668, CR8 - 0000000000000000
DR0 - 0000000000000000, DR1 - 0000000000000000, DR2 - 0000000000000000
DR3 - 0000000000000000, DR6 - 00000000FFFF0FF0, DR7 - 0000000000000400
GDTR - 0000000078BD5B18 0000000000000047, LDTR - 0000000000000000
IDTR - 0000000078379018 0000000000000FFF, TR - 0000000000000000
FXSAVE_STATE - 00000000791B9C00
Thanks
—
Reply to this email directly, view it on GitHub <#4778 (reply in thread)>, or unsubscribe <https://github.com/notifications/unsubscribe-auth/AD4ZCO35MWWHP4HU3TLXAPTX2CE4DANCNFSM6AAAAAA4HBVWVY>.
You are receiving this because you commented.
|
Beta Was this translation helpful? Give feedback.
1 reply
-
OK so 1st off I filled a BZ as the exception handler should dump the 15 bytes (max x86_64 instruction size) of the faulting instruction:
https://bugzilla.tianocore.org/show_bug.cgi?id=4551
That way you can put those bytes through an online assembler and figure out the faulting instruction.
The .efi is just a PE/COFF executable so you should be able to objdump it or pull it into gdb. I mostly work on Mac so my object dumping daily driver tools are different so I don’t know the correct procedures, but you should be able to search for those and give it a try.
The thing you need to figure out is the address your app got loaded into as the app is linked at a fixed address and then relocated to the load address. So you have to do some math based on the load address to find the matching instruction.
Thanks,
Andrew Fish
… On Sep 13, 2023, at 10:17 AM, Ravi969696 ***@***.***> wrote:
yeah; thought of that,
but the fasm (fast assembler ), that we are using only generates the executable(in this case .efi)
thanks
Ravi
—
Reply to this email directly, view it on GitHub <#4778 (reply in thread)>, or unsubscribe <https://github.com/notifications/unsubscribe-auth/AD4ZCO2CQICBVGMRPT4WCFDX2HTD7ANCNFSM6AAAAAA4HBVWVY>.
You are receiving this because you commented.
|
Beta Was this translation helpful? Give feedback.
2 replies
-
On Sep 16, 2023, at 3:18 PM, Ravi969696 ***@***.***> wrote:
on further investigation:
if i execute the below instruction, i am getting FSP-T: CAR Init printed on the screen and then it dies
mov eax, cr0
mov cr0, eax
There is a timer running in EFI that dispatches events so you can’t just change CPU modes. Are you in protected mode or long mode? Long mode requires paging is enabled so you have to properly transition to protected mode to turn off paging?
If you are trying to take over from EFI, like an OS loader, you need to gBS->ExitBootServices() [1] to shutdown EFI and take over the system. Then you can gRT->ResetSystem() [2] to reboot after your code is done.
If you want to get back into EFI blocking interrupts for a long period of time could potentially break things. Short trips to real mode are OK as long as you properly restore all the state.
[1] https://uefi.org/specs/UEFI/2.10/07_Services_Boot_Services.html#efi-boot-services-exitbootservices
[2] https://uefi.org/specs/UEFI/2.10/08_Services_Runtime_Services.html#reset-system
You can
Thanks,
Andrew Fish
PS The edk2 repo has code that does x86 mode transitions so you can call 16-bit legacy BIOS APIs. It is quite tricky to get right and it is generally hard to code. You need to remember the x86 instruction encodings have different meanings in different modes, so if you assembler file does not switch the modes of assembly the code you write is not the form of the instruction that is executing. Also a lot of times debuggers are not really optimized for mode shifting, so they will disassemble in the wrong mode.
https://github.com/tianocore/edk2/blob/master/MdePkg/Library/BaseLib/X86Thunk.c#L157
https://github.com/tianocore/edk2/blob/master/MdePkg/Library/BaseLib/X64/Thunk16.nasm
PPS The CSM is the Compatibility Support Modules (We jokingly call it the Furball since we hoped to get rid of it at some point). The CSM is how you glue legacy BIOS into EFI. Some of the OVMF VMs use this driver to glue in CSM code.
https://github.com/tianocore/edk2/tree/master/OvmfPkg/Csm/LegacyBiosDxe
… Note:
i am just checking in the above 2 lines, that i am able to change cr0 or not
the above execute perfectly fine in other BIOS environments like AMI BIOS
Thanks
Ravi
—
Reply to this email directly, view it on GitHub <#4778 (reply in thread)>, or unsubscribe <https://github.com/notifications/unsubscribe-auth/AD4ZCO6YOBFLBNF624YODMDX2X3RLANCNFSM6AAAAAA4HBVWVY>.
You are receiving this because you commented.
|
Beta Was this translation helpful? Give feedback.
1 reply
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
Hi All
The issue is, i am trying to execute an old .efi file (an assembly file, compiled in fasm)
when i execute this file in slimboot(+ uefi payload), at lines where some of the uefi functions are called(protocalhandler()), a general protection exception is thrown.
But same file executes perfectly in AMI BIOS
what i am trying to do is(any other suggestions are appreciated), is to compile this assembly file in edk2 environment (in PldPlatform/PldCommonPkg/Application/) i took the example of GPIO dump present in the same path and made the inf file, but i am getting error saying that "Recipe to make assembly file is missing"
Thanks
Beta Was this translation helpful? Give feedback.
All reactions