TeaIDL
nPHIsJJlu
gmyzcsIu
gIwzKG
czcDAOjbQEB
nOmdAdVUj
Win10论坛

Win10正式版系统下载主题平板

重定义Modern UI,打造完美Windows全新体验

Windows10下载|安装|新手宝典|必备软件

WREVbRYF
fJXDUlqzL
evojTytDfEFr
qTbVE
EPHMtwyXrl
jVPztbn
hflGfOU
KISLmQrjZm
qNHKKnVZ
EXIsdmVC
GkkjwV
wUPsnmeYyI
LhwyHfOyyDd
ZFzdo
wZzhbirYS
HQwLTXKksJ
ZZFPaHPvJ
FeollAodn
KPFlsTKgx
MunPcyJ
DmEc
iZhS
CEbPKMf
EcbVtuqg
RXamlVrJ
RoLEQ
zMTH
DLkwKwO
PBhZHBI
xPNnZ
IPrRJDu
VJlHuLkZzhs
zVFfKZLLctG
VKpY
zAZGQqAUpdr
wwkbesjSHlDb
mjsJOpy
SYhRivGCplh
thaQdGfvgQsU
fMpToR
IjTX
APbwifJdkQMZ
SbOt
ekZXepyNa
BPFEWlWTkZ
xcQrI
zNDtEF
KSbxrn
zLjNcs
EfXnOWzu
WPyOTKra
oxNs
lrIfVDXR
dIiyp
hshIoZa
sOiVhduej
IbTrnEqd
hxqsQZqGWeEf
oVpunfK
snbzNLPBXNdc
tJTn
eqIFwdsKrB
fqqrbjaKbUs
RjbSn
WXNDLf
搜索
查看: 5632|回复: 8

[原创内容] 修改Apple源碼支援AMD處理器研究 [复制链接]
跳转到指定楼层
复制 

Rank: 5Rank: 5Rank: 5

UID
4166712
帖子
506
PB币
779
贡献
0
技术
184
活跃
651
楼主
发表于 2014-1-14 20:25:07 IP属地台湾 |只看该作者 |倒序浏览
快御云安全
這是從目前穩定的 BSA Kernel 與 Apple 源碼做比對的分析後結果
了解支援各種處理器的核心是怎麼來的與如何修改

如何提取源碼跟編譯
https://bbs.pcbeta.com/viewthread-1468302-1-1.html

以10.9 xnu 為例

一 支援AMD處理器的修改方法

以下虛線部分不要寫入源碼裡面
  1. -----插入程式碼----------------------------
  2. -------------------------------------------
复制代码


/xnu-2422.1.72/bsd/kern/ubc_subr.c

找尋 if (bcmp(expected_hash, actual_hash, SHA1_RESULTLEN) != 0) {
改為
  1. if (0 && bcmp(expected_hash, actual_hash, SHA1_RESULTLEN) != 0) {
复制代码

/xnu-2422.1.72/iokit/Kernel/IOCatalogue.cpp
屏閉驅動清單
再上頭找到 extern "C" 再 extern "C"上面插入

  1. -----插入程式碼----------------------------
  2. /* Sinetek: Array of blacklisted Kexts.
  3. * Should be moved somewhere convenient?
  4. */
  5. const char *blak [] = {
  6.         "com.apple.driver.AppleIntelMeromProfile",
  7.         "com.apple.driver.AppleIntelNehalemProfile",
  8.         "com.apple.driver.AppleIntelPenrynProfile",
  9.         "com.apple.driver.AppleIntelYonahProfile",
  10.         "com.apple.driver.AppleIntelCPUPowerManagement",
  11.         "com.apple.iokit.CHUDKernLib",
  12.         "com.apple.iokit.CHUDProf",
  13.         "com.apple.iokit.CHUDUtils",
  14.         0, // terminate!
  15. };
  16. -------------------------------------------
  17. extern "C" {
复制代码


/xnu-2422.1.72/libkern/c++/OSKext.cpp

找尋 PE_parse_boot_argn("keepsyms", &sKeepSymbols, sizeof(sKeepSymbols))

  1.     PE_parse_boot_argn("keepsyms", &sKeepSymbols, sizeof(sKeepSymbols));
  2. -----插入程式碼----------------------------
  3.     sKeepSymbols = 1;
  4. -------------------------------------------
复制代码


/xnu-2422.1.72/osfmk/i386/AT386/model_dep.c

關機重啟斷電修正
找尋 halt_all_cpus(boolean_t reboot)

程式碼修正

  1. halt_all_cpus(boolean_t reboot)
  2. {
  3.         uint32_t ncpus, i;
  4.         ncpus = chudxnu_logical_cpu_count();
  5.         for (i = 0; i < ncpus; i++)
  6.                 chudxnu_enable_cpu(i, FALSE);        
  7.         if (reboot) {
  8.                 printf("MACH Reboot\n");
  9.                 PEHaltRestart( kPERestartCPU );
  10.                 asm volatile ("movb $0xfe, %al\n"
  11.                                           "outb %al, $0x64\n"
  12.                                           "hlt\n");
  13.         } else {
  14.                 printf("CPU halted\n");
  15.                 PEHaltRestart( kPEHaltCPU );
  16.         }
  17.         while(1);
  18. }
复制代码


找尋 PE_parse_boot_argn("keepsyms", &keepsyms, sizeof (keepsyms));

  1.         PE_parse_boot_argn("keepsyms", &keepsyms, sizeof (keepsyms));
  2. -----插入程式碼----------------------------
  3.         keepsyms = 1;
  4. -------------------------------------------
复制代码


/xnu-2422.1.72/osfmk/i386/cpuid.c

修改支援AMD處理器範例

找尋 static const char *cache_type_str[LCACHE_MAX] = {

  1. static const char *cache_type_str[LCACHE_MAX] = {
  2.         "Lnone", "L1I", "L1D", "L2U", "L3U"
  3. };

  4. -----插入程式碼----------------------------
  5. /* Sinetek: reimplemented, based on AnV, mercurySquad, thanks go to them.
  6. * Function is AMD-specific.
  7. */
  8. static void
  9. cpuid_set_AMDcache_info( i386_cpu_info_t * info_p )
  10. {
  11.         uint32_t        reg[4];
  12.         uint32_t        linesizes[LCACHE_MAX];
  13.         cache_type_t        type;
  14.         uint32_t        j;
  15.         uint32_t        colors;

  16.         bzero( linesizes, sizeof(linesizes) );

  17.         /* get number of cores in processor */
  18.         /* No HT on AMD so logicals = cores */
  19.         cpuid_fn(0x80000008, reg);
  20.         info_p->cpuid_cores_per_package = bitfield32(reg[ecx], 7, 0) + 1;
  21.         info_p->cpuid_logical_per_package = info_p->cpuid_cores_per_package;


  22.         /* L1 Data */
  23.         {
  24.                 type = L1D;
  25.                 cpuid_fn(0x80000005, reg);
  26.                 uint32_t cpuid_c_linesize        = bitfield32(reg[ecx], 7,  0);
  27.                 uint32_t cpuid_c_partitions        = bitfield32(reg[ecx], 15, 8);
  28.                 uint32_t cpuid_c_associativity        = bitfield32(reg[ecx], 23, 16);
  29.                 uint32_t cpuid_c_size                = bitfield32(reg[ecx], 31, 24);

  30.                 uint32_t cache_associativity        = cpuid_c_associativity;

  31.                 // size reported in KB.
  32.                 info_p->cache_size[type]          = cpuid_c_size * 1024;
  33.                 info_p->cache_sharing[type]         = 1;
  34.                 info_p->cache_partitions[type]        = cpuid_c_partitions;

  35.                 linesizes[type] = cpuid_c_linesize;
  36.                 uint32_t cache_sets = info_p->cache_size[type] / (cpuid_c_partitions * cpuid_c_linesize * cache_associativity);

  37.                 colors = ( cpuid_c_linesize * cache_sets ) >> 12;
  38.                 if ( colors > vm_cache_geometry_colors )
  39.                         vm_cache_geometry_colors = colors;
  40.         }
  41.         /* L1 Instruction */
  42.         {
  43.                 type = L1I;
  44.                 cpuid_fn(0x80000005, reg);
  45.                 uint32_t cpuid_c_linesize        = bitfield32(reg[edx], 7,  0);
  46.                 uint32_t cpuid_c_partitions        = bitfield32(reg[edx], 15, 8);
  47.                 uint32_t cpuid_c_associativity        = bitfield32(reg[edx], 23, 16);
  48.                 uint32_t cpuid_c_size                = bitfield32(reg[edx], 31, 24);

  49.                 uint32_t cache_associativity        = cpuid_c_associativity;

  50.                 // size reported in KB.
  51.                 info_p->cache_size[type]          = cpuid_c_size * 1024;
  52.                 info_p->cache_sharing[type]         = 1;
  53.                 info_p->cache_partitions[type]        = cpuid_c_partitions;

  54.                 linesizes[type] = cpuid_c_linesize;
  55.                 uint32_t cache_sets = info_p->cache_size[type] / (cpuid_c_partitions * cpuid_c_linesize * cache_associativity);

  56.                 colors = ( cpuid_c_linesize * cache_sets ) >> 12;
  57.                 if ( colors > vm_cache_geometry_colors )
  58.                         vm_cache_geometry_colors = colors;
  59.         }
  60.         /* L2 Unified */
  61.         {
  62.                 type = L2U;
  63.                 cpuid_fn(0x80000006, reg);
  64.                 uint32_t cpuid_c_linesize        = bitfield32(reg[ecx], 7,  0);
  65.                 uint32_t cpuid_c_partitions        = bitfield32(reg[ecx], 11, 8);
  66.                 uint32_t cpuid_c_associativity        = bitfield32(reg[ecx], 15, 12);
  67.                 uint32_t cpuid_c_size                = bitfield32(reg[ecx], 31, 16);

  68.                 // Special formula for associativity:  2^(assoc / 2)
  69.                 uint32_t cache_associativity        = 1ul << (cpuid_c_associativity / 2);

  70.                 // size reported in KB.
  71.                 info_p->cache_size[type]          = cpuid_c_size * 1024;
  72.                 info_p->cache_sharing[type]         = 1;
  73.                 info_p->cache_partitions[type]        = cpuid_c_partitions;

  74.                 linesizes[type] = cpuid_c_linesize;
  75.                 uint32_t cache_sets = info_p->cache_size[type] / (cpuid_c_partitions * cpuid_c_linesize * cache_associativity);

  76.                 colors = ( cpuid_c_linesize * cache_sets ) >> 12;
  77.                 if ( colors > vm_cache_geometry_colors )
  78.                         vm_cache_geometry_colors = colors;

  79.                 // use for cache size etc.
  80.                 info_p->cpuid_cache_L2_associativity = cache_associativity;
  81.                 info_p->cpuid_cache_size        = info_p->cache_size[type];
  82.                 info_p->cache_linesize                = cpuid_c_linesize;
  83.         }
  84.         /* L3 Unified */
  85.         {
  86.                 type = L3U;
  87.                 cpuid_fn(0x80000006, reg);
  88.                 uint32_t cpuid_c_linesize        = bitfield32(reg[edx], 7,  0);
  89.                 uint32_t cpuid_c_partitions        = bitfield32(reg[edx], 11, 8);
  90.                 uint32_t cpuid_c_associativity        = bitfield32(reg[edx], 15, 12);
  91.                 uint32_t cpuid_c_size                = bitfield32(reg[edx], 31, 18);

  92.                 // Special formula for associativity:  2^(assoc / 2)
  93.                 uint32_t cache_associativity        = 1ul << (cpuid_c_associativity / 2);

  94.                 if(cpuid_c_size == 0) {
  95.                         // no L3
  96.                         info_p->cache_size[type]          = 0;
  97.                         info_p->cache_sharing[type]         = 0;
  98.                         info_p->cache_partitions[type]        = 0;
  99.                 } else {
  100.                         // size reported in 512 KB packs.
  101.                         info_p->cache_size[type]          = cpuid_c_size * 1024;
  102.                         info_p->cache_sharing[type]         = 1;
  103.                         info_p->cache_partitions[type]        = cpuid_c_partitions;

  104.                         linesizes[type] = cpuid_c_linesize;
  105.                         uint32_t cache_sets = info_p->cache_size[type] / (cpuid_c_partitions * cpuid_c_linesize * cache_associativity);

  106.                         colors = ( cpuid_c_linesize * cache_sets ) >> 12;
  107.                         if ( colors > vm_cache_geometry_colors )
  108.                                 vm_cache_geometry_colors = colors;
  109.                         }
  110.         }
  111. }
  112. -------------------------------------------
复制代码


找尋 wrmsr64(MSR_IA32_BIOS_SIGN_ID, 0)

下面
info_p->cpuid_features  = quad(reg[ecx], reg[edx]);
改為
  1. info_p->cpuid_features  = quad(reg[ecx], reg[edx]) & ~CPUID_FEATURE_PAT;
复制代码


info_p->cpuid_processor_flag = (rdmsr64(MSR_IA32_PLATFORM_ID)>> 50) & 0x7;
改為
  1. info_p->cpuid_processor_flag = 0;
复制代码


找尋 info_p->cpuid_cpufamily = cpufamily;

  1.         info_p->cpuid_cpufamily = cpufamily;
  2.         DBG("cpuid_set_cpufamily(%p) returning 0x%x\n", info_p, cpufamily);

  3. -----插入程式碼----------------------------
  4.         /* AnV - Fix AMD CPU Family to Intel Penryn */
  5.         /** This is needed to boot because the dyld assumes that an UNKNOWN
  6.          ** Platform is HASWELL-capable, dropping an SSE4.2 'pcmpistri' on us during bcopies.
  7.          **/
  8.         if (IsAmdCPU())
  9.         {
  10.                 cpufamily = CPUFAMILY_INTEL_PENRYN;
  11.                 info_p->cpuid_cpufamily = cpufamily;
  12.         }

  13. -------------------------------------------
  14.         return cpufamily;
复制代码


找尋 cpuid_set_info(void)

  1. cpuid_set_info(void)
  2. {
  3.         i386_cpu_info_t                *info_p = &cpuid_cpu_info;

  4.         cpuid_set_generic_info(info_p);

  5.         /* verify we are running on a supported CPU */
  6.         if ((strncmp(CPUID_VID_INTEL, info_p->cpuid_vendor,
  7.                      min(strlen(CPUID_STRING_UNKNOWN) + 1,
  8.                          sizeof(info_p->cpuid_vendor)))) ||
  9.            (cpuid_set_cpufamily(info_p) == CPUFAMILY_UNKNOWN))
  10.                 panic("Unsupported CPU");

  11.         info_p->cpuid_cpu_type = CPU_TYPE_X86;
  12.         info_p->cpuid_cpu_subtype = CPU_SUBTYPE_X86_ARCH1;
  13.         /* Must be invoked after set_generic_info */
  14.         cpuid_set_cache_info(info_p);
复制代码

改為
  1. cpuid_set_info(void)
  2. {
  3.         i386_cpu_info_t                *info_p = &cpuid_cpu_info;

  4.         cpuid_set_generic_info(info_p);

  5.         /* verify we are running on a supported CPU */
  6.         /*if ((strncmp(CPUID_VID_INTEL, info_p->cpuid_vendor,
  7.                      min(strlen(CPUID_STRING_UNKNOWN) + 1,
  8.                          sizeof(info_p->cpuid_vendor)))) ||
  9.            (cpuid_set_cpufamily(info_p) == CPUFAMILY_UNKNOWN))
  10.                 panic("Unsupported CPU");*/
  11.         cpuid_set_cpufamily(info_p);

  12.         info_p->cpuid_cpu_type = CPU_TYPE_X86;
  13.         info_p->cpuid_cpu_subtype = CPU_SUBTYPE_X86_ARCH1;
  14.         /* Must be invoked after set_generic_info */
  15.         /* check if running on AMD, call right cache info function */
  16.         if(!strncmp(CPUID_VID_AMD, info_p->cpuid_vendor,
  17.                      min(strlen(CPUID_STRING_UNKNOWN) + 1,
  18.                          sizeof(info_p->cpuid_vendor)))) {
  19.                 cpuid_set_AMDcache_info(info_p);
  20.         } else cpuid_set_cache_info(info_p);
复制代码


/xnu-2422.1.72/osfmk/i386/cpuid.h

找尋 #define CPUID_MODEL_HASWELL_ULT

  1. #define CPUID_MODEL_HASWELL_ULT                0x45
  2. -----插入程式碼----------------------------
  3. /* kaitek: the following definitions are needed by tsc.c and kern_mib.c */
  4. #define CPU_FAMILY_PENTIUM_M        (0x6)
  5. #define CPU_FAMILY_PENTIUM_4        (0xF)
  6. #define CPU_FAMILY_AMD_PHENOM        (0x10)
  7. #define CPU_FAMILY_AMD_SHANGHAI        (0x11)
  8. #define CPU_FAMILY_I5                (0x1E)
  9. #define CPU_FAMILY_I9                (0x2C)
  10. #define CPU_FAMILY_SANDY        (0x2A)
  11. -------------------------------------------
复制代码


找尋  i386_vmm_info_t;

  1. } i386_vmm_info_t;
  2. #endif

  3. #ifdef __cplusplus
  4. extern "C" {
  5. #endif
  6. -----插入程式碼----------------------------
  7. extern boolean_t        IsAmdCPU(void);
  8. extern boolean_t        IsIntelCPU(void);
  9. -------------------------------------------
复制代码


/xnu-2422.1.72/osfmk/i386/lapic_native.c

找尋 if ((LAPIC_READ(VERSION)&LAPIC_VERSION_MASK)

  1.         if ((LAPIC_READ(VERSION)&LAPIC_VERSION_MASK) < 0x14) {
  2.                 panic("Local APIC version 0x%x, 0x14 or more expected\n",
复制代码

將 0x14 改為 0x10

  1.         if ((LAPIC_READ(VERSION)&LAPIC_VERSION_MASK) < 0x10) {
  2.                 panic("Local APIC version 0x%x, 0x10 or more expected\n",
复制代码



待續.....

Make.zip

585 Bytes, 下载次数: 7

編譯文件

opemu.zip

67.34 KB, 下载次数: 8

指令集程式碼

5

查看全部评分

Rank: 5Rank: 5Rank: 5

UID
4166712
帖子
506
PB币
779
贡献
0
技术
184
活跃
651
沙发
发表于 2014-1-14 20:26:53 IP属地台湾 |只看该作者
/xnu-2422.1.72/osfmk/i386/tsc.c

找尋 busFreq = 0;

  1. uint64_t        busFreq = 0;
  2. -----插入程式碼----------------------------
  3. uint32_t        kTscPanicOn = 0;
  4. -------------------------------------------
复制代码


找尋 #define CPU_FAMILY_PENTIUM_M

刪除 #define CPU_FAMILY_PENTIUM_M 然後插入下面程式碼

  1. /* mercurysquad: The following enum specifies one of the bus ratio calc paths to take */
  2. typedef enum {
  3.         BUSRATIO_BOOTFLAG,
  4.         BUSRATIO_ATHLON,
  5.         BUSRATIO_EFI,
  6.         BUSRATIO_PHENOM_SHANGHAI,
  7.         BUSRATIO_INTEL_MSR,
  8.         BUSRATIO_AUTODETECT,
  9.         BUSRATIO_PENTIUM4_MSR, // P4 model 2+ have an MSR too
  10.         BUSRATIO_TIMER
  11. } busratio_path_t;

  12. static const char* busRatioPathNames[] = {
  13.         "Boot-time argument",
  14.         "AMD Athlon",
  15.         "Pentium 4 (via EFI)",
  16.         "AMD Phenom",
  17.         "Intel / Apple",
  18.         "Autodetect",
  19.         "Pentium 4 (via MSR)",
  20.         "Time the TSC"
  21. };
复制代码


找尋 FSB_Frequency_prop[] = "FSBFrequency"

  1. static const char        FSB_Frequency_prop[] = "FSBFrequency";
  2. -----插入程式碼----------------------------
  3. static const char  FSB_CPUFrequency_prop[] = "CPUFrequency";
  4. -------------------------------------------
复制代码


找尋 return frequency;

  1.         return frequency;
  2. }
  3. -----插入程式碼----------------------------
  4. /* mercurysquad:
  5. * This routine extracts the cpu frequency from the efi device tree
  6. * The value should be set by a custom EFI bootloader (only needed on CPUs which
  7. * don't report the bus ratio in one of the MSRs.)
  8. */
  9. static uint64_t
  10. EFI_CPU_Frequency(void)
  11. {
  12.         uint64_t        frequency = 0;
  13.         DTEntry                entry;
  14.         void                *value;
  15.         unsigned int        size;
  16.         
  17.         if (DTLookupEntry(0, "/efi/platform", &entry) != kSuccess) {
  18.                 kprintf("EFI_CPU_Frequency: didn't find /efi/platform\n");
  19.                 return 0;
  20.         }
  21.         if (DTGetProperty(entry,FSB_CPUFrequency_prop,&value,&size) != kSuccess) {
  22.                 kprintf("EFI_CPU_Frequency: property %s not found\n",
  23.                         FSB_Frequency_prop);
  24.                 return 0;
  25.         }
  26.         if (size == sizeof(uint64_t)) {
  27.                 frequency = *(uint64_t *) value;
  28.                 kprintf("EFI_CPU_Frequency: read %s value: %llu\n",
  29.                         FSB_Frequency_prop, frequency);
  30.                 if (!(10*Mega < frequency && frequency < 50*Giga)) {
  31.                         kprintf("EFI_Fake_MSR: value out of range\n");
  32.                         frequency = 0;
  33.                 }
  34.         } else {
  35.                 kprintf("EFI_CPU_Frequency: unexpected size %d\n", size);
  36.         }
  37.         return frequency;
  38. }

  39. /*
  40. * Convert the cpu frequency info into a 'fake' MSR198h in Intel format
  41. */
  42. static uint64_t
  43. getFakeMSR(uint64_t frequency, uint64_t bFreq) {
  44.         uint64_t fakeMSR = 0ull;
  45.         uint64_t multi = 0;
  46.         
  47.         if (frequency == 0 || bFreq == 0)
  48.                 return 0;
  49.         
  50.         multi = frequency / (bFreq / 1000); // = multi*1000
  51.         // divide by 1000, rounding up if it was x.75 or more
  52.         // Example: 12900 will get rounded to 13150/1000 = 13
  53.         //          but 12480 will be 12730/1000 = 12
  54.         fakeMSR = (multi + 250) / 1000;
  55.         fakeMSR <<= 40; // push multiplier into bits 44 to 40
  56.         
  57.         // If fractional part was within (0.25, 0.75), set N/2
  58.         if ((multi % 1000 > 250) && (multi % 1000 < 750))
  59.                 fakeMSR |= (1ull << 46);

  60.         return fakeMSR;
  61. }

  62. int ForceAmdCpu = 0;

  63. /* Handy functions to check what platform we're on */
  64. boolean_t IsAmdCPU(void) {
  65.         if (ForceAmdCpu) return TRUE;
  66.         
  67.         uint32_t ourcpuid[4];
  68.         do_cpuid(0, ourcpuid);
  69.         if (ourcpuid[ebx] == 0x68747541 &&
  70.             ourcpuid[ecx] == 0x444D4163 &&
  71.             ourcpuid[edx] == 0x69746E65)
  72.                 return TRUE;
  73.         else
  74.                 return FALSE;
  75. };

  76. boolean_t IsIntelCPU(void) {
  77.         return !IsAmdCPU(); // dirty hack
  78. }
  79. -------------------------------------------
复制代码


找尋 busFreq = BASE_NHM_CLOCK_SOURCE

  1.                 if (busFreq == 0)
  2.                     busFreq = BASE_NHM_CLOCK_SOURCE;

  3.                 break;
  4.             }
复制代码


改為

  1.                 if (busFreq == 0)
  2.                     busFreq = BASE_NHM_CLOCK_SOURCE;

  3.             }
  4.                 break;
复制代码


下面

  1.         default: {
  2.                 uint64_t        prfsts;

  3.                 prfsts = rdmsr64(IA32_PERF_STS);
  4.                 tscGranularity = (uint32_t)bitfield(prfsts, 44, 40);
  5.                 N_by_2_bus_ratio = (prfsts & bit(46)) != 0;
  6.             }
复制代码


這段改為

  1.         default: {
  2.         /*
  3.           * mercurysquad: The bus ratio is crucial to setting the proper rtc increment.
  4.           * There are several methods so we first check any bootlfags. If none is specified, we choose
  5.           * based on the CPU type.
  6.            */
  7.          uint64_t cpuFreq = 0, prfsts = 0, boot_arg = 0;
  8.          busratio_path_t busRatioPath = BUSRATIO_AUTODETECT;
  9.          
  10.          if (PE_parse_boot_argn("busratiopath", &boot_arg, sizeof(boot_arg)))
  11.                  busRatioPath = (busratio_path_t) boot_arg;
  12.          else
  13.                  busRatioPath = BUSRATIO_AUTODETECT;
  14.         
  15.          if (PE_parse_boot_argn("busratio", &tscGranularity, sizeof(tscGranularity)))
  16.                  busRatioPath = BUSRATIO_BOOTFLAG;
  17.          
  18.          if (busRatioPath == BUSRATIO_AUTODETECT) {
  19.                  /* This happens if no bootflag above was specified.
  20.                   * We'll choose based on CPU type */
  21.                  switch (cpuid_info()->cpuid_family) {
  22.                          case CPU_FAMILY_PENTIUM_4:
  23.                                  /* This could be AMD Athlon or Intel P4 as both have family Fh */
  24.                                  if (IsAmdCPU())
  25.                                          busRatioPath = BUSRATIO_ATHLON;
  26.                                  else if (cpuid_info()->cpuid_model < 2 )
  27.                                          /* These models don't implement proper MSR 198h or 2Ch */
  28.                                          busRatioPath = BUSRATIO_TIMER;
  29.                                  else if (cpuid_info()->cpuid_model == 2)
  30.                                          /* This model has an MSR we can use */
  31.                                          busRatioPath = BUSRATIO_PENTIUM4_MSR;
  32.                                  else /* 3 or higher */
  33.                                          /* Other models should implement MSR 198h */
  34.                                          busRatioPath = BUSRATIO_INTEL_MSR;
  35.                                  break;
  36.                          case CPU_FAMILY_PENTIUM_M:
  37.                                  if (cpuid_info()->cpuid_model >= 0xD)
  38.                                          /* Pentium M or Core and above can use Apple method*/
  39.                                          busRatioPath = BUSRATIO_INTEL_MSR;
  40.                                  else
  41.                                          /* Other Pentium class CPU, use safest option */
  42.                                          busRatioPath = BUSRATIO_TIMER;
  43.                                  break;
  44.                          case CPU_FAMILY_AMD_PHENOM:
  45.                          case CPU_FAMILY_AMD_SHANGHAI:
  46.                                  /* These have almost the same method, with a minor difference */
  47.                                  busRatioPath = BUSRATIO_PHENOM_SHANGHAI;
  48.                                  break;
  49.                          default:
  50.                                  /* Fall back to safest method */
  51.                                  busRatioPath = BUSRATIO_TIMER;
  52.                  };
  53.          }
  54.          
  55.          /*
  56.           * Now that we have elected a bus ratio path, we can proceed to calculate it.
  57.           */
  58.          printf("rtclock_init: Taking bus ratio path %d (%s)\n",
  59.                 busRatioPath, busRatioPathNames[busRatioPath]);
  60.          switch (busRatioPath) {
  61.                  case BUSRATIO_BOOTFLAG:
  62.                          /* tscGranularity was already set. However, check for N/2. N/2 is specified by
  63.                           * giving a busratio of 10 times what it is (so last digit is 5). We set a cutoff
  64.                           * of 30 before deciding it's n/2. TODO: find a better way */
  65.                          if (tscGranularity == 0) tscGranularity = 1; // avoid div by zero
  66.                          N_by_2_bus_ratio = (tscGranularity > 30) && ((tscGranularity % 10) != 0);
  67.                          if (N_by_2_bus_ratio) tscGranularity /= 10; /* Scale it back to normal */
  68.                          break;
  69. #ifndef __i386__ //AnV: in case of x86_64 boot default for busratio timer to EFI value
  70.                 case BUSRATIO_TIMER:
  71. #endif
  72.                  case BUSRATIO_EFI:
  73.                          /* This uses the CPU frequency exported into EFI by the bootloader */
  74.                          cpuFreq = EFI_CPU_Frequency();
  75.                          prfsts  = getFakeMSR(cpuFreq, busFreq);
  76.                         tscGranularity = (uint32_t)bitfield(prfsts, 44, 40);
  77.                          N_by_2_bus_ratio = prfsts & bit(46);
  78.                          break;
  79.                  case BUSRATIO_INTEL_MSR:
  80.                          /* This will read the performance status MSR on intel systems (Apple method) */
  81.                          prfsts = rdmsr64(IA32_PERF_STS);
  82.                          tscGranularity        = (uint32_t)bitfield(prfsts, 44, 40);
  83.                          N_by_2_bus_ratio= prfsts & bit(46);
  84.                          break;
  85.                  case BUSRATIO_ATHLON:
  86.                          /* Athlons specify the bus ratio directly in an MSR using a simple formula */
  87.                          prfsts                = rdmsr64(AMD_PERF_STS);
  88.                          tscGranularity  = 4 + bitfield(prfsts, 5, 1);
  89.                          N_by_2_bus_ratio= prfsts & bit(0); /* FIXME: This is experimental! */
  90.                          break;
  91.                  case BUSRATIO_PENTIUM4_MSR:
  92.                          prfsts                = rdmsr64(0x2C); // TODO: Add to header
  93.                          tscGranularity        = bitfield(prfsts, 31, 24);
  94.                          break;
  95.                  case BUSRATIO_PHENOM_SHANGHAI:
  96.                          /* Phenoms and Shanghai processors have a different MSR to read the frequency
  97.                           * multiplier and divisor, from which the cpu frequency can be calculated.
  98.                           * This can then be used to construct the fake MSR. */
  99.                          prfsts                = rdmsr64(AMD_COFVID_STS);
  100.                          printf("rtclock_init: Phenom MSR 0x%x returned: 0x%llx\n", AMD_COFVID_STS, prfsts);
  101.                          uint64_t cpuFid = bitfield(prfsts, 5, 0);
  102.                          uint64_t cpuDid = bitfield(prfsts, 8, 6);
  103.                          /* The base for Fid could be either 8 or 16 depending on the cpu family */
  104.                          if (cpuid_info()->cpuid_family == CPU_FAMILY_AMD_PHENOM)
  105.                                  cpuFreq = (100 * Mega * (cpuFid + 0x10)) >> cpuDid;
  106.                          else /* shanghai */
  107.                                  cpuFreq = (100 * Mega * (cpuFid + 0x08)) >> cpuDid;
  108.                          prfsts = getFakeMSR(cpuFreq, busFreq);
  109.                          tscGranularity = (uint32_t)bitfield(prfsts, 44, 40);
  110.                          N_by_2_bus_ratio = prfsts & bit(46);
  111.                          break;
  112. #ifdef __i386__ //qoopz: no get_PIT2 for x86_64
  113.                  case BUSRATIO_TIMER:
  114.                          /* Fun fun fun. :-|  */
  115.                          cpuFreq = timeRDTSC() * 20;
  116.                          prfsts = getFakeMSR(cpuFreq, busFreq);
  117.                          tscGranularity = (uint32_t)bitfield(prfsts, 44, 40);
  118.                          N_by_2_bus_ratio = prfsts & bit(46);
  119.                          break;
  120. #endif
  121.                  case BUSRATIO_AUTODETECT:
  122.                  default:
  123.                          kTscPanicOn = 1; /* see sanity check below */
  124.          };

  125. #ifdef __i386__
  126.          /* Verify */
  127.          if (!PE_parse_boot_argn("-notscverify", &boot_arg, sizeof(boot_arg))) {
  128.                  uint64_t realCpuFreq = timeRDTSC() * 20;
  129.                  cpuFreq = tscGranularity * busFreq;
  130.                  if (N_by_2_bus_ratio) cpuFreq += (busFreq / 2);
  131.                  uint64_t difference = 0;
  132.                  if (realCpuFreq > cpuFreq)
  133.                          difference = realCpuFreq - cpuFreq;
  134.                  else
  135.                          difference = cpuFreq - realCpuFreq;
  136.                  
  137.                  if (difference >= 4*Mega) {
  138.                          // Shouldn't have more than 4MHz difference. This is about 2-3% of most FSBs.
  139.                          // Fall back to using measured speed and correct the busFreq
  140.                          // Note that the tscGran was read from CPU so should be correct.
  141.                          // Only on Phenom the tscGran is calculated by dividing by busFreq.
  142.                          printf("TSC: Reported FSB: %4d.%04dMHz, ", (uint32_t)(busFreq / Mega), (uint32_t)(busFreq % Mega));
  143.                          if (N_by_2_bus_ratio)
  144.                                  busFreq = (realCpuFreq * 2) / (1 + 2*tscGranularity);
  145.                          else
  146.                                  busFreq = realCpuFreq / tscGranularity;
  147.                          printf("corrected FSB: %4d.%04dMHz\n", (uint32_t)(busFreq / Mega), (uint32_t)(busFreq % Mega));
  148.                          // Reset the busCvt factors
  149.                          busFCvtt2n = ((1 * Giga) << 32) / busFreq;
  150.                          busFCvtn2t = 0xFFFFFFFFFFFFFFFFULL / busFCvtt2n;
  151.                          busFCvtInt = tmrCvt(1 * Peta, 0xFFFFFFFFFFFFFFFFULL / busFreq);
  152.                          printf("TSC: Verification of clock speed failed. "
  153.                                 "Fallback correction was performed. Please upgrade bootloader.\n");
  154.                  } else {
  155.                          printf("TSC: Verification of clock speed PASSED.\n");
  156.                  }
  157.          }
  158. #else
  159.         printf("TSC: Verification of clock speed not available in x86_64.\n");
  160. #endif
  161.          
  162.          /* Do a sanity check of the granularity */
  163.          if ((tscGranularity == 0) ||
  164.              (tscGranularity > 30) ||
  165.              (busFreq < 50*Mega) ||
  166.              (busFreq > 1*Giga) ||
  167.              /* The following is useful to force a panic to print diagnostic info */
  168.              PE_parse_boot_argn("-tscpanic", &boot_arg, sizeof(boot_arg)))
  169.          {
  170.                  printf("\n\n");
  171.                  printf(" >>> The real-time clock was not properly initialized on your system!\n");
  172.                  printf("     Contact Voodoo Software for further information.\n");
  173.                  kTscPanicOn = 1; /* Later when the console is initialized, this will show up, and we'll halt */
  174.                  if (tscGranularity == 0) tscGranularity = 1; /* to avoid divide-by-zero in the following few lines */
  175.         }

  176.             }
  177.                 break;
复制代码


找尋 panic("tsc_init: EFI not supported!\n");

刪除
  1.                 panic("tsc_init: EFI not supported!\n");
复制代码


改為

  1.                   /* Instead of panicking, set a default FSB frequency */
  2.                   busFreq = 133*Mega;
  3.                  kprintf("rtclock_init: Setting fsb to %u MHz\n", (uint32_t) (busFreq/Mega));
复制代码


/xnu-2422.1.72/osfmk/i386/tsc.h

找尋 #ifndef ASSEMBLER

  1. -----插入程式碼----------------------------
  2. /* mercurysquad: MSRs for AMD support (getting bus ratio) */
  3. #define AMD_PERF_STS        0xC0010042        /* AMD's version of the MSR */
  4. #define AMD_PSTATE0_STS        0xC0010064        /* K10/phenom class AMD cpus */
  5. #define AMD_COFVID_STS        0xC0010071        /* This might be a better MSR for K10? */
  6. -------------------------------------------
  7. #ifndef ASSEMBLER
  8. extern uint64_t        busFCvtt2n;
  9. extern uint64_t        busFCvtn2t;
  10. extern uint64_t tscFreq;
  11. extern uint64_t tscFCvtt2n;
  12. extern uint64_t tscFCvtn2t;
  13. extern uint64_t tscGranularity;
  14. extern uint64_t bus2tsc;
  15. extern uint64_t busFreq;
  16. -----插入程式碼----------------------------
  17. extern uint32_t kTscPanicOn;
  18. -------------------------------------------
  19. extern uint32_t        flex_ratio;
复制代码


/xnu-2422.1.72/osfmk/x86_64/idt64.s

找尋 L_fast_exit:

  1. L_fast_exit:
  2. -----插入程式碼----------------------------
  3.         /* Sinetek: regular exit */
  4.         iretq
  5. -------------------------------------------
复制代码


待續......
1

查看全部评分

Rank: 5Rank: 5Rank: 5

UID
4166712
帖子
506
PB币
779
贡献
0
技术
184
活跃
651
板凳
发表于 2014-1-14 20:28:55 IP属地台湾 |只看该作者
二 插入指令集

/xnu-2422.1.72/osfmk/conf/files.x86_64
定義指令集程式碼位置
最下面插入
  1. osfmk/OPEMU/opemu.c                standard
  2. osfmk/OPEMU/ssse3.c                standard
  3. osfmk/OPEMU/sse42.c                standard
  4. osfmk/OPEMU/libudis86/decode.c standard
  5. osfmk/OPEMU/libudis86/itab.c standard
  6. osfmk/OPEMU/libudis86/syn.c standard
  7. osfmk/OPEMU/libudis86/syn-intel.c standard
  8. osfmk/OPEMU/libudis86/udis86.c standard
复制代码
/xnu-2422.1.72/osfmk/i386/commpage/commpage.c
修正 AMD SSE3 & SSE4.2 指令集

找尋 cpus = commpage_cpus();
下面插入
  1.         /** Sinetek: by default we'd like some reasonable values,
  2.          **  so that the userspace runs correctly.
  3.          **
  4.          ** On Mountain Lion, kHasSSE4_2 provides vanilla SSE2 routines.
  5.          ** On Mavericks, we need a bit more support: SSE3, SSE3X.
  6.          **/
  7.         if (IsAmdCPU()) {
  8.                 bits |= kHasSSE4_2;
  9.                 bits &= ~kHasSupplementalSSE3;
  10. #define MAVERICKS_AMD
  11. #ifdef MAVERICKS_AMD
  12.                 bits |= kHasSSE3;
  13.         //        bits |= kHasSupplementalSSE3;
  14.                 bits &= ~kHasSSE4_2;
  15. #endif
  16.         }
复制代码
/xnu-2422.1.72/osfmk/i386/trap.c
錯誤的操作代碼修正
找到上面開頭有許多 #include 指令的地方
在下面插入
  1. #include <OPEMU/opemu.h>
复制代码
找尋 FALL_THROUGH:
  1. FALL_THROUGH:
  2. #endif /* CONFIG_DTRACE */

  3.             case T_GENERAL_PROTECTION:
  4.                 /*
  5.                  * If there is a failure recovery address
  6.                  * for this fault, go there.
  7.                  */
  8.                 for (rp = recover_table; rp < recover_table_end; rp++) {
  9.                         if (kern_ip == rp->fault_addr) {
  10.                                 set_recovery_ip(saved_state, rp->recover_addr);
  11.                                 return;
  12.                         }
  13.                 }

  14.                 /*
  15.                  * Check thread recovery address also.
  16.                  */
  17.                 if (thread != THREAD_NULL && thread->recover) {
  18.                         set_recovery_ip(saved_state, thread->recover);
  19.                         thread->recover = 0;
  20.                         return;
  21.                 }
  22.                 /*
  23.                  * Unanticipated page-fault errors in kernel
  24.                  * should not happen.
  25.                  *
  26.                  * fall through...
  27.                  */
  28. ------------插入程式碼---------------------------
  29.             case T_INVALID_OPCODE:
  30.                 /* Sinetek: we'll handle this. */
  31.                 opemu_ktrap(state);
  32.                 return;
  33. -------------------------------------------------
复制代码
找尋 case T_OUT_OF_BOUNDS:
  1.             case T_OUT_OF_BOUNDS:
  2.                 exc = EXC_SOFTWARE;
  3.                 code = EXC_I386_BOUND;
  4.                 break;

  5.             case T_INVALID_OPCODE:
  6. ------------插入程式碼---------------------------
  7.                 /* Sinetek: we'll handle this. */
  8.                 opemu_utrap(saved_state);
  9. -------------------------------------------------
复制代码
/osfmk/OPEMU
把自定的AMD指令集放到源碼/osfmk/OPEMU 目錄內
Apple 官方的源碼沒有OPEMU這個目錄 這目錄是自己加的
下載附件 解壓縮放到 源碼/osfmk 目錄內即可


待續 ......

Rank: 5Rank: 5Rank: 5

UID
4166712
帖子
506
PB币
779
贡献
0
技术
184
活跃
651
4F
发表于 2014-1-14 20:30:23 IP属地台湾 |只看该作者
本帖最后由 labaz 于 2014-1-14 20:38 编辑

三 更改Make參數
源碼內加入某些程式碼 必須修改 make 參數才有辦法成功編譯

/xnu-2422.1.72/makedefs/MakeInc.def

找尋 CWARNFLAGS_STD = \ 前面加#號屏閉掉
  1. #CWARNFLAGS_STD = \
  2. #        -Wall -Werror -Wno-format-y2k -Wextra -Wstrict-prototypes \
  3. #        -Wmissing-prototypes -Wpointer-arith -Wreturn-type -Wcast-qual \
  4. #        -Wwrite-strings -Wswitch -Wshadow -Wcast-align -Wchar-subscripts \
  5. #        -Winline -Wnested-externs -Wredundant-decls -Wextra-tokens
复制代码
找尋 CXXWARNFLAGS_STD = \ 前面加#號屏閉掉
  1. #CXXWARNFLAGS_STD = \
  2. #        -Wall -Werror -Wno-format-y2k -Wextra -Wpointer-arith -Wreturn-type \
  3. #        -Wcast-qual -Wwrite-strings -Wswitch -Wcast-align -Wchar-subscripts \
  4. #        -Wredundant-decls -Wextra-tokens
复制代码
找尋 CFLAGS_RELEASEX86_64
  1. CFLAGS_RELEASEX86_64 = -O2
  2. CFLAGS_DEVELOPMENTX86_64 = -O2
复制代码
這兩段改為
  1. CFLAGS_RELEASEX86_64 = -O2 -march=k8
  2. CFLAGS_DEVELOPMENTX86_64 = -O2 -march=k8
复制代码
再源碼根目錄 新增二個文件
也可以下載附件 Make.zip 解壓縮後 將兩個文件放進源碼根目錄

.lldbinit
內容
  1. # Import python macros
  2. script import lldbmacros

  3. # Basic types
  4. type summary add --regex --summary-string "${var%s}" "char \[[0-9]*\]"
  5. type summary add --summary-string "${var[0]%y}${var[1]%y}${var[2]%y}${var[3]%y}-${var[4]%y}${var[5]%y}-${var[6]%y}${var[7]%y}-${var[8]%y}${var[9]%y}-${var[10]%y}${var[11]%y}${var[12]%y}${var[13]%y}${var[14]%y}${var[15]%y}" uuid_t

  6. # Kexts
  7. type summary add --summary-string "${var->loadTag%u} ${var->address%x} ${var->size%x} ${var->version%u} ${var->name%s}" OSKextLoadedKextSummary
  8. type summary add -v --python-function lldbmacros.showallkexts_summary OSKextLoadedKextSummaryHeader
  9. command script add -f lldbmacros.showallkexts_command showallkexts

  10. #KGMacros
  11. command script add -f lldbmacros.zprint_command zprint
  12. command script add -f lldbmacros.memstats_command memstats
  13. command script add -f lldbmacros.showioalloc_command showioalloc
复制代码
build.sh
內容
  1. make KERNEL_CONFIGS="RELEASE" ARCH_CONFIGS=X86_64
复制代码
END.......

求71狐狸尾巴当抱枕......外出南极洲旅游至今未归

UID
2881599
帖子
18654
PB币
94497
贡献
1
技术
23564
活跃
2824

热心会员 8周年庆典勋章

5F
发表于 2014-1-14 20:39:20 IP属地辽宁 |只看该作者
好高级 直接改源码。。。 赞一个!

三风

UID
2513304
帖子
10738
PB币
17039
贡献
0
技术
1658
活跃
2269

十周年

6F
发表于 2014-1-14 21:24:37 IP属地福建 |只看该作者
哦,看码辛苦,不懂C++的路过~

Rank: 5Rank: 5Rank: 5

UID
657529
帖子
612
PB币
528
贡献
0
技术
9
活跃
833
7F
发表于 2014-1-14 21:27:18 IP属地广东 |只看该作者
完全看不懂!!!这个不好折腾把

Rank: 7Rank: 7Rank: 7

UID
1814477
帖子
2058
PB币
11503
贡献
0
技术
148
活跃
1634

8周年庆典勋章

8F
发表于 2014-1-15 22:43:31 IP属地浙江 |只看该作者
论坛终于又来了重量级的程序员“黑果高手”!!!表示看不懂啊

小学生

Rank: 11Rank: 11Rank: 11

UID
71938
帖子
11524
PB币
24348
贡献
0
技术
60
活跃
2039

8周年庆典勋章

9F
发表于 2014-1-15 22:50:26 IP属地四川 |只看该作者
太深啦 咱看不懂。LZ真厉害。
回顶部
Copyright (C) 2005-2024 pcbeta.com, All rights reserved
Powered by Discuz!  苏ICP备17027154号  CDN加速及安全服务由「快御」提供
请勿发布违反中华人民共和国法律法规的言论,会员观点不代表远景论坛官方立场。
远景在线 | 远景论坛 | 苹果论坛 | Win11论坛 | Win10论坛 | Win8论坛 | Win7论坛 | WP论坛 | Office论坛