Newsgroup: it.comp.os.linux.development
Titolo: Richiamare funzioni implementate in un modulo kernel

Ho un piccolo dubbio:
non sono molto bravo nella programmazione Linux; ho un modulo Kernel in 
cui sono implementate delle funzioni che permettono di movimentare un 
robot industriale; sto poi sviluppando una libreria C++ (in spazio 
utente) che deve utilizzare in alcuni punti le funzioni del modulo 
kernel per muovere il robot (queste funzioni devono per forza stare in 
un modulo per il kernel). Io ho pensato di utilizzare una mailbox per 
inviare dei "comandi" al modulo in modo da eseguire le funzioni su 
richiesta e restituire i risultati, non c'è un modo per chiamare 
direttamente queste funzioni, passando direttamente anche i parametri, 
senza dover utilizzare la mailbox?


due osservazioni:
1) sei proprio sicuro he il driver debba stare nel kernel? Come è
connesso il robot al pc? O hai necessità di un kerel thread per ottenere
qualcosa che sia un po' soft realtime?
2) unix prevde due modi per comunicare col driver. Passando per un device
file oppure con le ioctl. Quindi o trovi il modo di serializzare il
comando passando attraverso il device file o fai una ioctl che passa al
modulo un puntatore ad un strattura coi dati necessari al funzionamento.

 modulo un puntatore ad un strattura coi dati necessari al funzionamento.
I robot sono connessi su porta parallela (o seriale, non ricordo), ed il 
thread deve girare in hard real time (il kernel è "patchato" con RTAI 
per avere il real-time). Comunque, se le cose stanno così, preferisco 
inviare la struttura dati attraverso messaggi di mailbox. Credevo che 
utilizzando le macro EXPORT_SYM del kernel le funzioni fossero 
accessibili anche in spazio utente. In alternativa dovrei creare una 
ioctl per ogni funzione che devo richiamare, no?

 ioctl per ogni funzione che devo richiamare, no?
EXPORT_SYMBOL (symbol);
	macro used to export a symbol to the kernel.
quindi non è quello che serve a te. In spazio utente per comunicare col
un driver hai i device files e le ioctl. Secondo me è più facile passare
per i device files, però non dovrebbe essere impossibile con le ioctl.
altrimenti mi ricordi di aver visto una patch di un giapponese che
permetteva di prendere i programmi e di spostarli al volo da userspace a
kernelspace. So che è su freshmeat, ma non ricordo il nome.

 richiamare, no?
No, sono multiplexati:
ioctl(fd, REQ_TYPE1, &mystruct1); 
ioctl(fd, REQ_TYPE2, &mystruct2);
ecc.
Non sono una bella interfaccia. Meglio creare delle syscall, una per
ogni funzione.
Luca
-- 
Home: 
http://kronoz.cjb.net
"New processes are created by other processes, just like new
 humans. New humans are created by other humans, of course,
 not by processes." -- Unix System Administration Handbook

 ogni funzione.
però creare una syscall è una cosa più complessa, o sbaglio? Non
coinvolge anche modifiche in parti esterne al driver?

 Non coinvolge anche modifiche in parti esterne al driver?
Si`, ma sono estremamente semplici:
* si edita arch/i386/kernel/entry.S e si aggiungono le nuove entry alla
  sys_call_table. Es:
  .data
  ENTRY(sys_call_table)
  ....
        .long sys_mq_getsetattr
        .long sys_ni_syscall            /* reserved for kexec */
        .long sys_foobar                /* my new syscall */
 
* Quindi in include/asm-i386/unistd.h si aggiungono i nuovi numeri (in
  accordo con quanto fatto sopra e si incrementa NR_syscalls
  oppurtunamente.
* Si crea la syscall vera e propria, che potrebbe essere un semplice
  stub che verifica i parametri e chiama la funzione che effettua il
  lavoro:
  asmlinkage long sys_foobar(int something, char *whatever, int size) {
        char buf[MAX_LEN];
        if (size > MAX_LEN)
                return -ENOMEM;
        if (something < 0 || something > 123)
                return -EINVAL;
 
        if (copy_from_user(buf, whatever, size))
                returnt -EFAULT;
        /* ecc. */
        ret = do_real_work(something, buf, size);
 
        return ret;
  }
Luca
-- 
Home: 
http://kronoz.cjb.net
Windows NT crashed.
I'm the Blue Screen of Death.
No one hears your screams.

 Si`, ma sono estremamente semplici:
scusa eh, ma non dovrebbe essere taroccata anche la glibc? Più che altro
perché quando uno fa un #include <linux/*> non va a beccare direttamente
i file dei sorgenti del kernel, ma becca i file di include della glibc....

 di include della glibc....
Non servono i prototipi, si usa direttamente syscall(2) oppure un
wrapper.
Luca
-- 
Home: 
http://kronoz.cjb.net
Una donna sposa un uomo sperando che cambi, e lui non cambiera`. Un
uomo sposa una donna sperando che non cambi, e lei cambiera`.