Возвращаемое значение register_chdev ядра Linux

Возвращаемое значение register_chdev ядра Linux

Это видеопоказывает пример модуля ядра Raspberry Pi Linux, который создает новое символьное устройство. Он использует API ядра register_chdev. В комментарии к видео (я не могу сгенерировать прямую ссылку на него), что касается возвращаемого значения register_chdev, автор заявляет:

Если возвращаемое значение не равно 0, номер устройства уже используется. Верхние 12 бит возвращаемого значения — это ваш основной номер устройства, нижние 20 бит — это дополнительный номер устройства.

Полагаю, что под «номер устройства уже используется» он подразумевает «ненулевой основной номер устройства, произвольно выбранный в модуле ядра, уже используется».

Несмотря на то, что несколько веб-страниц посвящены этому вопросу (официальный, затемВот этотиВот этот), я не нашел никакой информации об этом внутреннем подразделении возвращаемого значения.

Если я выбираю создать (с помощью модуля ядра) устройство с уже используемым старшим номером, ядро ​​никогда его не примет и откажется регистрировать устройство. Это происходит как в случае, когда выбранный мной старший номер совпадает с номером блочного устройства, так и в случае, когда выбранный мной старший номер совпадает с номером символьного устройства. register_chdevвсегда возвращают отрицательное значение. В последнем случае вместо этого я ожидал положительного ненулевого возвращаемого значения, при этом старшие 12 бит представляют старший номер устройства, а нижние 20 бит представляют младший номер устройства (возможно, больше 0: если старший номер уже использовался, возможно, в системе уже было по крайней мере устройство, связанное с ним, с младшим номером 0).

Правда ли то, что говорится в комментарии на Youtube? Где я могу найти документацию по этому поводу?


У меня Raspbian 10, uname -aпоказывает:

Linux raspberrypi 5.10.63-v7+ #1459 SMP Wed Oct 6 16:41:10 BST 2021 armv7l GNU/Linux

решение1

register_chrdevсам по себе не документирован в ядре, ноего определение короткое:

static inline int register_chrdev(unsigned int major, const char *name,
                  const struct file_operations *fops)
{
    return __register_chrdev(major, 0, 256, name, fops);
}

что по сути означает, что он звонит__register_chrdevдля регистрации major с полным диапазоном minors (256 minors, начиная с 0) и возврата результата этой функции. Последнее документируется как

Еслиmajor== 0 эта функция динамически выделит основной номер и вернет его номер.

Еслиmajor> 0 эта функция попытается зарезервировать устройство с указанным старшим номером и вернет ноль в случае успеха.

В случае возникновения ошибки возвращается значение -ve.

Нет положения для возврата несовершеннолетних, закодированных или иным образом. Цель этих функций — зарегистрировать мажор в любом случае, потенциально с подмножеством несовершеннолетних; а не с одним несовершеннолетним.

Theкодированиевступает в игру, когда драйвер устройства обрабатывает openвызов или в любое другое время, когда ему нужно определить, какому младшему (и, возможно, старшему, если он обрабатывает несколько старших) соответствует данное устройство. Драйверу дается inode, который он должен обработать; для узла устройства, который включает номер устройства, который кодирует старший и младший.MAJORиMINORмакросы, или начиная с инода,imajorиiminorфункции следует использовать для извлечения значений.

Некоторые символьные устройства предлагают мультиплексирование поверх основных механизмов регистрации, описанных выше; см.Как один драйвер управляет всем этим различным оборудованием?для примера.

Связанный контент