Pagina 1 di 1

[C]Errore compilazione programma che include kernel header

Inviato: ven 16 lug 2010, 5:59
da mr.simo
Ciao a tutti, ho questo piccolo programma

Codice: Seleziona tutto

#include <stdio.h>
#include <linux/sched.h> /*from /usr/src/linux/include/linux */

int main( void )
{
   struct task_struct *task = &init_task;

   do
   {
      printf("%s [%d] parent %s\n", task->comm, task->pid, task->parent->comm );
   } while((task = next_task(task)) != &init_task );

  return 0;
}
Sto provando a compilarlo con gcc con le opzioni -I, -isystem visto che "linux/sched.h" si trova in /usr/src/linux/include/, ma ricevo il segunete errore:

Codice: Seleziona tutto

p.c: In function 'main':
p.c:7: error: 'init_task' undeclared (first use in this function)
p.c:7: error: (Each undeclared identifier is reported only once
p.c:7: error: for each function it appears in.)
p.c:12: error: dereferencing pointer to incomplete type
p.c:12: error: dereferencing pointer to incomplete type
p.c:12: error: dereferencing pointer to incomplete type
p.c:14: warning: assignment makes pointer from integer without a cast
Ma init_task é dichiarata in sched.h. Se includo linux/init_task.h mi da una sfilza di errori, es:

Codice: Seleziona tutto

simo@localhost:~/Desktop/d$ gcc -I /usr/src/linux/include/ p.c -o p
In file included from /usr/src/linux/include/linux/preempt.h:9,
                 from /usr/src/linux/include/linux/spinlock.h:50,
                 from /usr/src/linux/include/linux/rcupdate.h:37,
                 from /usr/src/linux/include/linux/init_task.h:4,
                 from p.c:4:
/usr/src/linux/include/linux/thread_info.h:26: error: expected specifier-qualifier-list before 'u32'
/usr/src/linux/include/linux/thread_info.h:34: error: expected specifier-qualifier-list before 'clockid_t'
In file included from /usr/src/linux/include/asm/bitops.h:13,
                 from /usr/src/linux/include/linux/bitops.h:17,
                 from /usr/src/linux/include/linux/thread_info.h:46,
                 from /usr/src/linux/include/linux/preempt.h:9,
                 from /usr/src/linux/include/linux/spinlock.h:50,
                 from /usr/src/linux/include/linux/rcupdate.h:37,
                 from /usr/src/linux/include/linux/init_task.h:4,
                 from p.c:4:
/usr/src/linux/include/asm/alternative.h:45: error: expected specifier-qualifier-list before 'u8'
In file included from /usr/src/linux/include/linux/bitops.h:17,
                 from /usr/src/linux/include/linux/thread_info.h:46,
                 from /usr/src/linux/include/linux/preempt.h:9,
                 ....
Con il flag --with-headers mi segnala che l'opzione non é riconosciuta, probabilmente perché gcc non é configurato? :-k Sono molto confuso.. :oops:
Il codice arriva da questa pagina, io peró l'ho editato un pó appunto per non eseguirlo come un modulo. Se é possibile compilarlo, e penso di si, quali sono i flag corretti? O é proprio necessario un makefile?
Grazie per il vostro insegnamento

Re: [C]Errore compilazione programma che include kernel head

Inviato: ven 16 lug 2010, 11:16
da masalapianta
???
non puoi far girare quel codice in user land in quanto non è possibile, da user land, accedere direttamente alle aree di memoria utilizzate dall'istanza del kernel in uso (quindi non puoi accedere alla task_struct init_task; puoi creartene una tu, ma i dati da metterci non li puoi pigliare direttamente dalla task_struct usata dal kernel); gli unici modi per scambiare dati con il kernel sono utilizzando system call, filesystem proc, ecc..
Inoltre quel lkm in quella pagina del sito ibm, non funziona con i kernel 2.6, in quanto utilizza direttamente le vecchie funzioni init_module() e cleanup_module(), anzichè definire due funzioni di init e cleanup e passare i puntatori alle suddette a module_init() e module_exit().

Ecco la sintassi corretta per il 2.6:

Codice: Seleziona tutto

/* test.c */
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/sched.h>

static int my_init_module( void )
{
  /* Set up the anchor point */
  struct task_struct *task = &init_task;

  /* Walk through the task list, until we hit the init_task again */
  do {

    printk( KERN_INFO "*** %s [%d] parent %s\n",
		task->comm, task->pid, task->parent->comm );

  } while ( (task = next_task(task)) != &init_task );

  return 0;

}

static void my_cleanup_module( void )
{
  return;
}

module_init(my_init_module);
module_exit(my_cleanup_module);
ed un Makefile minimale:

Codice: Seleziona tutto

KSRC=/lib/modules/`uname -r`/build

KERNEL_VERSION_H = /lib/modules/`uname -r`/build/include/linux/version.h

obj-m=test.o

build:
        make -C $(KSRC) SUBDIRS=`pwd` modules
clean:
        rm -rf *.o *.mod.c *.ko .*.cmd .tmp_versions Module.symvers *order


Re: [C]Errore compilazione programma che include kernel head

Inviato: ven 16 lug 2010, 17:11
da mr.simo
Inoltre quel lkm in quella pagina del sito ibm, non funziona con i kernel 2.6 ..
No funziona, almeno a me, l'ho provato con un 2.6.27-31.. L'output di printk viene scritto su /var/log/messages.

Re: [C]Errore compilazione programma che include kernel head

Inviato: ven 16 lug 2010, 17:56
da masalapianta
mr.simo ha scritto:
Inoltre quel lkm in quella pagina del sito ibm, non funziona con i kernel 2.6 ..
No funziona, almeno a me, l'ho provato con un 2.6.27-31.. L'output di printk viene scritto su /var/log/messages.
ho controllato con un 2.6.26 ed effettivamente le init_module() e cleanup_module(), senza module_init() e module_exit() sembran funzionare; mi sembrava di ricordare che dal 2.6 fossero obbligatorie (ed infatti all'epoca dovetti modificare un paio di lkm che avevo scritto sul 2.4 per farne il porting al 2.6 e tra le modifiche c'era anche questo); bho forse per retrocompatibilità hanno riaggiunto la precedente sintassi da usare in alternativa alla nuova, oppure mi sono bevuto il cervello io (possibilissimo) e non l'hanno mai tolta :-k :-k :-k

Re: [C]Errore compilazione programma che include kernel head

Inviato: ven 16 lug 2010, 21:54
da mr.simo
Non ti preouccupare, piccola confusione :D In ogni caso ti ringrazio per il suggerimento. Onestamente mi aspettavo che non fosse possibile, anche se speravo in una piccola percentuale di possibilitá.
Quindi
puoi creartene una tu, ma i dati da metterci non li puoi pigliare direttamente dalla task_struct usata dal kernel); gli unici modi per scambiare dati con il kernel sono utilizzando system call, filesystem proc, ecc..
dici che con delle combinazioni di
open & read from /proc/
write (stdout ...)
la cosa sembra ed é fattibile.
In effetti sembra la soluzione piú ovvia... Grazie ancora per il chiarimento.