Linux Kernel - stoping a running kernel timer from user space - linux

I am trying to blink an LED in my embedded device while Linux is booting. Basically the LED blink shows that Linux is in the process of booting.
To blinks the LED, I am doing the following things
Created a global timer (LED blink timer) in init/main.c
static struct timer_list pwr_led_timer;
Started the timer as soon as init_timers() function is finished in start_kernel()
setup_timer and mod_timer functions used.
When timer fires, in the timer handler, LED is toggled. And timer restarted.
When kernel finishes the whole boot process, I am switching off the LED and deleting the timer.
del_timer_sync(&pwr_led_timer);
Question:
I would like to stop the timer and switch of the LED from user space from my application instead of stopping at the kernel (that is point number 4). Is there a standard way to stop the kernel running timer from user space ?
since pwr_led_timer is global struct, can any IOCTL call be used to stop the timer from user space ? My Idea is do some IOCTL and get access to kernel. Since the pwr_led_timer is global, in IOCTL I can call the del_timer_sync() with pwr_led_timer. But not sure which device I should open to IOCTL (?)
Sorry, I am new to kernel/driver programming. I tried to search the net but could not get any clue.
Kindly let me know if anyone has any inputs. Thanks in advance.
Regards,
Emerson

Have you considered trying netlink? It's a powerful method for user-to-kernel (or process-to-process) communication which both simple and lightweight.

Related

Last command during poweroff

I am writing some software to shutdown some external hardware wired into my control board. The catch is that I need to wait for the VERY end of the poweroff operation to send the signal (through a gpio output). I am weighing some options right now, but I am curious as to where I can see what the kernel actually does right before poweroff.
Is there a file somewhere that I can look into?
Start at the function kernel_power_off in kernel/reboot.c and follow the code. The final power-off operations are very platform specific, so if you want to follow down to the bitter end, you'd need to figure out exactly which bits of arch-specific code you're using.
One simpler possibility for sending your signals is to register a kmsg_dump handler. The last thing kernel_power_off does before invoking the platform-specific power-off code is to execute kmsg_dump(KMSG_DUMP_POWEROFF);. (Just ignore any kmsg_dump calls other than that one.)

Linux keyboard delay

So I want to build a kernel module (I suppose) which would insert little delay after a keyboard key is pressed (let's say 500ms). I managed to do this in Windows through hooks, but it seems to be different in Linux. Note that I do not wish to use x11 methods, as I want it to also work from the linux console (even if there is no X server running). From what I was able to understand, it would require to build a kernel module and insert it dynamically into the kernel with insmod. I managed to build a key logger which would dump each pressed key to the kernel log, but inserting a delay would require sending the thread that handles the keyboard interrupt handler to sleep, which is a very bad idea, and also to rewrite the entire USB_KBD driver, because the current script calls the request_irq function with the IRQF_SHARED flag set, so I guess the original driver still does its job before executing my function.
I am currently requesting an interrupt handler like this
request_irq (1, (irq_handler_t) irq_handler, IRQF_SHARED, "keyboard_stats_irq", (void *)(irq_handler));
Any suggestions on how to handle this (any other way) ?
You can write a user space daemon that reads the input events from /dev/input/input* (whatever the keyboard device is), while grabbing the device to block the events to go through the rest of the system (ioctl(fd, EVIOCGRAB, 1)).
Then, the daemon can create a virtual input device, using /dev/uinput and write the input events there after some delay. Since the delay will be implemented in user-space, that will be quite easy.
Starting your daemon will be equivalent to hot-plugging a virtual keyboard, and modern X servers (less than 10 years?) are able to cope with hot-plugged input devices. And the vconsole driver works fine too with those.

Restoring Keyboard IRQ

I'm very new to the Linux Kernel Module development and trying to write a simple kernel module which can later be extended as the keyboard driver.
I tried following two approaches:
Interrupt Based Approach
I started writing the code after following the guide given here. But the only problem is that the machine freezes when I run rmmod because it is not able to restore the IRQ to the original keyboard driver.
Is there any way to save the device name & device id of the original keyboard driver before requesting the IRQ in init() and then restore everything back to normal once the exit() i.e. cleanup_module() is fired?
void cleanup_module() {
/* Something to restore everything back to normal */
free_irq(1, NULL);
}
Polling Approach
In this approach, I am continuously polling for the Key Pressed & Released by using a while loop and then copying the input back to the user.
while(!(inb(0x64) & 0x1) || (input = inb(0x60)) & 0x80);
The problem I'm facing here is that it never comes out of the while loop. I'm assuming that is because the original keyboard driver serves the request.
Is there any way to get the request forwarded from the original keyboard driver?
I appreciate any help/pointers on this.
Thanks!
I'm afraid that I do not see how this can work as long as the normal kernel keyboard driver is also controlling the keyboard, since both drivers will be attempting to control the device. The kernel i8042 driver (I assume that is the relevant one for you) registers its interrupt as shared, and if your driver managed to register for the same interrupt then it will also have registered its handler as shared, so that both got notified on interrupts and would race to access the device.
If you registered a shared handler, this might also explain the crash when you unload it: unregistering a shared interrupt handler only works when the second parameter contains a valid dev_id; so unregistering would fail when called with NULL as you did, but the handler code would still be unloaded from memory. This would leading to a crash on a future interrupt.
Regarding your polling approach, yes, since the normal driver is notified on interrupts it is rather likely to beat you to reading the keyboard.

Track user thread life in kernel space

I'm trying to track the life span of a user thread in a kernel module. I want to detect when a user thread is no longer executing (exit() has been called). How would I go about doing that? I'm digging into the kernel source code as I write this, but there's a lot to take in!
I did find task_struct.vfork_done, and it looks like something I can hook into. Am I on the right track?
Before anything, let me confirm that by 'no longer executing' you mean the process has been signaled to die and will soon expire. If I were you, I would register a notification chain within a simple misc driver module.
I would then trigger the notification from within the signal handling code of the kernel when the process under question has been signalled with a fatal signal. I would specifically tinker with the function get_signal_to_deliver (kernel/signal.c). I've recently answered a similar query here

Is the driver using the Linux NAPI Interface?

Is there a way to confirm if a Linux Ethernet driver is using the NAPI interface?
I know this sounds like an obvious answer, but check the source to see if the NAPI API is being used.
For example:
In your driver's interrupt handler, does it use any of the calls below?
Does your driver implement a poll() method for the NAPI? If so, see if it uses
netif_receive_skb() instead of netif_rx().
If both of those questions lead to 'YES', the your driver is using NAPI.
Note: The following was copied from here
NAPI API
netif_rx_schedule(dev)
Called by an IRQ handler to schedule a poll for device
netif_rx_schedule_prep(dev)
puts the device in a state ready to be added to the CPU polling list if it is up and running. You can look at this as the first half of netif_rx_schedule(dev).
__netif_rx_schedule(dev)
Add device to the poll list for this CPU; assuming that netif_schedule_prep(dev) has already been called and returned 1
__netif_rx_schedule_prep(dev)
similar to netif_rx_schedule_prep(dev) but no check if device is up, usually not used
netif_rx_reschedule(dev, undo)
Called to reschedule polling for device specifically for some deficient hardware.
netif_rx_complete(dev)
Remove interface from the CPU poll list: it must be in the poll list on current cpu. This primitive is called by dev->poll(), when it completes its work. The device cannot be out of poll list at this call, if it is then clearly it is a BUG().
__netif_rx_complete(dev)
same as netif_rx_complete but called when local interrupts are already disabled.
Check out this wikipedia article and the external links in it for more detailed information.
I hope that helps.

Resources