From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-io1-f49.google.com (mail-io1-f49.google.com [209.85.166.49]) by mx.groups.io with SMTP id smtpd.web10.27305.1655444542989183108 for ; Thu, 16 Jun 2022 22:42:23 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@gmail.com header.s=20210112 header.b=S1ab33K1; spf=pass (domain: gmail.com, ip: 209.85.166.49, mailfrom: ayushdevel1325@gmail.com) Received: by mail-io1-f49.google.com with SMTP id a10so3556864ioe.9 for ; Thu, 16 Jun 2022 22:42:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=FCMwOZrN/FxIIzEAuHukQeJa7NLlTz5rIZvNWjUlfZo=; b=S1ab33K17uMB2W2LO4MBTbw12OJUDDBU7BxhOM7AVTUugUaiT8rU5+JY7gfC+d0QYC rk086Zl1MixYspNdhBPmrAXl93InzqpvrK+BgOxRBPa3P5ivuaxyoglSLMauTABS8aQW 0gpYyTHdUrI1RGtigvf9/QI3wNyPhGDr+BufBJIrTXhPlTBXl02Jj2FtMvlbUI0zq5pB v+zNQugANtqwLXMGKFyfYJwuWtk9xA7cwAXa68txca9C9q5ZrodPHzvJ1xAjXDbBhdYe BoIlX9KA8FLWfVxI6cfUrMj5vVZ8UnnhfAbDhG3v1lyFPSZRUxcmoFoZveiitTAR3Ebd vB8w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=FCMwOZrN/FxIIzEAuHukQeJa7NLlTz5rIZvNWjUlfZo=; b=vj17WAvwWcSSTgQPkhOQzNKhLt0gw1XazkU/du/DdQYS6M3VIYl5hOWOrB29YMkfQ7 8W7CkDlhQs4r0s1nde7h0TAhyHlaWQbm0+l0zq1jEv7f6pUaiwoC9DRI1hyRMR7wcMaA lM2qTS4wc2UDbh53UEEYYKl4G72a5sHqmZ+0HXkw+SR8Aps/AOatUDxO4hPhyDKQBFKa KQU2rw6PfD/nPZyGnD/i4u1Vvj6QYZzm97wDLhwtYgAtwIO9610zNBch67hboUVs2TPQ f8EWUgd/I3BACdVuV/gLwTmqM7YKjTzCj3aQN0spZDNDzyt6uBVg3iHxS0jkWbceyYc3 bfWQ== X-Gm-Message-State: AJIora8tZvqFs1GAaa/+WJw/2sXvvNIAyOvd5PneKNcORyocKvf68CRi JZPl5qS/GuVjRHfj6FWR7R/VRPr9aRdV81PtTyMlnOaEn+Qs1mKl X-Google-Smtp-Source: AGRyM1vs4i7ef/PP/Ylj2van3tgk+d12NfUWqU3XHodRDq6uXkrD6VnYKcvFrq1TkUBczXxnPbjme7PjdcSnmaNCRKQ= X-Received: by 2002:a05:6602:2b0b:b0:64f:acc1:52c3 with SMTP id p11-20020a0566022b0b00b0064facc152c3mr4118240iov.38.1655444542310; Thu, 16 Jun 2022 22:42:22 -0700 (PDT) MIME-Version: 1.0 References: <4410FE99-43C7-4331-AB96-42ADB294AE30@apple.com> <57AF5203-22DB-49C8-987B-A889FA36CE03@apple.com> In-Reply-To: <57AF5203-22DB-49C8-987B-A889FA36CE03@apple.com> From: "Ayush Singh" Date: Fri, 17 Jun 2022 11:12:17 +0530 Message-ID: Subject: Re: [edk2-devel] Does edk2 also link to crt0-efi like GNU-EFI * To: Andrew Fish Cc: edk2-devel-groups-io Content-Type: multipart/alternative; boundary="000000000000e3cd8405e19e37ff" --000000000000e3cd8405e19e37ff Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable > The C we have is free standing so there is nothing that is set up for the C language, other than libs the user asked for. It is possible to have freestanding Rust as well, but the current goal of the project is to make it possible to use the standard library for UEFI applications. So, some setup is needed. If someone wants to use freestanding Rust for UEFI, that is already quite possible. > I=E2=80=99m not 100% clear on all the dependencies but the big picture is= for C edk2 injects code between the entry point and the main function. I think you will want that in your Rust world. Yes, that is exactly what I wish to do. But the code will be injected before the `lang_start` function instead of just main. `lang_start` basically is the actual entry point for Rust applications (I guess it is like crt0 in a way since it is basically sets up Rust runtime) . Instead of autogenerating this code though, I probably need to manually write it. > 1) Have some custom code, per driver type, to maybe convert the EFI/PEI/edk2 define entry point arguments maybe into standard Rust args. > argc =3D 2 > argv[0] =3D ImageHandle > argv[1] =3D *SystemTable This is possible. I was alternatively thinking of making SystemTable a global static instead. As you said, Apps cannot do anything without the SystemTable. similarly, the standard library cannot do much without having access to the SystemTable. > You could get really fancy and pass the mode BASE/PEIM/DXE in argv[0], and the args in args[1], =E2=80=A6. By doing that you might need small stub= s that are mode specific to capture the different entry point APIs, but all the other lib infrastructure could be common. The little tiny entry stub libs could depend on the common lib so the INF files would only need to specify the entry point stub lib. Currently, the entry point is defined by the `target.json` file. As such, using a different entry point is as simple as using a different `target.json` file to compile the project. As such, it can be taken care of at the AutoGen stage instead of trying to put it into Rust itself. Or we can just use Rust conditional compilation macros and just pass a feature depending on which entry point we want to use. The current focus isn't to get Rust integrated into edk2, but to make it possible and actually worthwhile to even do the integration. The way we currently use Rust in UEFI is not exactly great since the standard library isn't available. There are raw pointers everywhere and a lot of unsafe code is needed. It is mostly, just a slightly better C in this context, without the amazing modules that edk2 and other projects have written in C. Once that can be fixed, then we will start looking at the edk2 integration (although that might be beyond the scope of the project) On Fri, Jun 17, 2022 at 4:51 AM Andrew Fish wrote: > > > On Jun 16, 2022, at 1:17 PM, Ayush Singh wrote= : > > Thanks for the great answer. After some discussion in the zulip [1], I > have some approaches that I will try first. > > As for calling C, EFIABI from Rust, yes, it is quite well supported. > Rust also has a specific EFIABI now, since some EFI platforms don't > use C calling conventions. > > As for the entry point, llvm has an `-entry:efi_main` that can be used > to define the entry function for UEFI targets. I just was not sure I > could integrate it with the actual `main()` function. > > > For the C builds the tools_def.txt file uses $(IMAGE_ENTRY_POINT). The > build maps that over to the _ModelEntryPoint label I mentioned. It would > probably be good to sue the same symbol. > > The C we have is free standing so there is nothing that is setup for the = C > language, other that libs the user asked for. > > In normal Rust, the control flow is somewhat like this: crt0 -> libc > main -> rust lang_start -> rust lang_start_internal -> rust main > > In UEFI, I would have to do something like this: efi_main -> rust > lang_start -> rust lang_start_internal -> rust main > > > The edk2 way to do this seems to me is to create an edk2 RustEntryPoint > lib that models the edk2 *EntryPointLib [1]. The entry point would be > _ModelEntryPoint. > > I=E2=80=99m not 100% clear on all the dependencies but the big picture is= for C > edk2 injects code between the entry point and the main function. I think > you will want that in your Rust world. > > The other thing you need to manage is the entry point hands-off the only > way to bind to all the EFI Services so that needs to make it into your Ru= st > world. > > EFI_STATUS > EFIAPI > _ModuleEntryPoint ( > IN EFI_HANDLE ImageHandle, > IN EFI_SYSTEM_TABLE *SystemTable > ) > The Apps need access to SystemTable to do just about anything. The > ImageHandle lets them get access to args and info on how the driver/app w= as > loaded. > > We have different flavors of these entry point libs as the handoff, and > sometimes entry exit behavior are different: > $ git grep 'EntryPoint|' -- \*.inf | grep LIBRARY_CLASS > MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.inf:18: LIBRARY_CLASS > =3D DxeCoreEntryPoint|DXE_CORE > MdePkg/Library/PeiCoreEntryPoint/PeiCoreEntryPoint.inf:18: LIBRARY_CLASS > =3D PeiCoreEntryPoint|PEI_CORE > MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf:18: LIBRARY_CLASS > =3D PeimEntryPoint|PEIM > MdePkg/Library/StandaloneMmDriverEntryPoint/StandaloneMmDriverEntryPoint.= inf:21: > LIBRARY_CLASS =3D StandaloneMmDriverEntryPoint|MM_STANDA= LONE > MdePkg/Library/UefiApplicationEntryPoint/UefiApplicationEntryPoint.inf:18= : > LIBRARY_CLASS =3D UefiApplicationEntryPoint|UEFI_APPLICA= TION > MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf:18: > LIBRARY_CLASS =3D UefiDriverEntryPoint|DXE_DRIVER > DXE_RUNTIME_DRIVER UEFI_DRIVER SMM_CORE DXE_SMM_DRIVER > StandaloneMmPkg/Library/StandaloneMmCoreEntryPoint/StandaloneMmCoreEntryP= oint.inf:18: > LIBRARY_CLASS =3D > StandaloneMmCoreEntryPoint|MM_CORE_STANDALONE > > I think what this means from a practical point after reading your Rust > thread is: > 1) Have some custom code, per driver type, to maybe convert the > EFI/PEI/edk2 define entry point arguments maybe into standard Rust args. > argc =3D 2 > argv[0] =3D ImageHandle > argv[1] =3D *SystemTable > > 2) Then you can call the common Rust init flow from your link. > > 3) rt_entry() is custom for edk2. It would basically do the same things a= s > the edk2 C *EntryPoint libs _ModuleEntryPoint() functions. Call the auto > generated lib constructor functions, call the auto generated entry point > function that calls the function in the users Rust code. Call the lib > destructor. Also provide support for the Exit function. > > You can kind of hard code bits to get started, but If you think about it > this way I think it will be easier to layer in edk2 like build features a= s > we grow the Rust support. > > You could get really fancy and pass the mode BASE/PEIM/DXE in argv[0], an= d > the args in args[1], =E2=80=A6. By doing that you might need small stubs = that are > mode specific to capture the different entry point APIs, but all the othe= r > lib infrastructure could be common. The little tiny entry stub libs could > depend on the common lib so the INF files would only need to specify the > entry point stub lib. > > [1] > https://github.com/tianocore/edk2/blob/master/MdePkg/Library/UefiApplicat= ionEntryPoint/ApplicationEntryPoint.c > > Thanks, > > Andrew Fish > > The problem was that I couldn't find a way to go from `efi_main -> > rust lang_start` earlier. After all, it is such a low-level detail > that there is almost no documentation for anything that happens before > `rust lang_start`. Still, I do have some idea now, so will see how it > goes. > > Ayush Singh > > [1]: ( > https://rust-lang.zulipchat.com/#narrow/stream/182449-t-compiler.2Fhelp/t= opic/Run.20a.20function.20before.20.60lang_start.60/near/286376012 > ) > > On Fri, Jun 17, 2022 at 12:06 AM Andrew Fish wrote: > > > > > On Jun 16, 2022, at 7:20 AM, Ayush Singh wrote= : > > Hello everyone, I wanted to ask if the edk2 build system also links to > crt0-efi, like GNU-EFI? > > If yes, I would also like to see how that is actually implemented. If > not, how does edk2 support custom entry functions? It is possible with > llvm backend but I am not sure how it is done in GCC and am curious, > > > The general answer for edk2 is and library that a `CONSTRUCTOR =3D` > statement in its INF that lib constructor will get called when the > Driver/App is started. > > The actually entry point for a Driver/App is _ModuleEntryPoint(). The > typical way it is done is this is implemented in a phase specific > library[1]. This phase specific basically calls 3 C functions that got > generated by the build: ProcessLibraryConstructorList(), > ProcessModuleEntryPointList(), and ProcessLibraryDestructorList(). The > library constructor/destructors functions call the lib > constructor/destructors function based in the sequence of the dependency > graph of the libraries that get pulled in. > > Currently, rust does not support the custom implementation of > `lang_start` (which is started by crt0 in most platforms), so I was > trying to find ways to be able to use custom crt0 which sets up > `SystemTable` and `SystemHandler` and start the `lang_start` from it. > This way, the user will be able to call the normal `main` function > rather than using the `no_main` feature. > > > If you look in the build output of an edk2 C driver/app you will see an > AutoGen.h and AutoGen.c file. This was the C code the build system > autogenerated to glue everything together. It manages gluing in the libs, > abstracting the PCD implementation, and adding C constants for EFI_GUID > values. > > Sorry I don=E2=80=99t know Rust yet. Is it possible to call C, EFIABI, fr= om Rust > code? If yes maybe what you need is a Rust ModuleEntryPoint that can call > the C library constructor and a C EFIABI entry function for your Rust. I= =E2=80=99m > not sure how you manage dealing with C includes in Rust? With C++ you can > just decorate them. > > I guess the other 100% Rust option is to know the INF is building Rust > (INF has Code.rs files) and build Rust (or Rust compatible) AutoGen > > My blog post [1] shows how we currently use the `efi_main` function. > > Yours sincerely, > Ayush Singh > > [1]: (https://www.programmershideaway.xyz/post5/) > > > > [1] > https://github.com/tianocore/edk2/blob/master/MdePkg/Library/UefiApplicat= ionEntryPoint/ApplicationEntryPoint.c > > Thanks, > > Andrew Fish > > > > > > > > >=20 > > > > --000000000000e3cd8405e19e37ff Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
> The C we have is free standing so there is nothi= ng that is set up for the C language, other than libs the user asked for.

It is possible to have freestanding Rust as well, b= ut the current goal of the project is to make it possible to use the standa= rd library for UEFI applications. So, some setup is needed. If someone want= s to use freestanding Rust for UEFI, that is already quite possible.
<= div>
> I=E2=80=99m not 100% clear on all the dependencies = but the big picture is=20 for C edk2 injects code between the entry point and the main function. I think you will want that in your Rust world.

Yes,= that is exactly what I wish to do. But the code will be injected before th= e `lang_start` function instead of just main. `lang_start` basically is the= actual entry point for Rust applications (I guess it is like crt0 in a way= since it is basically sets up Rust runtime)
. Instead of aut= ogenerating this code though, I probably need to manually write it.

> 1) Have=20 some custom code, per driver type, to maybe convert the EFI/PEI/edk2=20 define entry point arguments maybe into standard Rust args.=C2=A0>=C2=A0 argc =3D 2
>=C2=A0 argv[0] =3D ImageHandle
<= div>>=C2=A0 argv[1] =3D =C2=A0*SystemTable

This= is possible. I was alternatively thinking of making SystemTable a global s= tatic instead. As you said, Apps cannot do anything without the SystemTable= . similarly, the standard library cannot do much without having access to t= he SystemTable.

> You could get reall= y fancy and pass the mode BASE/PEIM/DXE in argv[0],=20 and the args in args[1], =E2=80=A6. By doing that you might need small stub= s=20 that are mode specific to capture the different entry point APIs, but=20 all the other lib infrastructure could be common. The little tiny entry=20 stub libs could depend on the common lib so the INF files would only=20 need to specify the entry point stub lib.

Currentl= y, the entry point is defined by the `target.json` file. As such, using a d= ifferent entry point is as simple as using a different `target.json` file t= o compile the project. As such, it can be taken care of at the AutoGen stag= e instead of trying to put it into Rust itself. Or we can just use Rust con= ditional compilation macros and just pass a feature depending on which entr= y point we want to use.

The current focus isn&= #39;t to get Rust integrated into edk2, but to make it possible and actuall= y worthwhile to even do the integration. The way we currently use Rust in U= EFI is not exactly great since the standard library isn't available. Th= ere are raw pointers everywhere and a lot of unsafe code is needed. It is m= ostly, just a slightly better C in this context, without the amazing module= s that edk2 and other projects have written in C.

= Once that can be fixed, then we will start looking at the edk2 integration = (although that might be beyond the scope of the project)

On Fri, Jun 17, 2022 at 4:51 AM Andrew Fish <afish@apple.com> wrote:

On Jun 16, 2022, at 1:17 PM, Ayush= Singh <ay= ushdevel1325@gmail.com> wrote:

Thanks for the gre= at answer. After some discussion in the zulip [1], I
have some approache= s that I will try first.

As for calling C, EFIABI from Rust, yes, it= is quite well supported.
Rust also has a specific EFIABI now, since som= e EFI platforms don't
use C calling conventions.

As for the e= ntry point, llvm has an `-entry:efi_main` that can be used
to define the= entry function for UEFI targets. I just was not sure I
could integrate = it with the actual `main()` function.

=
For the C builds the tools_def.txt file uses=C2=A0=C2=A0$(IM= AGE_ENTRY_POINT). The build maps that over to the _ModelEntryPoint label I = mentioned. It would probably be good to sue the same symbol.=C2=A0

The C we have is free standing so there is nothing that is= setup for the C language, other that libs the user asked for.

In normal Rust, the control flow is somewh= at like this: crt0 -> libc
main -> rust lang_start -> rust lang= _start_internal -> rust main

In UEFI, I would have to do somethin= g like this: efi_main -> rust
lang_start -> rust lang_start_intern= al -> rust main


The = edk2 way to do this seems to me is to create an edk2 RustEntryPoint lib tha= t models the edk2 *EntryPointLib [1]. The entry point would be =C2=A0_Model= EntryPoint.

I=E2=80=99m not 100% clear on all the = dependencies but the big picture is for C edk2 injects code between the ent= ry point and the main function. I think you will want that in your Rust wor= ld.

The other thing you need to manage is the entr= y point hands-off =C2=A0the only way to bind to all the EFI Services so tha= t needs to make it into your Rust world.=C2=A0

EFI_STATUSEFIAPI_ModuleEntryPoint ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemT= able )<= /tr>= The Apps need access to SystemTable to do just about anything. The = ImageHandle lets them get access to args and info on how the driver/app was= loaded.=C2=A0

We have different flavors of these = entry point libs as the handoff, and sometimes entry exit behavior are diff= erent:
$ git grep 'EntryPoint|' -- \*.inf | grep L= IBRARY_CLASS
MdePkg/Library/DxeCoreEntryPoint/DxeCoreEnt= ryPoint.inf:18:=C2=A0 LIBRARY_CLASS=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =3D DxeCoreEntryPoint|DXE_CORE
= MdePkg/Library/PeiCoreEntryPoint/PeiCoreEntryPoint.inf:18:=C2=A0 LIBRARY_CL= ASS=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =3D PeiCo= reEntryPoint|PEI_CORE
MdePkg/Library/PeimEntryPoint/Peim= EntryPoint.inf:18:=C2=A0 LIBRARY_CLASS=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =3D PeimEntryPoint|PEIM
Mde= Pkg/Library/StandaloneMmDriverEntryPoint/StandaloneMmDriverEntryPoint.inf:2= 1:=C2=A0 LIBRARY_CLASS=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =3D StandaloneMmDriverEntryPoint|MM_STANDALONE
MdePkg/Library/UefiApplicationEntryPoint/UefiApplicationEntryPoint.inf:18= :=C2=A0 LIBRARY_CLASS=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =3D UefiApplicationEntryPoint|UEFI_APPLICATION
MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf:18:=C2=A0 LI= BRARY_CLASS=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =3D UefiDriverEntryPoint|DXE_DRIVER DXE_RUNTIME_DRIVER UEFI_DRIVER SMM_CORE= DXE_SMM_DRIVER
StandaloneMmPkg/Library/StandaloneMmCore= EntryPoint/StandaloneMmCoreEntryPoint.inf:18:=C2=A0 LIBRARY_CLASS=C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =3D StandaloneMmCoreEn= tryPoint|MM_CORE_STANDALONE

I think what this means from a practical= point after reading your Rust thread is:
1) Have some custom code, per dr= iver type, to maybe convert the EFI/PEI/edk2 define entry point arguments m= aybe into standard Rust args.=C2=A0
=C2=A0 argc =3D 2
=C2=A0 argv[0] =3D ImageHandle
=C2=A0 argv[1] =3D =C2=A0*Sy= stemTable

2) Then you can call the common Rust ini= t flow from your link.=C2=A0

3) rt_entry() is cust= om for edk2. It would basically do the same things as the edk2 C *EntryPoin= t libs _ModuleEntryPoint() functions. Call the auto generated lib construct= or functions, call the auto generated entry point function that calls the f= unction in the users Rust code. Call the lib destructor. Also provide suppo= rt for the Exit function.=C2=A0

You can kind of ha= rd code bits to get started, but If you think about it this way I think it = will be easier to layer in edk2 like build features as we grow the Rust sup= port.=C2=A0

You could get really fancy and pass th= e mode BASE/PEIM/DXE in argv[0], and the args in args[1], =E2=80=A6. By doi= ng that you might need small stubs that are mode specific to capture the di= fferent entry point APIs, but all the other lib infrastructure could be com= mon. The little tiny entry stub libs could depend on the common lib so the = INF files would only need to specify the entry point stub lib.

Thanks,

Andrew Fish

<= blockquote type=3D"cite">
The problem was that I couldn't find= a way to go from `efi_main ->
rust lang_start` earlier. After all, i= t is such a low-level detail
that there is almost no documentation for a= nything that happens before
`rust lang_start`. Still, I do have some ide= a now, so will see how it
goes.

Ayush Singh

[1]: (ht= tps://rust-lang.zulipchat.com/#narrow/stream/182449-t-compiler.2Fhelp/topic= /Run.20a.20function.20before.20.60lang_start.60/near/286376012)

= On Fri, Jun 17, 2022 at 12:06 AM Andrew Fish <afish@apple.com> wrote:



On Jun 16, 2022, at 7:20 = AM, Ayush Singh <ayushdevel1325@gmail.com> wrote:

Hello everyone, I wan= ted to ask if the edk2 build system also links to
crt0-efi, like GNU-EFI= ?

If yes, I would also like to see how that is actually implemented.= If
not, how does edk2 support custom entry functions? It is possible wi= th
llvm backend but I am not sure how it is done in GCC and am curious,<= br>

The general answer for edk2 is and library that a `= CONSTRUCTOR =3D` statement in its INF that lib constructor will get called = when the Driver/App is started.

The actually entry point for a Drive= r/App is _ModuleEntryPoint(). The typical way it is done is this is impleme= nted in a phase specific library[1]. This phase specific basically calls 3 = C functions that got generated by the build: ProcessLibraryConstructorList(= ), ProcessModuleEntryPointList(), and ProcessLibraryDestructorList(). The l= ibrary constructor/destructors functions call the lib =C2=A0constructor/des= tructors function based in the sequence of the dependency graph of the libr= aries that get pulled in.

Currently, rust = does not support the custom implementation of
`lang_start` (which is sta= rted by crt0 in most platforms), so I was
trying to find ways to be able= to use custom crt0 which sets up
`SystemTable` and `SystemHandler` and = start the `lang_start` from it.
This way, the user will be able to call = the normal `main` function
rather than using the `no_main` feature.
<= br>

If you look in the build output of an edk2 C driver/app= you will see an AutoGen.h and AutoGen.c file. This was the C code the buil= d system autogenerated to glue everything together. It manages gluing in th= e libs, abstracting the PCD implementation, and adding C constants for EFI_= GUID values.

Sorry I don=E2=80=99t know Rust yet. Is it possible to = call C, EFIABI, from Rust code? If yes maybe what you need is a Rust Module= EntryPoint that can call the C library constructor and a C EFIABI entry fun= ction for your Rust. I=E2=80=99m not sure how you manage dealing with C inc= ludes in Rust? With C++ you can just decorate them.

I guess the othe= r 100% Rust option is to know the INF is building Rust (INF has Code.rs files) and build Rust (or Rus= t compatible) AutoGen

My blog post [1] sho= ws how we currently use the `efi_main` function.

Yours sincerely,Ayush Singh

[1]: (https://www.programmershideaway.xyz/post5/)
=


[1] https://github.com/tianocore/edk2/blob/master/MdePkg/Li= brary/UefiApplicationEntryPoint/ApplicationEntryPoint.c

Thanks,<= br>
Andrew Fish











<= br> --000000000000e3cd8405e19e37ff--