← laboratuvar · bellek eğitimi · ders

Bir Dakikalık Kara Ekran

Önce evrensel kısım: bellek neden eğitilir, eğitim neyi arar, neden her seferinde biraz farklı sonuç verir. Sonra vaka: bir dizüstünün firmware'i "ne zaman baştan eğiteyim" sorusuna ne cevap veriyor, ve bu cevap kasa açmadan, yalnız saati oynatarak nasıl bulundu.

Vakadaki makinenin belleği saniyede 5200 milyon kez veri aktarıyor. Tek bir bitin telde kalma süresi bunun tersi: 1 / 5 200 000 000 saniye, yani yaklaşık 192 pikosaniye.

Bunu bir mesafeye çevirelim. Işık 192 pikosaniyede 6 santimetre kadar gider. Bir devre kartının üstündeki sinyal ışıktan kabaca iki kat yavaştır, yani bir bit kartta 3 santimetre kadar yol alırken ömrünü doldurur.

Bellek modülüyle işlemci arasında onlarca paralel hat var. Hepsi aynı anda yola çıkan bitleri taşıyor, ama hiçbiri tam aynı uzunlukta değil. Birkaç milimetrelik fark, pencerenin azımsanmayacak bir kısmını yer. Üstüne her çip biraz farklı hızda, her transistör sıcaklıkla biraz yavaşlıyor.

Soru şu: alıcı, her hat için biti tam ne zaman okumalı?

Tek bir hattan geçen binlerce biti üst üste çizersen şöyle bir resim çıkar: bitler 0'dan 1'e, 1'den 0'a geçerken çizgiler iki kenarda çaprazlanır, ortada ise boş bir alan kalır. O boşluk, bitin "kesin" olduğu bölge. Şekli bir göze benzediği için adı göz diyagramı (İngilizce eye diagram).

Alıcının iki ayarı var. Biri ne zaman okuduğu: saat kenarına eklenen küçük gecikme adımları, adı tap. Öbürü hangi eşikle okuduğu: "bu gerilimin üstü 1" dediği çizgi, adı Vref (İngilizce reference voltage — "karşılaştırma gerilimi"). Doğru ayar gözün tam ortası: iki kenara da, üste de alta da en uzak nokta.

Eğitim bu ortayı bulmaktır. Aşağıdaki tezgâhta dene: tara ve eğite bas. Her (tap, Vref) noktası kısa bir denemeden geçer, hatasız okunanlar boyanır, göz ortaya çıkar ve eğitim ortasına bir işaret koyar. Sonra yeniden eğite birkaç kez bas ve işaretin nereye düştüğüne bak.

Bu bir model, ölçüm değil: bir veri hattının basitleştirilmiş taklidi. Gürültü ve sıcaklık katsayıları temsilî. Yön ve biçim gerçek davranışla aynı.

İşaret her seferinde bir iki adım oynuyor. Hat aynı, koşul aynı, ama sonuç farklı. Çünkü tarama bir ölçüm, ve her ölçüm gibi gürültülü: kenardaki bir nokta bir taramada şans eseri geçer, öbüründe kalır. Merkez de ona göre kayar.

Bu, vakada gerçek eğitimlerde de görüldü. Aynı bellek yedi kez eğitildiğinde ayarların ezici çoğunluğu her seferinde aynı çıktı, oynayanlar ise bir iki adım oynadı. Rakamlar 8. bölümde.

İşin tuhaf yanı: bu ölçüm yapılırken bildiğin işlemci, yani programları çalıştıran x86 çekirdekleri, daha uyanmamış oluyor. Belleği eğitilmemiş bir işlemci program çalıştıramaz; programı koyacak güvenilir bir yeri yok.

AMD işlemcilerde eğitimi, yonganın içindeki ayrı ve küçük bir çekirdek yönetiyor. Adı PSP (İngilizce Platform Security Processor). x86 değil, bir ARM çekirdeği. Güç gelince ilk o uyanır, BIOS çipinden kendi yazılımını okur, imzasını denetler, belleği eğitir ve ancak ondan sonra x86 çekirdeklerini serbest bırakır.

Bellek hatlarını fiilen tarayan şey ise bellek denetleyicisinin fiziksel katmanındaki bir başka küçük işlemci. Yani tek bir yongada, sen hiç görmeden, birkaç ayrı işlemci sırayla çalışıyor.

açılış zinciri, güç düğmesinden ilk x86 talimatına

Kabaca sıra şöyle (AMD platformları için açık kaynak belgelerle uyumlu, ayrıntı nesilden nesile değişir):

  1. Güç gelir; PSP kendi silikonuna gömülü, değiştirilemeyen küçük ROM'dan çalışmaya başlar.
  2. ROM, BIOS çipinde PSP'nin yazılım dizinini bulur. Her parçanın imzası AMD'nin anahtarıyla denetlenir; anahtarın özeti işlemcinin içine kalıcı olarak yazılmıştır.
  3. PSP'nin kendi önyükleyicisi ve küçük işletim sistemi çalışır.
  4. Bellek eğitimini yöneten kod ve DDR5 fiziksel katmanının eğitim yazılımı yüklenir. Eğitim burada olur ya da kayıttan geri yüklenir.
  5. Güç yönetimi işlemcisi gibi diğer iç işlemcilerin yazılımları da bu aşamalarda yüklenir; hangisinin eğitimden önce, hangisinin sonra geldiği nesle göre değişir.
  6. PSP, BIOS'un ilk bölümünü artık çalışan belleğe yerleştirir ve x86 çekirdeklerini serbest bırakır. x86'nın ilk talimatı ancak şimdi çalışır.

Yani kara ekranın sürdüğü o bir dakikada ekranı çizecek olan x86 henüz hiç çalışmamış oluyor. Ekran bu yüzden kara.

Tam bir eğitim onlarca saniye sürüyor, çünkü her hat için yüzlerce (tap, Vref) noktası denenmeli. Her açılışta bunu yapmak kimsenin istemeyeceği bir şey. Bu yüzden eğitimin sonucu, hat başına seçilmiş ayarlardan oluşan bir tablo, BIOS çipine kaydedilir. Sonraki açılışlar ölçmez, tabloyu yükler. Vakadaki makinede fark: tam eğitimle yaklaşık 57 saniye, kayıttan yaklaşık 7 saniye firmware süresi.

Ama kayıt bir fotoğraf: çekildiği anın koşullarını gösterir. RAM değiştirilmişse, işlemci başkasıysa, sıcaklık çok farklıysa, yazılım güncellendiyse, o fotoğraf artık bugünü göstermeyebilir. Bayat bir ayarla açılmak rastgele bellek hataları demek.

Firmware her açılışta bir karar veriyor: kayda güveneyim mi, baştan mı ölçeyim? Hızla güvenlik arasında bir denge. Bu kararın kuralı ise genellikle hiçbir yerde yazmıyor.

Bu kararı kendin vermeyi denemek istersen: tezgâhtaki politika oyunu. Sekiz olay kartı, her birinde "güven mi, eğit mi".

Vakadaki makinede bir gün açılış iki kez üst üste bir dakika sürdü, sonra normale döndü. Sebebini bulmak için kaydın kendisine bakıldı. Makinenin firmware'i, kendi üzerinde ve salt okunarak incelendi; hiçbir şey yazılmadı, değiştirilmedi. (Bu sayfa inceleme yöntemini anlatmıyor, yalnız bulunanları.)

AMD bu kayda APOB diyor (İngilizce AGESA PSP Output Buffer — "PSP'nin çıktı tamponu"). Eğitimden sonra PSP bu tamponu belleğe yazar, bir kopyasını da BIOS çipinde saklar. Açılışta geri yüklenen şey o kopya.

Tamponun yapısı AMD'nin açık kaynak başlatma projesi openSIL'in başlık dosyalarında tanımlı. Vakadaki kopya bu tanımlara birebir oturdu: APOB imzası, 62 KB, 25 giriş. Her giriş bir grup ve tür numarası taşıyor: bellek, çekirdekler, genel ayarlar, olay günlüğü…

her girişin bir imzası var

openSIL tanımına göre her girişin başlığında 32 baytlık bir HMAC var: yalnız anahtarı bilenin üretebileceği bir özet. PSP, bir sonraki açılışta kaydın kendi yazdığı kayıt olduğunu buradan denetleyebilir. Vakada da içeriği değişen her girişin HMAC'i değişti, içeriği aynı kalanların aynı kaldı.

Yani kayıt okunabiliyor, ama anahtarı bilmeyen birinin yazdığı sahte bir kaydın kabul edilmemesi amaçlanıyor: imza okumayı değil, sahteciliği engellemek için.

İlk kanıt: bellek modülünün kimliği

Bellek modülünün üstünde, kimliğini ve hız değerlerini taşıyan küçük bir bilgi çipi var: SPD (İngilizce Serial Presence Detect). Linux bu çipi spd5118 sürücüsüyle okuyabiliyor: DDR5'te 1024 bayt.

Kayıttaki "DIMM SPD verisi" girişi ile modülün kendi çipinden okunan 1024 bayt karşılaştırıldı: 1024 baytın 1024'ü aynı. x86 daha uyanmadan PSP modülün kimliğini okumuş ve kaydına koymuş. Tanımların doğru okunduğunun da ilk kanıtı bu oldu.

Bir ayrıntı: modül 5600 MT/s için yapılmış, ama makine onu 5200'de çalıştırıyor. Hızı modül değil, eğitimi yapan platform belirliyor.

Kayıttaki tarih

"Açılış bilgisi" girişinde AMD'nin tanımında adı LastPmuTrainTime olan bir alan var: son eğitimin zamanı. Değeri 0x00260924. Onaltılık okuyunca anlamsız bir sayı, ama iki haneli gruplar halinde okununca: 26 · 09 · 24, yani 24 Eylül 2026. Kayıt alındığı gün.

Firmware son eğitimin tarihini tutuyor. Saatini değil, yalnız gününü.

neden onaltılık okunuş "26-09-24" veriyor

Bu kodlamanın adı BCD (İngilizce binary-coded decimal — "ikilikle kodlanmış onluk"): her 4 bit tek bir onluk rakam tutar. 0x26 onaltılıkta 38 eder, ama BCD'de "2 ve 6" demek. Bilgisayarların gerçek zaman saati tarihleri tarihsel olarak böyle tutar; kayıt da saatten okuduğunu aynen yazmış.

Makinenin açılış süreleri sistem günlüğünde duruyordu. O günkü iki uzun açılışın öncesinde bilgisayarın saati bozulmuştu: bir tanı aracı, çalışırken saatin içine veri yazan bir yöntem kullanmış ve tarihi 2024'e atmıştı. Günlük şunu gösteriyordu:

  • Saat 2024'e düştükten sonraki açılış: 57 s. Tarih, son eğitim tarihinden geride.
  • Saat ağdan düzeltildikten sonraki açılış: 57 s. Tarih, 2024'teki o yeni kayda göre yaklaşık 22 ay ileride.
  • Aynı gün içindeki öbür açılışlar: 7 s.

Hipotez: tarih son eğitimden geriye giderse ya da çok ileri sıçrarsa firmware kayda güvenmiyor. Ama her gün yeni bir tarih ve açılışlar her gün 7 saniye, yani "tarih değişti" tek başına sebep değil. "Çok ileri" ne kadar?

Deney basit: bilgisayarın donanım saatini (RTC) belli bir tarihe al, yeniden başlat, iki şeye bak. Biri firmware süresi (57 s mi, 7 s mi). Öbürü kaydın içindeki tarih: eğitim olduysa yeni tarih yazılmış olmalı. İki bağımsız kanıt, aynı soru.

Saat oynatılırken ağ saati geçici olarak kapatıldı ve her deneyin sonunda geri açıldı. Saatin ileri atladığı açılışlarda zamanlanmış görevlerin bir şey silmediği ayrıca denetlendi. Her adım bir öncekinin sonucuna göre seçildi:

deneysaat, son eğitime görefirmwareeğitim
E11 gün geri57,6 svar
E21 gün ileri, aynı ay7,0 syok · kayda dokunulmadı bile
E39 gün ileri, ay değişti57,6 svar
E3 dönüşü8 gün geri57,6 svar
E46 gün ileri, aynı ay7,0 syok
E4 dönüşüönceki açılışa göre geri, ama son eğitimle aynı gün7,0 syok
E5a37 gün ileri (ayın son günü)57,6 svar
E5b1 gün ileri, ama ay değişti57,6 svar
E5 dönüşügeri57,6 svar

İki sonuç kilit. E4 dönüşü: saat bir önceki açılışa göre geri gitti ama eğitim olmadı, çünkü son eğitimin tarihiyle aynı gündü. Yani firmware bir önceki açılışla değil, kayıttaki tarihle karşılaştırıyor.

E5b: yalnız bir gün ileri gidildi, ama ay değişti ve eğitim oldu. E2'de de bir gün ileri gidilmişti, ay aynıydı, eğitim olmamıştı. İkisi arasındaki tek fark ay.

Kural

Saat, son eğitimin tarihinden gerideyse ya da ay (veya yıl) farklıysa: baştan eğit. Aynı ay içinde ileriyse: kayda güven.

Pratik anlamı: bu makinede her ayın ilk açılışı yaklaşık bir dakika sürüyor. O günkü gizemin cevabı da buydu: saat önce geriye, sonra yirmi iki ay ileriye gitmişti.

Yalnız yılın değişip ayın aynı kaldığı durum (örneğin bir Eylül'den ertesi Eylül'e) denenmedi; kural "ay ya da yıl" diye yazıldı ama o parça çıkarım.

Deney bir yan ürün bıraktı: aynı belleğin yedi ayrı eğitim kaydı. Eğitim sonuçlarının durduğu 16 384 baytlık giriş yedi kayıtta karşılaştırıldı:

  • %96,6'sı hiç oynamadı. 16 384 baytın 15 832'si yedi eğitimde de aynı çıktı.
  • Oynayan 552 baytın dörtte üçü en fazla 2 adım oynadı. Tezgâhtaki işaretin bir iki adım kaymasının gerçek hali.
  • Hiçbir eğitim ötekilerden ayrışmadı: "kötü bir eğitim" yok, gürültü her birinde benzer.

En ilginç olanı iki durumlu bir alan: yedi eğitimde ya 0x55 ya 0x44 çıktı, arası hiç çıkmadı; biri dört, öbürü üç kez. Sürekli bir değer olsaydı arada bir yerler de görülürdü. Görülmedi. Eğitim burada iki aday arasında kalıyor ve ikisi neredeyse eşit iyi olduğu için bazen birini, bazen öbürünü seçiyor. En iyi nokta sivri bir tepe değil, bir düzlük.

Hangi baytın hangi hatta, hangi ayara karşılık geldiği bulunamadı: o yerleşim fiziksel katmanın üreticisine ait ve açık bir kaynakta bulunamadı. Buradaki sayılar yalnız "ne kadar oynuyor" sorusunu cevaplıyor.

  • Tek makine. Kural bu dizüstünün firmware'ine ait. Başka AMD makinelerinde, başka firmware sürümlerinde farklı olabilir. AMD'nin gelişmiş ayarlarında bu davranışın bir adı var (Memory Context Restore) ve bu makinede gizli bir menüde "Auto" durumunda.
  • Takvim kuralının yıl kısmı ayrı denenmedi.
  • RAM ya da işlemci değişince ne olduğu denenmedi. Kayıtta modülün kimliği ve bir işlemci seri alanı var; değişince baştan eğitmesi beklenir ama ölçülmedi.
  • Sıcaklık. Bütün deneyler oda sıcaklığında yapıldı; kuralın sıcaklığı sorup sormadığı bilinmiyor. Sormuyorsa, aynı ay içinde soğuk ya da sıcak her açılışta kayda güvenir. Tezgâhtaki model bunun neden risk olabileceğini gösteriyor; gerçek bellekte kenar payı ne kadar, ölçülmedi.

Bu sayfa ne yapıldığını ve ne bulunduğunu anlatıyor, kopyalanıp çalıştırılacak komutlar vermiyor. Bilerek. Saati geri almak dosya zamanlarını, yedekleme araçlarını ve zamanlanmış görevleri şaşırtabilir; firmware'le ilgili her işlem makineden makineye değişir. Merak edip kendi makinende bakmak istersen, önce ne yaptığını anlaman gerekiyor. Anlayan biri için bu sayfadaki anlatım yeterli.