靠近kernel/power/suspend.c
注释顶部的行:
static struct platform_suspend_ops *suspend_ops;
这意味着这suspend_ops
是该文件私有的全局变量。这意味着为了有任何用处,必须在suspend.c
. 因此,让我们寻找任务。搜索我们只看到一个赋值suspend.c
,suspend_ops
在 subroutine 中suspend_set_ops
。搜索suspend_set_ops
insuspend.c
我们看到没有调用它。所以,电话必须在其他地方!
我们在整个内核中搜索suspend_set_ops
:
yba@tavas:~/linux-2.6/linux-2.6.31$ find . -type f | xargs grep suspend_set_ops
./kernel/power/suspend.c: * suspend_set_ops - Set the global suspend method table.
./kernel/power/suspend.c:void suspend_set_ops(struct platform_suspend_ops *ops)
./arch/mips/alchemy/devboards/pm.c: suspend_set_ops(&db1x_pm_ops);
./arch/arm/mach-sa1100/pm.c: suspend_set_ops(&sa11x0_pm_ops);
./arch/arm/plat-s3c/pm.c: suspend_set_ops(&s3c_pm_ops);
./arch/arm/mach-omap2/pm24xx.c: suspend_set_ops(&omap_pm_ops);
./arch/arm/mach-omap2/pm34xx.c: suspend_set_ops(&omap_pm_ops);
./arch/arm/mach-pxa/pm.c: suspend_set_ops(&pxa_pm_ops);
./arch/arm/mach-pxa/sharpsl_pm.c: suspend_set_ops(&sharpsl_pm_ops);
./arch/arm/mach-pxa/sharpsl_pm.c: suspend_set_ops(NULL);
./arch/arm/mach-at91/pm.c: suspend_set_ops(&at91_pm_ops);
./arch/arm/mach-omap1/pm.c: suspend_set_ops(&omap_pm_ops);
./arch/arm/mach-pnx4008/pm.c: suspend_set_ops(&pnx4008_pm_ops);
./arch/sh/kernel/cpu/shmobile/pm.c: suspend_set_ops(&sh_pm_ops);
./arch/sh/boards/mach-hp6xx/pm.c: suspend_set_ops(&hp6x0_pm_ops);
./arch/powerpc/platforms/83xx/suspend.c: suspend_set_ops(&mpc83xx_suspend_ops);
./arch/powerpc/platforms/52xx/mpc52xx_pm.c: suspend_set_ops(&mpc52xx_pm_ops);
./arch/powerpc/platforms/52xx/lite5200_pm.c: suspend_set_ops(&lite5200_pm_ops);
./arch/avr32/mach-at32ap/pm.c: suspend_set_ops(&avr32_pm_ops);
./arch/blackfin/mach-common/pm.c: suspend_set_ops(&bfin_pm_ops);
./include/linux/suspend.h: * suspend_set_ops - set platform dependent suspend operations
./include/linux/suspend.h:extern void suspend_set_ops(struct platform_suspend_ops *ops);
./include/linux/suspend.h:static inline void suspend_set_ops(struct platform_suspend_ops *ops) {}
./drivers/macintosh/via-pmu.c: suspend_set_ops(&pmu_pm_ops);
./drivers/acpi/sleep.c: suspend_set_ops(old_suspend_ordering ?
我们看到的是,几乎所有的调用suspend_set_ops
都在特定于体系结构的目录中,除了输出末尾的两个驱动程序:macintosh/via-pmu.c
和acpi/sleep.c
. 因此,下一步是查看某些平台的特定于体系结构的代码。我们将./arch/powerpc/platforms/83xx/suspend.c
用作示例。无论您使用什么平台,您都应该自己执行此操作。如果是 x86,那么您可能需要查看./drivers/acpi/sleep.c
.
在该文件中搜索,suspend_set_ops
我们看到它在pmc_probe
静态子程序中被调用一次。所以我们在同一个文件中寻找调用,pmc_probe
直到找到一个不是静态的。我们找到了一个`of_platform_driver
名为“pmc_driver that assigns
pmc_probe probe”类型的结构的静态声明to element
。
由于pmc_driver
结构是静态的,我们在同一个文件中查找对它的引用,并且在静态函数中查找pmc_init
。我们查找调用pmc_init
并找到一个,作为module_init
调用的参数。
我们module_init
从内核树的顶部开始搜索,稍微限制了我们的搜索:
find . -type f | xargs grep -w "module_init.*)[^;]" |more
在我们得到的结果中,最有希望的是:
./include/linux/init.h:#define module_init(initfn) \
往里看,./include/linux/init.h
我们看到这module_init
是一个调用,__initcall
如果 MODULE 没有定义,否则
#define module_init(initfn) \
static inline initcall_t __inittest(void) \
{ return initfn; } \
int init_module(void) __attribute__((alias(#initfn)));
在这一点上,我们真的在讨论另一个主题——如何注册驱动程序和模块。HTH。