[GURU KERNEL] wd1100.c: Can't register sysctl

wd1100.c: Can't register sysctl [GURU KERNEL] - Divers - Linux et OS Alternatifs

Marsh Posté le 15-09-2006 à 03:53:06    

:hello:
 
Je m'amuse un peu sur de l'embarqué (WRAP de chez pc-engines) et je bloque sur le dernier truc.
 
La carte est dotée d'une watchdog wd1100. J'ai trouvé un patch porté sur le 2.6 par voyage-linux. Ca patch et ca build bien.
Cependant une fois que j'insère le module je me mange un "wd1100.c: Can't register sysctl"
 
Qu'est ce que ca signifie ?
 
Voici le code qui arrive à cette erreur :

  ret = misc_register(&sc1x00wd_miscdev);
   if (ret)
     printk(KERN_ERR "wd1100.c: Can't register device.\n" );
   else
   {
     wd_table_header = register_sysctl_table(wd_root_table, 1);  
      if (wd_table_header == NULL)
        printk(KERN_ERR "wd1100.c: Can't register sysctl.\n" );
   }


 
Pourriez vous m'expliquer ce qui se passe ?
 
Merci :jap:

Reply

Marsh Posté le 15-09-2006 à 03:53:06   

Reply

Marsh Posté le 15-09-2006 à 04:02:18    

Code :
  1. /*
  2. *   National Semiconductor SC1x00 CPU watchdog driver
  3. *   Copyright (c) Inprimis Technologies 2002
  4. *
  5. *   by Mark Grosberg <markg@inprimis.com>
  6. *   and Rolando Goldman <rolandog@inprimis.com>
  7. *
  8. *   This program is free software; you can redistribute it and/or
  9. *   modify it under the terms of the GNU General Public License
  10. *   as published by the Free Software Foundation; either version
  11. *   2 of the License, or (at your option) any later version.
  12. *   
  13. *   09/10/2003
  14. *   - Module parameter support   
  15. *   - Modern processor support
  16. *   added by Erich Titl erich.titl@think.ch
  17. *   
  18. *   09/01/2005
  19. *   - port to 2.6 kernel
  20. *   added by Punky Tse punkytse@yahoo.com
  21. *
  22. */
  23. #include <linux/module.h>
  24. #include <linux/types.h>
  25. #include <linux/kernel.h>
  26. #include <linux/fs.h>
  27. #include <linux/mm.h>
  28. #include <linux/miscdevice.h>
  29. #include <linux/watchdog.h>
  30. #include <linux/spinlock.h>
  31. #include <linux/sysctl.h>
  32. #include <linux/pci.h>
  33. /*  
  34. * Since the SC1100 is an x86 clone, we don't even bother with  
  35. * allowing other architectures to compile us.
  36. */
  37. #ifndef CONFIG_X86
  38. # error Sorry this driver is only for x86.
  39. #endif
  40. #include <asm/system.h>
  41. #include <asm/io.h>
  42. #include <asm/uaccess.h>
  43. #include <asm/processor.h>
  44. /*
  45. #define DEBUG_WD1100  
  46. */
  47. static int proc_wd_timeout(ctl_table   *ctl,
  48.                            int          write,
  49.                            struct file *file,
  50.                            void        *buffer,
  51.                            size_t      *lenp,
  52.                            loff_t      *ppos);
  53. static int proc_wd_graceful(ctl_table   *ctl,
  54.                             int          write,
  55.                             struct file *file,
  56.                             void        *buffer,
  57.                             size_t      *lenp,
  58.                             loff_t      *ppos);
  59.                          
  60. /* Register definitions */
  61. #define SC1100_F5_VENDOR_ID  0x100B
  62. #define SC1100_F5_DEVICE_ID  0x0515 
  63. #define CPU_WDTO_REG    0x00 /* watchdog time out, 16 bit register */
  64. #define CPU_WDCNFG_REG  0x02 /* watchdog config , 16 bit register */
  65. #define CPU_WDSTS_REG   0x04 /* watchdog status , 8 bit register */
  66. /* Default timeout: 4 seconds (changeable via sysctl) */
  67. static unsigned int    sysctl_wd_timeout  = 4;
  68. static unsigned int    sysctl_wd_graceful = 1;
  69. static int             in_use    = 0;
  70. static unsigned short  cpu_base;
  71. static struct semaphore wd_semaphore;
  72. /**************************************************************************/
  73. #define GCB_LOCATION 0x1234 // just a dummy value
  74. int gcb = GCB_LOCATION;
  75. MODULE_PARM (gcb, "i" );
  76. MODULE_PARM_DESC (gcb, "The GCB location (default is to look into the scratch pad)" );
  77. MODULE_PARM (sysctl_wd_graceful, "i" );
  78. MODULE_PARM_DESC (sysctl_wd_graceful, "Graceful shutdown on close" );
  79. MODULE_PARM (sysctl_wd_timeout, "i" );
  80. MODULE_PARM_DESC (sysctl_wd_timeout, "Watchdog timeout value in seconds" );
  81. /**************************************************************************/
  82. /* XXX To-do: DEV_WATCHDOG must be in include/linux/sysctl.h */
  83. enum
  84. { DEV_WATCHDOG = 6 };
  85. enum
  86. {
  87.    DEV_WD_TIMEOUT   = 1,
  88.    DEV_WD_GRACEFUL  = 2
  89. };
  90. static struct ctl_table_header *wd_table_header;
  91. static ctl_table wd_table[] = {
  92.    {
  93.     DEV_WD_TIMEOUT, "timeout",
  94.     &sysctl_wd_timeout, sizeof(int), 0644, NULL, &proc_wd_timeout
  95.    },
  96.  
  97.    {
  98.     DEV_WD_GRACEFUL, "graceful",
  99.     &sysctl_wd_graceful, sizeof(int), 0644, NULL, &proc_wd_graceful
  100.    },
  101.    {0}
  102. };
  103. static ctl_table wd_dir_table[] = {
  104.    {DEV_WATCHDOG, "wd", NULL, 0, 0555, wd_table},
  105.    {0}
  106. };
  107. static ctl_table wd_root_table[] = {
  108.    {CTL_DEV, "dev", NULL, 0, 0555, wd_dir_table},
  109.    {0}
  110. };
  111. static int proc_wd_timeout(ctl_table   *ctl,
  112.                            int          write,
  113.                            struct file *file,
  114.                            void        *buffer,
  115.                            size_t      *lenp,
  116.                            loff_t      *ppos)
  117. {
  118.   int   rc;
  119.  
  120.   rc = proc_dointvec(ctl, write, file, buffer, lenp, ppos);
  121.   if (write && (rc == 0))
  122.   {
  123.      /* Clamp to limits. */
  124.      if (sysctl_wd_timeout < 1)
  125.        sysctl_wd_timeout = 1;
  126.      else if (sysctl_wd_timeout > 65535)
  127.        sysctl_wd_timeout = 65535;
  128.   }
  129.  
  130.   return (rc);
  131. }
  132. static int proc_wd_graceful(ctl_table   *ctl,
  133.                             int          write,
  134.                             struct file *file,
  135.                             void        *buffer,
  136.                             size_t      *lenp,
  137.                             loff_t      *ppos)
  138. {
  139.   int   rc;
  140.  
  141.   rc = proc_dointvec(ctl, write, file, buffer, lenp, ppos);
  142.   if (write && (rc == 0))
  143.   {
  144.      /* Clamp to true/false. */
  145.      if (sysctl_wd_graceful)
  146.        sysctl_wd_graceful = 1;
  147.   }
  148.  
  149.   return (rc);
  150. }                         
  151. /**************************************************************************/
  152. static __inline__ void reset_wd(void)
  153. {
  154.   outw(sysctl_wd_timeout * 8, cpu_base + CPU_WDTO_REG);
  155. }
  156. static int reboot_reason(void)
  157. {
  158.    unsigned static char sr;
  159.    static int    fetched = 0;
  160.    if (!fetched)
  161.    {
  162.    
  163.      sr = inb(cpu_base + CPU_WDSTS_REG);
  164.      outb(sr | 1, cpu_base + CPU_WDSTS_REG);
  165.  
  166.      fetched = 1;
  167.    }
  168.  
  169.    return ((sr & 0x01) ? 1 : 0);
  170. }
  171. static struct watchdog_info wd_info =
  172. {
  173.    0,   /* Options          */
  174.    0,   /* Firmware version */
  175.    "NSC SC1x00 WD"
  176. };
  177. static int wd_ioctl(struct inode *inode,
  178.                     struct file  *file,
  179.                     unsigned int  cmd,
  180.                     unsigned long arg)
  181. {
  182.    int  i;
  183.  
  184.    switch (cmd)
  185.    {
  186.       default:
  187.         return (-ENOTTY);
  188.        
  189.       case WDIOC_GETSUPPORT:
  190.         i = access_ok(VERIFY_WRITE, (void *)arg, sizeof(struct watchdog_info));
  191.         if (i)
  192.           return (i);
  193.         else
  194.           return copy_to_user((struct watchdog_info *)arg,
  195.                               &wd_info,
  196.                               sizeof(wd_info));
  197.         break;
  198.        
  199.       case WDIOC_KEEPALIVE:
  200.         reset_wd();
  201.         return (0);
  202.        
  203.       case WDIOC_GETBOOTSTATUS:
  204.         i = reboot_reason();
  205.         return (put_user(i, (int *)arg));
  206.        
  207.       case WDIOC_GETSTATUS:
  208.         i = inw(cpu_base + CPU_WDTO_REG) / 8;
  209.         return (put_user(i, (int *)arg));
  210.    }     
  211. }                   
  212. static int wd_open(struct inode *inode,
  213.                    struct file  *file)
  214. {
  215.   int i;
  216.   if (down_trylock(&wd_semaphore))
  217. return -EBUSY;
  218.   /*
  219.    * Configure the chip to do a reset if the timer goes to 0.
  220.    * Set the clock divisor to 4096.
  221.    */
  222.    
  223.   i = inw(cpu_base + CPU_WDCNFG_REG);
  224.   // keep the high order 7 bits of the config register
  225.   // clear bit 8 and write 0xfc to the low order 8 bits
  226.   outw((i & 0xfe00) | 0x00fc, cpu_base + CPU_WDCNFG_REG);
  227.  
  228.   /* Start the watchdog: It won't run until we write the TO reg. */
  229.   reset_wd();
  230.   return nonseekable_open(inode, file);
  231. }
  232. static int wd_release(struct inode *inode,
  233.                        struct file  *file)
  234. {
  235.   in_use = 0;
  236.  
  237.   /*
  238.    * If graceful shutdown is not set, then don't bother to stop the
  239.    * watchdog timer. This handles the scenario where the user process
  240.    * that is poking the watchdog gets terminated due to some error
  241.    * (say a SEGV or some VM condition).  
  242.    *
  243.    * In that case, the kernel would happily close the descriptor for
  244.    * us and leave us in a state where we aren't watching the dog...
  245.    *
  246.    * To work around this, the "graceful" sysctl prevents reset of the
  247.    * watchdog on close.
  248.    */
  249. #ifdef DEBUG_WD1100
  250.   printk(KERN_INFO "wd1100.c: releasing wd1100 sysctl_wd_graceful = %x\n",sysctl_wd_graceful);
  251. #endif
  252.   if (sysctl_wd_graceful)
  253.     outw(0, cpu_base + CPU_WDCNFG_REG);
  254.  
  255.   up(&wd_semaphore);
  256.  
  257.   return (0);
  258. }         
  259. static ssize_t wd_write(struct file *file,
  260.                         const char  *data,
  261.                         size_t       len,
  262.                         loff_t      *ppos)
  263. {
  264.   if (len > 0)
  265.     reset_wd(); 
  266.  
  267.   return (len);
  268. }
  269. static struct file_operations wd_fops=
  270. {
  271.    owner:      THIS_MODULE,
  272.    write:      wd_write,
  273.    ioctl:      wd_ioctl,
  274.    open:       wd_open,
  275.    release:    wd_release,
  276. };
  277. static struct miscdevice sc1x00wd_miscdev=
  278. {
  279.    WATCHDOG_MINOR,
  280.    "watchdog",
  281.    &wd_fops
  282. };
  283. static int __init wd_init(void)
  284. {
  285.    int              ret;
  286.    struct pci_dev  *dev;
  287.    unsigned int     cw;
  288.    if (strcmp(boot_cpu_data.x86_vendor_id, "Geode by NSC" ) != 0)
  289.    {
  290.       printk(KERN_ERR "wd1100.c: This is not an SC1100 processor!\n" );
  291.       return (0);
  292.    }
  293.    switch (boot_cpu_data.x86_model)
  294.    {
  295. case 4: // those are the models we know
  296. case 9:
  297.  break;
  298. default:
  299.  printk(KERN_WARNING "wd1100.c: unknown model value %d, trying anyway\n",boot_cpu_data.x86_model);
  300.  break;
  301.    }
  302.    if (gcb == GCB_LOCATION) // this is the assigned dummy value  
  303.    {
  304. #ifdef DEBUG_WD1100
  305.     printk(KERN_INFO "wd1100.c: fetching the value for gcb from scratch pad\n" );
  306. #endif
  307.     /* get the CONFIG BLOCK ADDRESS from scratch pad register */
  308.     dev = pci_find_device(SC1100_F5_VENDOR_ID,SC1100_F5_DEVICE_ID,0);
  309.     if (dev == NULL)
  310.     {
  311.        printk(KERN_ERR "wd1100.c: Can not find bridge device.\n" );
  312.        return (0);
  313.     }
  314.     // read a double word at offset 0x64 into cw
  315.     pci_read_config_dword(dev, 0x64, &cw);
  316.     cpu_base = (unsigned short )cw;
  317.    }
  318.    else // it is not the default value, just use it
  319.    {
  320. #ifdef DEBUG_WD1100
  321.     printk(KERN_INFO "wd1100.c: using the assigned value for gcb \n" );
  322. #endif
  323.     cpu_base = (unsigned short) gcb;
  324.    }
  325.  
  326. #ifdef DEBUG_WD1100
  327.    printk(KERN_INFO "wd1100.c: CPU base = 0x%X\n", (unsigned int )cpu_base);
  328. #endif
  329.    printk(KERN_INFO "SC1x00 Watchdog driver by Inprimis Technolgies.\n" );
  330.    printk(KERN_INFO "wd1100.c: a few hacks by erich.titl@think.ch\n" );
  331.    /*
  332.     * We must call reboot_reason() to reset the flag in the WD.
  333.     *
  334.     * Even though it is available as an ioctl(), we call it during
  335.     * module initialization to perform the clear. You can take out
  336.     * the printk(), but don't take out the call to reboot_reason().
  337.     */
  338.    if (reboot_reason())
  339.       printk(KERN_INFO "Last reboot was by watchdog!\n" );
  340.    
  341.    sema_init(&wd_semaphore, 1);
  342.        
  343.    ret = misc_register(&sc1x00wd_miscdev);
  344.    if (ret)
  345.      printk(KERN_ERR "wd1100.c: Can't register device.\n" );
  346.    else
  347.    {
  348.      wd_table_header = register_sysctl_table(wd_root_table, 1);
  349.       if (wd_table_header == NULL)
  350.         printk(KERN_ERR "wd1100.c: Can't register sysctl.\n" );
  351.    }
  352.    return 0;
  353. static void __exit wd_exit(void)
  354. {
  355.    if (wd_table_header != NULL)
  356.       unregister_sysctl_table(wd_table_header);
  357.  
  358.    misc_deregister(&sc1x00wd_miscdev);
  359. }
  360. module_init(wd_init);
  361. module_exit(wd_exit);
  362. MODULE_LICENSE("GPL" );
  363. MODULE_AUTHOR("Mark Grosberg <markg@inprimis.com> and Rolando Goldman <rolandog@inprimis.com>" );
  364. MODULE_DESCRIPTION("National Semiconductor SC1x00 CPU watchdog driver" );
  365. MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);


Message édité par M300A le 15-09-2006 à 04:03:19
Reply

Marsh Posté le 15-09-2006 à 04:03:42    

Vu qu'il est pas énorme j'ai posté wd1100.c ;)

Reply

Marsh Posté le 15-09-2006 à 12:41:29    

:hot:

Reply

Marsh Posté le 15-09-2006 à 22:41:16    

:hello:
 
Je suis sur que quelqu'un dev un peu et pourrait m'expliquer ;)

Reply

Marsh Posté le 15-09-2006 à 23:50:17    

ctrl+F =
  wd_table_header = register_sysctl_table(wd_root_table, 1);  
      if (wd_table_header == NULL)
        printk(KERN_ERR "wd1100.c: Can't register sysctl.\n" );
   }
 
c'est l'err  wd_table_header  
 
 
Ok ok je sort... :whistle:


Message édité par dchost99 le 15-09-2006 à 23:50:42
Reply

Marsh Posté le 16-09-2006 à 00:22:58    

Merci j'avais même déduit que soit la fonction n'a pas marché "register_sysctl_table"  soit que la structure "wd_root_table" qui a été passée à la fonction n'etait pas valide.
 
J'ai pa su aller plus loin par contre :D
 
Ok ok je sors aussi... :whistle:

Reply

Marsh Posté le 16-09-2006 à 00:54:51    

moi j'ai regarder un peu, je mettrais bien un 0 à la place du 1 dans l'appel de register_sysctl_table. Sinon c'est pas facile de trouver de la doc sur sysctl donc ...
 
je sort
 
edit: tout bien réfléchis ça devrais pas changer grand chose. Sinon le problème c'est qu'il n'arrive pas à créer les fichiers de controle dans /proc/sys/dev ...

Message cité 1 fois
Message édité par ellimac le 16-09-2006 à 01:14:10
Reply

Marsh Posté le 16-09-2006 à 00:58:54    

ellimac a écrit :

moi j'ai regarder un peu, je mettrais bien un 0 à la place du 1 dans l'appel de register_sysctl_table. Sinon c'est pas facile de trouver de la doc sur sysctl donc ...
 
je sort


 
Tu as une raison pour mettre un 0 au lieu de 1 ? ;)

Reply

Marsh Posté le 16-09-2006 à 01:30:05    

Code :
  1. static ctl_table wd_table[] = {
  2.   {
  3.    .ctl_name = DEV_WD_TIMEOUT,
  4.    .procname = "timeout",
  5.    .data = &sysctl_wd_timeout,
  6.    .maxlen = sizeof(int),
  7.    .mode = 0644,
  8.    .proc_handler = &proc_wd_timeout
  9. },
  10.  
  11.   {
  12.    .ctl_name = DEV_WD_GRACEFUL,
  13.    .procname = "graceful",
  14.    .data = &sysctl_wd_graceful,
  15.    .maxlen = sizeof(int),
  16.    .mode = 0644,
  17.    .proc_handler = &proc_wd_graceful
  18.   },
  19. { .ctl_name = 0}
  20. };
  21. static ctl_table wd_dir_table[] = {
  22.   {
  23.     .ctl_name = DEV_WATCHDOG,
  24.     .procname = "wd",
  25.     .maxlen = 0,
  26.     .mode = 0555,
  27.     .child = wd_table
  28.   },
  29.   { .ctl_name = 0}
  30. };
  31. static ctl_table wd_root_table[] = {
  32.   {
  33.     .ctl_name = CTL_DEV,
  34.     .procname = "dev",
  35.     .maxlen = 0,
  36.     .mode = 0555,
  37.     .child =wd_dir_table
  38.   },
  39. {.ctl_name = 0}
  40. };


 
Sinon essaye de remplacer les déclaration de la ligne 110 à 132 par ce code là ( modulo mes éventuels erreur de frappe )


Message édité par ellimac le 16-09-2006 à 01:47:29
Reply

Marsh Posté le 16-09-2006 à 01:30:05   

Reply

Marsh Posté le 16-09-2006 à 01:37:37    

Je teste ca immédiatement :)
 
PS : C'est normalisé cette indentation, c'est très étrange ? :o

Reply

Marsh Posté le 16-09-2006 à 01:42:28    

j'ai trouvé ça dans d'autres fichiers source du kernel et j'ai adapter à ton cas en croisant les doigts. L'indentation j'ai pas trop fait gaffe mais grosso modo c'étais présenter comme ça, et les .clt_name et autre ça permet de nommer les champs directement pour être sur que tout est au bon endroit.

Reply

Marsh Posté le 16-09-2006 à 01:43:36    

Tu développe pour le kernel ou dans un module ? :??:

Reply

Marsh Posté le 16-09-2006 à 01:44:52    

ni l'un ni l'autre, enfin juste un module qui fait rien pour l'école d'ingé ...

Reply

Marsh Posté le 16-09-2006 à 01:45:17    

 CC [M]  drivers/char/watchdog/wd1100.o
drivers/char/watchdog/wd1100.c:118: error: unknown field ‘date’ specified in initializer
drivers/char/watchdog/wd1100.c:129: error: unknown field ‘date’ specified in initializer
drivers/char/watchdog/wd1100.c:164: error: request for member ‘mode’ in something not a structure or union
drivers/char/watchdog/wd1100.c:165: error: request for member ‘child’ in something not a structure or union
make[4]: *** [drivers/char/watchdog/wd1100.o] Erreur 1
make[3]: *** [drivers/char/watchdog] Erreur 2
make[2]: *** [drivers/char] Erreur 2
make[1]: *** [drivers] Erreur 2
make[1]: quittant le répertoire « /usr/src/wrap-kernel/2.6.15/linux-2.6.15.7 »
make: *** [debian/stamp-build-kernel] Erreur 2


 
Ca passe pas ;)

Reply

Marsh Posté le 16-09-2006 à 01:47:03    

date = data , désolé pour la faute de frappe, et il manque quelque virgule, j'ai corrigé


Message édité par ellimac le 16-09-2006 à 01:47:51
Reply

Marsh Posté le 16-09-2006 à 01:49:50    

J'ai corrigé aussi, mci :)
 
Le module est passé je termine le build du kernel et je le test sur la machine !

Reply

Marsh Posté le 16-09-2006 à 01:56:35    

Toujours le même message lors de l'insertion :(

Reply

Marsh Posté le 16-09-2006 à 02:11:53    

Tu as raison il est temps d'aller dormir ;)
 
Merci pour ton aide en tout cas, si tu as d'autre idées n'hésite pas.
 
Etant donné que cette watchdog n'est présente que sur les Geode SC1100 d'AMD je ne trouve aucune info part google... :/

Reply

Marsh Posté le 16-09-2006 à 02:13:29    

t'as bien CONFIG_SYSCTL=y dans ton .config ? on sait jamais

Reply

Marsh Posté le 16-09-2006 à 02:22:13    

Oops :D
 
/me se frappe la tête contre le clavier
 
Je rebuild avec le support sysctrl, ca risque de mieux marcher...
 
Merci beaucoup :jap:

Reply

Marsh Posté le 16-09-2006 à 02:46:27    

Le moduel s'insere maintenant sans message cependant il ne fait rien :D
 
J'ai créé /dev/watchdog et j'ai inseré le module de cette facon :

modprobe wd1100 sysctl_wd_graceful=0 sysctl_wd_timeout=30


 
Evidemment au bout de 30sec, aucun reboot matériel (je n'ai pas le demon watchdog installé).
 
Une idée ?

Reply

Marsh Posté le 16-09-2006 à 12:50:38    

je pense que tu dois avoir besoin du demon, car d'apres les commentaires dans le code, le reglage du watchdog se fait à l'ouverture du péripherique.

Reply

Marsh Posté le 16-09-2006 à 13:12:01    

Okay :jap:

Reply

Marsh Posté le 16-09-2006 à 13:16:05    

Tu pourrais m'expliquer ou ca se fait dans le code, j'essaye de comprendre si possible :p
 
Je ne vois aucun références à /dev/watchdog ??

Reply

Marsh Posté le 16-09-2006 à 13:25:58    

En fait pour l'écriture d'un module du noyau, il y a 4 méthode obligatoire si mes souvenirs sont bons, register, unregister, open, release. register s'éxécute au chargement du module, unregister au déchargement du module, open quand un processus ouvre le peripherique, release quand il le ferme ( bizarre il me semblais que c'étais close) donc ici on a wd_register, wd_unregister, wd_open, wd_release. dans le code wd_open, on a une indication comme quoi c'est reset_wd qui démarre le watchdog, et il n'y a pas d'appel à reset_wd dans wd_register, j'en déduis donc quand tant que le peripherique n'a pas été ouvert,  le watchdog fonctionne pas malgré que le module soit chargé.


Message édité par ellimac le 16-09-2006 à 13:26:39
Reply

Marsh Posté le 16-09-2006 à 16:24:57    

Merci beaucoup pour ton aide :jap:
 
Le module est maintenant fonctionnel. Si je fais un echo vers le dev, 30 sec apres ca reboot hard et au rebot le module m'indique que le dernier reboot à été provoqué par la watchdog ;)
 
Plus qu'a mettre le démon en place heheh !
 
PS : Tu crois que c'est possible de compiler ce module de facon indépendante ? Pour l'instant il est distribué sous forme de patch sur les sources du kernel.
 
J'ai essayé d'écrire un Makefile mais c'est pas concluant...

Reply

Marsh Posté le 16-09-2006 à 16:27:50    

Code :
  1. KVERS = $(shell uname -r)
  2. KSRCS = /lib/modules/$(KVERS)/build
  3. TARGET  = wd1100.o
  4. SOURCE  = wd1100.c
  5. MODNAME = wd1100
  6. CFLAGS+ = -c -Wall -Wstrict-prototypes -Wno-trigraphs -O2 -fomit-frame-pointer -fno-strict-aliasing -fno-common -pipe
  7. INCLUDE = -I$(KSRCS)/include
  8. all: $(TARGET)
  9. help:
  10. @echo Possible targets:
  11. @echo -e all\\t- default target, builds kernel module
  12. @echo -e install\\t- copies module binary to /lib/modules/$(KVERS)/extra/
  13. @echo -e clean\\t- removes all binaries and temporary files
  14. wd1100.o: $(SOURCE)
  15. $(CC) $(INCLUDE) $(CFLAGS) -DMODVERSIONS -DMODULE -D__KERNEL__ -o $(TARGET) $(SOURCE)
  16. # $(MAKE) -C $(KSRCS) SUBDIRS=$(PWD) modules
  17. clean:
  18. rm -f *.ko
  19. load: $(TARGET)
  20. insmod $(TARGET)
  21. unload:
  22. rmmod $(MODNAME)
  23. install: $(TARGET)
  24. mkdir -p /lib/modules/$(KVERS)/extra
  25. cp -v $(TARGET) /lib/modules/$(KVERS)/extra/
  26. depmod -a


Message édité par M300A le 16-09-2006 à 16:30:56
Reply

Marsh Posté le 16-09-2006 à 20:33:14    

Code :
  1. obj-m := wd1100.o
  2. KDIR := /lib/modules/$(shell uname -r)/build
  3. PWD := $(shell pwd)
  4. all:
  5. $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules


 
c'est un peu minimal mais c'est ce que j'utilisais, tu peut peut-être t'en inspirer pour corriger le tien.
 
cela dis il y a peut-être des corrections à faire dans le source, j'ai un unresolve symbol au chargement sur verify_area.


Message édité par ellimac le 16-09-2006 à 21:46:39
Reply

Marsh Posté le 16-09-2006 à 21:55:21    

Il y'a sans doute des modifs à faire, tout ce que je peux dire c'est qu'il roule sur le 2.6.15 vanilla.
 
Merci pour ton aide encore une fois :jap:

Reply

Marsh Posté le 16-09-2006 à 22:02:09    

KVERS = $(shell uname -r)
KSRCS = /lib/modules/$(KVERS)/build
TARGET  = wd1100.o
SOURCE  = wd1100.c
MODNAME = wd1100
 
obj-m    := wd1100.o
 
all: $(TARGET)
 
help:
        @echo Possible targets:
        @echo -e all\\t- default target, builds kernel module
        @echo -e install\\t- copies module binary to /lib/modules/$(KVERS)/extra/
        @echo -e clean\\t- removes all binaries and temporary files
 
wd1100.o: $(SOURCE)
        $(MAKE) -C $(KSRCS) SUBDIRS=$(PWD) modules
 
clean:
        rm -f *.ko *.o *.mod.c
 
load:   $(TARGET)
        insmod $(TARGET)
 
unload:
        rmmod $(MODNAME)
 
install: $(TARGET)
        mkdir -p /lib/modules/$(KVERS)/extra
        cp -v $(TARGET) /lib/modules/$(KVERS)/extra/
        depmod -a


 
Voila un Makefile qui roule :)
:jap:
 
Quand j'essaye de le build contre un 2.6.17 je me prend ces erreurs :
 

gandalf@hellscream:~/devel/wd1100$ make  
make -C /lib/modules/2.6.17-2-686/build SUBDIRS=/home/gandalf/devel/wd1100 modules
make[1]: entrant dans le répertoire « /usr/src/linux-headers-2.6.17-2-686 »
  CC [M]  /home/gandalf/devel/wd1100/wd1100.o
/home/gandalf/devel/wd1100/wd1100.c:87: error: expected ‘)’ before string constant
/home/gandalf/devel/wd1100/wd1100.c:90: error: expected ‘)’ before string constant
/home/gandalf/devel/wd1100/wd1100.c:93: error: expected ‘)’ before string constant
make[2]: *** [/home/gandalf/devel/wd1100/wd1100.o] Erreur 1
make[1]: *** [_module_/home/gandalf/devel/wd1100] Erreur 2
make[1]: quittant le répertoire « /usr/src/linux-headers-2.6.17-2-686 »
make: *** [wd1100.o] Erreur 2


 
Tu peux me donner une piste ? :jap:

Reply

Marsh Posté le 17-09-2006 à 00:23:31    

il faut remplacer les lignes  
 

Code :
  1. MODULE_PARM (gcb, "i" );
  2. MODULE_PARM (sysctl_wd_graceful, "i" );
  3. MODULE_PARM (sysctl_wd_timeout, "i" );


 
par

Code :
  1. module_param(gcb,int ,0);
  2. module_param(sysctl_wd_graceful, uint, 0);
  3. module_param(sysctl_wd_timeout, uint, 0);


 
bon évidemment je ne peut pas tester, j'ai pas le matériel en question, mais bon ça compile sur mon 2.6.17

Reply

Marsh Posté le 17-09-2006 à 01:42:00    

gandalf@hellscream:~/devel/wd1100$ make
make -C /lib/modules/2.6.17-2-686/build SUBDIRS=/home/gandalf/devel/wd1100 modules
make[1]: entrant dans le répertoire « /usr/src/linux-headers-2.6.17-2-686 »
  CC [M]  /home/gandalf/devel/wd1100/wd1100.o
/home/gandalf/devel/wd1100/wd1100.c:87: error: expected ‘)’ before ‘int’
/home/gandalf/devel/wd1100/wd1100.c:90: error: expected ‘)’ before ‘uint’
/home/gandalf/devel/wd1100/wd1100.c:93: error: expected ‘)’ before ‘uint’
make[2]: *** [/home/gandalf/devel/wd1100/wd1100.o] Erreur 1
make[1]: *** [_module_/home/gandalf/devel/wd1100] Erreur 2
make[1]: quittant le répertoire « /usr/src/linux-headers-2.6.17-2-686 »
make: *** [wd1100.o] Erreur 2


 
Pas mieux :/

Reply

Marsh Posté le 17-09-2006 à 11:43:35    

euh t'a bien changé toute la ligne, la case compte en C, il suffit pas de rajouter int et uint dans la macro. Sinon c'est que j'ai fait une autre modification pour que ça compile mais là je vois pas.

Reply

Marsh Posté le 17-09-2006 à 12:27:19    

Oui j'ai bien tout remplacer :)
 
Tu peux me filer ton source ?
 
Si tu sais pas ou le mettre : gandalf_at_le-vert_dot_net

Reply

Marsh Posté le 17-09-2006 à 12:34:01    

ok, je te l'ai envoyé, tu me dira quand même ce que j'ai changé pasque là je vois pas du tout.

Reply

Marsh Posté le 17-09-2006 à 13:31:33    

Erreur de typo, s/parm/param/ ;)
 
Sinon il y'a ca comme différence encore  

-        i = access_ok(VERIFY_WRITE, (void *)arg, sizeof(struct watchdog_info));
+        i = verify_area(VERIFY_WRITE, (void *)arg, sizeof(struct watchdog_info));


 
Tu peux me transmettre ton nom et ton mail pour que je t'ajoute au copyright et au changelog ?

Reply

Marsh Posté le 17-09-2006 à 13:38:54    

pour cette différence laisse access_ok, j'ai pas du partir du même patch que toi. je t'envoie le reste par mail.

Reply

Marsh Posté le 17-09-2006 à 13:39:37    

printk(KERN_ERR "wd1100.c: Can't register sysctl.\nwd1100.c: Is this kernel built with CONFIG_SYSCTL=y ?\n" );


 
Elle ne te pose pas de problèmes cette ligne ?

Reply

Marsh Posté le 17-09-2006 à 13:54:42    

ça ne devrais pas poser de problème, juste s/nwd1100.c/wd1100.c . On pourrais aussi modifier le source pour ne pas être obligé d'utiliser sysctl.

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed