操作系统实战 45 讲
彭东
网名 LMOS,Intel 傲腾项目关键开发者
65203 人已学习
新⼈⾸单¥68
登录后,你可以任选4讲全文学习
课程目录
已完结/共 60 讲
尝尝鲜:从一个Hello到另一个Hello (2讲)
特别放送 (1讲)
操作系统实战 45 讲
15
15
1.0x
00:00/00:00
登录|注册

29 | 部门建立:如何在内核中注册设备?

安装中断回调函数
向内核注册设备
设备与驱动的联系
标准流程
调用驱动程序入口函数
准备驱动描述符指针
初始化驱动程序表
定义函数指针数组
将driver_t结构的实例变量挂载到设备表中
一个驱动程序入口函数的例子
调用驱动程序入口函数
驱动程序表的设计
驱动程序向操作系统内核注册鼠标设备
操作系统加载驱动程序
调用操作系统内核相关的服务,查找USB鼠标对应的驱动程序
USB总线驱动的中断处理程序执行
操作系统收到中断
驱动加入内核
运行驱动程序
驱动程序表
设备的注册流程
部门建立:如何在内核中注册设备?

该思维导图由 AI 生成,仅供参考

你好,我是 LMOS。
在上节课里,我们对设备进行了分类,建立了设备与驱动的数据结构,同时也规定了一个驱动程序应该提供哪些标准操作方法,供操作系统内核调用。这相当于设计了行政部门的规章制度,一个部门叫什么,应该干什么,这些就确定好了。
今天我们来继续探索部门的建立,也就是设备在内核中是如何注册的。我们先从全局了解一下设备的注册流程,然后了解怎么加载驱动,最后探索怎么让驱动建立一个设备,并在内核中注册。让我们正式开始今天的学习吧!
这节课配套代码,你可以从这里下载。

设备的注册流程

你是否想象过,你在电脑上插入一个 USB 鼠标时,操作系统会作出怎样的反应呢?
我来简单作个描述,这个过程可以分成这样五步。
1. 操作系统会收到一个中断。
2.USB 总线驱动的中断处理程序会执行。
3. 调用操作系统内核相关的服务,查找 USB 鼠标对应的驱动程序。
4. 操作系统加载驱动程序。
5. 驱动程序开始执行,向操作系统内核注册一个鼠标设备。这就是一般操作系统加载驱动的粗略过程。对于安装在主板上的设备,操作系统会枚举设备信息,然后加载驱动程序,让驱动程序创建并注册相应的设备。当然,你还可以手动加载驱动程序。
为了简单起见,我们的 Cosmos 不会这样复杂,暂时也不支持设备热拨插功能。我们让 Cosmos 自动加载驱动,在驱动中向 Cosmos 注册相应的设备,这样就可以大大降低问题的复杂度,我们先从简单的做起嘛,相信你明白了原理之后,还可以自行迭代。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

本文深入介绍了在操作系统内核中注册设备的过程,包括设备的注册流程、驱动程序表的设计和初始化、驱动程序入口函数的运行过程、设备与驱动的联系等。文章通过具体的代码和流程图,深入浅出地介绍了在操作系统内核中注册设备的过程,适合读者快速了解并掌握相关技术特点。文章重点强调了操作系统内核与驱动程序的交互过程,以及为驱动程序开发者提供的一系列接口,构成了一个最简化的驱动模型。整体而言,本文对操作系统内核中注册设备的过程进行了详尽的解析,为读者提供了深入的技术理解和应用指导。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《操作系统实战 45 讲》
新⼈⾸单¥68
立即购买
登录 后留言

全部留言(6)

  • 最新
  • 精选
  • neohope
    置顶
    一、数据结构 有一个全局的drventyexit_t数组变量osdrvetytabl,用于保存全部驱动程序入口函数 主要是为了便于理解,通过全局数组方式枚举并加载驱动,不需要涉及动态加载内核模块的相关内容 二、初始化 init_krl->init_krldriver 遍历驱动程序表中的每个驱动程序入口,并把它作为参数传给 krlrun_driverentry 函数 在krlrun_driverentry函数中 ->new_driver_dsc->driver_t_init,初始化驱动结构,驱动处理函数默认指向drv_defalt_func ->drventry,调用驱动入口函数 ->krldriver_add_system只需要将驱动加入设备表的驱动链表就好了 其中,在驱动入口函数drventry中【systick_entry为例】: ->建立设备描述符结构 ->将驱动程序的功能函数指针,设置到driver_t结构中的drv_dipfun数组中 ->将设备挂载到驱动中 ->调用krlnew_device向内核注册设备 ->->确认没有相同设备ID,注册到对应设备类型的列表以及全局设备列表 ->调用krlnew_devhandle->krladd_irqhandle,安装中断回调函数systick_handle ->->获取设备中断phyiline对应的中断异常描述符intfltdsc_t结构中 ->->新建一个intserdsc_t结构体 ->->初始化结构体,并设置好回调函数 ->->将新的intserdsc_t结构体挂载到对应的intfltdsc_t结构中 ->->也就是把驱动程序的中断处理回到函数,加入到了对应中断处理回调函数链表中 ->初始化物理设备 ->启用中断

    作者回复: 老哥 总结的很好

    2021-07-19
    6
  • pedro
    想复杂了,应该可以这样实现,全局定义一个 device_id =0,获取id的时候返回该值,然后++,注意加锁。 早上看的时候犯迷糊了😂

    作者回复: 哈哈

    2021-07-14
    3
  • O俊
    内核会调用驱动的接口,如果驱动做死循环不返回内核咋办。

    作者回复: 可以使用看门狗定时器来解决

    2021-09-23
    1
  • pedro
    uint_t device_id(device_t *devp) { return devp->dev_intlnenr }

    作者回复: 这不行哦

    2021-07-14
    2
    1
  • 艾恩凝
    打卡,

    编辑回复: 速度很快嘛,加油加油~

    2022-05-08
  • Fan
    代码没看懂,看懂的大致的流程。😂

    作者回复: 加油 哈哈

    2021-08-03
收起评论
显示
设置
留言
6
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部