Would you please help me ASAP? Thanks a lot.
Weining Gu
1. My char driver code does NOT work in Linux 2.2.12 version as follows:
(I cannot access any memory from 0 to cxxxxxxx)
(I got either segmentation fault or copy_to_user(..) just return 1)
static int xyz_ioctl (struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg)
{
unsigned long address;
int tmp;
unsigned long value;
...
switch(cmd) {
case MEMDS_BAR:
if( get_user(address, (int *)arg) ) return -1;
tmp = virt_to_phys((void *)address);
value = (*(int *)tmp)^16;
(*(int *)tmp) = value;
if ( copy_to_user ((void *)arg, (void *)&tmp, sizeof(int)) )
return -1;
break;
default:
return -1;
}
return 0;
}
2. My char driver code works perfectly in 2.0 as follows:
(I can read/write any kernel symbols /boot/System.map by address)
static int abc_ioctl (struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg)
{
unsigned long address;
unsigned long tmp;
unsigned long value;
...
switch(cmd) {
case MEMDS_BAR:
if (verify_area(VERIFY_WRITE, (void *)arg, sizeof(int *))) {
return -EINVAL;
}
address = get_user((int *)arg);
tmp = virt_to_phys((void *)address);
memcpy_tofs( (void *)arg, (void *)tmp, sizeof(int)); /*send to user
space*/
(value) = (*(int *)tmp)^16;
(*(int *)tmp) = value;
printk("<1> 0x%08x -> tmp=0x%08x(modified=0x%08x)\n",
(int)address, *(int *)tmp, value);
break;
default: /* redundant, as cmd was checked against MAXNR */
return -EINVAL;
}
return 0;
}