2011-06-07 8 views
5

Supongamos que he definido lo siguiente.¿Cómo se llama una compatibilidad ioctl desde el espacio de usuario? ¿Alguien puede dar algunos ejemplos?

#define MY_IOCTL_CMD1 _IOR(MAGIC_NUMBER, 0x01, arg1) 
#define MY_IOCTL_CMD2 _IOW(MAGIC_NUMBER, 0x02, arg2) 
#ifdef CONFIG_COMPAT 
#define MY_COMPAT_IOCTL_CMD1 _IOR(MAGIC_NUMBER, 0x01, compat_arg1) 
#define MY_COMPAT_IOCTL_CMD2 _IOW(MAGIC_NUMBER, 0x02, compat_arg2) 
#endif 

Ahora cuando hacemos ioctl desde el espacio de usuario, por lo general lo hacen

ioctl(fd, MY_IOCTL_CMD1, &arg1) 

Q: es lo que realmente necesita tener una ioctl con MY_COMPAT_IOCTL_CMD1 como petición?

En el código de distribución, tengo controladores definidos de la siguiente manera. ioctl: device_ioctl

#ifdef CONFIG_COMPAT 
compat_ioctl: device_compat_ioctl 
#endif 

¿Puede alguien por favor proporcionar algunas explicaciones de todo esto?

Respuesta

6

Este material compatible es para ejecutar un programa de 32 bits en un núcleo de 64 bits. Cuando llama al ioctl(fd, MY_IOCTL_CMD1, &arg1) desde un programa de 32 bits en un kernel de 64 bits, el kernel desviará el ioctl a la función .compat_ioctl en la estructura file_operations. Esta función compat_ioctl es responsable de copiar el argumento de usuario arg1 como si fuera compat_arg1, que utiliza el diseño de 32 bits. El typedef compat_arg1 se define en el núcleo para que cuando se compila para 64 bits, la estructura tenga exactamente el mismo diseño que el arg1 compilado para 32 bits.

La definición de MY_IOCTL_CMD1 tendrá en cuenta sizeof arg1 al crear la id del cmd. Cuando compila un programa para una máquina de 32 bits, el valor de MY_IOCTL_CMD1 será diferente que si lo compiló para una máquina de 64 bits. Sin embargo, el MY_IOCTL_CMD1 de 32 bits debería tener el mismo valor que el MY_COMPAT_IOCTL_CMD1 de 64 bits en el kernel.

Nunca es necesario utilizar compat_arg1 o MY_COMPAT_IOCTL_CMD1 en una aplicación de espacio de usuario. Esos son solo para código compilado en el kernel.

Cuestiones relacionadas