Indagando en el kernel de linux
|
|
Por BorZung
departamento hurgando_en_las_tripas , Sección Diarios Puesto a las Thu Mar 6th, 2003 at 03:28:29 PM CET
|
|
Despues de tener problemas con la carga en un kernel 2.4 de una tarjeta ethernet con chip rtl8139C que funcionaba perfectamente en un kernel 2.2 me toco investigar a que era debido esto ...
|
Partiendo del fichero "drivers/net/8139too.c" buscamos el punto de carga del modulo, que esta en la función rtl8139_init_module esta función lo que hace es llamar a la función pci_module_init definida en "include/linux/pci.h" e implementada en el mismo fichero (hay dos opciones para esta funcion, en base a la configuración del kernel, una que no hace nada y la otra que es la que ahora describiré).
pci_module_init:
Lo unico que hace es llamar a la función pci_register_driver y despues comprobar el valor de retorno para actuar en consecuencia, devuelve 0 en caso de que todo haya ido bien, en nuestro caso estaba devolviendo -ENODEV (dispositivo no encontrado)
pci_register_driver:
Implementada en "drivers/pci/pci.c" y definida en "includes/linux/pci.h", lo que hace esta funcion es recorrer una lista en la que estan todos los dispositivos pci que el kernel tiene localizados, para eso utiliza las utilidades genericas que estan en "include/linux/list.h" y la macro pci_foreach_dev definida en "include/linux/pci.h", la funcion que se utiliza para comprobar si el driver es el correcto es pci_announce_device.
pci_announce_device:
Implementada en "drivers/pci/pci.c" comienza a comprobar la tabla de identificadores de la estructura pci_driver para saber si tiene valores, como en el caso que nos ocupa los tiene se llama a la función pci_match_device.
pci_match_device:
Implementada en "drivers/pci/pci.c" hace una comprobacion de todos los valores de la tabla del drivers que intentamos cargar con aquellos que tiene en la lista de dispositivos, cuando encuentra alguno que coincide devuelve el identificador de este, es en este punto exacto donde esta fallando la deteción de la tarjeta.
Revisando ahora la estructura que esta en el driver se encuentra esto:
static struct pci_device_id rtl8139_pci_tbl[] __devinitdata = {
{0x10ec, 0x8139, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
{0x10ec, 0x8138, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139_CB },
{0x1113, 0x1211, PCI_ANY_ID, PCI_ANY_ID, 0, 0, SMC1211TX },
/* {0x1113, 0x1211, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MPX5030 },*/
{0x1500, 0x1360, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DELTA8139 },
{0x4033, 0x1360, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ADDTRON8139 },
{0x1186, 0x1300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DFE538TX },
{0x1186, 0x1340, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DFE690TXD },
{0x13d1, 0xab06, PCI_ANY_ID, PCI_ANY_ID, 0, 0, FE2000VX },
{0x1259, 0xa117, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ALLIED8139 },
#ifdef CONFIG_8139TOO_8129
{0x10ec, 0x8129, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8129 },
#endif
/* some crazy cards report invalid vendor ids like
* 0x0001 here. The other ids are valid and constant,
* so we simply don't match on the main vendor id.
*/
{PCI_ANY_ID, 0x8139, 0x10ec, 0x8139, 0, 0, RTL8139 },
{PCI_ANY_ID, 0x8139, 0x1186, 0x1300, 0, 0, DFE538TX },
{PCI_ANY_ID, 0x8139, 0x13d1, 0xab06, 0, 0, FE2000VX },
{0,}
};
Pese a que el desarrollador ya nos dice que hay tarjetas extrañas, que tienen identificadores raros, esta que estoy intentando hacer funcionar no concuerda con ninguna de estas descripciones, asi es que añado una linea con los valores que obtengo al hacer un "cat /proc/pci" y al recompilar el modulo y volverlo a cargar la tarjeta funciona sin ningun problema.
Durante esta depuración he entendido un poco mejor como funciona el sistema de detección de hardware pci y todo este proceso no me llevo mas de un par de horas.
PD: ¿Y como hacer esto en un sistema propietario?" |
|
|