Torna indietro   Hardware Upgrade Forum > Software > Programmazione

Marvel's Wolverine, la recensione: Logan torna protagonista in un'avventura brutale e intensa
Marvel's Wolverine, la recensione: Logan torna protagonista in un'avventura brutale e intensa
Marvel's Wolverine porta Logan in un'avventura inedita, violenta e fortemente narrativa, costruita attorno alla sua natura di combattente e al difficile rapporto con il proprio passato. Insomniac Games punta su combattimenti spettacolari, progressione e personalizzazione, inserendo l'azione in un mondo segnato dalla persecuzione dei mutanti. Un viaggio intenso, che alterna mattanza, esplorazione e momenti sorprendentemente emotivi.
DJI Romo 2: tante novità lo rendono un robot completo
DJI Romo 2: tante novità lo rendono un robot completo
Romo 2 è la seconda generazione di robot lavapavimenti di DJI, un modello che si caratterizza per la precisione nel sistema di navigazione e per il funzionamento particolarmente silenzioso. Con le modifiche introdotte in questa seconda versione, e un posizionamento di prezzo più allineato alla concorrenza, rappresenta una valida alternativa sul mercato delle soluzioni di pulizia domestica
Sony Bravia 9 II: il True RGB alla prova, dove l'LCD sfida l'OLED
Sony Bravia 9 II: il True RGB alla prova, dove l'LCD sfida l'OLED
Il primo Sony con retroilluminazione True RGB alla prova del banco di misura e dei contenuti: luminanza enorme, colori accurati in HDR e un antiriflesso molto efficace. I limiti sono due sole HDMI 2.1 e il blooming fuori asse
Tutti gli articoli Tutte le news

Vai al Forum
Rispondi
 
Strumenti
Old 22-11-2007, 11:39   #1
Dawidh
Member
 
L'Avatar di Dawidh
 
Iscritto dal: Oct 2007
Città: Terlago --> Trento
Messaggi: 88
[Kernel] kthread e accesso ai device

Allora, ho un problema con la programmazione del kernel.
Mi è stato chiesto di realizzare un modulo che:
creo due device (char) e creo dei kthread (che attendono ciclicamente degli input su uno dei device).

Codice:
static int output_thread(void *arg)
{
  while (!kthread_should_stop()) {
    
  wait_for_completion(&available_data);
    
  printk("1");  //è solo per test
  
  return 0;
}
qunado vado a mettere (tramite echo) qualcosa nel device faccio anche una complete(&available_data); così mi si può sbloccare un kthread. Il mio problema è questo: come faccio dopo la wait a dire al kthread di prendere i dati dal device?

Noi a lezione abbiamo fatto solo cat da spazio utente per estrarre i dati del device, ma come si può fare da kthread.
Oppure, avete un approccio diverso a questo esercizio per risolvere il problema?
Grazie
Dawidh è offline   Rispondi citando il messaggio o parte di esso
Old 22-11-2007, 14:29   #2
ilsensine
Senior Member
 
L'Avatar di ilsensine
 
Iscritto dal: Apr 2000
Città: Roma
Messaggi: 15625
Il kernel thread viene eseguito in un contesto di processo diverso dal processo utente che effettua la scrittura, quindi non ha modo di accedere direttamente ai dati. Devi usare quindi un buffer intermedio che riempi direttamente nella read e leggi nel kernel thread (protetto da un mutex o uno spinlock ovviamente).
__________________
0: or %edi, %ecx; adc %eax, (%edx); popf; je 0b-22; pop %ebx; fadds 0x56(%ecx); lds 0x56(%ebx), %esp; mov %al, %al
andeqs pc, r1, #147456; blpl 0xff8dd280; ldrgtb r4, [r6, #-472]; addgt r5, r8, r3, ror #12
ilsensine è offline   Rispondi citando il messaggio o parte di esso
Old 22-11-2007, 18:47   #3
Dawidh
Member
 
L'Avatar di Dawidh
 
Iscritto dal: Oct 2007
Città: Terlago --> Trento
Messaggi: 88
ah, ho capito.. non lo sapevo, vabbè peccato sarebbe stato molto più comodo accedere direttamente con il kernel.
dovrò fare così perfetto grazie mille per l'info

ci sentiamo più avanti (non credere che i problemi siano già finiti ) dopo tutto abbiamo iniziato il progetto oggi quindi mi vedrai spesso qui a chiedere consigli.

Bye. e grazie ancora
Dawidh è offline   Rispondi citando il messaggio o parte di esso
Old 22-11-2007, 22:26   #4
recoil
Senior Member
 
L'Avatar di recoil
 
Iscritto dal: Jul 2002
Città: Milano
Messaggi: 19150
non puoi accedere a memoria in user space da kernel
le funzioni copy_to_user e copy_from_user sono fatte apposta
quando il processo in user space fa una write sul dispositivo a caratteri viene chiamata la funzione che tu hai specificato nella struttura fops per rispondere ad una scrittura
lì metti la copy_from_user per prendere i dati che l'utente ha scritto
recoil è offline   Rispondi citando il messaggio o parte di esso
Old 23-11-2007, 09:59   #5
ilsensine
Senior Member
 
L'Avatar di ilsensine
 
Iscritto dal: Apr 2000
Città: Roma
Messaggi: 15625
Quote:
Originariamente inviato da Dawidh Guarda i messaggi
ah, ho capito.. non lo sapevo, vabbè peccato sarebbe stato molto più comodo accedere direttamente con il kernel.
Sempre "con il kernel" accedi (intendevi: dal kernel thread forse?)

Puoi spiegare esattamente cosa devi fare? Forse la soluzione è banale, a che ti serve un kernel thread?
__________________
0: or %edi, %ecx; adc %eax, (%edx); popf; je 0b-22; pop %ebx; fadds 0x56(%ecx); lds 0x56(%ebx), %esp; mov %al, %al
andeqs pc, r1, #147456; blpl 0xff8dd280; ldrgtb r4, [r6, #-472]; addgt r5, r8, r3, ror #12
ilsensine è offline   Rispondi citando il messaggio o parte di esso
Old 23-11-2007, 11:25   #6
Dawidh
Member
 
L'Avatar di Dawidh
 
Iscritto dal: Oct 2007
Città: Terlago --> Trento
Messaggi: 88
Si si, intendevo kernel thread, ho dimenticato una parola. sorry.

praticamente i kthread devono ciclicamente attendere -sul device chiamato controllo- delle richieste (che verranno fatte da spazio utente sullo stesso device). le richieste contengono una parola, un tempo e una priorità, il kthread deve solo prendere la parola e stamparla con una printk una volta al secondo per un tempo t.
Se non ci sono kthread disponibili (perchè tutti stanno stampando)metto le richieste in una coda in attesa che un kthread finisca di servire una richiesta e prenda quella in coda.

Però è un progetto per scuola quindi devo proprio svilupparlo così, con i kthread. non è che ho altre scelte.

Tu come mi consiglieresti di procedere? Faccio un buffer intermedio e i kthread prendono le richieste da lì?
Perchè il mio dubbio è la .read della struttura fops non ho modo di chiamarla io diciamo manualmente con una cat per poi passare i dati al kthread. ma qunado faccio la .write questa mi sblocca un kthread (in attesa su una completion) e quindi non so come prendere i dati della .write
Consigli? grazie.
Spero di essermi spiegato decentemente altrimenti ti posso postare i pezzi di codice.
Dawidh è offline   Rispondi citando il messaggio o parte di esso
Old 23-11-2007, 13:47   #7
ilsensine
Senior Member
 
L'Avatar di ilsensine
 
Iscritto dal: Apr 2000
Città: Roma
Messaggi: 15625
Abbastanza semplice sembra; non devi però usare il completion, ma una waitqueue.
__________________
0: or %edi, %ecx; adc %eax, (%edx); popf; je 0b-22; pop %ebx; fadds 0x56(%ecx); lds 0x56(%ebx), %esp; mov %al, %al
andeqs pc, r1, #147456; blpl 0xff8dd280; ldrgtb r4, [r6, #-472]; addgt r5, r8, r3, ror #12
ilsensine è offline   Rispondi citando il messaggio o parte di esso
Old 23-11-2007, 14:08   #8
ilsensine
Senior Member
 
L'Avatar di ilsensine
 
Iscritto dal: Apr 2000
Città: Roma
Messaggi: 15625
Quote:
Originariamente inviato da Dawidh Guarda i messaggi
Perchè il mio dubbio è la .read della struttura fops non ho modo di chiamarla io diciamo manualmente con una cat per poi passare i dati al kthread. ma qunado faccio la .write questa mi sblocca un kthread (in attesa su una completion) e quindi non so come prendere i dati della .write
Avevo scritto male io, intendevo la write non la read.
__________________
0: or %edi, %ecx; adc %eax, (%edx); popf; je 0b-22; pop %ebx; fadds 0x56(%ecx); lds 0x56(%ebx), %esp; mov %al, %al
andeqs pc, r1, #147456; blpl 0xff8dd280; ldrgtb r4, [r6, #-472]; addgt r5, r8, r3, ror #12
ilsensine è offline   Rispondi citando il messaggio o parte di esso
Old 23-11-2007, 14:39   #9
Dawidh
Member
 
L'Avatar di Dawidh
 
Iscritto dal: Oct 2007
Città: Terlago --> Trento
Messaggi: 88
ok capito.....allora procedo con le waitqueue.
Grazie mille per i consigli.
Dawidh è offline   Rispondi citando il messaggio o parte di esso
Old 26-11-2007, 10:21   #10
Dawidh
Member
 
L'Avatar di Dawidh
 
Iscritto dal: Oct 2007
Città: Terlago --> Trento
Messaggi: 88
Ciao, avrei un'altra domandina riguardo il programma descritto sopra.ù

Allora, io ho fatto il mio kthread che prende i dati da un buffer riempito dalla write, adesso però dovrei implementare anche una specie di log per il kthread, cioè ad esempio quando il kthread parte e si ferma sulla waitqueue io dovrei loggare l'evento "il thread è in attesa di richieste e blablabla" scrivendo su un altro device creato appositamente (che poi potrà venire letto con una cat /dev/logging).

Posso scrivere dal kthread direttamente sul device? se si come potrei fare e i dati scritti posso visualizzarli tranquillamente con una cat?

Grazie e ciao.
Dawidh è offline   Rispondi citando il messaggio o parte di esso
Old 26-11-2007, 12:36   #11
ilsensine
Senior Member
 
L'Avatar di ilsensine
 
Iscritto dal: Apr 2000
Città: Roma
Messaggi: 15625
Quote:
Originariamente inviato da Dawidh Guarda i messaggi
Posso scrivere dal kthread direttamente sul device?
Non ha senso questa affermazione. Il tuo driver _è_ il device. Potresti (duale della precedente) riempire un buffer dal thread e passarlo in userspace dalla read.

Però non reinventarti la ruota, esistono tanti metodi per il logging. Uno già lo conosci (printk), ma ci sono anche debugfs/netlink/sysfs/connector ecc.

Nel tuo caso vedo bene il connector, non un device node.
__________________
0: or %edi, %ecx; adc %eax, (%edx); popf; je 0b-22; pop %ebx; fadds 0x56(%ecx); lds 0x56(%ebx), %esp; mov %al, %al
andeqs pc, r1, #147456; blpl 0xff8dd280; ldrgtb r4, [r6, #-472]; addgt r5, r8, r3, ror #12
ilsensine è offline   Rispondi citando il messaggio o parte di esso
Old 03-12-2007, 07:33   #12
Dawidh
Member
 
L'Avatar di Dawidh
 
Iscritto dal: Oct 2007
Città: Terlago --> Trento
Messaggi: 88
EDIT: Scusate sono veramente fuso!! ho già risolto il problema.
Quote:
printk("%s",logging)
;
Non so perché ma c'era questo comando!! probabilmente per debug. vabbè........



Di nuovo ciao a tutti.
Intanto grazie per i vostri consigli, abbiamo quasi finito il progetto.

Quote:
Nel tuo caso vedo bene il connector, non un device node.
Purtroppo dovevo per forza usare un chardevice per fare il logging, è una richiesta del progetto da parte del professore.

Ora, ho un ultimo problemino. Non sono proprio pratico dei device e non capisco perché nel progetto quando vado a fare una lettura sul device "log" tutto ok però quando faccio una scrittura sul device "controllo" mi viene anche fatta una lettura su quello di "log", il che è abbastanza seccante perché l'utente dovrebbe decidere lui quando fare una lettura del log e non che mi venga stampata ogni volta che faccio una scrittura (tra l'altro su un altro device!!)
Sono abbastanza sicuro che il problema sta in conflitti che forse creo durante le open dei device. Cmq vi posto il codice perché proprio non riesco a venirne a capo.
Grazie infinite. Ciao.

Codice:
#include <linux/poll.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/miscdevice.h>
#include <linux/list.h>
#include <linux/string.h>
#include <linux/delay.h>


#include "ex_thread.h"
#include "ex_dev.h"

int nthread = 1;
int coda = 1;
int num = 0;

static struct miscdevice log_out_device;
static struct miscdevice controllo_out_device;
static int my_len;
char logging[2048] = "";

struct node  blist;
struct node* iter; 


int list_full()
{
return (num == coda);
}

int list_vuota()
{
return (num == 0);
}

int list_insert(struct node *n)
{
while(list_full()) {
  mutex_unlock(&buff_m);
  strcat(logging, "La coda e' piena! richiesta in attesa.\n");
  wait_for_completion(&coda_piena);
  mutex_lock(&buff_m);
}

if(list_vuota()) {
  num++;
  list_add(&n->list, &(blist.list));
  strcat(logging, "Una richiesta e' stata inserita in coda\n");
  return 1;
}


struct node *tmp = NULL;
num++;
struct list_head* l;

list_for_each(l, &blist.list){
  tmp = list_entry(l, struct node, list);
  if(tmp->p < n->p) {
    list_add_tail(&n->list, &tmp->list);
    strcat(logging, "Una richiesta e' stata inserita in coda\n");
    return 1;
  }
}
list_add(&n->list, &tmp->list);
strcat(logging, "Una richiesta e' stata inserita in coda\n");
return 1;
}


static int log_open(struct inode *inode, struct file *file)
{
  int *cont;

  cont = kmalloc(sizeof(int), GFP_USER);
  if (cont == NULL) {
    return -1;
  }

  *cont = 0;
  file->private_data = cont;

  return 0;
}


static int controllo_close(struct inode *inode, struct file *file)
{
  return 0;
}
static int log_close(struct inode *inode, struct file *file)
{
  return 0;
}
ssize_t log_read(struct file *file, char __user *p, size_t len, loff_t *ppos)
{
  int err, res;
  int *cont;

  cont = file->private_data;

  if (*cont == 1) {
    return 0;
  }

  err = copy_to_user(p, logging, 2048);
  if (err)
    return -EFAULT;

  *cont = 1;
  return 2048;
}

ssize_t controllo_write(struct file *file, const char __user * buf, size_t count, loff_t *ppos)
{

  int err;
printk("%s",logging);
  mutex_lock(&buff_m);
  if (my_pointer) {
    mutex_unlock(&buff_m);
    return -1;
  }
  my_pointer = kmalloc(count, GFP_USER);
  if (my_pointer == NULL) {
    mutex_unlock(&buff_m);
    return -1;
  }
  my_len = count;

  err = copy_from_user(my_pointer, buf, count);
  if (err) {
    mutex_unlock(&buff_m);
    return -EFAULT;
  }

  char msg[25];
  int t, p;
  sscanf(my_pointer, "%s %d %d", msg, &t, &p); 


  struct node* tmp;
  tmp = (struct node*)kmalloc(sizeof(struct node), GFP_USER);
  if(!tmp) {
    return(-1);
  }
  strcpy(tmp->msg, msg);
  tmp->t = t;
  tmp->p = p;

  list_insert(tmp);
  my_pointer = NULL;

  wake_up_interruptible(&my_waitqueue);
  mutex_unlock(&buff_m);

  return count;

}



int device_create(void)
{
  misc_register(&controllo_out_device);
  return misc_register(&log_out_device);
}

void device_destroy(void)
{
  misc_register(&log_out_device);
}

static struct file_operations log_fops = {
  .owner =        THIS_MODULE,
  .read =         log_read,
  .open =         log_open,
  .release =      log_close,
};

static struct miscdevice log_out_device = {
  MISC_DYNAMIC_MINOR, "log", &log_fops
};

static struct file_operations controllo_fops = {
  .owner =        THIS_MODULE,
//  .open =         controllo_open,
  .release =      controllo_close,
  .write =        controllo_write,
};

static struct miscdevice controllo_out_device = {
  MISC_DYNAMIC_MINOR, "controllo", &controllo_fops
};

module_param(nthread, int, 0000);
MODULE_PARM_DESC(nthread, "numero dei thread");
module_param(coda, int, 0000);
MODULE_PARM_DESC(coda, "grandezza della coda");

Ultima modifica di Dawidh : 03-12-2007 alle 08:26.
Dawidh è offline   Rispondi citando il messaggio o parte di esso
Old 03-12-2007, 09:34   #13
ilsensine
Senior Member
 
L'Avatar di ilsensine
 
Iscritto dal: Apr 2000
Città: Roma
Messaggi: 15625
Ora sono un pò occupato, appena posso do una occhiata. Se intanto puoi allegare i sorgenti completi, lì sembra che manchi qualcosa...
__________________
0: or %edi, %ecx; adc %eax, (%edx); popf; je 0b-22; pop %ebx; fadds 0x56(%ecx); lds 0x56(%ebx), %esp; mov %al, %al
andeqs pc, r1, #147456; blpl 0xff8dd280; ldrgtb r4, [r6, #-472]; addgt r5, r8, r3, ror #12
ilsensine è offline   Rispondi citando il messaggio o parte di esso
Old 03-12-2007, 10:18   #14
Dawidh
Member
 
L'Avatar di Dawidh
 
Iscritto dal: Oct 2007
Città: Terlago --> Trento
Messaggi: 88
No no, tranquillo... non serve più, ho messo anche l'edit in rosso perché non mi ero proprio accorto che avevo messo una printk di troppo che stampava il buffer contenente il log.
grazie per l'interessamento cmq, adesso il programmino funziona benone.
Ciao.
Dawidh è offline   Rispondi citando il messaggio o parte di esso
Old 03-12-2007, 12:10   #15
ilsensine
Senior Member
 
L'Avatar di ilsensine
 
Iscritto dal: Apr 2000
Città: Roma
Messaggi: 15625
Ok, credevo ci tenevate a farlo "bene"

(almeno, correggete il macroscopico bug nella log_read prima che il prof vi uccide poi c'è il memleak nella log_close, la device_destroy sballata, il sospetto memleak di my_pointer ecc.)
__________________
0: or %edi, %ecx; adc %eax, (%edx); popf; je 0b-22; pop %ebx; fadds 0x56(%ecx); lds 0x56(%ebx), %esp; mov %al, %al
andeqs pc, r1, #147456; blpl 0xff8dd280; ldrgtb r4, [r6, #-472]; addgt r5, r8, r3, ror #12

Ultima modifica di ilsensine : 03-12-2007 alle 12:13.
ilsensine è offline   Rispondi citando il messaggio o parte di esso
Old 03-12-2007, 19:37   #16
Dawidh
Member
 
L'Avatar di Dawidh
 
Iscritto dal: Oct 2007
Città: Terlago --> Trento
Messaggi: 88
bug, c'è un bug nella read? eppure è proprio come quella che ha fatto il prof negli esempi mi sembra strano.l'abbiamo solo adattata alle nostre esigenze ma è come l'ha fatta lui, cosa c'è che non va?non riesco proprio a vederlo

cmq l'esercizio di per se era un esercizio di sincronizzazione, gestire bene mutex, wait e quelle cose lì......linked list con priorità, bloccaggio client se la list è piena... etc... (ci ha addirittura detto che è lo stesso se togliendo il modulo crasha tutto... quindi immagina )

oggi abbaimo messo tutto un pò a posto, anche i memleak.... quello che ho postato era ancora solo un abbozzo non il definitivo....

Ultima modifica di Dawidh : 03-12-2007 alle 19:40.
Dawidh è offline   Rispondi citando il messaggio o parte di esso
Old 03-12-2007, 19:52   #17
ilsensine
Senior Member
 
L'Avatar di ilsensine
 
Iscritto dal: Apr 2000
Città: Roma
Messaggi: 15625
Quote:
Originariamente inviato da Dawidh Guarda i messaggi
bug, c'è un bug nella read? eppure è proprio come quella che ha fatto il prof negli esempi mi sembra strano.l'abbiamo solo adattata alle nostre esigenze ma è come l'ha fatta lui, cosa c'è che non va?non riesco proprio a vederlo
char buf[512];
int fd = open("/dev/log", O_RDONLY);
read(fd, buf, sizeof(buf)); // kabum
application buffer overflow
__________________
0: or %edi, %ecx; adc %eax, (%edx); popf; je 0b-22; pop %ebx; fadds 0x56(%ecx); lds 0x56(%ebx), %esp; mov %al, %al
andeqs pc, r1, #147456; blpl 0xff8dd280; ldrgtb r4, [r6, #-472]; addgt r5, r8, r3, ror #12
ilsensine è offline   Rispondi citando il messaggio o parte di esso
 Rispondi


Marvel's Wolverine, la recensione: Logan torna protagonista in un'avventura brutale e intensa Marvel's Wolverine, la recensione: Logan torna p...
DJI Romo 2: tante novità lo rendono un robot completo DJI Romo 2: tante novità lo rendono un ro...
Sony Bravia 9 II: il True RGB alla prova, dove l'LCD sfida l'OLED Sony Bravia 9 II: il True RGB alla prova, dove l...
Geely EX5, un mese al volante: il SUV elettrico cinese che ci ha sorpreso (quasi) senza riserve Geely EX5, un mese al volante: il SUV elettrico ...
Mova Z70 Ultra Roller Complete: motore potente, rullo di lavaggio e l'IA a guidare Mova Z70 Ultra Roller Complete: motore potente, ...
Avio si prepara ai test del Dimostratore...
Space Pioneer ha annunciato le cause del...
Anthropic avrebbe nuovi antibiotici cont...
Scoperto un 'moltiplicatore nascosto' ne...
DREO: a IFA 2026 4 novità fra cui...
Slackbot genera dashboard e microsite de...
Idrogeno, nuova cella a combustibile rag...
Con la NASA fuori dai giochi, l'ESA risc...
Una falla di ChatGPT permette di estrapo...
Piano clima, 1,34 miliardi per il bonus ...
Porsche esce definitvamente da Bugatti R...
NVIDIA App aggiunge una delle funzioni p...
Come sarebbe il mondo se la luce viaggia...
Titanio, ceramica e zaffiro per HUAWEI W...
Taglio delle accise sul gasolio prorogat...
Chromium
GPU-Z
OCCT
LibreOffice Portable
Opera One Portable
Opera One 106
CCleaner Portable
CCleaner Standard
Cpu-Z
Driver NVIDIA GeForce 546.65 WHQL
SmartFTP
Trillian
Google Chrome Portable
Google Chrome 120
VirtualBox
Tutti gli articoli Tutte le news Tutti i download

Strumenti

Regole
Non Puoi aprire nuove discussioni
Non Puoi rispondere ai messaggi
Non Puoi allegare file
Non Puoi modificare i tuoi messaggi

Il codice vB è On
Le Faccine sono On
Il codice [IMG] è On
Il codice HTML è Off
Vai al Forum


Tutti gli orari sono GMT +1. Ora sono le: 06:47.


Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
Served by www3v