• Linux内核中ideapad-laptop.c文件全解析1


    在将具体代码之前,先来科普一下ideapad是什么。

    IdeaPad,中文名为“思想本”,是联想公司于2008年推出的笔记本电脑品牌。目的是为了弥补收购欧洲第四大PC制造商Packard Bell失败后国际市场的空缺,定义为消费级产品(与商务级的ThinkPad呼应),并取代的国际上的LENOVO3000系列和国内的天逸系列。

    由于不是本文重点,简单介绍到这里就好。下边正式开始分析代码。

    ideapad-laptop.c文件位于Linux内核源码根目录/drivers/platform/x86/下,将近1750行代码(Kernel版本5.18.8)。由于代码很长,分段进行分析。先来看第1段代码:

    1. MODULE_AUTHOR("David Woodhouse ");
    2. MODULE_DESCRIPTION("IdeaPad ACPI Extras");
    3. MODULE_LICENSE("GPL");

    这段代码无需多言,分别列出了内核模块的作者、功能描述和遵守的许可证。

    再来看第2段代码:

    1. static const struct acpi_device_id ideapad_device_ids[] = {
    2. {"VPC2004", 0},
    3. {"", 0},
    4. };
    5. MODULE_DEVICE_TABLE(acpi, ideapad_device_ids);
    6. static struct platform_driver ideapad_acpi_driver = {
    7. .probe = ideapad_acpi_add,
    8. .remove = ideapad_acpi_remove,
    9. .driver = {
    10. .name = "ideapad_acpi",
    11. .pm = &ideapad_pm,
    12. .acpi_match_table = ACPI_PTR(ideapad_device_ids),
    13. },
    14. };
    15. module_platform_driver(ideapad_acpi_driver);

    module_platform_driver是一个宏,位于Linux内核源码根目录/include/linux/platform_device.h中,其定义如下:

    1. /* module_platform_driver() - Helper macro for drivers that don't do
    2. * anything special in module init/exit. This eliminates a lot of
    3. * boilerplate. Each module may only use this macro once, and
    4. * calling it replaces module_init() and module_exit()
    5. */
    6. #define module_platform_driver(__platform_driver) \
    7. module_driver(__platform_driver, platform_driver_register, \
    8. platform_driver_unregister)

    由代码注释可以看到,module_platform_driver替代了传统的module_init和module_exit。

    module_driver函数在include/linux/device/driver.h中,定义如下:

    1. /**
    2. * module_driver() - Helper macro for drivers that don't do anything
    3. * special in module init/exit. This eliminates a lot of boilerplate.
    4. * Each module may only use this macro once, and calling it replaces
    5. * module_init() and module_exit().
    6. *
    7. * @__driver: driver name
    8. * @__register: register function for this driver type
    9. * @__unregister: unregister function for this driver type
    10. * @...: Additional arguments to be passed to __register and __unregister.
    11. *
    12. * Use this macro to construct bus specific macros for registering
    13. * drivers, and do not use it on its own.
    14. */
    15. #define module_driver(__driver, __register, __unregister, ...) \
    16. static int __init __driver##_init(void) \
    17. { \
    18. return __register(&(__driver) , ##__VA_ARGS__); \
    19. } \
    20. module_init(__driver##_init); \
    21. static void __exit __driver##_exit(void) \
    22. { \
    23. __unregister(&(__driver) , ##__VA_ARGS__); \
    24. } \
    25. module_exit(__driver##_exit);

    宏定义完全展开,过程及最终代码如下:

    module_platform_driver(ideapad_acpi_driver) 

    ---> 展开为:

    module_driver(ideapad_acpi_driver, platform_driver_register, platform_driver_unregister) 

    ---> 进一步展开为:
     

    1. static int __init ideapad_acpi_driver_init, platform_driver_register, platform_driver_unregister)
    2. {
    3. return platform_driver_resgister(&ideapad_acpi_driver);
    4. }
    5. module_init(ideapad_acpi_driver_init);
    6. static void __exit ideapad_acpi_driver_exit(void)
    7. {
    8. platform_driver_unregister(&ideapad_acpi_driver);
    9. }
    10. module_exit(ideapad_acpi_driver_exit);

    其实还是“旧瓶装新酒”,所谓“换汤不换药,还是那一套”。

    ideapad_acpi_driver中各个成员的解析,且听下回分解。

  • 相关阅读:
    MAYA教程之建模基础命令介绍
    云原生时代下的 12-factor 应用与实践
    图文详解Linux基础经典教程(05)——配置虚拟机静态IP
    Mybatis 动态语言 - mybatis-thymeleaf
    HMM与LTP词性标注之命名实体识别与HMM
    vue中实现文件批量打包压缩下载(以及下载跨域问题分析)
    计算摄影——图像去噪(一)
    Android平台i2c-tools及16位地址读写,以及not executable: 64-bit ELF file解决办法
    JVM内存模型
    MQTT 服务器搭建(基于mosquitto)
  • 原文地址:https://blog.csdn.net/phmatthaus/article/details/128074105