- 积分
- 2102
- 最后登录
- 2024-3-28
- 精华
- 1
- 阅读权限
- 220
- 主题
- 288
- UID
- 3081083
- 帖子
- 2708
- PB币
- 88423
- 威望
- 169
- 贡献
- 0
- 技术
- 56
- 活跃
- 2772
嫉恶如仇,是非分明的冰境泽
- UID
- 3081083
- 帖子
- 2708
- PB币
- 88423
- 贡献
- 0
- 技术
- 56
- 活跃
- 2772
|
发表于 2020-4-13 12:27:51
IP属地黑龙江
|显示全部楼层
本帖最后由 penghubingzhou 于 2020-4-14 14:23 编辑
大家好,我是澎湖冰洲。上篇帖子写到了我们的第一个IOKit驱动helloworld。不知道试验的各位有没有成功加载呢?反正我是成功了~上一节也留下来了一些疑问,这节我们来一一解决它们。
首先是第一个问题,我们的驱动究竟做了什么。从控制台的输出看,我们似乎是只输出了几个简单的信息,并没有做什么啊。实际上,驱动做的事情,要比我们想象的,复杂得多得多得多。下面,让我们分析上面教程所写的代码,进行逐行的分析。
首先先看helloworld.hpp。学过c++/c的同学应该清楚,hpp/h文件,也叫头文件(header file),是定义一个程序基础函数的地方。通过头文件,可以实现多个c/cpp文件之间的功能以及数据共享。这里,我们的程序只有这一个头文件。看第一二行代码:
- #include <IOKit/IOService.h>
- #include <IOKit/IOLib.h>
复制代码
这两个头文件,是编写IOKit的基础头文件,在我们编写驱动时,需要引入相关的文件,才能获得IOKit框架支持。
在引入之后,我们声明了一个类(class),它叫Hello_World, 是一个继承自IOService类(IOService本质是一个OSMetaClass的子类,有关OSMetaClass各类特性我将在后面的章节一一讲述)的子类。而这个Hello_World类,最终也将对应到IORegistry(IO注册表,可以用IORegistryExplorer软件查看,经常折腾黑果的人,对这个应该不会很陌生吧)的一个条目,也就是我们所写的驱动。
- class Hello_World : public IOService{
- OSDeclareDefaultStructors(Hello_World);
-
- ..............
- };
复制代码
紧跟这个类声明的,是一个构造器与析构器声明。在c++里,一个类是需要一个构造器以及一个析构器的,这个构造器承担了这个类的入口模块功能,而析构器则承担出口功能。我们这里,使用的是IOKit给我们提供的默认构造器,它将为我们的Hello_World类提供一个默认的系统构造器。(注意:构造器声明必须紧跟在类声明的下一行)那么,对于一个OSMetaClass的子类而言,它应该按照怎么一个流程执行呢?按照IOKit的文档说明,我们可以了解到它的执行流程遵照这样一个顺序:
按照图中的顺序,在一个驱动的生命周期里,一个OSMetaClass的子类会执行这么多的函数。我们不难发现,除了probe()函数以外,它们都是成对出现的,声明了一个,就必然会声明另一个。其中,我们必须会写的成对函数是init()与free(),以及start()与stop()。而probe()函数虽然不成对出现,但也是必要的函数。所以,我们需要在我们这个驱动里,声明并实现相应的函数。
- ...
- virtual bool init(OSDictionary* dict) override;
-
- virtual void free(void) override;
-
- virtual IOService* probe(IOService* provider, SInt32* score) override;
-
- virtual bool start(IOService* provider) override;
-
- virtual void stop(IOService* provider) override;
复制代码
注意,我们对相关函数的声明,要与父类(也就是IOService)相应的函数构造一致,并且要加上override关键字,不能出现偏差的情况。这是因为,我们声明的这些函数,是对父类函数的重载(面向对象概念,指继承父类的函数并且对其进行重写)。
到这里,我们的头文件就分析完了。接下来我们转入cpp文件,看下它的代码实现。
|
附件: 你需要登录才可以下载或查看附件。没有帐号?注册
-
4
查看全部评分
-
|