2

デバイス ドライバーを 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 ビットの場合に返されるものです。

4

2 に答える 2

2

あなたの関数compat_ioctlはあまりにも多くのパラメータを取るように私には思えます。Linux カーネルの他の定義を見てください。

long compat_blkdev_ioctl(struct file *file, unsigned cmd, unsigned long arg)

http://lxr.linux.no/#linux+v3.5.3/block/compat_ioctl.c#L654

于 2012-08-27T17:03:57.507 に答える