copy_from_user( ) problem...help

Garcia Jérémie GARCIAJ at 3il.fr
Thu Jun 2 00:00:25 EST 2005


Hi everybody,
I'm tryin to write some device drivers modules in order to manage some of our devices of our ppc405EP based board.
I read the Allessandro Rubini book (Linux Kernel device drivers) in order to help me.
Before going on difficult stuff, I'd like to make some basic training and experiments.
What I want to do seems to be very easy (but...):
 - a user space programm has a global structure and contains an integer and a char
 - the user space programm loads the module with a parameter: the structure address
 - during the init_module(),I check that the address can be accessed in R/W mode with the access_ok()
 - the module copies the user structure in its own context and prints the values retreived

So, it's supposed to be a very easy operation, but something goes wrong. Could someone give me a clue cause
I read it again and again and I don't get what's the matter. Here is the code:

/******************************************************************************/
/*                           USER SPACE PROG                                  */
/******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
  
typedef struct une_structure
{
    int un_entier;
    char un_char;
}UNE_STRUCTURE;

UNE_STRUCTURE my_structure;

void main(void)
{
    char buff[100];

    /* Init of the structure */
    my_structure.un_entier = 5;
    my_structure.un_char = 'a';
    
    /* Build the shell command to load the module */
    sprintf(buff,"insmod -q ./un_module.o addr=%p",&my_structure);

    /* Print the shell command that loads the module */
    printf("\nCommmande : ");
    puts(buff);
    
    /* Load the module*/
    system(buff);

    sleep(2);

    /* Remove the module */
    system("rmmod un_module");  
}


/************************************************************************/
/*                      KERNEL MODULE                                   */
/************************************************************************/
[...]
typedef struct une_structure
{
    int un_entier;
    char un_char;
}UNE_STRUCTURE;

UNE_STRUCTURE *addr = 0x0;  /* default value */

MODULE_PARM(addr,"l");      /* get the address of the user space structure 
                               given in argument at insmod()               */


int init_module(void)
{
  int rc;
  UNE_STRUCTURE * my_structure;
  
  printk("Address of the user structure : %d\n",(int)addr);

  /* Alloc space for ou structure */
  my_structure = kmalloc(sizeof(UNE_STRUCTURE),GFP_DMA);
  if(my_structure==NULL)
  {
    printk("Kernel memory allocation failed!\n");
    return -1;
  }
  else
    printk("Kernel memory allocation succeeded!\n");

  rc = access_ok(VERIFY_READ,(void *)addr,sizeof(UNE_STRUCTURE));
  if(rc != 0)
  {       
     rc = access_ok(VERIFY_WRITE,(void *)addr,sizeof(UNE_STRUCTURE));
     if(rc != 0)
     {
          rc = copy_from_user(my_structure,(void *)addr,sizeof(UNE_STRUCTURE));
          if(rc)
              printk("Error in copy_from_user, rc=%d\n",rc);
          else
          {  
            printk("Values of the retreived user-space structure 's fields:\n");
            printk("\t -> un_entier = %d \n",my_structure->un_entier);
            printk("\t -> un_unsigned_char = %c \n",my_structure->un_char);
          }
             
      }
      else
      {
          printk("Erreur in accessing addr in WRITE mode\n");
          return -1;
      } 
    }
    else
    {
      printk("Erreur in accessing addr in READ mode\n");
      return -1;
    }
    return 0;
}

/***************************************************************************/
/*                         EXECUTION RESULTS                               */
/***************************************************************************/
root at 10.16.9.232:/home/testDir# ./une_appli.exe

[USER-SPACE]Commmande : insmod -q ./un_module.o addr=0x10010a74
[KERN-SPACE]Address of the user structure : 268503668               // is the same if converted in hexa 
[KERN-SPACE]Kernel memory allocation succeeded!
[KERN-SPACE]Values of the retreived user-space structure 's fields:
               -> un_entier = -1857486844                           // weird result and != 5
               -> un_unsigned_char = .                              // weird result and != 'a'

[KERN-SPACE]Now releasing the module...


As you can see, I don't really retreived the user-space structure in the kernel. Is it an address problem?
If I understood well, no ioremap is needded here cause the address given in argument of insmod is from MMU.
So what's the problem ; I really think that I'm dealing with a wrong address. 

Please help a newbie that would like to understand... Tks for your precious help.
Jeremie
 



More information about the Linuxppc-dev mailing list