2012-08-01 9 views
7

Estoy tratando de entender algún código de controlador de kernel de Linux escrito en C para un adaptador de Wi-Fi USB. Línea 1456 en el archivo /drivers/net/wireless/rtl818x/rtl8187/dev.c (por si acaso alguien quisiera hacer referencia al código del núcleo de contexto) se lee:código C, ¿por qué la dirección 0xFF00 se convierte en una estructura?

priv->map = (struct rtl818x_csr *)0xFF00; 

Tengo curiosidad acerca de lo que el operando de la derecha está haciendo aquí - (struct rtl818x_csr *)0xFF00;. He estado interpretando esto como diciendo "enviar dirección de memoria 0xFF00 para que sea del tipo rtl818x_csr y luego asignarlo a priv->map". Si mi interpretación es correcta, ¿qué tiene de especial la dirección de memoria 0xFF00 para que el controlador pueda decir con certeza que lo que busca siempre estará en esta dirección? La otra cosa que me interesa es que 0xFF00 solo tiene 16 bits. Esperaría 32/64 bits si estuviese emitiendo una dirección de memoria.

¿Alguien puede aclarar exactamente qué está pasando en esta línea de código? Me imagino que hay un error en mi comprensión de la sintaxis C.

+0

Parece que el registro de control/estado para el chipset RTL818x está mapeado en memoria para direccionar 0xFF00. –

Respuesta

2

Lanzar una dirección absoluta a un puntero a una estructura es una forma común en los controladores para acceder a los registros (de memoria asignada) de un dispositivo como una estructura C normal.

El uso de 0xff00 funciona porque C no firma extensiones de números.

+0

Esto no es una conversión a una estructura, sino a un puntero. –

2

0xFF00 es una dirección en el espacio de direcciones IO del sistema. Si observa el código, la dirección nunca se desreferencia directamente, sino que se accede a través de las funciones IO.

Por ejemplo, en la llamada

rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, 
       RTL818X_EEPROM_CMD_CONFIG); 

que a su vez llama a funciones IO núcleo Linux bajo nivel.

La dirección es arrojado a un puntero a una estructura para dar acceso a las compensaciones de la dirección, ejemplo aquí:

0xFF00 + offsetof(struct rtl818x_csr, EEPROM_CMD) 

Tenga en cuenta que en el rtl818x_iowrite8 llamada anterior, sin eliminar la referencia se produce cuando se pasa el argumento &priv->map->EEPROM_CMD porque del operador &, solo se calcula la dirección + desplazamiento. La desreferencia se logra aún más con las funciones internas de bajo nivel llamadas dentro de rtl818x_iowrite8.

2

Debe tener esto en cuenta desde el punto de vista del dispositivo.

Comenzando en la dirección 0xFF00 dentro del espacio de direcciones mapeado para el dispositivo rtl8187 hay un rango de memoria que contiene información estructurada de la misma manera que la estructura rtl818x_csr definida como here.

De modo que después de mapear lógicamente esa región, puede comenzar a leer y escribir en el bus para controlar el dispositivo. Como here (tuve que cortar dos hipervínculos más porque no tengo la reputación necesaria para publicar más de 3, pero entiendes el punto). Estos son sólo un par de ejemplos. Si lee el archivo completo verá que las lecturas y escrituras están salpicadas en todas partes.

Para entender por qué esa estructura se ve de esa manera y por qué se usa 0xFF00 en lugar de 0xBEEF o 0xDEAD, tendrá que consultar la hoja de datos para ese dispositivo.

Por lo tanto, si desea comenzar a buscar el código del kernel, y especialmente los controladores del dispositivo, deberá tener más que solo el código.También necesitará la hoja de datos o las especificaciones. Esto puede ser bastante difícil de encontrar (ver los tropecientos millones de temas de correo electrónico y artículos que solicitan la documentación abierta de los proveedores).

De todos modos, espero haber respondido a su pregunta. ¡Feliz hacking!

Cuestiones relacionadas