积分 2102 最后登录 2024-4-19 精华 1 阅读权限 220 主题 288 UID 3081083 帖子 2708 PB币 90423 威望 169 贡献 0 技术 56 活跃 2785
这货不是澎湖冰洲
UID 3081083 帖子 2708 PB币 90423 贡献 0 技术 56 活跃 2785
板凳
发表于 2020-4-13 10:14:00
IP属地黑龙江
| 只看该作者
本帖最后由 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驱动上的疑点依旧很多。这些疑点,我将在下一节内容中继续讲述,敬请期待~
展开阅读全文​
附件:
你需要登录 才可以下载或查看附件。没有帐号?注册