I am making a driver for windows kernel and I am using COM1 for getting log of kernel, the host machine is Ubuntu and guest is qemu. Windows 10 is installed inside it. The problem is there is a bulk of data to be write on COM1. So if it has to write a line ABCDEFGHI and in the next line, it has to write JKLMNOPQ.. it is doing something like ABCDEF in one line and GHIJKLMNOPQ in the second line, means one line data is incomplete and 2nd line data is also corrupting due to this.. is there any lock we can apply? that if one connection is using COM1 then no any other should write on COM1?
QEMU does not control who can write to serial port address at certain time. It's the guest OS's job. QEMU just receives whatever data it sees in the virtual registers.
If you really need to write bulk data to the serial port in the guest OS, you would expect very long time of process. I ever had the same problem and had to test the speed on a very fast Intel CPU. The best speed I can get is 220KBps.
If processing time is not a problem for you, from guest Windows perspective, if you directly write to COM1's port address, it's your driver's responsibility to make locking mechanism, assuming there is no other drivers/processes writing to COM1 either. If you write data via a handle to the COM1 device, there is no locking provided directly by Windows built-in serial port driver. But you still can do it in other ways: open a handle to the serial port device exclusively, so only one process can write to it, or make a device filter driver sitting above Windows serial port driver to add this additional access control, or even directly modify Windows serial port driver's source code to add what you want. Its source code is available now on github.
If none of above applies to your case, you might want to double check how you capture the output of COM1 on host, usually redirected to files, shell and etc. They also could cause some mystery of troubles.
Related
Win32API environment.
I need to identify which program is using a particular serial COM port. For example, if putty has opened COM4 and I later try to start another program that also wants to open COM4, how can I discover that putty is the program preventing this?
In other words, assuming I already have a list of all ports installed on the system, how do I work backwards to discover which programs have opened which ports?
I am programming a pci device with verilog and also writing its driver,
I have probably inserted some bug in the hardware design and when i load the driver with insmod the kernel just gets stuck and doesnt respond. Now Im trying to figure out what's the last driver code line that makes my computer stuck. I have inserted printk in all relevant functions like probe and init but non of them get printed.
What other code is running when i use insmod before it gets to my init function? (I guess the kernel gets stuck over there)
printks are often not useful debugging such a problem. They are buffered sufficiently that you won't see them in time if the system hangs shortly after printk is called.
It is far more productive to selectively comment out sections of your driver and by process of elimination determine which line is the (first) problem.
Begin by commenting out the entire module's init section leaving only return 0;. Build it and load it. Does it hang? Reboot system, reenable the next few lines (class_create()?) and repeat.
From what you are telling, it is looks like that Linux scheduler is deadlocking by your driver. That's mean that interrupts from the system timer doesn't arrive or have a chance to be handled by kernel. There are two possible reasons:
You hang somewhere in your driver interrupt handler (handler starts its work but never finish it).
Your device creates interrupts storm (Device generates interrupts too frequently as a result your system do the only job -- handling of your device interrupts).
You explicitly disable all interrupts in your driver but doesn't reenable them.
In all other cases system will either crash, either oops or panic with all appropriate outputs or tolerate potential misbehavior of your device.
I guess that printk won't work for such extreme scenario as hang in kernel mode. It is quite heavy weight and due to this unreliable diagnostic tool for scenarios like your.
This trick works only in simpler environments like bootloaders or more simple kernels where system runs in default low-end video mode and there is no need to sync access to the video memory. In such systems tracing via debugging output to the display via direct writing to the video memory can be great and in many times the only tool that can be used for debugging purposes. Linux is not the case.
What techniques can be recommended from the software debugging point of view:
Try to review you driver code devoting special attention to interrupt handler and places where you disable/enable interrupts for synchronization.
Commenting out of all driver logic with gradual uncommenting can help a lot with localization of the issue.
You can try to use remote kernel debugging of your driver. I advice to try to use virtual machine for that purposes, but I'm not aware about do they allow to pass the PCI device in the virtual machine.
You can try the trick with in-memory tracing. The idea is to preallocate the memory chunk with well known virtual and physical addresses and zeroes it. Then modify your driver to write the trace data in this chunk using its virtual address. (For example, assign an unique integer value to each event that you want to trace and write '1' into the appropriate index of bytes array in the preallocated memory cell). Then when your system will hang you can simply force full memory dump generation and then analyze the memory layout packed in the dump using physical address of the memory chunk with traces. I had used this technique with VmWare Workstation VM on Windows. When the system had hanged I just pause a VM instance and looked to the appropriate .vmem file that contains raw memory latout of the physical memory of the VM instance. Not sure that this trick will work easy or even will work at all on Linux, but I would try it.
Finally, you can try to trace the messages on the PCI bus, but I'm not an expert in this field and not sure do it can help in your case or not.
In general kernel debugging is a quite tricky task, where a lot of tricks in use and all they works only for a specific set of cases. :(
I would put a logic analyzer on the bus lines (on FPGA you could use chipscope or similar). You'll then be able to tell which access is in cause (and fix the hardware). It will be useful anyway in order to debug or analyze future issues.
Another way would be to use the kernel crash dump utility which saved me some headaches in the past. But depending your Linux distribution requires installing (available by default in RH). See http://people.redhat.com/anderson/crash_whitepaper/
There isn't really anything that is run before your init. Bus enumeration is done at boot, if that goes by without a hitch the earliest cause for freezing should be something in your driver init AFAIK.
You should be able to see printks as they are printed, they aren't buffered and should not get lost. That's applicable only in situations where you can directly see kernel output, such as on the text console or over a serial line. If there is some other application in the way, like displaying the kernel logs in a terminal in X11 or over ssh, it may not have a chance to read and display the logs before the computer freezes.
If for some other reasons the printks still do not work for you, you can instead have your init function return early. Just test and move the return to later in the init until you find the point where it crashes.
It's hard to say what is causing your freezes, but interrupts is one of those things I would look at first. Make sure the device really doesn't signal interrupts until the driver enables them (that includes clearing interrupt enables on system reset) and enable them in the driver only after all handlers are registered (also, clear interrupt status before enabling interrupts).
Second thing to look at would be bus master transfers, same thing applies: Make sure the device doesn't do anything until it's asked to and let the driver make sure that no busmaster transfers are active before enabling busmastering at the device level.
The fact that the kernel gets stuck as soon as you install your driver module makes me wonder if any other driver (built in to kernel?) is already driving the device. I made this mistake once which is why i am asking. I'd look for the string "kernel driver in use" in the output of 'lspci' before installing the module. In any case, your printk's should be visible in dmesg output.
in addition to Claudio's suggestion, couple more debug ideas:
1. try kgdb (https://www.kernel.org/doc/htmldocs/kgdb/EnableKGDB.html)
2. use JTAG interfaces to connect to debug tools (these i think vary between devices, vendors so you'll have to figure out which debug tools you need to the particular hardware)
I'm interfacing to a hardware serial device using QT, I've based my application roughly around the Terminal example, but as the communication needs to be very synchronous the serial handler is living in another thread. The connection is via a 2xRS232 to USB adaptor with an FTDI chipset.
The serial comms are fine, I can connect, send commands, etc. However, when I quit and reload the application the serial port seems to be blocked.
Let COM1 be the connected device, COM2 is unconnected.
If I run the program, do a bit of talking to the hardware and quit, I can no longer connect to COM1 the next time I run the program (the data leds don't flash on the adaptor) unless I attempt to connect to COM2 first. Once I've tried this I can then connect back to COM1 as usual. This behaviour is not seen in the reference utility for the hardware and so must be down to some way I'm handling the port.
My close code is:
void mydevice::closeSerialPort()
{
this->stop();
serial->close();
emit serialClosed();
emit log("Serial port closed.");
}
serial is a QTSerialPort. First a stop command is sent to turn off the hardware (not relevant to the problem, it's just a convenience) and then I send a close command to the serial.
I have a subclassed QWidget for my main window, which calls this command on exit:
/* In the constructor */
connect(this, SIGNAL(WindowClosed()), mydevice, SLOT(closeSerialPort()));
void mainwindow::closeEvent(QCloseEvent *event)
{
emit WindowClosed();
event->accept();
}
Is there any reason for this behaviour? I assume I'm blocking the port open somehow, but surely it would complain that it's already open.
Another odd issue is that say the device is on COM1 and I open it in my application, COM1 is unresponsive in the other utility and the device appears on COM2. However, when I switch back to my program and fiddle a bit, the device appears on COM1 again (though always in COM2 in the other application).
So there seems to be a fairly simple solution, though I don't understand exactly what was causing the problem.
I have two threads, each controlling a different serial device. The serial configuration is accessed through a dialog which I stole from a QT example (the terminal). Each thread has an instance of this settings dialog. It seems that something goes wrong when selecting the port - for instance all the selections in the dialog actually point to the same COM port if checked in a debugger.
Anyway, I chalked this up to non-thread-safe code and changed the program to just ask for the serial port name as the data rates, stop bits, parity, etc are fixed by the hardware and aren't going to change. This has fixed the problem.
There are two possible answers, I think:
Your process doesn't terminate in spite of you closing the main window. How have you verified that the process is, in fact, terminated?
Your use of qt's serialport module exposes a bug in FTDI's driver. That's not unthinkable, but I'd call it a remote possibility at the moment.
Personally I don't see any use for the serial port emulation of the FTDI driver, it's adding an extra layer for no good reason. The D2XX interface is the way to do it, if you don't want to use something like libftdi. On Windows, I've found D2XX and libftdi to be the only viable alternatives, with libftdi working much better than D2XX on virtual machines.
Don't know if this could be useful.
I have a similar issue (but not the same) with a prolific pl2303.
In my case when i close the port (or even at startup, before opening it!), data is received anyway somehow and presented immediately when i open the port.
This happens only with an usb-rs232 adapter, if I use the ttyS0 (physical serial port) the problem does not appear.
The solution for me was forcing QSerialPort::clear() to clear buffers just after QSerialPort::open(). This avoids signal readyRead to be emitted and thus unwanted data to be received.
Is there any way to create a block device via user space in OSX (10.8+), without 3rd party libraries (FUSE, etc)?
I am trying to create a userspace tool. The idea is the user supplies a file to the tool and the tool creates a virtual interface. Whenever the interface is written to, the tool applies an operation to the data and then writes to the original file. Whenever the interface is read from, the tool reads from the original file and applies the inverse operation.
I don't necessarily need a block device. The tool needs to create some kind of virtual interface that can be treated as a file, i.e. it can be opened and saved to by another application.
I looked at the userspace routines of the I/O Kit, but nothing seemed aplicable, as creating a virtual USB/FireWire/MMC/SCSI device seems excessive.
The closest thing I can think of without going into kernel space is a fifo or named pipe - this is essentially a pipe with a file name. Unfortunately, being a pipe, you can't seek, etc. - you can just open the fifo for reading in one process and for writing in another. You create these either with the mkfifo command line utility or the mkfifo() C function.
There are also UNIX domain sockets, which are similar to IP sockets but again are identified by a file name, not a networking construct. These can be read and written from both ends, but again no seeking.
As for actually implementing the ops functions for a vnode (the in-kernel representation of a file in OSX) I believe you do have to drop to the kernel. Note that the I/O kit isn't strictly necessary for creating a block device - if the BSD device nodes are sufficient, and you don't need support for hardware or ejecting volumes etc. you can simply create a node with bdevsw_add(), supplying the ops vector as a parameter. (for an I/O Kit based storage device, the IOMediaBSDClient does this automatically, along with creating the character device with cdevsw_add_with_bdev()) Another, rather more elaborate option is to implement your own file system.
Amongst features of terminal desktop services running RDP port, there is port redirection of parallel/serial from remote to local PC.
Can this redirection be somehow used to transfer large data to avoid using Clipboard (due to the known stack bug which may force user to close terminal desktop and re-logon)?
To transmit and receive data I'd use VBA for Excel on both terminal desktop as well as in local PC. Both would be running infinetely or at the same time.
Please advise if it's possible.
At least one company makes a library for doing Kermit (i.e. serial file transfer), which includes VBA support and samples for Access, Excel and Word.
It's not cheap though, and there are a lot of better ways of sending data around than serial file transfer protocols over virtual serial ports so I'd strongly consider better alternatives (file sharing, TCP sockets etc.).