Skip to content

Commit 0ccd95e

Browse files
authored
Rewrite without Lilu (#5)
2 parents 8fdaa35 + cef5fb5 commit 0ccd95e

File tree

9 files changed

+312
-375
lines changed

9 files changed

+312
-375
lines changed

Changelog.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
11
Innie Changelog
22
===============
33
#### v1.2.1
4-
- Initial release.
4+
- Initial release
5+
6+
#### v1.3.0
7+
- Improve detection logic
8+
- Rewrite to use I/O Kit startup

Innie.xcodeproj/project.pbxproj

Lines changed: 72 additions & 161 deletions
Large diffs are not rendered by default.

Innie/Info.plist

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@
1515
<key>CFBundlePackageType</key>
1616
<string>KEXT</string>
1717
<key>CFBundleShortVersionString</key>
18-
<string>$(MODULE_VERSION)</string>
18+
<string>$(MARKETING_VERSION)</string>
1919
<key>CFBundleVersion</key>
20-
<string>$(MODULE_VERSION)</string>
20+
<string>$(CURRENT_PROJECT_VERSION)</string>
2121
<key>IOKitPersonalities</key>
2222
<dict>
2323
<key>com.cdf.Innie</key>
@@ -36,24 +36,12 @@
3636
</dict>
3737
<key>NSHumanReadableCopyright</key>
3838
<string>Copyright © 2020 cdf. All rights reserved.</string>
39-
<key>OSBundleCompatibleVersion</key>
40-
<string>1.0</string>
4139
<key>OSBundleLibraries</key>
4240
<dict>
43-
<key>as.vit9696.Lilu</key>
44-
<string>1.2.0</string>
45-
<key>com.apple.kpi.bsd</key>
46-
<string>12.0.0</string>
47-
<key>com.apple.kpi.dsep</key>
48-
<string>12.0.0</string>
4941
<key>com.apple.kpi.iokit</key>
50-
<string>12.0.0</string>
42+
<string>9.0.0</string>
5143
<key>com.apple.kpi.libkern</key>
52-
<string>12.0.0</string>
53-
<key>com.apple.kpi.mach</key>
54-
<string>12.0.0</string>
55-
<key>com.apple.kpi.unsupported</key>
56-
<string>12.0.0</string>
44+
<string>9.0.0</string>
5745
</dict>
5846
<key>OSBundleRequired</key>
5947
<string>Root</string>

Innie/Innie.cpp

Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
//
2+
// Innie.cpp
3+
// Innie
4+
//
5+
// Copyright © 2021 cdf. All rights reserved.
6+
//
7+
8+
#include <IOKit/IOLib.h>
9+
#include <IOKit/IORegistryEntry.h>
10+
#include <IOKit/IODeviceTreeSupport.h>
11+
12+
#include "Innie.hpp"
13+
14+
#define super IOService
15+
16+
OSDefineMetaClassAndStructors(Innie, IOService)
17+
18+
bool Innie::init(OSDictionary *dict) {
19+
if (!super::init())
20+
return false;
21+
22+
return true;
23+
}
24+
25+
void Innie::free(void) {
26+
super::free();
27+
}
28+
29+
IOService *Innie::probe(IOService *provider, SInt32 *score) {
30+
if (super::probe(provider, score)==0)
31+
return 0;
32+
33+
return this;
34+
}
35+
36+
bool Innie::start(IOService *provider) {
37+
DBGLOG("starting\n");
38+
39+
if (!super::start(provider))
40+
return false;
41+
42+
processRoot();
43+
super::registerService();
44+
return true;
45+
}
46+
47+
void Innie::stop(IOService *provider) {
48+
super::stop(provider);
49+
}
50+
51+
void Innie::processRoot() {
52+
if (auto entry = IORegistryEntry::fromPath("/AppleACPIPlatformExpert", gIOServicePlane)) {
53+
IORegistryEntry *pciRoot = nullptr;
54+
size_t repeat = 0;
55+
bool found = false;
56+
57+
do {
58+
if (auto iterator = entry->getChildIterator(gIOServicePlane)) {
59+
while ((pciRoot = OSDynamicCast(IORegistryEntry, iterator->getNextObject())) != nullptr) {
60+
const char *name = pciRoot->getName();
61+
if (name && !strncmp("PC", name, 2)) {
62+
found = true;
63+
DBGLOG("found PCI root %s", pciRoot->getName());
64+
while (OSDynamicCast(OSBoolean, pciRoot->getProperty("IOPCIConfigured")) != kOSBooleanTrue) {
65+
DBGLOG("waiting for PCI root to be configured");
66+
IOSleep(1);
67+
}
68+
recurseBridge(pciRoot);
69+
}
70+
}
71+
iterator->release();
72+
}
73+
} while (repeat++ < 0x10000000 && !found);
74+
75+
DBGLOG("found PCI root in %lu attempts", repeat);
76+
entry->release();
77+
}
78+
}
79+
80+
void Innie::recurseBridge(IORegistryEntry *entry) {
81+
if (auto iterator = entry->getChildIterator(gIODTPlane)) {
82+
IORegistryEntry *childEntry = nullptr;
83+
84+
// Go through child entries of bridge, finding every other bridge and every SATA and NVMe device
85+
while ((childEntry = OSDynamicCast(IORegistryEntry, iterator->getNextObject())) != nullptr) {
86+
uint32_t code = 0;
87+
if (auto class_code = childEntry->getProperty("class-code")) {
88+
if (auto codeData = OSDynamicCast(OSData, class_code)) {
89+
code=*(uint32_t*)codeData->getBytesNoCopy();
90+
if (code == classCode::SATADevice || code == classCode::NVMeDevice){
91+
DBGLOG("found device %s", childEntry->getName());
92+
if (auto built_in = childEntry->getProperty("built-in")) {
93+
DBGLOG("device is already built-in");
94+
} else {
95+
internalizeDevice(childEntry);
96+
}
97+
break;
98+
}
99+
if (code == classCode::PCIBridge) {
100+
DBGLOG("found bridge %s", childEntry->getName());
101+
while (OSDynamicCast(OSBoolean, childEntry->getProperty("IOPCIResourced")) != kOSBooleanTrue) {
102+
DBGLOG("waiting for bridge to be resourced");
103+
IOSleep(1);
104+
}
105+
recurseBridge(childEntry);
106+
}
107+
}
108+
}
109+
}
110+
iterator->release();
111+
}
112+
}
113+
114+
void Innie::internalizeDevice(IORegistryEntry *entry) {
115+
DBGLOG("adding built-in property");
116+
117+
setBuiltIn(entry);
118+
119+
// Stop if entry is not yet resourced
120+
if (OSDynamicCast(OSBoolean, entry->getProperty("IOPCIResourced")) != kOSBooleanTrue)
121+
return;
122+
123+
// Otherwise update existing properties
124+
if (auto driverIterator = IORegistryIterator::iterateOver(entry, gIOServicePlane, kIORegistryIterateRecursively)) {
125+
IORegistryEntry *driverEntry = nullptr;
126+
while ((driverEntry = OSDynamicCast(IORegistryEntry, driverIterator->getNextObject())) != nullptr) {
127+
DBGLOG("updating other properties");
128+
updateOtherProperties(driverEntry);
129+
}
130+
driverIterator->release();
131+
}
132+
}
133+
134+
void Innie::setBuiltIn(IORegistryEntry *entry) {
135+
if (entry) {
136+
char dummy = '\0';
137+
entry->setProperty("built-in", &dummy, 1);
138+
}
139+
}
140+
141+
void Innie::updateOtherProperties(IORegistryEntry *entry) {
142+
if (entry) {
143+
OSString *internal = OSString::withCString("Internal");
144+
OSString *internalIcon = OSString::withCString("Internal.icns");
145+
146+
// Update icon
147+
if (auto icon = entry->getProperty("IOMediaIcon")) {
148+
if (auto dict = OSDynamicCast(OSDictionary, icon)) {
149+
dict = OSDictionary::withDictionary(dict);
150+
if (auto res = dict->getObject("IOBundleResourceFile")) {
151+
dict->setObject("IOBundleResourceFile", internalIcon);
152+
entry->setProperty("IOMediaIcon", dict);
153+
}
154+
dict->release();
155+
}
156+
}
157+
158+
// Update interconnect
159+
if (auto loc = entry->getProperty("Physical Interconnect Location")) {
160+
if (auto prop = OSDynamicCast(OSString, loc)) {
161+
entry->setProperty("Physical Interconnect Location", internal);
162+
}
163+
}
164+
165+
// Update update protocol characteristics
166+
if (auto proto = entry->getProperty("Protocol Characteristics")) {
167+
if (auto dict = OSDynamicCast(OSDictionary, proto)) {
168+
dict = OSDictionary::withDictionary(dict);
169+
if (auto loc = dict->getObject("Physical Interconnect Location")) {
170+
if (auto prop = OSDynamicCast(OSString, loc)) {
171+
dict->setObject("Physical Interconnect Location", internal);
172+
entry->setProperty("Protocol Characteristics", dict);
173+
}
174+
}
175+
dict->release();
176+
}
177+
}
178+
internal->release();
179+
internalIcon->release();
180+
}
181+
}

Innie/Innie.hpp

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
//
2+
// Innie.hpp
3+
// Innie
4+
//
5+
// Copyright © 2021 cdf. All rights reserved.
6+
//
7+
8+
#ifndef Innie_hpp
9+
#define Innie_hpp
10+
11+
#include <IOKit/IOService.h>
12+
13+
class Innie : public IOService {
14+
OSDeclareDefaultStructors(Innie)
15+
16+
public:
17+
virtual bool init(OSDictionary *dictionary = NULL) override;
18+
virtual void free(void) override;
19+
virtual IOService *probe(IOService *provider, SInt32 *score) override;
20+
virtual void stop(IOService *provider) override;
21+
virtual bool start(IOService *provider) override;
22+
23+
private:
24+
void processRoot();
25+
void recurseBridge(IORegistryEntry *entry);
26+
void internalizeDevice(IORegistryEntry *entry);
27+
void setBuiltIn(IORegistryEntry *entry);
28+
void updateOtherProperties(IORegistryEntry *entry);
29+
30+
struct classCode {
31+
enum : uint32_t {
32+
PCIBridge = 0x060400,
33+
SATADevice = 0x010601,
34+
NVMeDevice = 0x010802,
35+
};
36+
};
37+
};
38+
39+
#ifdef DEBUG
40+
#define DBGLOG(args...) do { IOLog("Innie: " args); } while (0)
41+
#else
42+
#define DBGLOG(args...) do { } while (0)
43+
#endif
44+
45+
#endif /* Innie */

Innie/kern_innie.cpp

Lines changed: 0 additions & 114 deletions
This file was deleted.

0 commit comments

Comments
 (0)