The MASM Forum

Projects => ObjAsm => Topic started by: HSE on April 09, 2022, 07:53:46 AM

Title: UEFI UAsm64 ObjAsm
Post by: HSE on April 09, 2022, 07:53:46 AM
Hi All!!

Here some adaptation of johnsa's Unified Extensible Firmware Interface (UEFI) Example (http://masm32.com/board/index.php?topic=7942.msg88018#msg88018).

Code is that of Demo01B, with Triangle and Rectangle objects, but without Operative System  :biggrin: :biggrin: :biggrin:

Code (HelloOA.asm) Select

include efiOA.inc

% include @Environ(OBJASM_PATH)\Code\Macros\Model.inc   ;Include & initialize standard modules
SysSetup OOP, WIDE_STRING, EFI64;, DEBUG(CON)            ;Load OOP files and basic OS support

.data

    Handle           EFI_HANDLE 0
    SystemTablePtr   dq 0
    HelloMsg         dw 'H','e','l','l','o',' ','U','E','F','I',' ','W','o','r','l','d','!',13,10,0
    ;HelloMsg         dw 'Hello UEFI World!',13,10,0
   
    pConsole         PCONOUT 0
    pConsoleIn       PCONIN  0
    pBootServices    P_BOOT_SERVICES 0
    pRuntimeServices P_RUNTIME_SERVICES 0
   
    mapSize     UINTN  512*SIZEOF(EFI_MEMORY_DESCRIPTOR)
    descriptors EFI_MEMORY_DESCRIPTOR 512 DUP (<?>)
    mapKey      UINTN  0
    descSize    UINTN  0
    descVer     UINT32 0

include efiUtil.inc

MakeObjects Primer, Demo01

    pShape_1    $ObjPtr(Triangle)   NULL
    pShape_2    $ObjPtr(Rectangle)  NULL
   
.code

Main PROC FRAME imageHandle:EFI_HANDLE, SystemTable:PTR_EFI_SYSTEM_TABLE

    mov Handle,rcx
    mov SystemTablePtr,rdx

    mov rax,SystemTablePtr
    mov rsi,[rax].EFI_SYSTEM_TABLE.RuntimeServices
    mov pRuntimeServices,rsi
    mov rsi,[rax].EFI_SYSTEM_TABLE.BootServices
    mov pBootServices,rsi


    ;=====================================================================================
    ; The normal ASM way to make a 64bit FASTCALL.
    ;=====================================================================================
    sub rsp,20h
    lea rdx,HelloMsg
    mov rcx,SystemTablePtr
    mov rcx,[rcx + EFI_SYSTEM_TABLE_CONOUT]
    call qword ptr [rcx + EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL_OUTPUTSTRING]
    add rsp,20h

    ;=====================================================================================
    ; The smarter UASM way...
    ;=====================================================================================
    mov rcx,SystemTablePtr
    mov rax,[rcx].EFI_SYSTEM_TABLE.ConIn
    mov pConsoleIn,rax
    mov rax,[rcx].EFI_SYSTEM_TABLE.ConOut
    mov pConsole,rax
    invoke [rax].ConOut.OutputString, pConsole, L"Hello Smarter UEFI World!\r\n"

    mov rax, pConsole
    invoke [rax].ConOut.SetAttribute, pConsole, 017h

    ; Or if you have a list of calls to make against the same protocol/interface
    ASSUME rcx:PTR ConOut
    mov rcx,pConsole
    invoke [rcx].OutputString, pConsole, ADDR HelloMsg
    ASSUME rcx:NOTHING

   ;-----------------------------------
   ; Here !!!!!!!
   ;-----------------------------------
    mov rax, pConsole                                     ;Colors change
    invoke [rax].ConOut.SetAttribute, pConsole, 05Fh

    New Triangle                                          ;Create an new instance of Triangle
    mov pShape_1, xax                                     ;Store instance pointer

    OCall pShape_1::Triangle.Init, 10, 15                 ;Initialize Triangle
    OCall pShape_1::Shape.GetArea                         ;Invoke GetArea method of Triangle
    invoke PrintHexDWORD, eax                             ;Result = 75
    mov rcx,pConsole
    invoke [rcx].ConOut.OutputString, pConsole, L"\r\n"

    New Rectangle                                         ;Create an new instance of Rectangle
    mov pShape_2, xax                                     ;Store instance pointer
    OCall pShape_2::Rectangle.Init, 10, 15                ;Initialize Rectangle
    OCall pShape_2::Shape.GetArea                         ;Invoke GetArea method of Rectangle
    invoke PrintHexDWORD, eax                             ;Result = 150
    mov rcx,pConsole
    invoke [rcx].ConOut.OutputString, pConsole, L"\r\n"

    OCall pShape_2::Rectangle.GetPerimeter                ;Invoke GetPerimeter method
    invoke PrintHexDWORD, eax                             ;Result = 50
    mov rcx,pConsole
    invoke [rcx].ConOut.OutputString, pConsole, L"\r\n"

    Destroy pShape_2                                      ;Invoke Rectangle's Done and disposes it
    Destroy pShape_1                                      ;Invoke Triangle's Done and disposes it

    mov rax, pConsole                                     ;Colors change
    invoke [rax].ConOut.SetAttribute, pConsole, 07h

loop1:
    jmp loop1

    mov rax, pBootServices
    invoke [rax].EFI_BOOT_SERVICES.Exit, Handle, EFI_SUCCESS, 10, L"Complete\r\n"
   
    ret
Main ENDP

END Main


These are very elemental objects and calculations that only requiere to replace Win HeapAlloc and HeapFree by UEFI AllocatePool and FreePool. 

Just a little crazy how easy that can be done!

Regards, HSE
   
Note:
     I put an endless loop, to see results of calculations when booting. That can be removed if program run from UEFI Shell.
Title: Re: UEFI UAsm64 ObjAsm
Post by: Biterider on April 09, 2022, 03:35:13 PM
Hi HSE
Brilliant idea!  :thumbsup:
Now I fully understand what you meant here http://masm32.com/board/index.php?topic=7942.msg109335#msg109335 (http://masm32.com/board/index.php?topic=7942.msg109335#msg109335)
Since I haven't followed the UEFI thread closely (due to lack of time), I now need to install and run whatever is needed until I can build the binary.
Maybe I need help from you...

Biterider
Title: Re: UEFI UAsm64 ObjAsm
Post by: HSE on April 09, 2022, 10:04:47 PM
Hi Biterider!

Quote from: Biterider on April 09, 2022, 03:35:13 PM
Now I fully understand what you meant here http://masm32.com/board/index.php?topic=7942.msg109335#msg109335 (http://masm32.com/board/index.php?topic=7942.msg109335#msg109335)
That is the idea. With UEFI you can boot from an almost regular X64 file of any size. UEFI is more like a micro OS than Bios, but perhaps will requiere to build some functions, I don't know yet.

The ideal is that somebody else with OS knowledge make that if necesary, but PC with only UEFI are very recent, and that could take time. Developers of simple BIOS OS, FreeDos for example, are not interested. 

Quote from: Biterider on April 09, 2022, 03:35:13 PM
I now need to install and run whatever is needed until I can build the binary.
There is an additional UASM package in UASM EFI/UEFI Library v1.1 (http://www.terraspace.co.uk/uasm.html#p15) with explanations.

Quote from: Biterider on April 09, 2022, 03:35:13 PM
Maybe I need help from you...
I will try :biggrin:

I'm using QEMU (https://www.qemu.org/), but bitRAKE (also known as Rickey Bowers Jr.) help me with that. He have a package for UEFI development using fasmg in GitHub.

Regards, HSE.
Title: Re: UEFI UAsm64 ObjAsm
Post by: Biterider on April 11, 2022, 03:45:11 AM
Hi HSE
I'm still trying to build the dll.
I suspect I don't have the correct version installed as I can't find the original definition of RAWINTERFACE, RAWINTERFACEEND and STDFUNC. Maybe you can point me in the right direction?
From here http://masm32.com/board/index.php?topic=7942.0 (http://masm32.com/board/index.php?topic=7942.0) I copied the macros but there is still something wrong...

I think I messed things up trying to put everything in the right order.

So far I had VirtualBox installation, which I updated now, I got the package from UASM EFI/UEFI Library v1.1 and the EDK2 from Github.

Biterider
Title: Re: UEFI UAsm64 ObjAsm
Post by: HSE on April 11, 2022, 05:48:56 AM
Hi Biterider!!

STDFUNC etc. are UASM internal macros, then  not use " nomlib", but you are going to have collisions. In this simple objects only you have to disable CStr macro ( I presume you see modification in model.inc and object.inc). Perhaps more easy thing will be to make that macros external, and disable all internals. Brilliant HLL things in an assembler, soon or later, are a problem. Is just a first step now. UEFI is a great static object and later can be writed includes in a more ObjAsm way.

Usually UEFI only can read FAT32. I formated an USB because my hard disks are NFTS.

You have then tools to run UEFI Shell. VirtualBox UEFI not boot from USB, you have to make a trick.
https://www.howtogeek.com/187721/how-to-boot-from-a-usb-drive-in-virtualbox/

HSE.
Title: Re: UEFI UAsm64 ObjAsm
Post by: HSE on April 18, 2022, 05:02:07 AM
Hi All!

Here a little update because simulation work perfectly from boot.


Like expected very little things must be modified to run from UEFI. Even if calculations are complex, from OOP point of view objects used here are like Triangle and Rectangle examples. Beside SmplMath use CPU and FPU instructions, and not OS functions.

This must be improved a little. And something is not in place because I have to link from prompt.

But first point (http://masm32.com/board/index.php?topic=7942.msg109501#msg109501) is accomplished  :thumbsup:

Regards, HSE.

A note: I was thinking that nothing worked because emulation in qemu is  so.. slow...  :rolleyes:

Title: Re: UEFI UAsm64 ObjAsm
Post by: Biterider on May 29, 2022, 05:45:50 PM
Hi HSE
I've made some progress here.  :biggrin:
I was able to compile the DarylUEFI project and load the BOOT.efi created onto a fresh FAT32 formatted USB stick in the correct path.
I also created a VirtualBox machine and configured it to boot from the USB stick. Thanks for the link above.
When I started the machine I got into the "UEFI Interactive Shell" but I think this is not correct. BOOTX64.EFI should be running instead. I'm right?
Can you post your BOOTX64.EFI so I can be sure to have a working version?

Biterider
Title: Re: UEFI UAsm64 ObjAsm
Post by: HSE on May 29, 2022, 10:30:15 PM
 :biggrin: :biggrin:

Hi Biterider!!

I don't know. I just copy 2 times same file. In the prompt I type "app1"  :azn:

\masm32\bin64\uasm64\uasm64 -c -win64 -nomlib -Zp8 DarylUEFI.asm
link /dll /IGNORE:4086 DarylUEFI.obj %OBJASM_PATH%\Code\Lib\64\ObjAsm\ObjMemEFI.lib
\UEFI\EFI_Toolkit_2.0\build\tools\bin\fwimage app DarylUEFI.dll DarylUEFI.EFI
copy DarylUEFI.EFI e:\EFI\BOOT\BOOTX64.EFI
copy DarylUEFI.EFI e:\App1.EFI


I think that in QEMU booting work well, but I fail to set more than 1 core  :rolleyes:.

Regards, HSE.
Title: Re: UEFI UAsm64 ObjAsm
Post by: Biterider on May 30, 2022, 06:42:07 AM
Hi HSE
I'm getting closer to the problem. I found that VM tries to boot all available devices before dropping into the shell. This means that the USB stick is not recognized as a boot device. Did you do anything special about this?

Biterider
Title: Re: UEFI UAsm64 ObjAsm
Post by: HSE on May 30, 2022, 08:08:48 AM
Hi Biterider

Quote from: Biterider on May 30, 2022, 06:42:07 AM
This means that the USB stick is not recognized as a boot device. Did you do anything special about this?

Yes. I don't lost more time trying to boot from USB.

I just call the application from prompt.

HSE.
Title: Re: UEFI UAsm64 ObjAsm
Post by: HSE on May 30, 2022, 08:31:38 AM
 :biggrin: :biggrin: :biggrin:

Just a last shoot. And that work.

When you are in the shell, type "exit"

Boot maintenance manager > Boot options > Change boot order

If you don't see the hardisk, you can try Add boot option ( or other because I cliked everywhere  :biggrin:)
Title: Re: UEFI UAsm64 ObjAsm
Post by: Biterider on June 01, 2022, 06:20:16 AM
Hi HSE
I finally managed to launch DarylUEFI.EFI from the UEFI shell.
The trick for me was to use the Virtual Machine USB Boot program https://github.com/DavidBrenner3/VMUB/releases (https://github.com/DavidBrenner3/VMUB/releases). With this helper I could use the stick on the host and on the VM alternately without rebooting.
Now that I've done this step, the fun can begin  :cool:

Biterider
Title: Re: UEFI UAsm64 ObjAsm
Post by: HSE on June 01, 2022, 06:40:48 AM
Hi Biterider!

Quote from: Biterider on June 01, 2022, 06:20:16 AM
The trick for me was to use the Virtual Machine USB Boot program

I know existence of that trick. But it's a hack from 2013 that perhaps only work for VirtualBox of that time. I never tried that.

I pointed you to a easy current trick before (http://masm32.com/board/index.php?topic=9981.msg109428#msg109428), and that work. VirtualBox think that USB is a Hard Disk, and you see in Shell UEFI configuration like a Hard Disk.

Anyway, now I see the problem probably it's not related to USB :biggrin:

Multiprocess is about multicore systems, and you have only one core!!

This mean CPU2, then you have also CPU0 and CPU1 (at least 3 cores):
    mov tcb.ProcNum, 2


HSE

Title: Re: UEFI UAsm64 ObjAsm
Post by: Biterider on June 01, 2022, 06:55:44 AM
Hi HSE
Virtual Machine USB Boot V1.72 is from April 2018 and works perfectly with the latest VirtualBox version 6.1.
The reason I chose it is that creating the USB.vmdk didn't work for me. The VM didn't recognize a file system and what's worse, you have to detach and recreate the USB.vmdk file every time you boot your computer. The reason is that internally some UUIDs change during boot process and the previous file becomes unusable.
Maybe QEMU works differently, but I didn't have time to check it.

Biterider
Title: Re: UEFI UAsm64 ObjAsm
Post by: HSE on June 01, 2022, 07:08:03 AM
Quote from: Biterider on June 01, 2022, 06:55:44 AM
Virtual Machine USB Boot V1.72 is from April 2018 and works perfectly with the latest VirtualBox version 6.1.
The reason I chose it is that creating the USB.vmdk didn't work for me. The VM didn't recognize a file system and what's worse, you have to detach and recreate the USB.vmdk file every time you boot your computer. The reason is that internally some UUIDs change during boot process and the previous file becomes unusable.

Fantastic  :thumbsup: 

Here I only need one .vmdk for each different stick. Because I'm using only 2 sticks, I use a different VM for each stick  :biggrin:

Quote from: Biterider on June 01, 2022, 06:55:44 AM
Maybe QEMU works differently, but I didn't have time to check it.

There is a problem to make a machine with more than one core in QEMU. Then I'm using VirtualBox now.

Title: Re: UEFI UAsm64 ObjAsm
Post by: Biterider on June 01, 2022, 07:24:38 AM
Hi HSE
I find it odd that your machine behaves so differently than mine.
I've noticed that on my machine, even if I don't unplug the USB stick from the machine, the disk ID doesn't always stay the same after I boot the machine
In this situation I was forced to rebuild the USB.vmdk file.
After doing this several times, I got 2 files with the same disk id. I compared these 2 files and noticed that the referenced UUIDs had also changed, so only one of the files was working correctly in this session.

Nonetheless, it now works and I can boot the EFI binaries, which is a big step forward.  :cool:

Biterider
Title: Re: UEFI UAsm64 ObjAsm
Post by: Biterider on June 03, 2022, 07:55:20 AM
Hi
Thanks to HSE who did a great job I was finally able to run the translated UEFI Multiprocessor Demo by Daryl McDaniel (06/2010).
I've made some changes to the ObjAsm startup sequence and I think we need to discuss how best to integrate UEFI support.
This will come next  :cool:

Biterider

Title: Re: UEFI UAsm64 ObjAsm
Post by: HSE on June 03, 2022, 11:37:34 AM
:thumbsup: