Ich entwerfe einen Gerätetreiber, der einfach einen Zeichenpuffer liest und schreibt. Meine Frage bezieht sich jedoch auf die beiden Funktionen in der file_operations
Struktur read
und write
. Ich verstehe nicht wirklich was loff_t *offp
wirklich ist. Ich kenne das sowohl für die Lese- als auch für die Schreiboperationen *offp
ist der Dateioffset, der die aktuelle Lese-/Schreibposition der Datei bedeutet, aber ich bin mir nicht einmal sicher, was es bedeutet, in eine Gerätedatei zu schreiben oder daraus zu lesen.
Aus dem, was ich gesammelt habe, und so schreibe und lese ich von meinem Gerät, erschaffe ich eine Struktur, die mein Gerät darstellt, das ich anrufe my_char_struct
was unten gezeigt wird.
struct my_char_structure{
struct cdev my_cdev;
struct semaphore sem;
char *data;
ssize_t data_size;
unsigned int access_key;
unsigned long size;
};
Dies ist eine statische Struktur, die initialisiert wird und auf die verwiesen wird, wenn mein Treiber vorhanden ist insmod
als solche.
static dev_t dev_num;
static struct my_char_structure Dev;
int start_mod(void){
//Because we are dealing with a fictitious device, I want
//the driver to create my two devices with arbitrarily
//assigned major numbers.
struct my_char_structure *my_dev = &Dev;
int err;
alloc_chrdev_region(&dev_num, FIRST_MINOR, COUNT, DEVICE_NAME);
sema_init(&(my_dev->sem),1);
cdev_init(&(my_dev->my_cdev), &fops);
my_dev->my_cdev.owner = THIS_MODULE;
my_dev->my_cdev.ops = &fops;// fops is my file operations struct
err = cdev_add(&my_dev->my_cdev, dev_num, COUNT);
if(err<0)
printk(KERN_ALERT "There was an error %d.",err);
printk(KERN_ALERT " insmod to major number %d",MAJOR(dev_num));
return 0;
}
module_init(start_mod);
Wenn mein Gerät geöffnet ist, erstelle ich einfach einen Zeiger für die geöffnete Datei, um auf die statische Struktur zu verweisen, die ich währenddessen eingerichtet habe module_init(start_mod)
als solche …
int dev_open(struct inode *in_node, struct file *filp){
static struct my_char_structure *my_dev;
my_dev = container_of(in_node->i_cdev, struct my_char_structure, my_cdev);
printk(KERN_ALERT "The device number is %d",iminor(in_node));
if(!my_dev)
printk(KERN_ALERT "something didn't work. my_dev not initialized.");
filp->private_data = my_dev;
return 0;
}
Meine Lese- und Schreibmethoden ändern diese anfängliche Struktur Dev, auf die ich mit meinen geöffneten Dateien verwiesen habe. Was immer ich copy_to_user
Aus meiner Struktur ist das, was der Benutzer als auf das Gerät geschrieben betrachtet und was auch immer ich copy_from_user
der Benutzer denkt, dass er schreibt. Abgesehen davon, dass ich meine ursprüngliche Struktur Dev geändert habe, macht die Idee der Dateiposition oder des Offsets keinen Sinn, es sei denn, sie bezieht sich auf einen Zeiger auf den gepufferten Speicher innerhalb des Kernels für eine beliebige Struktur oder einen beliebigen Typ. Das ist die einzige Interpretation, die ich für den Datei-Offset habe … ist das richtig? Ist das was loff_t *offp
bezieht sich hier auf?
write(struct file *filp, const char __user *buff, size_t count, loff_t *offp)
read(struct file *filp, char __user *buff, size_t count, loff_t *offp)
(vorausgesetzt, mein Verständnis ist richtig) Wenn eine Dateioperation wie Lesen / Schreiben aufgerufen wird und ich sie nicht eingestellt hatte *offp
persönlich, was ist loff_t *offp anfangs eingestellt?
Wenn in der letzten file_operation offp = some_arbitrary_address (weil ich es so gesagt habe), ist das das, worauf offp gesetzt würde, wenn diese Operation erneut aufgerufen wird?
Was passiert, wenn andere file_opens-Operationen ausgeführt werden, wird es auf das gesetzt, was die letzte file_operation verlassen hat, oder wird es einen Überblick darüber behalten, welche file_open-Operation es verwendet hat, und *offp durch das ersetzen, wo file_open es hatte?
Das Konzept eines Zeichengeräts ist mir zu abstrakt, wenn es scheint, dass das Gerät selbst die Informationen nicht einmal wie eine Datei speichert, sondern der Treiber, der die Informationen speichert. Ich hoffe, ich habe meine Nebelhaftigkeit erklärt und werde alles klären, was mir zweideutig erscheint.