1 puan yazan GN⁺ 2024-04-07 | 1 yorum | WhatsApp'ta paylaş
  • UEFIRC, işletim sistemi başlamadan önce anakart belleniminin UEFI önyükleme öncesi ortamında çalışan grafiksel bir IRC istemcisidir ve önyükleyiciye yönelik bir ortamda bile normal uygulamalara yakın bir arayüz ve ağ işlevlerinin uygulanabileceğini gösterir
  • Uygulama, UEFI'nin ağdan önyükleme için sunduğu NIC sürücüleri ve TCP yığınını kullanır; QEMU için vmnet ağ arka ucu da geliştirmeyi mümkün kılar
  • En zorlu kısım, Rust içinde UEFI TCP protokolünü ele almaktı; global durum, yeniden girişli callback'ler, scatter-gather buffer'lar ile event, token, handle ve protocol'ler karmaşık biçimde iç içe geçer
  • GUI, axle'ın Rust GUI araç takımı ile TrueType renderer'ının UEFI'ye taşınmış hâlidir; fare girişi, kaydırma çubuğu ve kaydırma görünümünde metin render etmek için libgui iyileştirmeleri de birlikte yapıldı
  • Ortaya çıkan sonuç, pratik bir IRC istemcisinden çok özenle hazırlanmış şaka amaçlı bir projeye daha yakındır; yine de UEFI TCP/IP yığınına dair şikâyetleri UEFI içinden IRC ile dile getirmeye yarayan bir araçtır

UEFIRC ne yapıyor?

  • UEFIRC, UEFI'de çalışan grafiksel bir IRC istemcisidir
  • Rust ile yazılmıştır ve axle kullanıcı alanı için geliştirilmiş GUI araç takımı ile TrueType renderer'ını kullanır
  • IRC sunucusuna bağlanıp sohbet edebilir ve mesajları okuyabilir
  • Geliştirmede QEMU için vmnet ağ arka ucu kullanıldı

Çalışma sahnesi olarak UEFI

  • İşletim sisteminin önyükleyicisi, anakart ROM'unda saklanan bellenimin yardımıyla yüklenir
  • Geçmişte BIOS'un çeşitli kısıtları vardı ve bunların yerine UEFI standardı oluşturuldu
    • BIOS, önyükleyicinin 16-bit modda başlamasını gerektirir
    • İlk aşama yükleyicinin 512 bayta sığması gerekliliği de vardır
  • UEFI, önyükleyiciyi en baştan 64-bit bir ortama koyar ve VESA ekran çözünürlüğü değiştirme, bellek ayırma, EFI dosya sistemine erişim gibi API'ler sunar
  • BIOS'a göre büyük bir ilerleme olsa da aşırı tasarlanmış olduğuna dair eleştiriler de alır

Ağdan önyükleme işlevini IRC için yeniden kullanmak

  • Bazı önyükleyiciler, işletim sistemini yerel blok aygıtları yerine ağ üzerinden yükleyebilir
  • Bu kullanım senaryosunu desteklemek için UEFI belleniminin bir ağ yığını içermesi gerekir
    • NIC sürücüsü
    • TCP uygulaması
    • Önyükleme öncesi ortamda çalışan uygulamaların bu yığına erişmesini sağlayan API
  • Önyükleyicinin mutlaka bir işletim sistemi yüklemesi gerekmediğinden, aynı ortamda bir IRC istemcisi de çalıştırılabilir

Rust içinde UEFI TCP ile çalışmanın zorlukları

  • Projedeki en zor kısım, UEFI TCP protokol istemcisini Rust ile uygulamaktı
  • UEFI TCP protokolü, Rust'ta ifade edilmesi zor veri ömürleri ve etkileşimler gerektirir
    • global durum
    • yeniden girişli callback'ler
    • scatter-gather buffer'lar
    • event'ler, token'lar, handle'lar, protocol'ler
  • Bellek sızıntılarını ve TCP alma buffer'ındaki use-after-free sorunlarını gidermek için Rust kodu günlerce test edildi

NOTIFY_SIGNAL ve NOTIFY_WAIT karmaşası

  • UEFI event API'sinin davranışını yalnızca isimlerine bakarak tahmin etmek zordur
  • NOTIFY_SIGNAL belirtildiğinde event oluşunca callback çağrılır ve wait() kullanımı hata olur
  • NOTIFY_WAIT belirtilip wait() çağrıldığında, UEFI event gerçekleşmeden önce callback'i birden çok kez çağırabilir; event gerçekleşince de wait() çözülür
  • İki mod, aynı callback için bile tamamen farklı anlamlar taşır
    • NOTIFY_SIGNAL: Event gerçekleşti, bir sonraki işe geçme zamanı
    • NOTIFY_WAIT: Event henüz gerçekleşmedi, ilerlemeyi teşvik etme zamanı
  • Alınan paket verilerini asenkron tamponlamak için sonunda NOTIFY_WAIT döngüsü ile kısa zaman aşımı timer'ı birlikte kullanıldı

Fare ve imleç desteği

  • IRC istemcisi için fare şart değildir ama uygulamanın daha etkileşimli hissettirmesini sağlar
  • UEFI'nin Simple Pointer Protocol özelliği kullanılarak fare hareketi ve tuş girdileri okunur, GUI'ye de imleç konumu geri bildirimi eklenir
  • Simple Pointer Protocol kaydırma tekerleğini desteklemez
    • UEFIRC'de ok tuşlarını kullanmak veya imleçle kaydırma çubuğunu sürüklemek gerekir
  • Standart OVMF UEFI belleniminde fare event'leri alınamadığı için, UsbMouseDxe gibi gerekli sürücü ve protocol'leri içeren özel bir UEFI bellenimi derlendi
  • UEFIRC'nin QEMU üzerinde denenebilmesi için ilgili UEFI bellenimi de sürümler sayfasına yüklendi

Fare hareketi ölçekleme

  • Fare sürücüsü mutlak konum yerine konum değişimini bildirir
  • Sadece delta_x ve delta_y değerlerini doğrudan ekleyen doğrusal ölçekleme hantalmış gibi hissettirir
  • İşletim sistemleri, hızlı hareket ile ince ayarı birlikte mümkün kılan bir yaklaşıma daha yakın ölçekleme kullanır
  • Örnek uygulamada, hareket miktarlarının mutlak değerler toplamına log2() uygulanıp çıkan değerle imleç hareketi çarpılarak artırılır
  • Doğrusal hareket eden imleç, tüm ortamın yavaş ve tepkisiz olduğu hissini kolayca verebilir

IRC mesajlarını modellemek

  • IRC mesajlarını modellemek nispeten basit ve keyifliydi
  • IRC, parse edilmesi kolay metin tabanlı satır formatı kullanır
  • Ancak onlarca yıla yayılan genişlemeler nedeniyle yalnızca bazı bölümleri standartlaştırılmıştır

UEFI'de libgui kullanımı

  • axle'ın Rust GUI araç takımı, axle dışındaki bağlamlarda da kullanılabilsin diye zaten büyük ölçüde hazırlanmıştı; bu yüzden UEFI'de çalıştırmak çok zor olmadı
  • Temel iş, UEFI içinde kullanılabilecek bir AwmWindow uygulaması sağlamaktı
  • Sonrasında libgui'nin çeşitli özellikleri doğrudan kullanıldı
    • event yönetimi
    • font render etme
    • katman birleştirme
    • görünüm süslemeleri
    • scroll view gibi daha karmaşık bileşenler

Kaydırma çubuğu ve kaydırma görünümünde metin render etme

  • axle'ın C tabanlı libgui'sinde kaydırma çubuğu işlevi vardı ama Rust sürümünde bazı özellikler henüz eksikti
  • UEFIRC'nin ana etkileşimi metinle dolu bir scroll view içinde gerçekleştiğinden, Rust libgui'de kaydırma çubuğu işlevi yeniden uygulandı
  • Scroll view, sabit boyutlu bir görünümden daha yüksek piksel render maliyetine sahiptir
    • Sabit boyutlu görünüm için width * height boyutunda bir RGB buffer düşünmek yeterlidir
    • Scroll view ise sonsuza dek genişleyebilecek bir canvas ile uğraşmak zorundadır
  • axle'ın Rust GUI araç takımı, scroll view'ü tile tabanlı olarak işler
    • Her tile, birkaç yüz piksel genişliğinde kare bir piksel buffer'ıdır
    • Yalnızca içeriğin gerçekten render edildiği alan için gereken tile'lar ayrılır
    • Görünen tile'lar hesaplanıp son görüntüye birleştirilir
  • TrueType renderer her glif pikseli için putpixel() çağırdığında, scroll view tüm render alanını önceden bilemediği için verimsizlik oluşur
  • Bunu çözmek için polygon stack'e çizgi, daire, dikdörtgen gibi temel çizim birimleri eklendi
    • Scroll view büyük bir poligon çizileceğini bilerek gerekli tile'ları önceden ayırabilir
    • Rastgele poligon doldurmayı temel primitive yapmak pek hoş görünmese de pratikte iyi çalışır

UEFIRC yapılırken geliştirilen libgui

Tamamen gereksiz bir sonuç

  • IRC istemcisinin kendisi, özenli bir şaka projesi olduğundan gerçek kullanım açısından çok pratik değildir
  • UEFI TCP/IP yığınına sinirlendiğinizde, bu şikâyetleri anlatmak için kullanılabilir
  • Son olarak, UEFI içinden UEFI #edk2 geliştirme IRC kanalına bağlanıp selam verildi

1 yorum

 
GN⁺ 2024-04-07
Hacker News yorumları
  • Şaka olsun diye yalnızca UEFI önyükleme öncesi ortamında çalışan grafiksel bir IRC istemcisi yaptım; TrueType yazı tipleri, imleç, GUI süslemeleri gibi gereğinden fazla özellikler de ekledim
    Aslında sıfırdan yaptığım GPS alıcısından yorulup hızlı ve hafif bir şey denemek istemiştim, ama her zamanki gibi beklediğimden çok daha uzun sürdü
    Yazıda kaydırma görünümünü modelleyip sabit bir viewport'a render etme yöntemini gösteren görselleştirmeye de epey zaman harcadım; umarım keyifle bakarsınız
    Başta “UEFI'ye olmaması gereken bir şeyi zorla sokalım” fikriyle bir Twitter istemcisi düşündüm, ama birileri zaten UEFI'nin HTTP protokolüyle bunu gayet iyi yapmış olduğu için HTTP'den kaçınmaya karar verdim
    Bu yüzden TCP üzerinde çalışan ve önyükleme öncesi ortamla hiç uyuşmayan sosyal medya hissi de taşıyan IRC'yi seçtim

    • “Önyükleme öncesi ortamın yakınında bile olmaması gereken bir şey” deniyor ama, önyükleme sorununda yardım istemek için aslında tam da uygun yer gibi görünüyor
    • Gereksiz derecede büyük işletim sistemini ve türlü ek özellikleri bırakıp daha küçük ve daha basit UEFI'ye geçmek istiyorum. Hem daha hızlı başlar hem de “embedded” geliştirme daha kolay olurdu
      Tabii şaka yapıyorum. Bir yere kadar
      Minimalist biri olarak GUI'ye ya da fareye de ihtiyacım yok; UEFI bile bana gerekenin fazlası gibi geliyor
      Bahsi geçen Twitter istemcisi burada: https://github.com/arata-nvm/mitnal
    • UEFI'ye tıkıştırılamayacak kadar büyük bir yazılımsa, baştan gereksiz şişkin yazılım sayılmalı. Eskiden iki tane 360KB disket yeterdi
    • Gerçekten harika. Uzun zamandır VPN kimlik bilgilerini UEFI'de saklayıp sistemin bir sunucuya bağlanarak PXE ağ önyüklemesi yapmasını sağlayıp sağlayamayacağımı merak ediyordum
      Kurulum tamamen bozulup normal açılış yapılamayan uzak sistemleri otomatik kurtarmayı belki güvenli biçimde mümkün kılan oldukça iyi bir yöntem olabilir gibi görünüyor
    • Sıfırdan yapılan GPS alıcısı kısmını daha çok merak ettim
  • Gerçekten çok iyi. Çoğu insanın sistemin altında sandığından daha karmaşık ve güçlü yazılımlar bulunduğunu da güzel gösteriyor
    İşletim sisteminin yazılım yığınının “en alt katmanı” olduğu sık sık yanlış sanılır, ama gerçekte sistemi gerçekten sahiplenen firmware benzeri kod vardır
    Bazen işini bitirip ortadan kaybolur, bazense işletim sisteminin bile fark etmediği şekilde sistem açık kaldığı sürece orada kalır
    “Sadece aygıtları çalıştıran düşük seviyeli kod, orada ciddi bir şey olmaz” yaklaşımı var; ama bunun altına bir IRC istemcisi bile sığabiliyorsa, başka kötü niyetli şeyleri de rahatça hayal etmek mümkün

  • “Neden?” mi? “Neden” nasıl bir soru? Ben HN'ye tam da bu ruhu görmek için geliyorum
    “En korkunç farkındalık üzerime çöktü. Yaptığım şey için hiçbir neden yoktu. Neden yaptığımı biliyordum. Sadece eğlenceli olacağını düşündüğüm için yaptım. Ama insanların ‘Bunu neden yaptın?’ diye soracağını ve yeterince makul bir cevabım olmazsa beni akıl hastanesine kapatacaklarını düşündüm.” — Boyd Rice

  • Kendini küçümsemene gerek yok. Burada bir botnet komuta-kontrol istemcisi projesi var
    Arayüz biraz komik gerçi

  • Gerçekten harika. UEFI API'sinin bu kadar erişilebilir ve iyi belgelenmiş olduğunu bilmiyordum
    Geliştirme döngüsünün nasıl olduğunu merak ediyorum. Muhtemelen bir VM'de çalıştırılmıştır; istemciyi her çalıştırdığında gerçekten yeniden “önyükleme” mi yapman gerekiyordu?

    • Tipik çalışma döngüsü, UEFI uygulamasını yükleyip bir QEMU örneğini önyüklemek şeklindeydi
      Ana çalışma betiği, UEFIRC'in yeni derlemesini içeren EFI dosya sistemini yeniden oluşturuyor ve bunu QEMU'ya veriyordu
      Ama GUI yaparken bu ek yük iyice can sıkıcı hale geldiği için, uygulamanın hem saf UEFI'yi hem de Mac üzerinde çalışan bir host ortamını hedefleyecek şekilde derlenmesini ayarladım
      Derleme bayraklarını değiştirince GUI araç takımı ya UEFI'nin sağladığı framebuffer'a doğrudan çiziyor ya da Mac'in pencere sistemine bağlanıp olay gönderip alıyor
      Bu çift hedefli yaklaşımın ek yükü giriş noktasında da görülebilir: https://github.com/codyd51/uefirc/blob/main/src/main.rs
      IRC mesaj ayrıştırmasını ayrı bir süsleme gerektirmediği için doğrudan Mac'te çalışan birim testleriyle geliştirdim; bazıları burada: https://github.com/codyd51/uefirc/blob/main/src/irc/response...
    • QEMU, UEFI uygulamalarını çalıştırabilir
  • Bir gün hâlâ çalışan IRC botum için yazdığım işletim sistemini bitirmek istiyorum
    Belki de söylenebilecek en faydasız şey ama, doğrusal olmayan fare hareketi yani ivmelenme, yeni bir işletim sistemi açtığımda kapattığım ilk ayardır. Garip biçimde elim gerçekten ağrıyor
    Örneğin Mac'te ücretsiz linearmouse var, Windows'ta ise ivmelenmeyi kapatmak yeterli. Linux'ta ise zaten kolay
    Fare ivmelenmesi kullanınca, farenin fiziksel hareket mesafesiyle ekrandaki hareket arasındaki eşlemeyi sezgisel olarak öğrenmek zorlaşıyor; uzun vadede ivmelenmesiz kullanmanın daha verimli olduğuna inanıyorum
    Bunu oyunculardan öğrendim ve oyuncuların hâlâ böyle yapması için geçerli nedenleri olduğunu düşünüyorum

    • Fare ayarlarını değiştirmediğim için varsayılanın ne olduğunu bilmiyorum, ama gizlenmiş ekran alanlarına da hâlâ doğru şekilde tıklayabiliyorum
      Her iki durumda da insanın hissi alışıyor gibi geliyor. Tıpkı bir arabanın gaz pedalının da genelde doğrudan hıza eşlenmemesi gibi
  • “Neden?” diye soruyorsanız, UEFI ilk tanıtıldığında böyle düşük seviyeli uygulamalar vaat edilmişti
    UEFI'yi geliştirenler, bazı üreticilerin önyükleme sırasında belirli bir tuşa basarak erişim verdiği Linux tabanlı yalnızca internet için mini işletim sistemlerinin bile yerini almasını hayal ediyordu. Adını hatırlamıyorum

    • Bu, eski Dell'lerde ve benzerlerinde bulunan Quick View / Quick Boot özelliğiydi. Genelde birkaç üretkenlik uygulamasına doğrudan açılıyordu
      YouTube'da bunu derinlemesine ele alan bir video izlemiştim; hatırladığım kadarıyla önce küçültülmüş Linux ya da başka özelleştirilmiş bir işletim sistemiydi, sonra UEFI uygulamasına taşındı ve sonunda modası geçti
  • Yazı güzel. İki yıl önce barebox önyükleyicisinin 1 Nisan şakasını hatırlattı. Diğer tüm önyükleme hedefleri başarısız olursa #barebox kanalına bağlayan bir özellikti[1]
    Onların odağı barebox'a TCP desteği eklemekti; buradaki gibi havalı GUI öğeleri yoktu
    Arayüz yalnızca komut satırıydı ve barebox EFI payload olarak derlenirse EFI GOP üzerinde çizim yapabiliyordu
    [1]: https://lore.barebox.org/barebox/20220401145902.GF4351@telli...

  • Aklıma hemen Cathode Ray Dude'un yakın tarihli videosu geldi. HP'nin “e-posta istemcisi”ni, aslında Outlook eklentisi olan QuickLook'u ele alıyordu; bu da böyle uygulanıp piyasaya sürülmüş bir üründü: https://www.youtube.com/watch?v=ssob-7sGVWs
    Videoda HP'nin yaptığı daha da tuhaf şeyler de var. Ama bu proje, QuickLook'un kaçındığı zor kısmı yani ağ iletişimini de başarıyor

  • Yazıdaki görselleştirme şaşırtıcı derecede iyi ve etkileyici