【问题标题】:How to find code called by suspend_ops->enter(state); [closed]如何查找suspend_ops->enter(state)调用的代码; [关闭]
【发布时间】:2013-05-11 02:30:03
【问题描述】:

我试图从底层理解 linux 内核电源管理,但由于我的 C 语言不是很强大,所以最终卡住了。我可以在suspend_enter(suspend_state_t state, bool *wakeup) 方法(kernel/power/suspend.c)中跟踪代码到它调用suspend_ops->enter(state); 的位置,但是我无法进一步跟踪代码。

据我了解,suspend_ops->enter(state) 在一些注册了suspend_ops 的驱动程序中调用了“enter”方法,但我不确定如何找到它们或正在调用的方法。有人可以告诉我如何关注suspend_ops->enter(state) 电话吗?

【问题讨论】:

  • 请注明您感兴趣的平台。您有手机或平板电脑名称吗? Johnathon 的列表缺少一些,因为他的来源已经很老了。当前内核中还有更多。它也有助于了解您的内核版本。电话是通过function pointers 进行的。运行 dmesg | grep -i power 可能会有所帮助。
  • 不是我的另一个问题的重复,因为我打算将此问题应用于一般的 linux 内核而不是特定的体系结构。感谢您提供有关函数指针的提示。
  • ARM Linux 挂起/恢复和非 ARM 挂起/恢复没有区别。他们只是为每个平台调用不同的函数指针。根据您的逻辑,您可以针对suspend_set_ops() 的每次出现提出相同的问题。这不是同一个相同的问题,但要说它有显着不同,简直让人毛骨悚然。

标签: debugging linux-kernel kernel power-management


【解决方案1】:

kernel/power/suspend.c 的顶部附近注意这一行:

static struct platform_suspend_ops *suspend_ops;

这意味着suspend_ops 是此文件专用的全局变量。这意味着为了有任何用途,必须在suspend.c 的某处进行分配。因此,让我们寻找任务。在suspend.c 中搜索suspend_ops,我们只看到一个赋值,在子例程suspend_set_ops 中。在suspend.c 中搜索suspend_set_ops,我们看到没有调用它。所以,电话一定是在别的地方!

我们在整个内核中搜索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.cacpi/sleep.c。因此,下一步是查看某些平台的特定于体系结构的代码。我们将以./arch/powerpc/platforms/83xx/suspend.c 为例。无论您使用什么平台,您都应该自己执行此操作。如果是 x86,那么你可能需要查看./drivers/acpi/sleep.c

在该文件中搜索suspend_set_ops,我们看到它在静态子程序pmc_probe 中被调用了一次。所以我们在同一个文件中寻找对pmc_probe 的调用,直到找到一个不是静态的。我们找到了一个名为 `pmc_driverthat assignspmc_probeto elementprobe` 的​​ `of_platform_driver 类型结构的静态声明。

由于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。

【讨论】:

  • +1 cd arch/arm 后跟 git grep suspend_set_ops 并得到相似。我猜他的平台是arm。当然,我不知道 Android PowerPC 的实现。
  • 抱歉回复晚了,有点忙。我一开始按照你的建议做了,但没想到要查看 acpi 驱动程序文件(这是一个漫长的一周),所以谢谢你帮助我。
猜你喜欢
  • 2010-09-19
  • 1970-01-01
  • 2010-11-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多