Tak więc próbuję napisać moduł jądra, który używa pliku linux/timer.h. Mam go do pracy wewnątrz modułu, a teraz próbuję go uruchomić z programu użytkownika.Jak używać ioctl() do manipulowania modułem jądra?
Oto mój moduł jądra:
//Necessary Includes For Device Drivers.
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/errno.h>
#include <linux/proc_fs.h>
#include <asm/uaccess.h>
#include <linux/timer.h>
#include <linux/ioctl.h>
#define DEVICE_NAME "mytimer"
#define DEVICE_FILE_NAME "mytimer"
#define MAJOR_NUM 61
#define MINOR_NUM 0
MODULE_LICENSE("Dual BSD/GPL");
static struct timer_list my_timer;
struct file_operations FileOps =
{
//No File Operations for this timer.
};
//Function to perform when timer expires.
void TimerExpire(int data)
{
printk("Timer Data: %d\n", data);
}
//Function to set up timers.
void TimerSetup(void)
{
setup_timer(&my_timer, TimerExpire, 5678);
mod_timer(&my_timer, jiffies + msecs_to_jiffies(5000));
}
//Module Init and Exit Functions.
int init_module(void)
{
int initResult = register_chrdev(MAJOR_NUM, "mytimer", &FileOps);
if (initResult < 0)
{
printk("Cannot obtain major number %d\n", MAJOR_NUM);
return initResult;
}
printk("Loading MyTimer Kernel Module...\n");
return 0;
}
void cleanup_module(void)
{
unregister_chrdev(MAJOR_NUM, "mytimer");
printk("Unloading MyTimer Kernel Module...\n");
}
Dokładniej, chcę mój program użytkownika, aby wywołać funkcję TimerSetup(). Wiem, że będę musiał użyć ioctl(), ale nie jestem pewien, jak określić w moim pliku MODULE, że TimerSetup() powinien być wywoływany przez ioctl().
Moje drugie pytanie: udało mi się insmodować mój moduł, a także mknod w/dev/mytimer z poprawnym numerem głównym. Ale kiedy próbowałem otworzyć() to tak, że mogę dostać deskryptor pliku z niego, to powracało, zwracając -1, co zakładam, jest złe. Upewniłem się, że uprawnienia są w porządku (w rzeczywistości zrobiłem to 777 tylko po to, aby się upewnić) ... To nadal nie działa ... Czy jest coś, czego mi brakuje?
Oto program użytkownika tylko w przypadku:
#include <stdio.h>
int main(int argc, char* argv[])
{
int fd = open("/dev/mytimer", "r");
printf("fd: %d\n", fd);
return 0;
}
Właściwie to obejrzałem, ale nie całkiem to rozumiałem ... Widziałem funkcję statyczne długie softdog_ioctl (plik pliku struct *, unsigned int cmd, unsigned long arg) , ale nie rozumiem, co jest w nim .. Czy to jedyna funkcja ioctl? – hahuang65
Awesome, wygląda na to, że wykonałeś dobrą robotę wyjaśniając interfejs w twoim poście :) Dziękuję. – hahuang65
Chociaż ta odpowiedź ma teraz ponad 5 lat, miałem pytanie. Jeśli dalsze implementacje 'ioctl' są mile widziane, jaka jest preferowana alternatywa? – sherrellbc