Использование linux/types.h в пользовательских программах или stdint.h в коде модуля драйверов... это имеет значение?

Я разрабатываю модуль драйвера устройства и связанные с ним библиотеки пользователей для обработки вызовов ioctl(). Библиотека берет соответствующую информацию и помещает ее в структуру, которая передается в модуль драйвера и распаковывается там, а затем обрабатывается (я опускаю много шагов, но общая идея).

Некоторые данные, передаваемые через struct через ioctl(), являются uint32_t. Я обнаружил, что этот тип определен в stdint.h И linux/types.h. До сих пор я использовал linux/types.h для определения этого значения, в том числе и в пользовательских библиотеках. Но я понимаю, что плохая форма использовать библиотеки linux/*. H в пользовательском пространстве, поэтому, если я удалю их и вместо этого использую stdint.h, тогда, когда мой модуль драйвера включает определение структуры, он должен включать в себя stdint.h также.

Мне кажется, что точка linux/types.h - это определение типов в файлах ядра, поэтому я не уверен, что это означает использование stdint.h, это плохая идея. Я также обнаружил, что когда TRYING использует stdint.h в моем модуле драйвера, я получаю ошибки компиляции о переопределениях, которые не исчезнут, даже если я заменю все экземпляры linux/types.h на stdint.h(и наденьте его на верхний порядок включения).

Soo....

  • Неплохо ли использовать linux/*.h в коде пользовательского пространства?
  • Неплохо ли использовать stdint.h в коде ядра?
  • Если ответы на оба из них да, то как мне обрабатывать ситуацию, когда структура, содержащая uint32_t, совместно используется как библиотекой пользователя, так и модулем драйвера?

Спасибо.

Ответ 1

  • Неплохо ли использовать linux/*.h в коде пользовательского пространства?

Да, обычно. Типичная ситуация заключается в том, что вы должны использовать заголовки C-библиотеки (в данном случае, stdint.h и друзей), а также интерфейс с библиотекой C, хотя эти типы пользовательского пространства, и пусть библиотека обрабатывает разговор с ядром через ядро типы.

Однако вы не в типичной ситуации. В вашем случае вы пишете библиотеку драйверов. Таким образом, вы должны представлять интерфейс для пользовательского пространства, используя stdint.h, но используя заголовки linux/*.h при взаимодействии с вашим драйвером ядра.

Таким образом, ответ отрицательный, в вашем случае.

  • Неплохо ли использовать stdint.h в коде ядра?

Наиболее определенно да.

Смотрите также: http://lwn.net/Articles/113349/

Ответ 2

Целые числа фиксированной длины в ядре Linux

Ядро Linux уже имеет фиксированные длины целых чисел, которые могут вас заинтересовать. В версии 4.9 в разделе include/asm-generic/int-ll64.h:

typedef signed char s8;
typedef unsigned char u8;

typedef signed short s16;
typedef unsigned short u16;

typedef signed int s32;
typedef unsigned int u32;

typedef signed long long s64;
typedef unsigned long long u64;

В LDD3 также есть глава о размерах данных: https://static.lwn.net/images/pdf/LDD3/ch11.pdf

LDD3 упоминает о том, что лучшая стратегия printk заключается в том, чтобы использовать только для того, чтобы просто наложить наибольшее целое число с правильной подписью: %lld или %llu. %ju появляется недоступным в

printk lib/linux/vsprintf.c.