デバイス ドライバーを 32 ビット RHEL 2.6.32 から 64 ビット RHEL 2.6.33.9 にアップグレードしています。
ioctl を使用してそのドライバーと通信するプログラムがあります。ドライバーとプログラムの両方が 64 ビットまたは 32 ビットの場合、完全に機能します。しかし、ドライバーが 64 ビットで、プログラムが 32 ビットの場合、ドライバーが (compat_ioctl で) 受信した ioctl コマンドは、_IOR および _IOW マクロで定義された値と一致しません。
私のドライバーの switch ステートメントでは、デフォルトのケースでは、有効なすべてのコマンドの値 (1 ~ 12) が出力されます。32 ビットの ioctl コマンドは、これらの値にはほど遠いものです。
32 ビット ユーザー プログラムからのコマンドが 64 ビット ドライバーで受信されたときに混乱する原因を誰か教えてもらえますか?
コードの一部を次に示します。入力する必要がありました。コードはインターネットにアクセスできない安全なシステム上にあるため、タイプミスはご容赦ください。それは実際にコンパイルして実行します!
// IOCTL commands from the include file - most omitted
// ...
#define PORTIO_GET_IRQ_CNT_CMD 10
#define PORTIO_CLR_IRQ_CNT_CMD 11
#define PORTIO_GET_IRQ_TIME_CMD 12
#define PORTIO_IOCTL 'k' // magic number for ioctl
// IOCTL Macros
#define PORTIO_GET_IRQ_CNT_IOCTL _IOR(PORTIO_IOCTL, PORTIO_GET_IRQ_CNT_CMD, unsigned long)
#define PORTIO_CLR_IRQ_CNT_IOCTL _IOR(PORTIO_IOCTL, PORTIO_CLR_IRQ_CNT_CMD, unsigned long)
#define PORTIO_GET_IRQ_TIME_IOCTL _IOR(PORTIO_IOCTL, PORTIO_GET_IRQ_TIME_CMD, unsigned long)
portio.c の 32 ビット互換 IOCTL ルーチンを次に示します。これは、プログラムが 32 ビットとしてコンパイルされ、ドライバーが 64 ビットの場合にのみ呼び出されることを確認しました。
static long portio_compat_ioctl( struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
{
unsigned char cmd_number;
int cmd_size=0;
//...
cmd_number = _IOC_NR( cmd );
cmd_size = _IOC_SIZE( cmd );
printk( KERN_ALERT "Portio Compat IOCTL number,size = %d,%d, cmd_number, cmd_size );
//... Switch statement and cases, based on cmd_number
}
出力は次のようになります。
Portio Compat IOTCL 番号、サイズ = 224,3157
もちろん、コードは 1 ~ 12 の IOCTL 番号を想定しており、サイズは 4 または 8 程度です。これは、コードとドライバーの両方が 64 ビットまたは 32 ビットの場合に返されるものです。