Strace command in Linux for tracing DMA transfers - performance

Is there a way to trace system calls related to DMA transfers with strace command in Linux. I use the Zedboard which consist of FPGA and ARM A9 Core. I use the Linardo version of Linux (Linaro 12.11) where tool support is not available for using perf command (No package error- when installing). Please share any alternative commands that can help in tracing system calls related to DMA transfers. In my case, I have an application running on Linux where it transfer data with FPGA via DMA (which is the part of interest).

Related

How to disable software SMI (System Management Interrupt) in Windows

Starting from Windows 10 1809, OS generates lots of software SMIs.
We are running our real time application on separate processor core and each SMI generates unpredictable delay. Before 1809 it was always possible to disable SMIs in BIOS.
Call stack in Windows looks like:
hal!HalEfiGetEnvironmentVariable+0x56
hal!HalGetEnvironmentVariableEx+0xb572
nt!IopGetEnvironmentVariableHal+0x2a
nt!IoGetEnvironmentVariableEx+0x85
nt!ExpGetFirmwareEnvironmentVariable+0x91
nt!ExGetFirmwareEnvironmentVariable+0x110ce3
nt!NtQuerySystemEnvironmentValueEx+0x6e
SMI is generated by OUT instruction into port 0xb2. It is required to read UEFI variables from NVRAM. When BIOS is in legacy mode, there is no SMIs.
Is it possible to configure Windows, so it will not access UEFI variables using SMIs?
The short answer is NO, it is not possible to configure Windows to not generate SW SMIs on UEFI Variable accesses, because those SMIs are not generated by Windows. The SMIs are generated inside the firmware.
All UEFI-aware OSes read/write UEFI variables via GetVariable() and SetVariable() services, which are part of Runtime Services exposed by a UEFI firmware to the OS via System Table - see UEFI Spec, section 8. The current implementation of Variable Services in most firmware is to process the actual Get/Set variable requests inside SMM, for security reasons.
So it is the device's firmware that's responsible for generating SW SMIs, not the OS. However, the OS and some system services/applications absolutely need to work with UEFI variables as it is how a UEFI-aware OS is supposed to run on a UEFI firmware.
On processors that supports AMD-V (e.g. AMD Processors, Hygon Processors), the answer is yes, but in kernel mode. There are two instructions called stgi and clgi, where stgi sets the GIF and clgi clears the GIF. The GIF is used to control the interrupt behaviors so that one may enter absolute atomic operations. As defined in AMD-V, Internal SMIs (e.g. I/O Trapping) are discarded and External SMIs (e.g. from external hardware, or IPIs by APIC) are held pending when GIF is cleared. Make sure you enabled the SVME bit in EFER MSR as you are to execute these instructions.
If you would like to make it happen in a more generic way, which does not rely on AMD-V, you may try to get your code into SMI handler, in that SMIs which occurs later will be latched while processor is in SMM.
Reference:
Chapter 10.3.3 "Exceptions and Interrupts", Volume 2 "System Programming", AMD64 Architecture Programmer's Manual.
Chapter 15.17 "Global Interrupt Flag, STGI and CLGI Instructions", Volume 2 "System Programming", AMD64 Architecture Programmer's Manual.
https://www.amd.com/system/files/TechDocs/24593.pdf

Can the Linux Kernel run on a processor that can't execute code out of RAM?

Running code exclusively in ROM has some security benefits and I was wondering if anything in the Linux kernel requires the ability to run code in RAM.
No it is not directly possible.
But you can start a normal process and then map some ROM ranges into the process space (maybe via device driver depending how the ROM is mapped) and then run code in this mapped range.

Are PCIe device drivers beneficial if using Linux as a bootloader for bare-metal code?

I am developing an embedded system on a PowerPC processor and there is need for communication with an FPGA via PCIe. I wish to use Linux/embedded-Linux as a bootloader to leverage its PCIe initialization code and driver API for simplified PCIe driver development. However in the end I want to be running bare-metal code (no OS running). So I am looking at using PetitBoot/kexec to jump from Linux to my own code.
Is this possible?
My current understanding of PCIe drivers leads me to believe that once the device is initialized, so long as I have a pointer to the address space, I should be able to simply execute MMIO R/W operations directly to the memory space. So even if kexec overwrites the driver code I should be able to use the device because the driver has done its job already.
Is this correct?
If not, what are my alternatives?
I don't think this approach would be a good idea. Drivers that were written with the Linux OS in mind are going to assume that all of the OS's resources are available, not just memory allocations. For example, it may configure interrupt handlers, but when the OS is not longer available, your hardware may get hung because nothing is acknowledging and servicing its interrupt requests.
I'm skeptical of the memory initialization as well. I suppose you could theoretically allocate some DMA memory and pass the resulting physical address to your bare-metal application as it takes over, but the whole process seems sketchy. It would be very difficult to make sure everything in Linux is shut down cleanly while leaving the PCIe subsystem running. You'll have to look at the driver's shut down routines and see what it does to the card to make sure it doesn't shut down the device and make it unresponsive to your bare-metal code.
I would suggest that you instead go through the Linux-based driver and use it as a guide to construct a new bare-metal driver. Copy the initialization code that you need, and leave out the Linux-specific configuration details.

Debugging processor registers when running an MMU

I am currently trying to access the registers of the ARM9 core on the Zynq Z702 SoC using the XIlinx's XMD tool provided as part of the SDK. When I try to read a part of memory, I am getting an MMU related error. Do i need some specialized hardware to read and write to these registers when running an OS on the processor. Please help.
P.S. : I am running Linux 3.x.x kernel on the processor and the memory region I am trying to access are memory mapped regions and are not occupied by any kernel or user-space code.

how to burn a uboot to board NAND flash

I am having a question regarding Uboot. I am looking forward to make a ARM based Board.
Now i want to to burn Uboot to NAND flash attached to my controller. How can i perform this operation ?
http://www.stlinux.com/u-boot/target-install
What i got from this link is that -- STx7111 Mboard - have some serial port which is capable to communicate with GDB.
And from GDB we use to burn following file u-boot. Is this file burned in RAM or NAND flash by gdb ?
Then execution moves to this u-boot program "u-boot". Now this program "u-boot" will burn the actual u-boot.bin onto the NAND flash.
Do every controller have some serial port which is capable to communicate with GDB ?
Do every controller follow this approach to burn uboot bootloader into its NAND flash ?
Please suggest.
What i got from this link is that -- STx7111 Mboard - have some serial port which is capable to communicate with GDB. And from GDB we use to burn following file u-boot. Is this file burned in RAM or NAND flash by gdb ?
No, you did not read that article accurately.
GDB is merely used as the interface to the JTAG.
This first step is to load an executable (a copy of U-Boot) into RAM.
Do every controller have some serial port which is capable to communicate with GDB ?
Do every controller follow this approach to burn uboot bootloader into its NAND flash ?
You should avoid making (or trying to make) sweeping generalizations (in this and your other postings).
The features and capabilities of microcontrollers, microprocessors and SoCs ("controllers" is something else) is so broad that very few generalization can be made. Rarely is there only "one way" to perform these procedures.
In order the write a copy of U-Boot (or any file image) to NAND flash, there are two steps:
transfer the image file from the host PC (or some storage device) into local memory;
erase the NAND flash blocks, and then write the image file to NAND flash with ECC if required and cognizant of bad blocks.
These are not trivial steps, so a capable utility is needed. There are at least three approaches:
The microcontroller can be configured (via input pins) to a "receive and write an image file" mode on power-up. A hardcoded program in ROM will load the image and write it to the integrated flash.
The SoC ROM has a bootloader that has capabilities to communicate with a host PC over RS232 or USB, and can perform as the client side of a proprietary utility program. On the host PC you would run the server side of this utility program. This scheme would allow transferring files and reading & writing the target's memories. Atmel's SAM-BA utility fits into this category.
Use an open-source utility, such as U-Boot, that is configurable and extensible to support the external NAND flash and any other memory types on your board, and also has file transfer capabilities. The console for U-Boot is typically a UART/USART serial port, but can be configured to use a USB-to-RS232 adapter.
In the case of using a program like U-Boot to install programs in NAND, a chicken versus egg situation arises: how to get this program loaded in the first place? The two common approaches are:
a. Install the utility (i.e. U-Boot) on a SDcard with any required bootloader, and then boot the SoC from the SDcard. This assumes that the SoC has this booting capability, but this scheme requires the least operator skill.
b. Load the utility (i.e. U-Boot) using JTAG, such as Segger J-Link, which will allow you to transfer the image file to RAM (assuming that RAM has been properly initialized if necessary) and then start its execution. The J-Link can be interfaced using its own JLINK program or GDB.
Once U-Boot is resident and executing, you have all of its capabilities available. U-Boot cannot write itself to NAND flash, so you have to load another copy of U-Boot in order to write it to NAND (or any other type of) flash.
If you load something using GDB, then it must be loaded in RAM..
Using gdb you will run that binary (u-boot), and the binary will give you the u-boot prompt, which you use to burn another image (it can be u-boot.img (configured for running from FLASH), linux kernel image, or any other image) into the flash (it can be NOR or NAND)..

Resources