Debugging 如何查找suspend_ops->;调用的代码;进入(州);

Debugging 如何查找suspend_ops->;调用的代码;进入(州);,debugging,linux-kernel,kernel,power-management,Debugging,Linux Kernel,Kernel,Power Management,我试图在较低的层次上理解linux内核的电源管理,但由于我的C不是很强,我最终陷入了困境。我能够跟踪代码,直到它调用suspend\u ops->enter(state)在suspend\u enter(suspend\u state\u t state,bool*wakeup)方法(kernel/power/suspend.c)中,但是我无法进一步了解代码 据我所知,suspend\u ops->enter(state)在一些向suspend\u ops注册的驱动程序中调用了“enter”方法

我试图在较低的层次上理解linux内核的电源管理,但由于我的C不是很强,我最终陷入了困境。我能够跟踪代码,直到它调用
suspend\u ops->enter(state)
suspend\u enter(suspend\u state\u t state,bool*wakeup)
方法(
kernel/power/suspend.c
)中,但是我无法进一步了解代码


据我所知,
suspend\u ops->enter(state)
在一些向suspend\u ops注册的驱动程序中调用了“enter”方法,但我不确定如何找到它们或调用的方法。有人能告诉我如何执行
suspend\u ops->enter(state)
调用吗?

靠近
kernel/power/suspend.c
的顶部请注意:

static struct platform_suspend_ops *suspend_ops;
这意味着
suspend_ops
是此文件专用的全局变量。这意味着为了有任何用处,必须在
suspend.c
中的某个地方有一个赋值。让我们来看看作业。在
suspend.c
中搜索
suspend\u ops
我们在子例程
suspend\u set\u ops
中只看到一个赋值。在
suspend.c
中搜索
suspend\u set\u ops
,我们发现没有调用它。所以,电话一定在别的地方

我们在整个内核中搜索
suspend\u set\u 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 ?
我们看到的是,除了输出末尾的两个驱动程序:
macintosh/via pmu.c
acpi/sleep.c
之外,几乎所有对
suspend\u set\u ops
的调用都在特定于体系结构的目录中。因此,下一步是查看某个平台的特定于体系结构的代码。我们将以
/arch/powerpc/platforms/83xx/suspend.c
为例。无论您使用什么平台,您都应该自己执行此操作。如果是x86,那么您可能需要查看
/drivers/acpi/sleep.c

在该文件中搜索
suspend\u set\u ops
,我们看到它在静态的子例程
pmc\u probe
中被调用了一次。因此,我们在同一个文件中查找对
pmc\u probe
的调用,直到找到一个不是静态的调用为止。我们找到一个称为“pmc\U driver
`of_platform\U driver
类型的结构的静态声明,该声明将
pmc\U probe
分配给元素
probe`

由于
pmc_驱动程序
结构是静态的,我们在同一个文件中查找对它的引用,在静态函数
pmc_init
中查找对它的引用。我们查找对
pmc_init
的调用,并找到一个,作为
模块_init
调用的参数

我们从内核树的顶部搜索
module_init
,稍微限制了我们的搜索:

find . -type f | xargs grep -w "module_init.*)[^;]" |more
在我们得到的结果中,最有希望的是:

./include/linux/init.h:#define module_init(initfn)                  \
查看
/include/linux/init.h
我们可以看到
模块_init
是对
\u initcall
的调用,如果模块未定义或

#define module_init(initfn)                                     \
    static inline initcall_t __inittest(void)               \
    { return initfn; }                                      \
    int init_module(void) __attribute__((alias(#initfn)));

现在,我们真正讨论的是另一个主题——如何注册驱动程序和模块。HTH.

可能重复:请指定您感兴趣的平台。你有手机或平板电脑的名字吗?约翰纳森的名单少了一些,因为他的资料来源很老。在当前内核中还有更多。了解内核版本也很有帮助。电话接通了。运行
dmesg | grep-i power
可能会有所帮助。这不是我的另一个问题的重复,因为我打算将此问题应用于linux内核,而不是特定的体系结构。感谢您提供有关函数指针的提示。ARM Linux挂起/恢复和非ARM挂起/恢复没有区别。它们只是为每个平台调用不同的函数指针。根据您的逻辑,每次出现
suspend\u set\u ops()
,您都可以问相同的问题。这不是一个完全相同的问题,但说它有显著的不同简直是吹毛求疵。+1
cd-arch/arm
,然后是
git-grep-suspend\u-set\u-ops
,并得到类似结果。我猜他的平台是手臂。当然,我不知道安卓PowerPC的实现。很抱歉反应太晚,我有点忙。我一开始按照你的建议做了,但没有考虑查看acpi驱动程序文件(这是一个漫长的一周),所以感谢你帮助我。