I have a uefi shell app and a uefi module, providing similar functionality, I am trying to merge them into a single entity that can be executed either as a module from Boot Menu or from uefi shell.
Is it possible to create an efi app that can be executed like this ?
The entry point for module is
ModMain (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
while for uefi shell app. it's,
MyAppMain (
IN UINTN Argc,
IN CHAR16 **Argv
)
Can I get the ImageHandle of an efi image implicitly (something like This pointer in C++ objects) ?
Thanks
What is the "module" in UEFI? There are only 2 types of UEFI binaries - UEFI application and PXE driver; If I did understand the question correctly I would do the following:
The "module" is a regular UEFI app that parses **argv;
Main UEFI App LoadImage() the "module" and passes the handle as a command line argument;
Related
I've got a Windows application with a GUI written in Rust and winapi. Despite its GUI, it behaves like a console application. When the exe file is started, a Command Prompt window pops up, and the application is run from it. This is not what I want; a main window should open instead, as in all real desktop apps. How can I achieve this goal in Rust with winapi?
I've investigated some options. You can develop Windows desktop applications using Tauri or gtk-rs, but both of these techniques have drawbacks when used for Windows apps. More options may be found here. I've also tried the windows-rs samples available on the internet, but they're all console apps with a graphical user interface, which isn't what I'm looking for.
I also note that C++ desktop applications use the function int APIENTRY wWinMain(...) as the entry point while console applications use int main(...), and wWinMain doesn't seem available in rust winapi.
Whether the system allocates a console for a newly created process is controlled by the Subsystem field in the Windows-specific optional PE header. The field is populated through the linker's /SUBSYSTEM command line option. The only relevant arguments for desktop applications are CONSOLE and WINDOWS. The former instructs the system to allocate a console on launch, whereas the latter won't.
You can instruct the linker to target the WINDOWS subsystem from Rust code by placing the per-module
#![windows_subsystem = "windows"]
attribute (see windows-subsystem) inside the main module of your application.
You'll find an example of this in the core_app sample of the windows crate.
This is the most convenient way to target the WINDOWS subsystem. You can also explicitly pass the linker flag along, e.g. by placing the following override into .cargo/config.toml:
[build]
rustflags = [
"-C", "link-arg=/SUBSYSTEM:WINDOWS",
]
This may or may not work, depending on the linker you happen to be using. Since the linker isn't part of the Rust toolchain, making sure that this works and has the intended effect is on you.
A note on the entry point's function name: It is irrelevant as far as the OS loader is concerned. It never even makes it into the final executable image anyway. The PE image only stores the (image-base-relative) AddressOfEntryPoint, and that symbol could have been named anything.
The concrete name is only relevant to the build tools involved in generating the respective linker input.
More info here: WinMain is just the conventional name for the Win32 process entry point. The underlying principles apply to Rust just the same, particularly the aspect that the user-defined entry point (fn main()) isn't actually the executable's entry point.
I am trying to write a program that uses IOAudioControl.h file in the IOKit, so that I learn dealing with IOKit directly without using Apple's APIs. Whenever I run a simple file like below I got tons of errors in IOAudioControl.h
#include <IOKit/audio/I0AudioControl.h>
#include <iostream>
int main(int argc, const char * argv]) (
{
// insert code here.
std: :cout << "Hello, world! \n"
return 0:
}
Here is a screenshot for my build settings
enter image description here
and here is a screenshot for the errors
enter image description here
IOAudioControl is a class that exists in the macOS Kernel (and its API is available to kexts), and it is also accessible from DriverKit extensions (dext) via the IOUserAudioControl API in AudioDriverKit.
From your code sample it looks like you're trying to include the kernel header file in a regular user space program. This will not work, kernel objects are not accessible from user space in this way.
You do not specify what you are ultimately trying to achieve, but:
If you are trying to implement an audio device driver, use either the Core Audio Server Plugin API or build your driver as a DriverKit extension. (Most kinds of audio kernel extensions are deprecated.)
If you want to access and modify the controls of an existing audio device in the system, use the Core Audio API.
If you wish to enumerate the kernel's IOAudioControl objects from user space, use the IOKit framework's service iteration APIs from your program.
My task is to load a program i built separately from the OS (it performs a set of actions on the system files so it must be done before the OS boots) on an embedded system. yea i know...
I chose to place it in a clean winpe.wim (got it from Windows AIK). everything works fine on modern bios computers, but when i try it on the embedded system i get stuck at the ACPI boot check: the bios on this system is non-acpi (standard hal)
restrictions : replacing BIOS / getting other winpe aren't options for now.
can i somehow disable the acpi-compatibility check in the winpe i got? through bcdedit maybe? any advice that will help me with this riddle is very appreciated.
also- the boot is performed form a bootable CD
Figured a workaround, if anyone ever needs this:
shrinked the partition on the embedded system and created a second one
installed another win2000 there and placed my program to run at start up
disabled explorer.exe and all unnecessary components
now this partition serves as PE replacement and can perform actions on the main os files if the user boots into it and runs my program
I want to run my .efi application using EFI shell script, is it possible? If yes, then would the startup.nsh script run this script each time a system boots?
Thanks.
I see a bit of misunderstanding in you question. Yes you can lunch your efi application from nsh script but it has nothing to do with booting the system. The NSH as you can understand is a shell script and naturally it is executed only when uefi shell is executed. If you want your application to be lunched while system boots that is an absolutely different story. The mechanism for that is called Boot Options and it was described in a bit more details in that post "How does UEFI work".
http://www.makelinux.net/ldd3/chp-2-sect-3#chp-2-ITERM-4135 this link describes the user space and kernel space communication.
could anyone explain it with a simple user space application program in c that links & communicates(send / receives values) to the kernel object.?
The program insmod, available on most Linux machines (but requiring sudo privileges to run) instructs the kernel to load a specified module (kernel object) through the system call init_module.
More generally, user-space programs communicate with the kernel through these system calls, which are essentially requests to the kernel from user space. Any application you write in C must use system calls in some way to interact with the system (for example, printf uses the write system call under the hood to put characters on the screen).
Just open a file with open(2). The compiler will add code to the application for this call which will put the function arguments on the stack and make it crash in a certain way (see system call). The kernel catches all the crashes and handles them.
Since this is a "good" crash, the kernel will look up which function to invoke, get the arguments from the stack and invoke the function.
The reason for this complicated approach is security: By "crashing", the application completely relinquishes control. The CPU will switch to a different mode, too. In this mode, it can access the hardware (in "application" mode, any access to the hardware leads to an "illegal access" crash which terminates your app).
The open(2) function itself can't do much. Instead, it will check which file system can handle the request and invoke the open function of the file system. File systems are implemented as kernel modules.