Virtualbox, belirli bir CPU'yu konuğa zorlama


14

VirtualBox, Windows 8 ana bilgisayarında bir XP misafirim var. Konuk işlemciyi ana bilgisayarla (i5 2500k) şeffaf bir şekilde gösterir. Ancak yükleyicilerin çoğu bu işlemcileri tanımıyor ve desteklenmeyen işlemciyi belirlemeye devam edemiyor.

Misafirin bu eski işlemci olduğunu düşünmeye kandırmanın bir yolu var mı? VMWare'in CPU maskeleme özelliği olduğunu doğru hatırlıyorsam, sanal kutuda benzer bir şey var mı?


CPU modelini kontrol eden hangi yazılımı yüklüyorsunuz?
Darth Android

Double Agent kontrolleri, Orca ve Wix. Bu, canlandırmaya çalıştığımız bir VB6 projesi için.
IBilinmeyen

Yanıtlar:


19

VirtualBox ve CPUID ile ilgili temel bilgiler

VBoxInternal/CPUM/HostCPUIDSanal makinenin extradatasını ayarlamanız gerekir . Bu , konuk için CPUID komutu için VirtualBox raporu özel sonuçları yapar . EAX kaydının değerine bağlı olarak, bu talimat işlemci, tür, aile, adım, marka, önbellek boyutu, özellikler (MMX, SSE, SSE2, PAE, HTT) vb. Gibi işlemciler hakkında bilgi döndürür. Eğer mangle, konuk aptal şansı o kadar yüksek.

vboxmanage setextradataSanal makineyi yapılandırmak için komutu kullanabilirsiniz . Örneğin,

vboxmanage setextradata WinXP VBoxInternal/CPUM/HostCPUID/80000003/ebx 0x50202952

EAX 80000003₍₁₆₎ olarak ayarlandığında CPUID'nin EBX kaydında 50202952₍₁₆₎ dönüş yapmasını sağlar. (Bundan sonra, onaltılık sayılar 0xNN veya NNh olarak yazılacaktır.)

CPU satıcı dizesini ayarlama

EAX 0 (veya AMD'de 80000000h) ise CPUID, satıcıyı EBX, EDX, ECX kayıtlarında ASCII dizesi olarak döndürür (siparişe dikkat edin). AMD CPU için şöyle görünürler:

| Register | Value      | Description                    |
|----------|------------|--------------------------------|
| EBX      | 6874_7541h | The ASCII characters "h t u A" |
| ECX      | 444D_4163h | The ASCII characters "D M A c" |
| EDX      | 6974_6E65h | The ASCII characters "i t n e" |

( AMD CPUID Spesifikasyonu , "CPUID Fn0000_0000_E" alt bölümünden alınmıştır)

EBX, EDX ve ECX'i birleştirirseniz alırsınız AuthenticAMD.

Bash ve geleneksel Unix yardımcı programlarına sahipseniz, satıcıyı aşağıdaki komutlarla kolayca ayarlayabilirsiniz:

vm='WinXP'  # UUID works as well
# The vendor string needs to have 12 characters!
vendor='AuthenticAMD'
if [ ${#vendor} -ne 12 ]; then
    exit 1
fi
ascii2hex() { echo -n 0x; od -A n --endian little -t x4 | sed 's/ //g'; }

registers=(ebx edx ecx)
for (( i=0; i<${#vendor}; i+=4 )); do
    register=${registers[$(($i/4))]}
    value=`echo -n "${vendor:$i:4}" | ascii2hex`
    # set value to an empty string to reset the CPUID, i.e.
    # value=""
    for eax in 00000000 80000000; do
        key=VBoxInternal/CPUM/HostCPUID/${eax}/${register}
        vboxmanage setextradata "$vm" $key $value
    done
done

CPU marka dizesini ayarlama

EAX 80000002h, 80000003h, 80000004h ise, CPUID, EAX, EBX, ECX, EDX kayıtlarında marka dizesinin 16 ASCII karakterini döndürür; toplam 3 * 16 = 48 karakter; dize null karakterle sonlandırılır . Bu özelliğin Pentium 4 işlemcilerle tanıtıldığını unutmayın. Marka dizesi bir Pentium 4 işlemcide şöyle görünebilir:

| EAX Input Value | Return Values   | ASCII Equivalent |
|-----------------|-----------------|------------------|
| 80000002h       | EAX = 20202020h | "    "           |
|                 | EBX = 20202020h | "    "           |
|                 | ECX = 20202020h | "    "           |
|                 | EDX = 6E492020h | "nI  "           |
|-----------------|-----------------|------------------|
| 80000003h       | EAX = 286C6574h | "(let"           |
|                 | EBX = 50202952h | "P )R"           |
|                 | ECX = 69746E65h | "itne"           |
|                 | EDX = 52286D75h | "R(mu"           |
|-----------------|-----------------|------------------|
| 80000004h       | EAX = 20342029h | " 4 )"           |
|                 | EBX = 20555043h | " UPC"           |
|                 | ECX = 30303531h | "0051"           |
|                 | EDX = 007A484Dh | "☠zHM"           |
|-----------------|-----------------|------------------|

( Intel Mimari Komut Seti Uzantıları Programlama Başvurusu , alt bölüm 2.9, "CPUID Talimatı", tablo 2-30'dan alınmıştır. ☠ null karakterdir (sayısal değer 0).)

Sonuçları bir araya getirirseniz elde edersiniz Intel(R) Pentium(R) 4 CPU 1500MHz☠.

Bash ve geleneksel Unix yardımcı programlarınız varsa, markayı aşağıdaki komutlarla kolayca ayarlayabilirsiniz:

vm='WinXP'  # UUID works as well
# The brand string needs to have 47 characters!
# The null terminator is added automatically
brand='              Intel(R) Pentium(R) 4 CPU 1500MHz'
if [ ${#brand} -ne 47 ]; then
    exit 1
fi
ascii2hex() { echo -n 0x; od -A n --endian little -t x4 | sed 's/ //g'; }

eax_values=(80000002 80000003 80000004)
registers=(edx ecx ebx eax)
for (( i=0; i<${#brand}; i+=4 )); do
    eax=${eax_values[$((${i} / 4 / 4))]}
    register=${registers[$((${i} / 4 % 4 ))]}
    key=VBoxInternal/CPUM/HostCPUID/${eax}/${register}
    value=`echo -n "${brand:$i:4}" | ascii2hex`
    # set value to an empty string to reset the CPUID, i.e.
    # value=""
    vboxmanage setextradata "$vm" $key $value
done

Bir Windows komut isteminiz varsa, markayı çalıştırarak Intel(R) Core(TM)2 CPU 6600 @ 2.40 GHz1 olarak ayarlayabilirsiniz :

set vm=your-vm-name-or-uuid
vboxmanage setextradata %vm% VBoxInternal/CPUM/HostCPUID/80000002/eax 0x65746e49
vboxmanage setextradata %vm% VBoxInternal/CPUM/HostCPUID/80000002/ebx 0x2952286c
vboxmanage setextradata %vm% VBoxInternal/CPUM/HostCPUID/80000002/ecx 0x726f4320
vboxmanage setextradata %vm% VBoxInternal/CPUM/HostCPUID/80000002/edx 0x4d542865
vboxmanage setextradata %vm% VBoxInternal/CPUM/HostCPUID/80000003/eax 0x43203229
vboxmanage setextradata %vm% VBoxInternal/CPUM/HostCPUID/80000003/ebx 0x20205550
vboxmanage setextradata %vm% VBoxInternal/CPUM/HostCPUID/80000003/ecx 0x20202020
vboxmanage setextradata %vm% VBoxInternal/CPUM/HostCPUID/80000003/edx 0x20202020
vboxmanage setextradata %vm% VBoxInternal/CPUM/HostCPUID/80000004/eax 0x30303636
vboxmanage setextradata %vm% VBoxInternal/CPUM/HostCPUID/80000004/ebx 0x20402020
vboxmanage setextradata %vm% VBoxInternal/CPUM/HostCPUID/80000004/ecx 0x30342e32
vboxmanage setextradata %vm% VBoxInternal/CPUM/HostCPUID/80000004/edx 0x007a4847

Bilgisayar: Intel (R) Core (TM) 2 CPU 6600 @ 2,40 GHz

1HostCPUID değerleri VirtualBox hata raporu alındı # 7865 .


Teşekkürler. VM'imi VERR_CFGM_INVALID_CHILD_PATH ile bozuldu.
Ben Sinclair

1
sed G bayrağıyla kullanılmalıdır:'s/ //g'
Ben Sinclair

1
Ne harika bir cevap! Ve Kaby Lake CPU'ların ortaya çıkmasıyla, bu, Redmond'un Windows 7'yi bu konularda desteklememesi nedeniyle belirli bir politika nedeniyle aniden en ilginç hale geldi ... İşlemci Bilgisi ve Özellik Bitleri "olarak adlandırılır (yalnızca CPU markası ile CPU-Z hala CPU'yu KL olarak tanır); kimse biliyor mu?
sxc731

1
Başına forums.virtualbox.org/viewtopic.php?f=2&t=77211#p359428 , bu değerleri ayarlayarak daha iyi (daha özlü, daha desteklenir) yol olabilir.
Mark Amery

@ MarkAmery, bağlantı için teşekkürler. Marka için iyi çalışıyor, ancak satıcı EAX kaydında ayarlanmadığı ve --cpuidalt komut EAX kaydı için bir değer gerektirdiği için satıcı için çok iyi değil .
Cristian Ciupitu

5

Burada, gerekli ayarları ikinci olarak tahmin etmeye çalışmak yerine ana CPU'yu kesin olarak belirli bir CPU olarak maskelemeye izin veren bir yaklaşım var. Bu ana bilgisayar CPU'sunda VirtualBox çalıştıran bir makineye erişmeniz gerekir, böylece cpuidkayıtlarını dökebilirsiniz (muhtemelen model olarak gerçek CPU'nuza oldukça benzer bir mimari seçmek en iyisidir). Eğer elinizde yoksa, etrafta sorabilirsiniz (örneğin Reddit'te başarılı oldum).

  1. Taklit etmek istediğiniz CPU'dan bir "model" dosyası oluşturun:

    vboxmanage list hostcpuids > i7_6600U
    
  2. Hedef ana bilgisayarda, değiştirmek istediğiniz VM'nin çalışmadığından emin olun; her ihtimale karşı bir yedek almak isteyebilirsiniz.
  3. Model dosyasını ( i7_6600Uburada) VBox VM'nizin tanımına ( burada) yüklemek için aşağıdaki komut dosyasını çalıştırın my_vm_name:

    #!/bin/bash
    vm=my_vm_name
    model_file=i7_6600U
    
    egrep -e '^[[:digit:]abcdef]{8} ' $model_file |
    while read -r line; do
        leaf="0x`echo $line | cut -f1 -d' '`"
        # VBox doesn't like applying leaves between the below boundaries so skip those:
        if [[ $leaf -lt 0x0b || $leaf -gt 0x17 ]]; then
            echo "Applying: $line"
            vboxmanage modifyvm $vm --cpuidset $line
        fi
    done
    
  4. İşte bu, şimdi VM'nizi çalıştırabilir ve maskelenmiş CPU'nun keyfini çıkarabilirsiniz (not: yukarıdaki komut dosyasını yalnızca bir kez çalıştırmanız gerekir).

CPU maskeli maskesini geri almanız gerekirse vboxmanage modifyvm $vm --cpuidremove $leaf, yukarıdaki döngüdeki yaprakların her biri için kullanabilirsiniz ( man vboxmanagearkadaşınızdır).

Bu benim için birkaç aydır sorunsuz bir şekilde çalışıyor, bir Kaby Lake CPU'yu (i7_7500U) VBox 5.1.22 çalıştıran bir Ubuntu 17.04 ana bilgisayarında Skylake biri (i7_6600U) olarak görüyor. Bu işletim sistemi için yukarıdaki küçük bash betiğinin eşdeğerini oluşturabilmeniz şartıyla, yaklaşım herhangi bir ana bilgisayar işletim sisteminde çalışmalıdır.


"CPU satıcı dizesini ayarlama" bölümü ile ilgili bir yorumum var: AMD CPU'da "AuthenticAMD" ve Intel CPU'da "GenuineIntel" olarak satıcı adını değiştirdiğinizden emin olmalısınız. Bir AMD CPU'da "GenuineIntel" kullanırsanız, sanal makine büyük olasılıkla kırılacaktır.
abulhol

Bunun için çok teşekkürler! Ryzen 7700K'mda bir cazibe gibi çalıştı. Eski bir AMD Socket SF2 anakartı kullanarak Ubuntu LiveCD'yi çalıştırarak, VirtualBox'ı canlı ortama yükleyerek ve vboxmanage komutunu çalıştırarak CPUID'i elde ettim. Ana bilgisayar tarafında, Linux için Windows Alt Sistemini yükledim, böylece Windows 10'da Bash istemi çalıştırabilir ve paylaştığınız komut dosyasını çalıştırabilirim. Şimdi Windows 7 VM'mi A8-5600K kullandığımı düşünerek kandırabiliyorum.
njbair

Bunun da senin için çalışmasına sevindim! Bunların hiçbirinin bir Linux ana bilgisayar gerektirmediğini açıklığa kavuşturmalıydım; hatta "model" dosyasını toplama, tek gereken o makinede çalışan VirtualBox olduğunu. Bash betiği karmaşık görünebilir, ancak tek yaptığı, model dosyasından satırları okumak, yaprakları arasında 0000000bve 00000017(dahil) atlamak ve bunları tek tek çalıştırmak, vboxmanage modifyvm my_vm_name --cpuidset <line>böylece bu bir kerelik olduğu için kolayca elle yapılabilir.
sxc731

Biggie yok, zaten WSL'yi ana bilgisayara kurmuştum ve Ubuntu LiveCD sadece eski AMD anakartını çevirmenin en hızlı yoluydu.
njbair
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.