我正在尝试创建一个简单的内核模块,使键盘LED闪烁。它在Linux 3.16(Ubuntu 14.04)上运行良好,但它不会改变4.5(Arch)上的LED状态。
我无法弄清楚它会带来什么样的差异,我在demsg中找不到任何有用的东西。知道我怎么能找到这个问题?
代码:
#include <linux/module.h>
#include <linux/device.h>
#include <linux/tty.h>
#include <linux/kd.h>
#include <linux/vt.h>
#include <linux/console_struct.h>
#include <linux/vt_kern.h>
#include "device.h"
#include "timer.h"
#define LEDS_ON 0x07
#define LEDS_OFF 0xFF
static int major_number;
static struct class *class;
static struct tty_driver *driver;
static unsigned long led_status = LEDS_OFF;
static void timer_callbak(void)
{
if (led_status == LEDS_OFF) {
led_status = LEDS_ON;
} else {
led_status = LEDS_OFF;
}
driver->ops->ioctl(vc_cons[fg_console].d->port.tty, KDSETLED, led_status);
}
static long device_ioctl(struct file *file, unsigned int command, unsigned long argument)
{
if (command == ON && led_status == LEDS_OFF) {
timer_init(&timer_callbak);
} else if (command == OFF && led_status == LEDS_OFF){
timer_exit();
} else if (command != OFF && command != ON) {
printk(KERN_WARNING "Invalid ioctl() command");
return -1;
}
return 0;
}
static struct file_operations operations = {
.unlocked_ioctl = device_ioctl
};
dev_t create_dev_type(void)
{
return MKDEV(major_number, 0);
}
void create_device(void)
{
major_number = register_chrdev(0, NAME, &operations);
printk("Keyboard leds registered with major_number \"%d\"", major_number);
class = class_create(THIS_MODULE, NAME);
device_create(class, NULL, create_dev_type(), NULL, NAME);
}
void device_init(void)
{
create_device();
driver = vc_cons[fg_console].d->port.tty->driver;
printk("Keyboard leds device Initialized");
}
void device_exit(void)
{
device_destroy(class, create_dev_type());
class_unregister(class);
class_destroy(class);
unregister_chrdev(major_number, NAME);
printk("Keyboard leds device exited");
}
MODULE_LICENSE("GPL");
这就是我试图调用它的方式:
#include <sys/ioctl.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include "src/device.h"
int main(void)
{
int fd;
if ((fd = open("/dev/keyboard_leds", O_RDWR|O_NONBLOCK)) < 0) {
perror("Open failed!");
return -1;
}
ioctl(fd, ON);
close(fd);
return 0;
}