Why can't I see the full Linux kernel panic inside my terminal in display, but can through the COM-port? - c

There are some cases when it is needed to see the full log of Linux kernel panic.
But it often can't be done through the regular terminal in display.
I thought that it should be done through the COM-port, but can't figure out:
How can I do that?
What is the reason of working well through COM-port, but not through terminal in my display?
UPD: I use debian-based custom Linux (4.9 kernel) with HDMI-display.
Related: How to get a Linux panic output to a USB serial console when system has also a display adapter

Simple direct connected console / VTY use the graphics card to convert character bytes (0 - 255) into display character cells. 80x25 is a common format. This is very simple and not hard for a crashing kernel to manage. Just copy some memory around.
The graphical console is more complicated because the kernel now has to locate the font bitmap for a character and copy the bitmap onto the display. It also needs to handle scrolling with more memory copies, or IOCTL calls into the graphics driver, etc.
A console running in a Gnome or KDE GUI session is very complicated. The kernel isn't involved in drawing it at all and doesn't know how.
The more complex the output process is, the less likely that a kernel that is already crashing can manage it successfully.
Serial port output is once again very simple. A buffered UART makes it a bit more complicated, but if a crashing kernel wants to ignore that and simply output bytes at a 9,600 line rate, any serial port will work with that without needing buffers or interrupt management.

Related

Writing a FreeBSD kernel module that handles arbitrary interrupt and output to device

I would like to write a FreeBSD kernel module that could accept some arbitrary interrupts and upon receiving these interrupt, output some data to an arbitrary device. Currently, I'm facing several issues:
How would I acquire interrupts through a specific IRQ? On Linux there is the request_irq() call but it seems there's no similar API for FreeBSD... Say, I want to be able to detect all the keyboard interrupt through my kernel module (the keyboard is on irq1), how would I do that? (On Linux it is possible through calling free_irq(1, NULL) and request_irq(1, ...), correct me if I'm wrong though).
Is it possible at all to write to a device file under /dev through a kernel module? I've read the question Example for reading text files in FreeBSD kernel module; following this example I was able to do read/write on regular files, but not a device file under /dev (the "device" was a pseudo "echo device", the classical one used in char device examples). I was able to open the file though.
I do understand that it is considered as a bad practice to do file I/O's in kernel, but I could not think any other way... If anyone has a better solution please tell me. (i.e. write to a device through its device_t node?)
The reason I was doing this in a kernel is that I really need all interrupts to be hit, and running it in the user space has the risk of missing interrupts due to kernel threads preempting user threads (the interrupts could come very frequent).
I would also appreciate if anyone could provide me with some other ideas on how to implement this program (basically, the idea is a kernel module that could do the job of a microcontroller...)
You can register an IRQ handler with bus_setup_intr.
Normally, what one would do in this situation is to have a driver collect the interrupts and any other useful data, and export it through a device, and then a (real-time maybe?) process in user-space can read from one device, do whatever it needs to do, and write to the other device.

Linux device driver for a RS232 device in embedded system

I have recently started learning to write Linux device drivers for a specific project that I am working on. Previously most of the work I have done has been with devices running no OS so Linux drivers and development is somewhat new to me.
For the project I am working on I have an embedded system running a Linux based operating system. I have an external device with is controlled via RS232 that I need to write a driver for.
Questions:
1) Is there a way to access serial ports from withing kernel space (and possibly use serial.h, serial_core.h, etc.), how is this usually done, any good examples?
2) From what I found it seems like it would be much easier to access the serial ports in user space by just opening dev/ttyS* and writing to it. When writing a driver for a device like this (RS232 device) is it preferred to do it in user space or is there a way to write a kernel module? How does one decide to write a driver as a kernel module over user space or vise versa?
Are drivers only for generic devices such as UART/serial and then above that is userspace or should this driver be written as a kernel module? I appreciate the help, I have been unable to find much information to answer my questions.
There are a few times when a module that communicates over a serial port may be in the kernel. The pppd (point to point protocol daemon) is one example as Linux has some kernel code devoted to that since it is a high traffic use of serial and it also needs to turn around and put the IP packets into kernel space.
Most other uses would work better from user space since you have a good API that already takes care of a lot of the errors that can happen. This also lessens the chance that your errors will result in massive system failure.
Doing things like this from user space does result in some latency. Reads and writes are buffered, and it's often difficult to tell where in the write operations the hardware actually is, and canceling an already succeeded write call isn't really doable from user space, even if the hardware hasn't yet received the bytes.
I would suggest attempting to do it from user space first and then move to OS driver if necessary. Even if it is necessary to move this into an OS level driver, you'll likely be able to get some progress made from user space.

Linux keyboard raw reading, what's better, reading from /dev/input/event0 or reading from stdin?

I'm working on a small C videogames library for the Raspberry Pi. I'm coding the input system from scratch and after reading and seeing some examples about raw input reading, I got some doubts.
For mouse reading, I just use /dev/input/event1, I open() it as O_NONBLOCK, I read() input_event(s) and I also put the mouse reading in a separate pthread. Easy.
For keyboard reading, I saw some examples that reconfigure stdin to O_NONBLOCK (using fcntl()), then save and reconfigure keyboard termios attibutes (ICANON, ECHO), and some example also save and reconfigure keyboard mode with ioctl(). What's the point of doing all that stuff instead of just reading /dev/input/event0 input_event(s) (same way as mouse)?
Note that I undestand what those functions do, I just don't undestand why should be better to do all that stuff instead of just reading input_event(s).
Reading stdin is not limited to reading locally connected keyboards (but has other limitation making it mostly unsuitable for games). Then reading stdin you could be reading keystrokes from a user logged in remotely, using a locally connected serial terminal or a terminal emulator (possibly operated from a remote X server).
For terminal based games it might make sense to use stdin. But then it would probably be better to use GPM instead of reading /dev/input/event1 for the mouse. And possibly even better to use ncurses for everything.
Otherwise you might want to look at SDL, if not for using it directly, at least for learning about different ways to read input. For example, SDL has full support for network transparency using X. Which means a game can execute on one computer but be played on another.
Expanding on Fabel answer - standard input and event1 are entirely different things. Starting from that the event1 does not have to be mouse but can be an other device depending on udev, kernel version, phase of moon etc. - on my (non Raspberry Pi) system it's input device Sleep Button - which has a keyboard interface. In short you cannot and should not assume it's keyboard - or the only keyboard for that matter (for example also YubiKey emulates the keyboard for it's function but it's rather useless as gaming device, and while 2 keyboards are rarely connected to same Raspberry Pi I don't think it's good idea to assume such setup never happens).
Furthermore typically input devices can be read only by privileged user (on older/current systems) or by user holding a 'seat' (on rootless X systems) - assuming you're not using bleeding edge system it means your game can only by used by root user which is usually considered a bad idea.
Finally it only allows for user to play using a evdev subsystem, which probably should be considered Linux/X11 implementation detail. If you try to connect via network (X11, vnc or whaterver), try to use on-screen keyboard or any accessible input program - you might run into problems.
On the other hand what you can do is either use standard input directly, use some more portable libraries like readline (which should be sufficient for rougulike) or use graphics server (probably indirectly via library like QT or SDL as X11 is not the nicest protocol to program against).
Reading from /dev/input/eventN works only on GNU/Linux.
Configuring and using stdin works on any system implementing POSIX.1-2008, specifically chapter 11: General Terminal Interface. So if you want portable code, like say to work on Linux and OS X without rewriting the input system, you'd do it this way.

Turning off (or otherwise manipulating) the LCD in Linux

I just tried the "2. Starting Steps" section on this page as my first code interacting with devices in Linux. I was curious to know if same things can be done with the display, and if so, how. I only know so much about ioctl() and I don't know if it applies here, and I'm not sure if the device is available in /dev or, rather say, not sure if all the things I'm getting from the example from the link are really relevant here. Where should I begin?
Just to be more clear about what I'm after, as an example to start with, I would like to write a code which would turn the display off and wait for a moment and turn it back on. Hints?
That varies greatly on the device. Generally, there will be a kernel module for the device, sometimes the single module can support many devices. You can look at the source code to see the ioctl handler. You can find the file_operations structure in the driver and look at the function in the ioctl position. There you can see what parameters an ioctl command on the device driver will do.
There's no guarantee that ioctl will do anything. The kernel drivers can be implemented in many different ways. But for turning off an LCD screen, ioctl sounds very likely.
I think what you first need to find out is what kernel module supports the device. Then you need to make sure a device file exists for it. You can create the device file using the mknod command. After that, you should look through the module's source (probably the header is most relevant), to see what ioctl command you need to use to turn the LCD backlight on and off.

Locking the frame buffer device

I am developing an application for linux based embedded system which directly writes on the framebuffer device of the Linux kernel.The writing works perfectly. But the problem happens when some other event occurs with a demand of display(Like plugging a flash drive or a kernel message). Every time when it happens, the screen gets interrupted and the unwanted things appear on the screen erasing the previous graphics from the overlapped portion(other things remain unchanged).
How can I get rid of this problem?
Add console=0 to the kernel command line. It disables both the kernel outputting anything to the console, and the console login. (For development purposes, I recommend having a separate boot option, so you can boot to a console.)
Alternatively, have your application create a new virtual terminal for the framebuffer, like X does. This avoids the kernel (kernel console, really) scribbling text all over your framebuffer.

Resources