How to access Xilinx Axi DMA from Linux? - xilinx

I'm a software developer but I'm a newbie to embedded software development.
I have a Zynq Ultrascale board that has an Axi DMA in its Hardware and I want to access this DMA from Linux.
I know I should use DMA-Engine to Access DMA in Linux and I found the following link which is the Xilinx DMA driver, but I can't add these files to my qt project without any errors and I received file(header file) not found errors.
drivers/dma/xilinx/xilinx_dma.c
I have a piece of scattered information about the DMA driver, Device tree, and DMA-Engine but I know nothing about how to utilize these to access hardware DMA.
I built a Petalinux project and add DMA-Engine and DMA Test client to its kernel.
I don't know adding DMAEngine to the Petalinux project is enough or I should have a driver as well.
I don't know adding hardware specification (by .xsa file and .bit file) to the Petalinux project is enough or I should add a device tree to my Linux for detecting DMA as well
I lookup a step-by-step tutorial on how to set up Linux and qt creator for accessing DMA,
or at least a clear roadmap to my target.
thank you in advance.

First of all, you are facing errors when adding xilinx_dma.c to the Qt project because this file is meant to be compiled as part of kernel or as a kernel module.
Adding DMA Engine to Petalinux is not enough to work with DMA from user space. DMA Engine only provides a standardized API to let different DMAs be integrated into kernel. You need to add a client driver as well. Xilinx, as far as I know, has provided a simple client driver called DMA Proxy Driver. It also includes some simple examples that show how you can access DMA from the user space. However, if your application needs high bandwidth, you probably need to consider other options.
There is also an open source client driver for Axi DMA which achieves higher bandwidths compared to Proxy DMA Driver. It's user space API also allows you to register a callback function to be called whenever a transaction is finished.
The third option is to implement the driver in the user space. This can be done by defining the DMA as a UIO device in the device tree and access its register map directly from the user space. In this case, you need to allocate some contiguous memory blocks in the kernel space to avoid complications with MMU, which cannot be dealt with from the user space.

Related

Is it possible to use EFI to create fully cross-platform disk driver?

I need to create a driver, which will behave similar to software RAID. E.g. driver will need to communicate to multiple physical disks (or maybe even network resources), and shall look like a disk to the OS.
So two main questions are:
1) Are EFI drivers recognized and supported by Windows, MacOS X and Linux? E.g. can these systems use EFI disk drivers, and ?
2) Is it possible in theory to write such a driver for EFI? My primary concern is possibility of accessing other EFI disk drivers from your own virtual disk driver.
I only have time for a quick-ish reply, forgive me for brevity!
Are EFI drivers recognized and supported by Windows, MacOS X and Linux? E.g. can these systems use EFI disk drivers, and ?
To my knowledge, only the bootloaders for these OSs use the UEFI driver stack for loading the native OS kernel and drivers. Once ExitBootServices() is called by the bootloader, most of the drivers are unloaded, and (according to the spec) no calls to handle-based drivers may happen after this, meaning no disk drivers. Like a traditional bootloader, a UEFI bootloader is only using the basic drivers long enough to load the OS's native drivers. You can also use these drivers in the preboot environment if you'd like (although it sounds like you don't!).
TL;DR No, these systems can't use UEFI drivers other than for loading the OS.
Is it possible in theory to write such a driver for EFI?
You should definitely be able to layer your UEFI driver on top of the existing stack. It might be a little tricky if you haven't worked with UEFI before, but conceptually the system is very modular. There appear to be a number of resources on the Internet to help you out, and there is always Beyond BIOS: Developing with the Unified Extensible Firmware Interface by Vincent Zimmer.
As far as testing goes, you can use one of the simulators provided in Intel's EDKII (if you're on Windows, you should probably use the Nt32 project, it works well with Visual Studio).
TL;DR Yes, you can write this driver, but it will only work for bootloaders and applications in the pre-boot environment.
1) Are EFI drivers recognized and supported by Windows, MacOS X and Linux? E.g. can these systems use EFI disk drivers, and ?
No. Once you run ExitBootServices() it goes bubye. You can have a RunTimeDXE Driver, but those are incredibly limited. They cannot allocate memory (the VM Map is controlled by the OS) and they don't have access to any EFI APIs any more. They can be used to transfer information from the Firmware to the OS, but a better choice would be a private EFI Table.
2) Is it possible in theory to write such a driver for EFI? My primary concern is possibility of accessing other EFI disk drivers from your own virtual disk driver.
The bootloader is the only one able to use the EFI drivers. If you want to go to the OS level, you need to write your own OS driver that gets the information from the EFI driver using EFI System Tables. Such examples are Full Disk Encryption implementations.
In theory you would need to write an EFI Block Driver based, a Windows IO Filter or BUS/Volume Driver, an OS X IOStorageFamily KEXT and a Linux Block Device Driver all of them transferring the information from firmware to OS using EFI Tables, Variables or RuntimeDXE.
RuntimeDXE implementations are incredibly difficult due to the conversion to Virtual Memory Maps from the flat addressing available in the EFI.

How 'Input/Output' ports are mapped into memory?

I have been trying to understand I/O ports and their mappings with the memory & I/O address space. I read about 'Memory Mapped I/O' and was wondering how this is accomplished by OS/Hardware. Does OS/Hardware uses some kind of table to map address specified in the instruction to respective port ?
Implementations differ in many ways. But the basic idea is that when a read or write occurs for a memory address, the microprocessor outputs the address on its bus. Hardware (called an 'address decoder') detects that the address is for a particular memory-mapped I/O device and enables that device as the target of the operation.
Typically, the OS doesn't do anything special. On some platforms, the BIOS or operating system may have to configure certain parameters for the hardware to work properly.
For example, the range may have to be set as uncacheable to prevent the caching logic from reordering operations to devices that care about the order in which things happen. (Imagine if one write tells the hardware what operation to do and another write tells the hardware to start. Reordering those could be disastrous.)
On some platforms, the operating system or BIOS may have to set certain memory-mapped I/O ranges as 'slow' by adding wait states. This is because the hardware that's the target of the operation may not be as fast as the system memory is.
Some devices may allow the operating system to choose where in memory to map the device. This is typical of newer plug-and-play devices on the PC platform.
In some devices, such as microcontrollers, this is all done entirely inside a single chip. A write to a particular address is routed in hardware to a particular port or register. This can include general-purpose I/O registers which interface to pins on the chip.

Raw access to HID devices in OS X

What is the simplest way to get raw access to HID devices on OS X?
I've been looking through the IOKit examples, but even opening a device seems needlessly complex, involving multiple callbacks and include things from half a dozen libraries.
libusb is available for OS X, but the kernel grabs all HID devices for exclusive access, and I have been getting strange behavior while trying to use a codeless .kext to block it from associating with my device (it prevents the kernel from grabbing the device initially, but any calls to configure the device seem to cause the kernel to grab the device away from under the little python libusb script I am testing with).
Basically, I have a HID device that just streams data. I want to open it for (ideally exclusive) access, and just get the datastream.
All the examples I have found in the IOKit docs are really complex, compared to the ~8 lines it would take in libusb. There must be a simpler way that isn't a 3'rd party library.
It's worth noting that I am entirely unfamiliar with programming for OS X in any capability.
Python support would be a nice plus
Unfortunately there is no other way than using HID Manager apis. Raw access to HID devices in OS X it's not supported.
The documentation makes it clear:
HID family. Through the HID Manager, the HID family provides a device
interface for accessing a variety of devices, including joysticks and other
game devices, audio devices, non-Apple displays, and UPS (uninterruptible
power supply) devices.
Raw access through POSIX apis it's only available for storage, network and serial devices:
Using POSIX APIs
For each storage, network, and serial device the I/O Kit dynamically
creates a device file in the file system’s /dev directory when it discovers
a device and finds a driver for it, either at system startup or as part of
its ongoing matching process. If your device driver is a member of the I/O
Kit’s Storage, Network, or Serial families, then your clients can access your
driver’s services by using POSIX I/O routines.
So you can either use HID Manager apis directly or you can use libusb or (as the other answer mentions) hidapi which are nothing more than wrapper libraries over HID Manager apis. The benefit of using these libraries is that they abstract most of the low level calls thus making them easier to use.
Take a look at the hidapi mac backend
http://www.signal11.us/oss/hidapi/
https://github.com/signal11/hidapi

How to write BIOS program that connects to the internet?

I am aware that there are programs out there like lojack for laptops that get installed on the BIOS, but I'm still a little confused. When reading about lojack, it seems to me that they can't fully located the laptop's location until the user logs in and tries to access the internet. So I'm thinking that it's a BIOS application so that it wouldn't matter if the thief reformats the HD.
So my question is, does anyone have any ideas of how an internet enables BIOS application would be written. I'm not looking for full answers -- just ideas or resources to get started. For example, is such a thing written in assembly? Once one such app is written, how does it get transfered to the BIOS.
Does the BIOS program itself recognize that there is an internet connection (when the thief logs on to the OS). Or upon logon, does additional processes get spawned? Are there any resources/websites that anyone can direct me too?
You didn't mention whether you were interested in legacy BIOS or EFI BIOS, but I would mention that with EFI there is the capability of writing EFI applications. See Intel Press:
Harnessing the UEFI Shell
The EFI Application toolkit comes with a complete TCP/IP network stack:
http://www.intel.com/technology/efi/toolkit_overview.htm
More at tianocore.org
Regarding "LoJack"-style solutions, one of the providers of this technology is Absolute Software's Computrace product.
Basically there are 3 components: 1) a software component that runs in the OS; 2) a BIOS component which is baked into the system BIOS (accomplished via Absolute working with the PC vendor); 3) servers at Absolute software that talk to the PC.
For more information on how it works visit:
http://www.absolute.com/en/company/Computrace-Persistence.aspx
(see especially the demo video on this site)
To learn something about BIOS, one good source is coreboot.org. It is an open source BIOS (or firmware) and support some physical machines.
Legacy BIOS is written in assembly language, but new generations, such as UEFI or coreboot, are written mostly in C language. BIOS program is stored in the ROM, and executed by the CPU automatically.
The BIOS program itself does not access the internet or perform any of the advertised functions. The LoJack addition to the BIOS firmware is a file copying/patching utility - at boot up it can check the harddrive for a copy of Windows and proceed to silently install/repair the LoJack service if it has been removed. The service itself includes several measures to lower it's profile and prevent itself from being disabled (similar to how many trojans and malware run several processes that each restore the other if one is disabled or killed).
The LoJack BIOS program can't do anything if a unsupported operating system (like Linux) is installed after the harddrive is wiped.

Writing Device Drivers for a Microcontroller(any)

I am very enthusiastic in writing device drivers for a microcontroller(like PIC, Atmel etc).
Since I am a newbie in this controller-coding-area I just want to know whether writing device drivers for controller is same as we write for linux( or any other OS) ?
Also can anyone suggest some online device driver building tutorial for the same ..?
Thanks,
If you are thinking about developing the device drivers to interface your device with a host computer (probably using USB), then most of the microcontrollers nowadays implement default classes that rely on native drivers.
A concrete example:
If you use a PIC18F4555, you can use the regular HID (human interface device) windows driver to communicate with your microcontroller (given you implemented it correctly). No need to develop any driver.
Writing a device driver for an MCU is a pretty far cry from writing it for a OS. Most MCUs won't have an OS running on them at all. You'll generally end up writing some low level Interrupt Service Routines (ISRs) and filling up buffers, that your application software will end up emptying. You don't have to fit into any device driver paradigm that an O/S has defined. You basically have to read the datasheet for the device you are wanting to interface with and read and write to its memory over whatever interface it might use (e.g. SPI, I2C, UART, etc.). Ultimately the device driver ought to provide intuitive function calls to the application software.
If you are using AVR MCU like atmega then you can use vusb (https://www.obdev.at/products/vusb/index.html) for those MCU that don't have any HID and handles the interrupts by connecting D+ and D- pins of the USB to digital I/O ports of the MCU.
The atmegaU2 packages have their own USB communication ports and HID.

Resources