Передача структуры драйверу устройства через IOCTL

Я пытаюсь передать структуру из пространства пользователя в пространство ядра. Я пытался в течение многих часов, и это не работает. Вот что я сделал до сих пор.

int device_ioctl(struct inode *inode, struct file *filep, unsigned int cmd, unsigned long arg){

int ret, SIZE;


switch(cmd){

    case PASS_STRUCT_ARRAY_SIZE:

        SIZE = (int *)arg;
        if(ret < 0){
            printk("Error in PASS_STRUCT_ARRAY_SIZE\n");
            return -1;  
        }
        printk("Struct Array Size : %d\n",SIZE);
        break;

    case PASS_STRUCT:


        struct mesg{
            int pIDs[SIZE];
            int niceVal;
        };

        struct mesg data;

        ret = copy_from_user(&data, arg, sizeof(*data));
        if(ret < 0){
            printk("PASS_STRUCT\n");
            return -1;  
        }

        printk("Message PASS_STRUCT : %d\n",data.niceVal);
        break;

    default :
        return -ENOTTY;
}

return 0;
  }

У меня проблемы с определением структуры. Как правильно его определить? Я хочу иметь int pIDs[SIZE]. Будет ли это делать int *pID (в пользовательском пространстве он определяется как pIDs[SIZE])?

РЕДАКТИРОВАТЬ:

С вышеуказанным изменением я получаю эту ошибку? ошибка: ожидаемое выражение перед «структурой», есть идеи?


person user340    schedule 26.08.2012    source источник
comment
что касается случая PASS_STRUCT, вы должны определить данные как struct , а не указатель на struct, а затем правильно передать размер copy_from_user. Ваша проблема, скорее всего, в C. imho, вы должны быть более опытными в C, прежде чем копаться в ядре.   -  person sardok    schedule 26.08.2012
comment
Как вы думаете, как мне определить эту функцию, #define PASS_STRUCT _IOW(MY_MAGIC, 2, struct mesg* )?   -  person user340    schedule 26.08.2012
comment
Я определил данные как структуру (struct mesg data;). Но выдает ошибку: размер хранилища «данных» неизвестен ... есть идеи?   -  person user340    schedule 26.08.2012
comment
эта ошибка, скорее всего, указывает на проблему в операторе switch, а не в макросе. Какая это строка? если вы считаете, что макрос проблематичен, попробуйте скомпилировать с параметром gcc -E, чтобы посмотреть, что произойдет после предварительной обработки.   -  person sardok    schedule 26.08.2012
comment
@sardok да, проблема не в макросе. Я проверил его после изменения структуры сообщения, он компилируется..   -  person user340    schedule 26.08.2012


Ответы (1)


В вашем вопросе есть два варианта структуры.

 struct mesg1{
  int *pIDs;
  int niceVal;
 };

 struct mesg2{
  int pIDs[SIZE];
  int niceVal;
 };

Они разные; в случае mesg1 у вас есть указатель на массив int (который находится вне структуры). В другом случае (mesg2) внутри структуры есть массив int.

Если ваш SIZE фиксирован (в API вашего модуля; то же значение используется в пространстве пользователя и ядра), вы можете использовать второй вариант (mesg2).

Чтобы использовать первый вариант структуры (mesg1), вы можете добавить поле size в саму структуру, например:

 struct mesg1{
  int pIDs_size;
  int *pIDs;
  int niceVal;
 };

и заполните его количеством целых чисел, указанным *pIDs.

PS: И, пожалуйста, никогда не используйте структуры с массивами переменного размера в середине структуры (так называемые VLAIS). Это проприетарное, странное, ошибочное и недокументированное расширение языка C от Компилятор GCC. Только последнее поле структуры может быть массивом переменного размера (VLA) в соответствии с международным стандартом C стандарт. Несколько примеров здесь: 1 2< /а>

PPS:

Вы можете объявить свою структуру с помощью VLA (если есть только один массив с переменным размером):

 struct mesg2{
  int niceVal;
  int pIDs[];
 };

но вы должны быть осторожны при выделении памяти для такой структуры с помощью VLA

person osgx    schedule 26.08.2012
comment
Ну, я хочу использовать тип mesg2. Перед передачей структуры я планирую передать SIZE. это будет работать? - person user340; 26.08.2012
comment
нет, вы должны либо исправить SIZE на этапе проектирования, а затем никогда не передавать его. Или вы должны переписать свою структуру таким образом, чтобы массив был последним полем структуры. - person osgx; 26.08.2012
comment
согласно определению Merriam-Webster: что-либо, что используется, производится или продается на условиях эксклюзивного законное право изобретателя или производителя; // используется, производится или продается лицом, имеющим исключительные законные права. Есть ли компилятор без GCC с поддержкой VLAIS? - person osgx; 19.03.2013