Can an EFI application automatically loaded and executed before BDS phase? - uefi

Can an EFI application be automatically loaded and executed before BDS phase, just after all the DXE drivers have been loaded?
If I include the application in .fdf file just after the DXE drivers, will it be automatically loaded and executed ?

This question is very board and I will only scratch the surface with my answer. Please read documentation that I mentioned to get more information.
If you have full source code of UEFI firmware for your hardware then you can add UEFI module to be executed before BDS phase. Otherwise you can affect only boot order (which is right before calling ExitBootServices) by adding UEFI Application using bcfg shell command, pleas check this question.
If you want to execute code before BDS it have to be DXE module (ie. DRIVER, RUNTIME_DRIVER). There are many module types that can be used and exact depend on your use case. More about module types you can find in Appendix G of INF file specification.
Adding to FDF file is not enough for code to be executed. FDF file describe only flash layout: how and where each binary would be placed in final flash image. To add DXE driver you also have to add your INF file to platform DSC file. Next thing is to have correct [Depex] section in INF, which can be as simple as:
[Depex]
TRUE
Last thing that you have to understand is DXE Dispatcher. Each boot DXE Dispatcher iterate over know image list and and call EFI_DRIVER_BINDING_SUPPORTED function (defined by EFI_DRIVER_BINDING_PROTOCOL). This method should check if supported hardware is available in platform. If EFI_DRIVER_BINDING_SUPPORTED return success then other driver binding method will be called (EFI_DRIVER_BINDING_START), which starts device. Entry point should be used only for protocol registration, starting device in entry point is not recommended.
Useful resources:
EDK II Specifications - specs for various file types (INF, FDF, DSC, DEC, etc.)
Developer Resources - Drivers Writers Guide and Drivers Wizard.
EDK2 sourceforge - repository of very useful resources about EDK2

Related

Where are the files defining NVIC for STM32 in PlatformIO when using CubeMX?

I've recently switched to using PlatformIO for developing for STM32 using the following workflow:
Create a .ioc file using the CubeMX utility
Generate source code and the PlatformIO configuration from that .ioc file from the stm32pio command line utility
Edit, build, and debug using the PlatformIO plug-in for VSCode (Mac)
Overall, this works very well. However, I was previously using the CubeMX code generation in ST's CubeMX IDE, which placed a .s file in the source directory that (as I understand it) defined the NVIC, as well as the default function that was used for exceptions/interrupts that are not explicitly defined (i.e., those handled by their default weak implementations.) I don't see where this is defined in the new workflow. Is this generated dynamically as part of the build process?
The reason I'm asking is (beside wanting a better understanding of the process overall), I'd like to write an interrupt handler for EXTI0, but trigger it as a software interrupt, and not assign a pin to it. If that is not possible, then perhaps the entire point is moot.
I was able to find the answer. These steps might be useful to somebody else who comes across this question. This was done on MacOS, but should be similar to the process for other operating systems.
During the build process, the filename can be seen. It will be prefaced with startup_, followed by the name of the particular chip you're developing for. In my case, the line is
Compiling .pio/build/disco_f072rb/FrameworkCMSISDevice/gcc/startup_stm32f072xb.o
Searching in the .platformio folder of my user directory, I found the matching .s file, which in my case was .platformio/packages/framework-stm32cube/f0/Drivers/CMSIS/Device/ST/STM32F0xx/Source/Templates/gcc/startup_stm32f072xb.s
The structure of the path leading to the file indicates the particulars of the hardware and frameworks I'm using: STM32Cube framework, a F0 series chip, and the GCC compiler. The easiest way to find this file, and how I was able to find it, is using the find command from the terminal to search the PlatformIO directory.
Reading this file gives the lines I was looking for, defining the names of the functions to be used for exception and interrupt handling, such as the following:
.weak EXTI0_1_IRQHandler
.thumb_set EXTI0_1_IRQHandler,Default_Handler
It seems like, while I am using the CubeMX HAL for some drivers, the basic startup code is done using CMSIS, so it should be the same for HAL, LL, or CMSIS based builds.

How to reference a specific DLL for functionality in said DLL

Good day,
I have an application that I developed that transfers files between two machines ("site" and "server"). This application was set to target dotNet 3.5. Furthermore, I am using Renci.SshNet to handle the connections between the machines and the transferring of said files.
The issue that I am facing currently though is that about 70% of the "site" machines do not have a standard dotNet and is also quite old; thus these machines do not support all the required functionality as the external dll makes calls to System.Threading.WaitHandle.WaitOne() and System.Threading.WaitHandle.WaitAny(WaitHandle[], Int32) and other overloads of these methods.
The workaround that I have for this though is to install netfx20SP2 or netfx30SP1, yet I am not in the position to perform this update on all machines as they are scattered across the country and have data limitations (bandwidth and cap).
What I want to do possibly is to embed the System.Threading dll that I have downloaded and then the application should use those classes instead, or alternatively just point the application to use the said dll.
Is this at all possible, or do you have to load the dll into the GAC? And also, will it be possible to "run" this higher version of System.Threading in the application while the system itself is on a lower framework version. Something is telling me that the best bet will be to actually run the service pack installation to avoid unnecessary coding but I'm not sure exactly how to approach this.
Thank you in advance for any assistance / suggestions,
JD
To allow the execution of an application that, let's say, targets .Net 4; while the machine itself only has let's say, .Net 3.5, installed, one can redirect Windows to check the local (executing) directory for dlls that should contain the required symbols loaded into memory instead of the default symbols that get loaded upon execution (the default would be the NetFx installed on the machine - which I believe the highest version of the framework that can be found upon loading when the execution starts or would be the highest available version that is lower or equal to the targeted framework).
This file's contents (myApp.exe.local) are ignored. It is just there to tell Windows to
look in that folder for the applicable symbols and if not found, the system will roll back to attempt to load these symbols from the NetFx directory.
Read more at Microsoft Dev Center - Docs (link is attached to the following paragraph which is a Copy-Paste of a section of this document).
To use DLL redirection, create a redirection file for your application. The redirection file must be named as follows: App_name.local. For example, if the application name is Editor.exe, the redirection file should be named Editor.exe.local. You must install the .local file in the application directory. You must also install the DLLs in the application directory.

How to open a builtin device

I am trying to come up to speed on writing device drivers for embedded Linux, specifically a V4L2 Media Controller driver for a video interface.
I can write the device driver using the typical V4L2 model for a non-builtin driver, that is, a module controlled by modprobe. When the module is loaded the __init function for this driver is called, and this then creates a node in the /dev directory showing up as /dev/video0. I can then write user-side programs which starts by opening /dev/video0 and I can now exercise all the driver code I've written. I understand this model and so I have a nice development environment where I can modify the driver code, reload the .ko driver, modify my user-side test code, and basically exercise all my driver functionality.
However, I am still confused about the builtin drivers when using the Media Controller and platform_device model for drivers. (These don't have a specific __init routine and are not loaded dynamically). I can configure my kernel to build my driver as a builtin Media Controller-based driver. I have all of the Kconfig files correct so I can now include my new driver in a kernel build. I know my driver is builtin correctly, because when my kernel boots, I can see my driver in the /sys/bus/platform/drivers directory. This directory has 3 write-only nodes for bind, uevent and unbind.
This is my confusion: How do I open this builtin device driver from user-side code so I can exercise my driver interface?
Since the driver is a builtin Media Controller-based driver, a new device node is not created in /dev when the kernel boots, or at least, I do not know WHAT device to open like I did for the module-based driver.
Do I have to write some udev rules to cause the kernel to create the device node in /dev directory so I can use a user-side open()? or is this driver accessed in a different way?
Thanks,
-Andres
If your driver based on media controller framework, there should be a pipeline (refer) have you implemented that in your driver refer media controller api. Even if your driver is builtin and is based on media controller framework it should still create /dev/video0. The reason I can think of video0 node not being created is missing subdev driver.

KERNEL_MODULE_AUTOLOAD and device not found in /dev/*

I am using Petalinux, built with Yocto SDK. I want to automatically install my kernel module and make the devices available in /dev/*.
With KERNEL_MODULE_AUTOLOAD+="modulename" I can see the appropriate entries in /etc/modules-load.d/ as well as entries in /sys/class/misc/** , but not in /dev/*. Is there something I am missing?
Well, the structure of Yocto has nothing to do with the creation of device nodes. Either your driver does that for you (upon loading / probing), or you had some script that made them earlier. As long as your module has been loaded upon boot, you've got KERNEL_MODULE_AUTOLOAD correctly. If the module gets loaded, but you're not getting any device nodes automatically (and you got that before) you'll need to investigate what has changed in your system. (Versions of kernel and eg mdev/udev etc)

How does one 'Extract Com Information' from an OCX without InstallShield?

In one of the projects our team is working on, we are trying to make an automated deployment system for an existing desktop application. In order to do that we need to understand how InstallShield installs the application to begin with.
We have access to the InstallShield manifest, but there is an OCX file that we cannot figure out how to install manually (without InstallShield). This particular OCX file is set to 'Extract COM Information'.
Here's a screenshot:
The other OCXs in this application are self-registering, so they can be registered with Regsvr32.exe. But the OCX we are having problems with cannot be registered in that fashion.
How would one manually install an OCX file that is set to 'Extract COM Information' in an InstallShield manifest?
RegSvr32.exe calls the LoadLibrary API to load your DLL and then invokes the DllRegisterServer entry point inside your DLL. The code inside that function does the actual COM registration. If RegSvr32 is failing, that typically means a dependency of your DLL is missing or invalid.
InstallShield does all of this along with some really low level bit hacking to virtualize all of this and then harvest it. An old article on the subject is:
Spying on Registry Entries
InstallShield doesn't actually use this technique per say ( they have several techniques, most of which is not documented and various filters and transform engines to clean up the data ). If you are just looking for a way to do it without InstallShield, then look at Windows Installer XML's "Heat" command line tool. This can "harvest" COM metadata into WxS XML elements.
Also WiX is open source so if you are really curious you could go looking at their code.
As Christopher mentioned, InstallShield extracts COM information from your .ocx by seeing what it registers when invoked similarly to regsvr32.exe will invoke it. Its various forms of redirection (for capturing purposes) have the added benefit of working around several potential permissions problems while the file is registering in your build environment. However if I'm not missing the point of your question, it's "why doesn't regsvr32.exe your.ocx work on the target machine?"
This is a bit of a stab in the dark, as you haven't included enough information. While missing dependencies can cause this, I'm going to guess you only see this failure on Windows Vista/Server 2008 or higher. If this is the case, there's a good chance your application is trying to write to registry keys that are protected by Windows Resource Protection (WRP), or is being tripped up by a per-user typelib registration problem.
When a poorly behaved self-registration routine encounters WRP, it attempts to write to a registry key it lacks permission to modify, then fails the entire registration. I'm uncertain what happens to the keys it wrote before that point, but all ones after it definitely never make it to the machine. You should be able to confirm whether this is the case with a tool like Process Monitor.
What do you do if this is the case? Well, you can stick with an extraction approach like that of InstallShield (which you say you want to leave). You can fix the file to not attempt to write to protected keys (which you say you cannot modify). Or you might be able to use the Application Compatibility Toolkit (ACT) to shim things, but I don't see how you can generally do that downstream. Generally speaking, I would recommend fixing the file, or continuing to use a working approach.