news 2026/9/5 4:01:52

20251229 - 驱动程序是如何向Linux内核注册(Register)自己的

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
20251229 - 驱动程序是如何向Linux内核注册(Register)自己的

驱动是如何向内核**注册(Register)**自己的?是 register_chrdev 还是 platform_driver_register?二者有什么区别?为什么有了register_chrdev还要有platform_driver_register?它们到底谁才是真正的“注册”?

答案是:它们都是注册,但注册的“对象”和“目的”完全不同。

简单来说:

  • platform_driver_register是为了找硬件(匹配设备树)。
  • register_chrdev是为了给用户提供接口(生成/dev/xxx)。

在现代 Linux 驱动开发中,通常是两者配合使用:先用 Platform 注册找到硬件,然后在找到硬件的回调函数(Probe)里,再进行字符设备注册。


学习笔记:Linux 驱动的两层注册机制

1. 核心区别概览

特性register_chrdev (字符设备注册)platform_driver_register (平台驱动注册)
所属层级接口层(Interface Layer)设备模型层(Device Model Layer)
核心目的告诉内核:“我是一个字符设备,我的操作函数是f_op告诉内核:“我就是这硬件的驱动,把符合名字的设备交给我”
面向谁?面向用户空间(APP)面向内核/硬件(Device Tree)
产出物主设备号、/dev/xxx节点(配合 class_create)触发probe函数的执行
必须性如果你想让 APP 操作,必须有 (或其变体cdev_add)不是必须的 (简单的驱动可以没有),但标准驱动都有

2. 深度解析:为什么要分两层?

第一层:platform_driver_register(我是谁?我去哪里上班?)

这是 Linux“总线-设备-驱动” (Bus-Device-Driver)模型的一部分。

  • 背景:

    在设备树(Device Tree)引入之前,驱动代码里写死了硬件地址(比如 0x020E0068)。

    现在,硬件信息都写在设备树 (.dts) 里,驱动代码里不再写死地址。

  • 作用:

    platform_driver_register 的作用就是**“相亲”**。

    • 设备树说:“我有一个硬件,名字叫my-led。”
    • 驱动代码说:“我是一个驱动,我能支持名字叫my-led的硬件。”
    • 内核:把两者撮合在一起。一旦名字匹配成功,内核就会调用驱动里的probe(探测)函数。

第二层:register_chrdev(我能干什么?)

这是我们之前讲过的字符设备功能注册

  • 作用:

    不管你是怎么找到硬件的,最终你都得让 APP 能控制它。

    register_chrdev 就是去申请一个主设备号,并挂载 file_operations,让 APP 可以通过 open/read/write 来操作。


3. 它们是如何配合工作的? (标准模板)

在现代驱动中,这套流程是固定的“套娃”模式:

  1. 模块入口 (module_init):只做一件事,调用platform_driver_register
  2. 匹配成功:内核发现设备树有对应节点,自动调用驱动的probe函数。
  3. Probe 函数这里才是真正干活的地方!
    • 获取硬件资源(读设备树里的寄存器地址、中断号)。
    • 调用register_chrdev(或者是现代的alloc_chrdev_region+cdev_add)。
    • 创建设备节点 (class_create,device_create)。

代码骨架(可以背下来这个结构!)

/* 1. 定义字符设备的操作函数 (给 APP 用的) */ static struct file_operations my_fops = { .owner = THIS_MODULE, .write = my_write, .open = my_open, }; /* 2. probe 函数:当驱动和设备树匹配成功时,内核自动调用 */ static int my_probe(struct platform_device *pdev) { printk("硬件匹配成功!开始初始化...\n"); // A. 获取硬件资源 (从设备树拿) // ... // B. 注册字符设备 (核心关联点!!!) // 只有到了这一步,APP 才能看到 /dev/xxx major = register_chrdev(0, "my_device", &my_fops); // C. 创建设备节点 // class_create(...); // device_create(...); return 0; } /* 3. remove 函数:卸载驱动或设备移除时调用 */ static int my_remove(struct platform_device *pdev) { // 注销字符设备 unregister_chrdev(major, "my_device"); return 0; } /* 4. 定义 Platform 驱动结构体 */ static const struct of_device_id my_match_table[] = { { .compatible = "100ask,led" }, // 这里的名字必须和设备树里的一样! { }, }; static struct platform_driver my_driver = { .probe = my_probe, // 匹配成功调这个 .remove = my_remove, // 移除时调这个 .driver = { .name = "my_led_driver", .of_match_table = my_match_table, // 指定匹配表 }, }; /* 5. 模块入口:只负责注册 Platform 驱动 */ static int __init my_driver_init(void) { // 向内核注册在这个 Platform 驱动 return platform_driver_register(&my_driver); } static void __exit my_driver_exit(void) { platform_driver_unregister(&my_driver); } module_init(my_driver_init); module_exit(my_driver_exit); module_license("GPL");

4. 图解流程

  1. insmod→ \rightarrow执行module_init
  2. platform_driver_register→ \rightarrow把驱动名字放入“相亲角”。
  3. Kernel Check→ \rightarrow发现设备树里也有个叫"100ask,led"的硬件。
  4. Match!→ \rightarrow触发my_probe函数。
  5. Inside Probe→ \rightarrow执行register_chrdev
  6. Result→ \rightarrow生成/dev/led,APP 可以使用了。

5. 常见疑惑解答

Q1: 我可以不用platform_driver_register,只写register_chrdev吗?

  • 可以。这就是所谓的“老式驱动”或“非设备树驱动”。
  • 后果:你必须在代码里硬编码寄存器物理地址(比如0x20200000)。这导致你的驱动只能在这个特定的板子上跑,换个板子(地址变了)就得改代码重新编译。
  • 现状:为了代码通用性,现在几乎都用 Platform 模式。

Q2: 我可以不用register_chrdev,只写platform_driver_register吗?

  • 不可以(除非你是做 LED 子系统、输入子系统这种高级开发)。
  • 如果你不注册字符设备,你就没有主设备号,没有/dev/xxx节点,APP 根本没办法通过文件操作来访问你的驱动。
  • platform_driver只是帮你管理硬件资源,它不负责给 APP 提供接口。

6. 总结

  • platform_driver_register:是管理层。负责让驱动程序和设备树里的硬件描述**“对上号”**。它让驱动更灵活、更通用。
  • register_chrdev:是业务层。负责实打实地生成用户接口
  • 关系:通常在platform_driverprobe函数中,去调用register_chrdev前者是壳,后者是核。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/3 7:09:32

diskinfo下载官网之外的选择:监控PyTorch训练磁盘IO性能

diskinfo下载官网之外的选择:监控PyTorch训练磁盘IO性能 在深度学习模型的训练过程中,GPU算力再强,也架不住数据“喂不进来”。你有没有遇到过这种情况:显卡风扇呼呼转,nvidia-smi 却显示 GPU 利用率长期徘徊在 10%~30…

作者头像 李华
网站建设 2026/9/3 3:34:55

小白勇做hot100

欢迎大佬指点 刚步入算法题也可以在评论区留下痕迹 成为我的第一位"股东",我们一起加油第一次面对算法题时,那种既兴奋又紧张的感觉,像极了翻开单词书第一页就撞见“Abandon”。明明还没开始,却仿佛被命运嘲弄。但这一次&#xff0…

作者头像 李华
网站建设 2026/8/29 4:32:51

Git worktree新建工作树并行开发PyTorch功能

Git Worktree 与 PyTorch-CUDA 容器化并行开发实践 在深度学习项目日益复杂的今天,AI 工程师经常面临这样的困境:一边是紧急的线上 bug 需要修复,另一边是新模型结构正在快速迭代;与此同时,数据加载性能优化也迫在眉睫…

作者头像 李华
网站建设 2026/9/3 3:34:49

校园二手商品交流平台python-vue

目录 已开发项目效果实现截图关于博主开发技术路线相关技术介绍核心代码参考示例结论源码lw获取/同行可拿货,招校园代理 :文章底部获取博主联系方式! 已开发项目效果实现截图 同行可拿货,招校园代理 ,本人源头供货商 校园二手商品交流平台python-vue …

作者头像 李华
网站建设 2026/9/4 3:19:00

Git tag打标签标记PyTorch里程碑版本

Git Tag 标记 PyTorch 里程碑版本:从代码到环境的全链路版本控制 在深度学习项目中,最让人头疼的往往不是模型结构设计或调参技巧,而是“我这边能跑,你那边报错”这类环境不一致问题。明明用的是同一个训练脚本,却因为…

作者头像 李华
网站建设 2026/9/3 22:00:29

企业软文推广的定心丸:如何精准锁定“包收录”媒体资源?

在当前数字营销领域,软文发稿已成为品牌建立信任、实现长效增长的重要方式之一。然而,不少企业会遇到这样的困扰:精心准备的内容发布后,在搜索引擎中却难以被找到,导致推广效果大打折扣,无法积累长期价值。…

作者头像 李华