- 积分
- 1925
- 最后登录
- 2021-3-7
- 精华
- 1
- 阅读权限
- 220
- 主题
- 269
- UID
- 3081083
- 帖子
- 2399
- PB币
- 32242
- 威望
- 160
- 贡献
- 0
- 技术
- 15
- 活跃
- 1903

嫉恶如仇,是非分明的冰境泽
- UID
- 3081083
- 帖子
- 2399
- PB币
- 32242
- 贡献
- 0
- 技术
- 15
- 活跃
- 1903
|
发表于 2020-4-13 10:14:00
|显示全部楼层
本帖最后由 penghubingzhou 于 2020-4-13 12:08 编辑
接下来,让我们开始给我们的项目添加代码进去。
首先打开helloworld.hpp文件,添加如下代码进去:
- #include <IOKit/IOService.h>
- #include <IOKit/IOLib.h>
- class Hello_World : public IOService{
- OSDeclareDefaultStructors(Hello_World);
- public:
- //初始化模块
- 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;
- };
复制代码
接下来,在helloworld.cpp 里 插入这些代码:
- #include "helloworld.hpp"
- //用C++ define关键字声明超类,从而使用父类函数
- #define super IOService
- OSDefineMetaClassAndStructors(Hello_World, IOService)
- //在头文件中定义函数的具体实现
- bool Hello_World::init(OSDictionary* dict){
- bool ret = super::init(dict);
- IOLog("驱动加载中");
- return ret;
- }
- void Hello_World::free(void) {
- IOLog("驱动正在释放");
- super::free();
- }
- IOService* Hello_World::probe(IOService* provider, SInt32* score) {
- IOService* myservice = super::probe(provider, score);
- IOLog("驱动正在匹配");
- return myservice;
- }
- bool Hello_World::start(IOService* provider) {
- bool ret = super::start(provider);
- IOLog("驱动正在启动");
- return ret;
- }
- void Hello_World::stop(IOService* provider) {
- IOLog("驱动正在停止");
- super::stop(provider);
- }
复制代码
做完这些,再打开info.plist,在IOKitPersonalities项目下,点击旁边加号,添加如下字典类型:
在OSBundleLibraries下面,添加如下字典内容:
这样,我们的驱动,就算构建好了。接下来,点击左上角的“播放”按钮(其实是编译,不过为了便于大家理解,我用了这个形象化的说法),等待显示“build successfully”之后,点击“Product”文件夹,右击“helloworld.kext”,点击“Show in Finder”,就会显示编译好的驱动文件:
将这个驱动拖拽到桌面上,接下来,我们将开始加载这个驱动。打开终端,输入以下命令:
- sudo -i
- chmod -Rf 755 /path/to/helloworld.kext
- chown -R root:wheel /path/to/helloworld.kext
- kextutil /path/to/helloworld.kext
复制代码
其中/path/to/helloworld.kext为你刚才拖拽的helloworld.kext路径。注意,在加载前,请先关闭系统的SIP保护,方法请在论坛内搜寻,这里不再重复。
如果加载完成,你会看到这个加载没有任何错误显示,并且等待终端返回提示符后,你可以再输入 kextstat | grep helloworld ,来证明驱动是否加载:
- kextstat | grep helloworld
- 165 0 0xffffff7f831d9000 0x4000 0x4000 as.phbz.helloworld (1) F3E8D1DB-74B8-332C-9E76-0FDC5C541BFD <4 3>
复制代码 如果有类似的返回输出,证明驱动成功加载。
接下来,我们运行这个命令,来让驱动卸载:
- kextunload /path/to/helloworld.kext
复制代码
卸载完成时,屏幕不会有任何输出,直接返回提示符。现在我们想知道,这个驱动究竟都干了些什么。让我们打开“控制台”app(系统自带)来看一下。打开“控制台”,在搜索里输入“kernel”进行检索,可以检索到这些信息:
这里面,输出了我们刚才在代码里写入的所有中文,它证明了我们的驱动从匹配到加载再到卸载的全过程。我们管驱动从加载到消亡叫做一个驱动的生命周期。这样的一个生命周期里,驱动将完成一系列的任务,驱动我们的各类硬件。
虽然我们已经成功让这个驱动加载了,可是,我们仍然有些问题没有解决:它的工作流程是什么?它的具体运行机制是什么?那些写的字典内容是什么?我们为什么要按照这么模块的结构来写?……环绕在这个helloworld驱动上的疑点依旧很多。这些疑点,我将在下一节内容中继续讲述,敬请期待~
|
附件: 你需要登录才可以下载或查看附件。没有帐号?注册
|