Best way to read/write to another block device from kernel mode - io

I'm writing a simple block dev driver to overcome some limitations with porting a previously hardware based RAID array to linux's software raid (mdadm).
This driver will create it's own block device, but proxy r/w requests to 1 or more other block devices (much like mdadm does already).
What is the best way for one kernel mode driver to read and write to another kernel mode (block device) driver?
[EDIT1]:
Ok, looking through the mdadm kernel module code - it looks like we need to do as the kernel does - use generic_make_request to the other disk drivers that handle the disks in the 'volume'. This avoids any user-mode filesystem block devices (/dev/xyz) to kernel mode device driver translations and keeps the I/O completely in kernel mode.
Now... How to obtain the bio handle from the several /dev/xyz strings passed to my module....
[EDIT2]:
Looking at this the wrong way, need to give my driver Major/Minors (translate the /dev/xyz in usermode and hand the dev_t value via ioctl to the driver, from there it can reference the driver.
Well on my way here, but still open to suggestions/recommendations.

The answer was to modify the BIO and re-send it off as I've done in this post:
https://unix.stackexchange.com/questions/171800/hp-smartarray-raid5-recovery-on-linux/171801#171801

Related

Linux kernel: Find all drivers reachable via syscalls

I am comparing a mainline Linux kernel source with a modified copy of the same source that has many drivers added. A little background: That modified source is an Android kernel source, it contains many drivers added by the vendor, SoC manufacturer, Google etc.
I am trying to identify all drivers added in the modified source that are reachable from userspace via any syscalls. I'm looking for some systematic or ideally automatic way to find all these to avoid the manual work.
For example, char device drivers are of interest, since I could perform some openat, read, write, ioctl and close syscalls on them if there is a corresponding device file. To find new character device drivers, I could first find all new files in the source tree and then grep them for struct file_operations. But besides char drivers, what else is there that I need to look for?
I know that the syscalls mentioned above do some kind of "forwarding" to the respective device driver associated with the file. But are there other syscalls that do this kind of forwarding? I think I would have to focus on all these syscalls, right?
Is there something I can grep for in source files that indicates that syscalls can lead there? How should I go about this to find all these drivers?
Update (narrowing down):
I am targeting specific devices (e.g. Huawei P20 Lite), so I know relevant architecture and hardware. But for the sake of this question, we can just assume that hardware for whatever driver is present. It doesn't really matter in my case if I invoked a driver and it reported back that no corresponding hardware is present, as long as I can invoke the driver.
I only look for the drivers directly reachable via syscalls. By directly reachable I mean drivers designed to have some syscall interface with userspace. Yes, syscalls not aimed at a certain driver may still indirectly trigger code in that driver, but these indirect effects can be neglected.
Maybe some background on my objective clarifies: I want to fuzz-test the found drivers using Syzkaller. For this, I would create descriptions of the syscalls usable to fuzz each driver that Syzkaller parses.
I'm pretty sure there is no way to do this programmatically. Any attempt to do so would hit up against a couple of problems:
The drivers that are called in a given case depend on the hardware. For example, on my laptop, the iwlwifi driver will be reachable via network syscalls, but on a server that driver won't be used.
Virtually any code loaded into the kernel is reachable from some syscall if the hardware is present. Drivers interact with hardware, which in turn either interacts with users, external devices, or networks, and all of these operations are reachable by syscalls. People don't write drivers that don't do anything.
Even drivers that aren't directly reachable by a system call can affect execution. For example, a driver for a true RNG would be able to affect execution by changing the behavior of the system PRNG, even if it weren't accessible by /dev/hwrng.
So for a generic kernel that can run on any hardware of a given architecture, it's going to be pretty hard to exclude any driver from consideration. If your hope is to trace the execution of the code by some programmatic means without actually executing it, then you're going to need to solve the halting problem.
Sorry for the bad news.

IRQ Handling from User Space Linux

I'm writting a driver for a synthesized device in an FPGA. The device has several IRQs and have requested them on my driver:
irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
rc = request_irq(irq, &Custom_driver_handler,IRQF_TRIGGER_RISING , DRIVER_NAME, base_addr);
My problem is that i want that the irq_handler calls a function of an user space application. Is there any way to call my user space application from the irq_handler of the driver on kernel space??
I know i could save a flag from the driver and mmap its direction from the user application to polling it, but what i want to know is if there is any faster/more correct way.
Thank you in advance
There are several ways of invoking user-space functions from kernel, usually named upcalls: http://lkml.iu.edu/hypermail/linux/kernel/9809.3/0922.html; check also https://lwn.net/Articles/127698/ "Handling interrupts in user space" and the http://wiki.tldp.org/kernel_user_space_howto overview from 2008, part "Sending Signals from the Kernel to the User Space".
To make writing drivers easier, there is UIO framework in the kernel now: https://unix.stackexchange.com/questions/136274/can-i-achieve-functionality-similar-to-interrupts-in-linux-userspace https://lwn.net/Articles/232575/ https://yurovsky.github.io/2014/10/10/linux-uio-gpio-interrupt/ https://www.osadl.org/fileadmin/dam/rtlws/12/Koch.pdf http://www.hep.by/gnu/kernel/uio-howto/
With UIO you can block or poll special file descriptor to wait for interrupt (block by using read() syscall; poll with poll syscall): https://lwn.net/Articles/232575/
On the user space side, the first UIO-handled device will show up as /dev/uio0 (assuming a normal udev setup). The user-space driver will open the device. Reading the device returns an int value which is the event count (number of interrupts) seen by the device; if no interrupts have come in since the last read, the operation will block until an interrupt happens (though non-blocking operation is supported in the usual way as well). The file descriptor can be passed to poll().
include/linux/uio_driver.h is available in linux kernel for many years, it is here for 3. and 4. versions of kernel.

Linux: access i2c device within board_init function

(iMX6 SOC running Linux 3.0)
I need to run a few I2C transactions in my board_init function. I tried calling i2c_get_adapter, then i2c_transfer, those being available in kernel mode, but i2c_get_adapter returns NULL. It's already called imx6q_add_imx_i2c, which is a wrapper around platform_device_register_full, but that isn't enough.
I can manipulate GPIO in board_init by calling gpio_request to obtain access, and gpio_free at the end. Is there something analogous to those functions for i2c?
--- added details ---
I've got a LAN9500A USB 100Base-T Ethernet MAC connected to a LAN9303 3-port switch with a virtual PHY. The MAC has a GPIO reset line that has to be turned off before it will spring to life and enumerate on the USB. That's done in board_init because it's completely nonstandard, so we don't want to patch the stock driver to manipulate some GPIO that's not part of the device.
The problem I'm having is that even though the MAC is permanently attached to the VPHY, it's not noticing it's connected, and an "ip link show eth1" command shows NO-CARRIER. I found I can kickstart it by unmasking the VPHY's Device Ready interrupt via I2C, but I also have to mask it immediately, or I get infinite interrupts. That's not the right solution, but Microchip has been no help in showing me a better way. But we don't want to patch the MAC driver with code to fiddle with the PHY.
There is no PHY driver for this part, and the MII interface to the VPHY doesn't include any interrupt-related registers, so it must be done through I2C. Writing a PHY driver just to flip a bit on and off once seems a lot of trouble, especially for a newbie like me who's never written a driver before.
I can do it in Python in a startup script, but that, too, seems like a heavyweight solution to a lightweight problem.
That's a wrong approach. Board file supposed to register device drivers and pass important information to them, rather than act as a device driver itself. I'm not sure if what you're trying to do is even possible.
If you really need to extract something from your I2C device on a very early stage - do that in the bootloader and pass the data to kernel via cmdline (U-boot, by the way, has I2C support for a quite some time). Then later, kernel might do appropriate actions depending on what you have passed to it.

Transfer data from linux to fpga and inversely?

I have booted a ubuntu on a ZedBoard. I want to transfer data between fpga and linux. For example, I want to write or read a register from linux. What is best way for doing it? I have not any idea.
Thanx.
First of all, you need to specifically say what you want to do, for example. if you want to access the IO signals on the FPGA, you need to first add the GPIO module to your system, synthesize and implement it.
Then you use the Linux GPIO Driver to access the port as it is explained in this page:
Linux GPIO Driver
The GPIO driver fits in the Linux GPIO framework which is not a char
mode driver. Yet it does provide access to the GPIO by user space
through the sysfs filesystem. This allows each GPIO signal to be read
and written in similar manner to a char mode device. The interface is
somewhat documented in the kernel tree at Documentation/gpio.txt. The
following text is aimed to augment, not replace the existing
documentation.
For other, more complex interfaces you need to create your own driver or use one of the drivers that are available and modify it to fit your needs.

Shutdown (embedded) linux from kernel-space

I'm working on a modified version of the 2.6.35 kernel for Olinuxino, an ARM9 based platform. I'm trying to modify the power management driver (the architecture specific part).
The processor is a Freescale i.MX23. This processor has a "special" pin, called PSWITCH, that triggers an interrupt that is handled by the power management driver.
If the switch is pressed,the system goes to standby. This is done in the driver by calling pm_suspend(PM_SUSPEND_STANDBY).
Given my hardware setup, I'd like to, instead, shutdown the system.
So my question is:
What is the preferred way for a kernel-space process to trigger a clean system halt/poweroff?
I suppose there's a nice little function call out there, but I couldn't find it so far.
My kernel code (the file I'm working on is arch/arm/mach-mx23/pm.c) can be found here: github.com/spairal/linux-for-lobster, though my question calls for a general Linux kernel approach.
The most general way would be for your driver to invoke shutdown as a userspace helper:
static const char * const shutdown_argv[] =
{ "/sbin/shutdown", "-h", "-P", "now", NULL };
call_usermodehelper(shutdown_argv[0], shutdown_argv, NULL, UMH_NO_WAIT);
(Presuming you have a /sbin/shutdown binary installed). This will shut userspace down cleanly, unmount filesystems and then request the kernel shutdown and power off.
However, you may be able to do better than this - for example if you can guarantee that there's no disk filesystems mounted read/write, you could tell a kernel thread to invoke the kernel_power_off() function (it shouldn't be done from interrupt context).

Resources