[eside-ghost] Que Comando??
yUnwEb
yunweb en yunweb.homeunix.org
Mie Dic 21 10:20:37 CET 2005
On ar., 2005-12-20 at 23:04 +0100, Jon Ander Hernández wrote:
> Aupi!
Ieup!
>
> On mar, 2005-12-20 at 21:33 +0100, yUnwEb wrote:
> > Aupa JonAn, cuanto tiempo :)
>
> Bueno hace 2 o 3 semanas que escribí la última vez, pero escribí tanto
> que me dí un descanso, jejejeje.
Joer, pero es que se aprende un huevo con tus e-mails :P
Voy a hacer un esfuerzo y voy a intentar explicarme yo también un poco.
>
> > He leido el hilo un poco rápido, pero si no he entendido mal puede que
> > /proc/bus/pci/devices pueda ayudaros. Es decir, si yo tengo por ejemplo
> > el módulo ehci_hcd para sacar su dispositivo haría algo del estilo de:
> >
> > # MODULE=ehci_hcd; lspci -d $(grep -B 1 ${MODULE} /proc/bus/pci/devices|tail -1|awk '{print $2}'|sed 's/^\([0-9]\{4\}\)/\1:/')
> > 00:1d.7 USB Controller: Intel Corp. 82801DB (ICH4) USB2 EHCI Controller (rev 01)
> >
> > Evidentemente esta guarrada sólo saca el primer dispositivo del módulo.
> > Ya que un módulo puede gobernar varios dispositivos. Pero vamos, os vale
> > para que os hagáis una idea :)
>
> Desde luego sabes pero mucho, mucho más que yo de sed/grep/awk, que
> suerte tienes buahhh como te envidio xDDDDDDD. A ver si me pillo un buen
> libro o me meto entre pecho y espalda una buena guía :)
>
> No conocía lo que había dentro de /proc/bus/pci/devices, es interesante,
> en mi caso no es de ayuda porque yo necesito saber cual es la relación
> entre módulo y dispositivo antes de cargar el módulo, y entiendo
> que /proc/bus/pci/devices es capaz de decirnos esta relación una vez que
> el módulo esta cargado y no antes.
Vale, de acuerdo. Entonces lo que tu dices sí que está
en /lib/modules/$(uname -r)/. Más concretamente en el fichero
modules.pcimap.
Al hacer un módulo o controlador, se utiliza la estructura pci_device_id
para comunicarle al núcleo que dispositivos soporta. Normalmente se hace
a traves de la macro PCI_DEVICE(vendorId, DeviceId). Y tú es lo que creo
que andas buscando.
/usr/include/linux/pci.h:
struct pci_device_id {
unsigned int vendor, device; /* Vendor and device ID
or PCI_ANY_ID */
unsigned int subvendor, subdevice; /* Subsystem ID's or
PCI_ANY_ID */
unsigned int class, class_mask; /*
(class,subclass,prog-if) triplet */
unsigned long driver_data; /* Data private to the
driver */
};
Según tengo entendido esta estructura se exporta al espacio de usuario a
traves de /lib/modules/$(uname -r)/modules.pcimap mediante la macro
MODULE_DEVICE_TABLE para el sistema hotplug y demás.
Es decir, por ejemplo, yo en el modulo ipw2100 tengo:
/usr/local/src/ipw2100-1.1.0/ipw2100.c:
#define IPW2100_DEV_ID(x) { PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, x }
static struct pci_device_id ipw2100_pci_id_table[] __devinitdata = {
IPW2100_DEV_ID(0x2520), /* IN 2100A mPCI 3A */
IPW2100_DEV_ID(0x2521), /* IN 2100A mPCI 3B */
IPW2100_DEV_ID(0x2524), /* IN 2100A mPCI 3B */
IPW2100_DEV_ID(0x2525), /* IN 2100A mPCI 3B */
IPW2100_DEV_ID(0x2526), /* IN 2100A mPCI Gen A3 */
...
IPW2100_DEV_ID(0x25A0), /* HP 2100 mPCI 3B */
{0,},
};
MODULE_DEVICE_TABLE(pci, ipw2100_pci_id_table);
Esta macro añade un símbolo externo llamado "__mod_pci_device_table"
apuntando al pci_device_id en el módulo tal y como se puede ver en:
/usr/include/linux/module.h:
#define MODULE_GENERIC_TABLE(gtype,name) \
static const unsigned long __module_##gtype##_size \
__attribute_used__ = sizeof(struct gtype##_id); \
static const struct gtype##_id * __module_##gtype##_table \
__attribute_used__ = name
...
#define MODULE_DEVICE_TABLE(type,name) \
MODULE_GENERIC_TABLE(type##_device,name)
Se puede ver que el ipw2100.ko tiene por ahí los
"__mod_pci_device_table":
# strings /lib/modules/2.6.11.9/kernel/drivers/net/wireless/ipw2100.ko|
grep "__mod_pci_device_table"
__mod_pci_device_table
__mod_pci_device_table
__mod_pci_device_table
# nm -g /lib/modules/2.6.11.9/kernel/drivers/net/wireless/ipw2100.ko|
grep "__mod_pci_device_table"
000003c0 D __mod_pci_device_table
Luego es el depmod el que se encarga de sacar esas variables de los
modulos de /lib/modules/$(uname -r)/ y meterlas en el modules.pcimap.
Échale una ojeada al "depmod -n", eso saca por pantalla los datos en vez
de escribirlos en /lib/modules/$(uname -r)/*
En /usr/src/module-init-tools-3.2/depmod.c:
static void parse_modules(struct module *list)
{
struct module *i;
for (i = list; i; i = i->next) {
i->ops->load_symbols(i);
i->ops->fetch_tables(i);
}
}
A parse_modules se le llama desde el main de depmod. En fetch_tables se
lee el "__mod_pci_device_table".
/usr/src/module-init-tools-3.2/depmod.h:
struct module
{
...
/* 64 or 32 bit? */
struct module_ops *ops;
...
}
struct module_ops PERBIT(mod_ops) = {
.load_symbols = PERBIT(load_symbols),
.calculate_deps = PERBIT(calculate_deps),
.fetch_tables = PERBIT(fetch_tables),
.get_aliases = PERBIT(get_aliases),
.get_modinfo = PERBIT(get_modinfo),
};
En /usr/src/module-init-tools-3.2/moduleops_core.c se puede ver que
llama a una función PERBIT desde la que se lee el símbolo
"__mod_pci_device_table" desde la secciones ".symtab" y ".strtab" del
módulo
struct module_ops PERBIT(mod_ops) = {
.load_symbols = PERBIT(load_symbols),
.calculate_deps = PERBIT(calculate_deps),
.fetch_tables = PERBIT(fetch_tables),
.get_aliases = PERBIT(get_aliases),
.get_modinfo = PERBIT(get_modinfo),
};
...
static void PERBIT(fetch_tables)(struct module *module)
{
module->pci_size = PERBIT(PCI_DEVICE_SIZE);
module->pci_table = PERBIT(deref_sym)(module->data,
"__mod_pci_device_table",
module->conv);
...
Bueno, que igual me he desviado un poco del tema. Total, que podría ser
algo tipo:
# MODULE=ipw2100; lspci -d $(grep "^${MODULE}" /lib/modules/$(uname
-r)/modules.pcimap|head -1|sed 's/0x0000//g'|awk '{print $2":"$3}')
Seguro que he que con tanto rollo he metido la pata en alguna parte o
se me escapa algo. Pero bueno, espero haberte acercado un poco más a la
solución con esto.
>
> Supongo que si a Jon le vale saber la relación módulo-dispositivo y para
> el bus pci, entonces entiendo que tu solución es perfecta.
Perfecta para él, pero a ti no te valía ;)
>
> En mi caso se que todo lo que necesito esta en ese script, el que he
> mandado. Ahora solo necesito saber más de bash/sed/grep/awk para
> entenderlo bien de pe a pa.
No lo he mirado, es que ahora mismo me da un poco de pereza.
>
> Un saludete!!
>
> JonAn.
>
> P.D: De todas maneras hoy estoy espeso, creo que mis explicaciones de
> antes pueden haberle alejado innecesariamente a Jon de una solución
> simple.
> Como dice azabel, la respuesta esta en los ficheros que están
> en /lib/modules/$(uname -r)/, y debería haberlo dicho al principio, solo
> que no se, me ha salido del alma dar toda la explicación de lo que había
> descubierto hasta ahora del tema.
Bueno, por hoy ya me vale.
Hasta la próxima :)
--
yUnwEb
Más información sobre la lista de distribución eside-ghost