I have written a custom QEMU framebuffer device. In support of this I also wrote a framebuffer driver for Linux. cat /dev/urandom > /dev/fb0 works wonderfully and calls my fb_write callback (nonstandard layout, can't be mmap'ed). However my attempt at a userspace application refuses to work.
I have opened /dev/fb0 with fopen([filename], "rwb"); and a non-null pointer is returned. But when I go to write to it with fwrite, although the FILE* is still non-null, an error is returned and perror prints "Bad File descriptor." Any ideas?
Related
I am passing pointer to below structure through ioctl.
typedef struct myparam_t {
int i;
char *myname;
}myparam;
I allocate memory for myname in the user space before passing the argument.
In the ioctl implementation at kernel space I use copy_from_user() to copy the argument in kspace variable (say kval). call is like copy_from_user(kval,uval,sizeof(myparam)); kval & uval are of myparam * type.
Now in ioctl function I have check like -
if (uval->myname != NULL) {
}
I thought this will result in to kernel crash or panic due to page fault.
However I see different behaviour with different version of kernel.
With 4.1.21 kernel I see no issue with NULL check, But with 4.10.17 kernel I see a page fault that results in to kernel panic.
My question is what might make NULL check working in kernel 4.1.21 ?
Is there a way I can make same code working for 4.10.17 as well ?
Note that I am facing this issue as part of kernel migration. We are trying to migrate from version 4.1.21 to 4.10.17. There may be many instance of such usage in our code base. Hence, if possible, I'd prefer to put a patch in kernel to fix the issue, rather than fixing all such instance.
Thanks
Dipak.
I am working on a Linux driver for usb device which fortunately is identical to that in the usb_skeleton example driver which is part of the standard kernel source.
With the 4.4 kernel, it was a breeze, I simply changed the VID and PID and a few strings and the driver compiled and worked perfectly both on x64 and ARM kernels.
But it turns out I have to make this work with a 3.2 kernel. I have no choice in this. I made the same modifications to the skeleton driver in the 3.2 source. Again, I did not have to change actual code, just the VID, PID and some strings. Although it compiles and loads fine (and shows up in /dev), it permanently hangs in the first attempt to do a read from /dev/myusbdev0.
The following code is from the read function, which is supposed to read from the bulk endpoint. When I attempt to read the device, I see the first message that it is going to block due to ongoing io. Then nothing. The user program trying to read this is hung, and cannot be killed with kill -9. The linux machine cannot even reboot - I have to power cycle. There are no error messages, exceptions or anything like that. It seems fairly certain it is hanging in the part that is commented 'IO May Take Forever'.
My question is: why would there be ongoing IO when no program has done any IO with the driver yet? Can I fix this in driver code, or does the user program have to do something before it can start reading from /dev/myusbdev0 ?
In this case the target machine an embedded ARM device similar to a Beaglebone Black. Incidently, the 4.4 kernel version of this driver works perfectly with on the Beaglebone with the same user-mode test program.
/* if IO is under way, we must not touch things */
retry:
spin_lock_irq(&dev->err_lock);
ongoing_io = dev->ongoing_read;
spin_unlock_irq(&dev->err_lock);
if (ongoing_io) {
dev_info(&interface->dev,
"USB PureView Pulser Receiver device blocking due to ongoing io -%d",
interface->minor);
/* nonblocking IO shall not wait */
if (file->f_flags & O_NONBLOCK) {
rv = -EAGAIN;
goto exit;
}
/*
* IO may take forever
* hence wait in an interruptible state
*/
rv = wait_for_completion_interruptible(&dev->bulk_in_completion);
dev_info(&interface->dev,
"USB PureView Pulser Receiver device completion wait done io -%d",
interface->minor);
if (rv < 0)
goto exit;
/*
* by waiting we also semiprocessed the urb
* we must finish now
*/
dev->bulk_in_copied = 0;
dev->processed_urb = 1;
}
Writing this up as an answer since there was no response to my comments. Kernel commit c79041a4[1], which was added in 3.10, fixes "blocked forever in skel_read". Looking at the code above, I see that the first message can trigger without the second being shown if the device file has the O_NONBLOCK flag set. As described in the commit message, if the completion occurs between read() calls the next read() call will end up at the uninterruptible wait, waiting for a completion which has already occurred.
[1] https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=c79041a4
Obviously I am not sure that this is what you are seeing, but I think there is a good chance. If that is correct then you can apply the change (manually) to your driver and that should fix the problem.
What does ioctl do in the structure struct tty_driver?
I know the ioctl() function provides the means to control the hardware (Keyboard, Mouse, Print) but for example a driver to control the leds on the keyboard I think that the ioctl is more than enough to do this task...
So why I need a tty_driver? I know tty_driver is a struct
P.D I've never tried to program a Device Driver. I've only read a bit of code in some books.
When developing a new driver, the struct tty_driver structure is used to register a tty_driver (using tty_register_driver() 1). This code creates a new device file and set the file operations to some tty specific functions.
The ioctl entry in the newly created file operations is set to tty_ioctl() 2 which after handling some of the basic commands will call the .ioctl function set in the struct tty_operations 3 referenced in the struct tty_driver.
By defining ioctl (note that it is checked if it is not NULL in 3) the developer can implement ioctl commands specific to its device or simply be notified of some other standard commands.
I am currently in the process of writing a Linux kernel module in C. The module provides an extremely basic driver for a USB light (the device consists of three colored LEDs). I have managed to get the driver to load and unload without problems and also create the device (/dev/wn0, /dev/wn1, etc.). However, I keep getting errors when attempting to write to the device:
$ echo "1" >/dev/wn0
bash: echo: write error: Broken pipe
The entire code for the module is here. However, the interesting part is the wn_set_color() function:
/* Create the data buffer to be sent to the device. */
u8 buf[8] = {
red, green, blue, 0, 0, 0, 0x1F, 0x05
};
/* Send the data to the device. */
return usb_control_msg(udev,
usb_sndctrlpipe(udev, 0),
0, 0, 0, 0,
buf, 8, 0);
For some reason, it returns -32 instead of sending the data to the device.
I am completely new to Linux kernel programming so I'm likely doing something silly. If you can shed some light on this at all, it would be greatly appreciated.
Edit: here is some further information:
lsusb -v output is here
the bDescriptorType member of the usb_endpoint_descriptor class contains '5' for the single endpoint exposed by the device (bEndpointAddress is 129 - or 0x81 in hex)
here is a screengrab of one of the control URBs sent to the device
usb_control_msg() eventually calls down to usb_submit_urb(). The Documentation/usb/error-codes.txt file describes the errors that this function can return:
-EPIPE The pipe type specified in the URB doesn't match the
endpoint's actual type.
If usb_submit_urb() succeeded, then usb_control_msg() returns an urb->status value. This lists under EPIPE:
-EPIPE (**) Endpoint stalled. For non-control endpoints,
reset this status with usb_clear_halt().
(**) This is also one of several codes that different kinds of host
controller use to indicate a transfer has failed because of device
disconnect. In the interval before the hub driver starts disconnect
processing, devices may receive such fault reports for every request.
Have you checked for any messages in the kernel log?
I have a feeling it has to do with your usb_sndctrlpipe call. The definition of this function is as follows: unsigned int usb_sndctrlpipe(struct usb_device *dev, unsigned int
endpoint).
You seem to be passing the device pointer appropriately, however your pass in the value 0 for your control endpoint, which as you mention, is not the address of your endpoint. I would recommend defining a constant at the beginning with the hex value of your endpoint and passing that to your calls.
However, I believe you have a bigger problem.
Looking at your lsusb, it seems that your endpoint is not actually a control endpoint, but an interrupt endpoint. This changes the functions that you need to call to communicate. For example, instead of usb_sndctrlpipe you will need usb_rcvintpipe(struct usb_device *dev, unsigned int endpoint) to generate the pipe (since it is an IN endpoint as listed in your lsusb) and use a different function instead of usb_control_msg. Unfortunately, from what I can gather, it seems like there are no functions available to automatically construct interrupt urbs so you will need to create a urb struct as described in section 13.3.2.1 of http://www.makelinux.net/ldd3/chp-13-sect-3. Even worse news is that (unless I am missing something) because your only endpoint seems to be the interrupt IN endpoint, it would seem that you can only receive interrupts from the device and are not able to send anything to the device. Do you know for sure that changing the colors of the lamp via usb is a functionality supported by the device?
More information can be found at the following:
http://www.beyondlogic.org/usbnutshell/usb4.shtml (thorough information on endpoints and how to read the descriptors)
http://www.makelinux.net/ldd3/chp-13-sect-3 and
http://www.makelinux.net/ldd3/chp-13-sect-5 (function definitions for usb communication)
Is it possible to somehow change standart I/O functions handle on Windows? Language preffered is C++. If I understand it right, by selecting console project, compiler just pre-allocate console for you, and operates all standart I/O functions to work with its handle. So, what I want to do is to let one Console app actually write into another app Console buffer. I though that I could get first´s Console handle, than pass it to second app by a file (I don´t know much about interprocess comunication, and this seems easy) and than somehow use for example prinf with the first app handle. Can this be done? I know how to get console handle, but I have no idea how to redirect printf to that handle. Its just study-purpose project to more understand of OS work behind this. I am interested in how printf knows what Console it is assiciated with.
If I understand you correctly, it sounds like you want the Windows API function AttachConsole(pid), which attaches the current process to the console owned by the process whose PID is pid.
If I understand you correct you can find the source code of application which you want to write in http://msdn.microsoft.com/en-us/library/ms682499%28VS.85%29.aspx. This example show how to write in stdin of another application and read it's stdout.
For general understanding. Compiler don't "pre-allocate console for you". Compiler use standard C/C++ libraries which write in the output. So if you use for example printf() the following code will be executed at the end will look like:
void Output (PCWSTR pszwText, UINT uTextLenght) // uTextLenght is Lenght in charakters
{
DWORD n;
UINT uCodePage = GetOEMCP(); // CP_OEMCP, CP_THREAD_ACP, CP_ACP
PSTR pszText = _alloca (uTextLenght);
// in the console are typically not used UNICODE, so
if (WideCharToMultiByte (uCodePage, 0, pszwText, uTextLenght,
pszText, uTextLenght, NULL, NULL) != (int)uTextLenght)
return;
WriteFile (GetStdHandle (STD_OUTPUT_HANDLE), pszText, uTextLenght, &n, NULL);
//_tprintf (TEXT("%.*ls"), uTextLenght, pszText);
//_puttchar();
//fwrite (pszText, sizeof(TCHAR), uTextLenght, stdout);
//_write (
}
So if one changes the value of STD_OUTPUT_HANDLE all output will be go to a file/pipe and so on. If instead of WriteFile the program use WriteConsole function such redirection will not works, but standard C/C++ library don't do this.
If you want redirect of stdout not from the child process but from the current process you can call SetStdHandle() directly (see http://msdn.microsoft.com/en-us/library/ms686244%28VS.85%29.aspx).
The "allocating of console" do a loader of operation system. It looks the word of binary EXE file (in the Subsystem part of IMAGE_OPTIONAL_HEADER see http://msdn.microsoft.com/en-us/library/ms680339%28VS.85%29.aspx) and if the EXE has 3 on this place (IMAGE_SUBSYSTEM_WINDOWS_CUI), than it use console of the parent process or create a new one. One can change a little this behavior in parameters of CreateProcess call (but only if you start child process in your code). This Subsystem flag of the EXE you define with respect of linker switch /subsystem (see http://msdn.microsoft.com/en-us/library/fcc1zstk%28VS.80%29.aspx).
If you want to redirect printf to a handle (FILE*), just do
fprintf(handle, "...");
For example replicating printf with fprintf
fprintf(stdout, "...");
Or error reporting
fprintf(stderr, "FATAL: %s fails", "smurf");
This is also how you write to files. fprintf(file, "Blah.");