On 12/16/13 02:03, Nik M wrote:
> Hi Guys,
>
> I am trying to port EDK 2 shell (ShellPkg) into our(vendor) BIOS and
> am facing a few problems.
>
> One of the Shell constructor function, ShellLibConstructorWorker()
> tries to locate and open protocol gEfiShellProtocolGuid which hasn't
> been installed yet. It only gets installed in the UefiMain() function
> (module entry point) by calling CreatePopulateInstallShellProtocol().
>
> In our BIOS, we always call the constructor functions first followed
> by the entry point function and then finally the destructors during
> exit. As I said above, the constructor tries to open protocol
> gEfiShellProtocolGuid but fails to find it and thus exits with an
> ASSERT failure.
>
> Why doesn't EDK have the same problem ? Does it even call the
> constructors explicitly ?
>
> PS: I am new to UEFI development, so forgive me if my question seems
> rudimentary.
I think that the library constructor is in fact called, but it exits
early because of the PCD check.
ShellLibConstructor () [ShellPkg/Library/UefiShellLib/UefiShellLib.c]
PcdGetBool (PcdShellLibAutoInitialize)
ShellLibConstructorWorker ()
OpenProtocol (... gEfiShellProtocolGuid ...)
"PcdShellLibAutoInitialize" is defined in "ShellPkg/ShellPkg.dec", and
it is set to FALSE when building the Shell app itself, in
"ShellPkg/ShellPkg.dsc".
The idea is I believe, when the Shell is built (and it links againts
UefiShellLib), the PCD is FALSE, hence ShellLibConstructor() exits
early. Then UefiMain() [ShellPkg/Application/Shell/Shell.c] is entered
indeed, and it calls ShellInitialize() explicitly (to initialize the
library) after installing the protocol:
UefiMain() [ShellPkg/Application/Shell/Shell.c]
CreatePopulateInstallShellProtocol ()
ShellInitialize ()
PcdGetBool (PcdShellLibAutoInitialize)
ShellLibConstructorWorker ()
In another application however (eg. one started from the shell), the PCD
is theoretically TRUE, so the library constructor does depend on the shell.
"PcdShellLibAutoInitialize" is basically a compile-time flag that delays
the effective initialization of UefiShellLib from its constructor,
ShellLibConstructor(), to an explicit function call made by the
application, ShellInitialize(). In the Shell app itself this
initialization is put off until the explicit call, in other code the
library constructor depends on the existing shell.
I think.
(BTW other client code does tend to delay this initialization too, by
setting the PCD to FALSE. I assume in some cases linking against
UefiShellLib is unavoidable, even though actual shell services are not
needed, and setting the PCD to FALSE could be the only way to avoid the
assert.)
I think the call order in your firmware is OK, just make sure you build
your (ported) Shell app with the PCD in question set to FALSE.
Laszlo
------------------------------------------------------------------------------
Rapidly troubleshoot problems before they affect your business. Most IT
organizations don't have a clear picture of how application performance
affects their revenue. With AppDynamics, you get 100% visibility into your
Java,.NET, & PHP application. Start your 15-day FREE TRIAL of AppDynamics Pro!
http://pubads.g.doubleclick.net/gampad/clk?id=84349831&iu=/4140/ostg.clktrk
_______________________________________________
edk2-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/edk2-devel