ドライバのロードからprobeの実行まで
カーネルがドライバをロードすると、まずmodule_init()が実行される。module_init()はマクロであり、プリコンパイル後は以下のように展開される(pxa2xx-ac97ドライバの場合)
static initcall_t __initcall_pxa2xx_ac97_init6 __attribute__( (__used__)) __attribute__((__section__(".initcall" "6" ".init"))) = pxa2xx_ac97_init;
その後、ドライバ固有のprobe関数(この例ではpxa2xx_ac97_probe)の実行までは以下の経路を辿る。
1. sound/arm/pxa2xx-ac97.c(427) : pxa2xx_ac97_init() start 2. drivers/base/platform.c(444) : platform_driver_register() start 3. drivers/base/driver.c(160) : driver_register() start 4. drivers/base/bus.c(540) : bus_add_driver() start 5. drivers/base/dd.c(332) : driver_attach() start 6. drivers/base/dd.c(292) : __driver_attach() start 7. drivers/base/dd.c(207) : driver_probe_device() start 8. drivers/base/dd.c(108) : really_probe() start 9. drivers/base/platform.c(390) : platform_drv_probe() start ※really_probe()内では drv->probe(dev) としてcallされる 10. platform_drv_probe()内で各ドライバ固有のprobeが実行される ※drv->probe(dev) としてcallされる
ただし、7番目のdriver_probe_device()において、8番目のreally_probe()をcallする前に以下の関数を実行する。この関数の結果如何によっては、really_probe()は実行されず、そのまま return 0 行い、結果としてドライバ固有のprobeは実行されない。
drivers/base/platform.c(571) : platform_match() start ※driver_probe_device()内では drv->bus->match(dev, drv) として実行される
platform_match()は以下のように定義されている。
static int platform_match(struct device * dev, struct device_driver * drv) { struct platform_device *pdev = container_of(dev, struct platform_device, dev); return (strncmp(pdev->name, drv->name, BUS_ID_SIZE) == 0); }
これをプリコンパイルして適当に分解してみた。
static int platform_match(struct device * dev, struct device_driver * drv) { int res ; int n; char *c; struct platform_device *pdev; pdev = ( { const typeof( ((struct platform_device *)0)->dev ) *__mptr; /* __mptrの宣言 */ __mptr = dev; c = (char *)__mptr; n = (size_t) &((struct platform_device *)0)->dev; (struct platform_device *) ( c - n ); } ); res = (strncmp(pdev->name, drv->name, BUS_ID_SIZE) == 0); return res; }
参考
pdev->name = pxa2xx-ac97 drv->name = pxa2xx-ac97