Chameleon

Chameleon Commit Details

Date:2010-05-22 21:48:59 (13 years 11 months ago)
Author:Evan Lojewski
Commit:158
Parents: 157
Message:Update kernel patch routine, works on 10.6.0/1 kernel now. Fixed usb loop, and temperarily disabled legacy_off code
Changes:
M/branches/meklort/i386/boot2/kernel_patcher.c
M/branches/meklort/i386/libsaio/usb.c
M/branches/meklort/CHANGES

File differences

branches/meklort/CHANGES
1
12
23
34
- Fixed lapic_init patch. Fixed _cpuid_set_info patch to work on the 10.6.0 / 10.6.1 kernel (patches cpumodel)
- Added USB Legacy Off patch. Modified to run immediately *before* the kernel is executed, that
way no files need to be loaded after the usb device is reset.
- Backup original dsdt to /dsdt/originaldsdt in the IORegistery
branches/meklort/i386/libsaio/usb.c
6464
6565
6666
67
68
69
70
71
72
73
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
7491
7592
7693
......
7895
7996
8097
81
82
83
84
98
99
100
101
85102
86103
104
87105
88106
89107
......
92110
93111
94112
95
113
96114
97115
98116
int usb_loop()
{
bool fix_ehci, fix_uhci, fix_usb, fix_legacy;
fix_ehci = fix_uhci = fix_usb = fix_legacy;
if (getBoolForKey(kUSBBusFix, &fix_usb, &bootInfo->bootConfig) && fix_usb) {
fix_ehci = fix_uhci = fix_legacy = true;
} else {
getBoolForKey(kEHCIacquire, &fix_ehci, &bootInfo->bootConfig);
getBoolForKey(kUHCIreset, &fix_uhci, &bootInfo->bootConfig);
getBoolForKey(kLegacyOff, &fix_legacy, &bootInfo->bootConfig);
fix_ehci = fix_uhci = fix_usb = fix_legacy = true;
if (!getBoolForKey(kUSBBusFix, &fix_usb, &bootInfo->bootConfig))
{
fix_ehci = fix_uhci = fix_legacy = true;// Enable all if none set
}
else
{
if(!getBoolForKey(kEHCIacquire, &fix_ehci, &bootInfo->bootConfig))
{
fix_ehci = false;
}
if(!getBoolForKey(kUHCIreset, &fix_uhci, &bootInfo->bootConfig))
{
fix_uhci = false;
}
if(!getBoolForKey(kLegacyOff, &fix_legacy, &bootInfo->bootConfig))
{
fix_legacy = false;
}
}
struct pciList* current = usbList;
while(current)
{
uhci_reset(current->pciDev);
ehci_acquire(current->pciDev);
legacy_off(current->pciDev);
if(fix_uhci) uhci_reset(current->pciDev);
if(fix_ehci) ehci_acquire(current->pciDev);
//if(fix_legacy) legacy_off(current->pciDev);
current = current->next;
}
return 1;
}
// Set usb legacy off modification by Signal64
// NOTE: This *must* be called after the last file is loaded from the drive in the event that we are booting form usb.
// NOTE2: This should be called after any getc() call. (aka, after the Wait=y keyworkd is used)
// AKA: Make this run immediatly before the kernel is calles
// AKA: Make this run immediatly before the kernel is called
uint32_tcapaddr, opaddr;
uint8_teecp;
uint32_tusbcmd, usbsts, usbintr;
branches/meklort/i386/boot2/kernel_patcher.c
8080
8181
8282
83
83
8484
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
85
86
87
88
89
90
91
92
93
11294
11395
114
96
97
98
99
115100
101
102
103
104
105
106
107
116108
117109
118110
119111
120112
121
113
122114
123115
124116
......
259251
260252
261253
262
254
263255
264256
265257
......
291283
292284
293285
286
287
288
289
290
291
292
293
294294
295
295296
296297
297298
298
299
299300
300301
301302
302303
304
303305
304306
305
306
307
308
307309
310
308311
309312
310313
......
345348
346349
347350
348
351
349352
350353
351354
352355
353356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
354413
355414
356
415
357416
358
359
360
361
362
363
364
365
417
418
366419
367420
368421
......
403456
404457
405458
406
459
407460
408461
409462
410463
411464
412
465
413466
414467
415468
......
431484
432485
433486
434
487
488
489
435490
436491
437492
patch_lapic_init(kernelData);
}
switch( Platform.CPU.Vendor )
switch(Platform.CPU.Model)
{
case 0x06:
switch(Platform.CPU.Model)
{
// Known good CPU's, no reason to patch kernel
case 13:
case CPUID_MODEL_YONAH:
case CPUID_MODEL_MEROM:
case CPUID_MODEL_PENRYN:
case CPUID_MODEL_NEHALEM:
case CPUID_MODEL_FIELDS:
case CPUID_MODEL_DALES:
case CPUID_MODEL_NEHALEM_EX:
break;
// Known unsuported CPU's
case CPUID_MODEL_ATOM:
// TODO: Impersonate CPU based on user selection
patch_cpuid_set_info(kernelData, CPUFAMILY_INTEL_PENRYN, CPUID_MODEL_PENRYN);// Impersonate Penryn CPU
break;
// Unknown CPU's
default:
// TODO: Impersonate CPU based on user selection
patch_cpuid_set_info(kernelData, 0, 0);// Remove Panic Call
break;
}
// Known good CPU's, no reason to patch kernel
case 13:
case CPUID_MODEL_YONAH:
case CPUID_MODEL_MEROM:
case CPUID_MODEL_PENRYN:
case CPUID_MODEL_NEHALEM:
case CPUID_MODEL_FIELDS:
case CPUID_MODEL_DALES:
case CPUID_MODEL_NEHALEM_EX:
break;
default:
// Known unsuported CPU's
case CPUID_MODEL_ATOM:
// TODO: Impersonate CPU based on user selection
patch_cpuid_set_info(kernelData, CPUFAMILY_INTEL_PENRYN, CPUID_MODEL_PENRYN);// Impersonate Penryn CPU
break;
// Unknown CPU's
default:
// TODO: Impersonate CPU based on user selection
patch_cpuid_set_info(kernelData, 0, 0);// Remove Panic Call
break;
}
}
/**
**This functions located the kernelSymbols[i] symbols in the macho header.
**This functions located the kernelSymbols[i] symbols in the mach-o header.
**as well as determines the start of the __TEXT segment and __TEXT,__text sections
**/
int locate_symbols(void* kernelData)
** Locate the fisrt instance of _panic inside of _cpuid_set_info, and either remove it
** Or replace it so that the cpuid is set to a valid value.
**/
void patch_cpuid_set_info(void* kernelData, UInt32 impersonateFamily, UInt8 inpersonateModel)
void patch_cpuid_set_info(void* kernelData, UInt32 impersonateFamily, UInt8 impersonateModel)
{
UInt8* bytes = (UInt8*)kernelData;
UInt32 patchLocation = (kernelSymbolAddresses[SYMBOL_CPUID_SET_INFO] - textAddress + textSection);
patchLocation--;
// Remove panic call, just in case the following patch routines fail
bytes[patchLocation + 0] = 0x90;
bytes[patchLocation + 1] = 0x90;
bytes[patchLocation + 2] = 0x90;
bytes[patchLocation + 3] = 0x90;
bytes[patchLocation + 4] = 0x90;
// Locate the jump call, so that 10 bytes can be reclamed.
// NOTE: This will *NOT* be located on pre 10.6.2 kernels
jumpLocation = patchLocation - 15;
while((bytes[jumpLocation - 1] != 0x77 ||
bytes[jumpLocation] != (patchLocation - jumpLocation - -8)) &&
(patchLocation - jumpLocation) < 0xEF)
(patchLocation - jumpLocation) < 0xF0)
{
jumpLocation--;
}
printf("Mode: %d Family %d P - JMP: 0x%X\n", impersonateModel, impersonateFamily, patchLocation - jumpLocation);
// If found... AND we want to impersonate a specific cpumodel / family...
if(impersonateFamily &&
inpersonateModel &&
((patchLocation - jumpLocation) < 0xEF))
impersonateModel &&
((patchLocation - jumpLocation) < 0xF0))
{
printf("Patching CPUID to %d.%d\n", impersonateFamily, impersonateModel);
bytes[jumpLocation] -= 10;// sizeof(movl$0x6b5a4cd2,0x00872eb4) = 10bytes
// Note: I could have just copied the 8bit cpuid_model in and saved about 4 bytes
// so if this function need a different patch it's still possible. Also, about ten bytes previous can be freed.
bytes[patchLocation + 1] = inpersonateModel;// cpuid_model
bytes[patchLocation + 1] = impersonateModel;// cpuid_model
bytes[patchLocation + 2] = 0x01;// cpuid_extmodel
bytes[patchLocation + 3] = 0x00;// cpuid_extfamily
bytes[patchLocation + 4] = 0x02;// cpuid_stepping
}
else if(impersonateFamily && impersonateModel)
{
// pre 10.6.2 kernel
// Locate the jump to directly *after* the panic call,
jumpLocation = patchLocation - 4;
while((bytes[jumpLocation - 1] != 0x77 ||
bytes[jumpLocation] != (patchLocation - jumpLocation + 4)) &&
(patchLocation - jumpLocation) < 0x20)
{
jumpLocation--;
}
// NOTE above isn't needed (I was going to use it, but I'm not, so instead,
// I'll just leave it to verify the binary stucture.
// NOTE: the cpumodel_familt data is not set in _cpuid_set_info
// so we don't need to set it here, I'll get set later based on the model
// we set now.
if((patchLocation - jumpLocation) < 0x20)
{
UInt32 cpuid_model_addr =(bytes[patchLocation - 14] << 0 |
bytes[patchLocation - 13] << 8 |
bytes[patchLocation - 12] << 16 |
bytes[patchLocation - 11] << 24);
// Remove jump
bytes[patchLocation - 9] = 0x90;/// Was a jump if supported cpu
bytes[patchLocation - 8] = 0x90;// jumped past the panic call, we want to override the panic
bytes[patchLocation - 7] = 0x90;
bytes[patchLocation - 6] = 0x90;
bytes[patchLocation - 5] = 0xC7;
bytes[patchLocation - 4] = 0x05;
bytes[patchLocation - 3] = (cpuid_model_addr & 0x000000FF) >> 0;
bytes[patchLocation - 2] = (cpuid_model_addr & 0x0000FF00) >> 8;
bytes[patchLocation - 1] = (cpuid_model_addr & 0x00FF0000) >> 16;
bytes[patchLocation - 0] = (cpuid_model_addr & 0xFF000000) >> 24;
// Note: I could have just copied the 8bit cpuid_model in and saved about 4 bytes
// so if this function need a different patch it's still possible. Also, about ten bytes previous can be freed.
bytes[patchLocation + 1] = impersonateModel;// cpuid_model
bytes[patchLocation + 2] = 0x01;// cpuid_extmodel
bytes[patchLocation + 3] = 0x00;// cpuid_extfamily
bytes[patchLocation + 4] = 0x02;// cpuid_stepping
patchLocation = jumpLocation;
// We now have 14 bytes available for a patch
}
else
{
// Patching failed, using NOP replacement done initialy
}
}
else
{
// Either We were unable to change the jump call due to the funciton's sctructure
// Either We were unable to change the jump call due to the function's sctructure
// changing, or the user did not request a patch. As such, resort to just
// removing the panic call. Note that the IntelCPUPM kext may still panic
// due to the cpu's Model ID not being patched
bytes[patchLocation + 0] = 0x90;
bytes[patchLocation + 1] = 0x90;
bytes[patchLocation + 2] = 0x90;
bytes[patchLocation + 3] = 0x90;
bytes[patchLocation + 4] = 0x90;
// removing the panic call (using NOP replacement above). Note that the
// IntelCPUPM kext may still panic due to the cpu's Model ID not being patched
}
}
if(kernelSymbolAddresses[SYMBOL_LAPIC_INIT] == 0)
{
printf("Unable to locate _cpuid_set_info\n");
printf("Unable to locate %s\n", SYMBOL_LAPIC_INIT_STRING);
return;
}
if(kernelSymbolAddresses[SYMBOL_PANIC] == 0)
{
printf("Unable to locate _panic\n");
printf("Unable to locate %s\n", SYMBOL_PANIC_STRING);
return;
}
patchLocation++;
panicIndex++;
}
bytes[--patchLocation] = 0x90;
patchLocation--;// Remove extra increment from the < 3 while loop
bytes[--patchLocation] = 0x90;
bytes[++patchLocation] = 0x90;
bytes[++patchLocation] = 0x90;
bytes[++patchLocation] = 0x90;

Archive Download the corresponding diff file

Revision: 158