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