Valor devuelto por el kernel de Linux Register_chdev

Valor devuelto por el kernel de Linux Register_chdev

Este videomuestra un ejemplo de módulo del kernel de Linux Raspberry Pi que crea un nuevo dispositivo de caracteres. Utiliza la API del kernel register_chdev. En un comentario al vídeo (no puedo generar un enlace directo al mismo), en cuanto al valor de retorno de register_chdev, el autor afirma:

Si el valor de retorno no es igual a 0, el número de dispositivo ya está en uso. Los 12 bits superiores del valor de retorno son el número de dispositivo principal, los 20 bits inferiores son el número de dispositivo menor.

Supongo que con "el número de dispositivo ya está en uso" quiere decir "el número de dispositivo principal distinto de cero elegido arbitrariamente en el módulo del kernel ya está en uso".

A pesar de que varias páginas web tratan sobre esto (el oficial, entoncesÉsteyÉste), no encontré ninguna información sobre esta subdivisión interna del valor de retorno.

Si elijo crear (con mi módulo del kernel) un dispositivo con un número mayor ya en uso, el kernel nunca lo acepta y se niega a registrar el dispositivo. Esto ocurre tanto cuando el número mayor que elijo es el mismo que el de un dispositivo de bloque, como cuando el número mayor que elijo es el mismo que el de un dispositivo de caracteres. register_chdevsiempre devuelve un valor negativo. En el último caso, en cambio, esperaba un valor de retorno positivo distinto de cero, con los 12 bits superiores representando el número de dispositivo principal y los 20 bits inferiores representando el número de dispositivo menor (tal vez mayor que 0: si el número principal era ya utilizado, tal vez el sistema ya tenía al menos un dispositivo relacionado con él, con el número menor 0).

¿Es cierto lo que dice en el comentario de Youtube? ¿Dónde puedo encontrar alguna documentación al respecto?


Estoy ejecutando Raspbian 10, uname -amuestra:

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

Respuesta1

register_chrdeven sí no está documentado en el kernel, perosu definición es corta:

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

lo que básicamente significa que llama__register_chrdevpara registrar un mayor con una gama completa de menores (256 menores comenzando en 0) y devolver el resultado de esa función. Esto último está documentado como

Simajor== 0 esta función asignará dinámicamente una especialidad y devolverá su número.

Simajor> 0 esta función intentará reservar un dispositivo con el número principal dado y devolverá cero si tiene éxito.

Devuelve un error -ve en caso de error.

No existe ninguna disposición para el regreso de menores, codificados o no. El objeto de estas funciones es registrar a un mayor en todo caso, potencialmente con un subconjunto de menores; ni un solo menor.

Elcodificaciónentra en juego cuando el controlador del dispositivo maneja una openllamada, o en cualquier otro momento en el que necesita determinar a qué menor (y quizás mayor, si maneja varios mayores) corresponde un dispositivo determinado. A un controlador se le da el inodo que se le pide que maneje; para un nodo de dispositivo, eso incluye el número de dispositivo, que codifica el mayor y el menor. ElMAJORyMINORmacros, o partiendo de un inodo, elimajoryiminorfunciones, deben usarse para extraer los valores.

Algunos dispositivos de caracteres ofrecen multiplexación además de los principales mecanismos de registro descritos anteriormente; ver¿Cómo controla un controlador misceláneo todo este hardware diferente?para ver un ejemplo de esto.

información relacionada