2 puan yazan GN⁺ 2025-04-06 | 1 yorum | WhatsApp'ta paylaş
  • Apple’ın Darwin sistemi, macOS, iOS ve modern Apple işletim sistemlerinin Unix tabanlı temelidir; XNU ise Mach ile BSD’yi tek bir çekirdek içinde birleştiren hibrit bir çekirdektir
  • XNU, Mach’ın görev, iş parçacığı, sanal bellek ve port tabanlı IPC yapısını korurken BSD hizmetlerini aynı çekirdek adres alanında tutarak, saf mikrokernel tarzı mesajlaşmanın maliyetini azaltır
  • NeXTSTEP’in Mach 2.5+4.3BSD soyu, Apple’ın 1996’da NeXT’i satın almasının ardından Mac OS X ve Darwin’e dönüştü; daha sonra FreeBSD kodu, I/O Kit, 64 bit, ARM ve Apple Silicon desteği aşamalı olarak eklendi
  • macOS ve iOS; sandbox, kod imzalama, SIP, APFS, DriverKit, QoS zamanlama, Jetsam ve sıkıştırılmış bellek gibi özellikleri çekirdek ile kullanıcı alanının iş birliğiyle genişletti
  • XNU’nun evrimi, çekirdeği baştan yazmaktan ziyade Mach/BSD temelini koruyup, performans gerektiren bölümleri çekirdeğe entegre etme ve yalıtım gerektiren bölümleri IPC ile kullanıcı alanına ayırma yaklaşımına daha yakındır

Darwin ve XNU’nun çıkış noktası

  • Darwin, macOS, iOS ve Apple’ın modern işletim sistemi platformlarını taşıyan Unix ailesinden çekirdek işletim sistemi temelidir
  • Merkezinde, “X is Not Unix” ifadesinin kısaltması olan XNU çekirdeği bulunur ve bu çekirdek Mach mikrokernel çekirdeği ile BSD Unix bileşenlerini birleştirir
  • Bu yapı, Mach’ın mesajlaşma tabanlı tasarımı ile BSD’nin kararlılığı ve POSIX uyumluluğunu birlikte kullanarak modülerlik ile performans arasında denge kurmayı hedefler

Mach, NeXTSTEP ve Mac OS X’e uzanan tarih

  • Mach, 1985’te Carnegie Mellon University’de Richard Rashid ve Avie Tevanian’ın öncülük ettiği bir proje olarak başladı
    • Bellek yönetimi, CPU zamanlama ve IPC gibi düşük seviyeli işlevleri çekirdekte tutup dosya sistemi, ağ ve sürücüleri kullanıcı alanı sunucularına taşımayı amaçlayan bir mikrokernel tasarımıydı
    • Görevler, iş parçacıkları, Mach portları, copy-on-write ve bellek nesneleri gibi kavramlar çekirdeğin temel nesneleri hâline geldi
  • NeXTSTEP, 1989’da Mach 2.5 çekirdeği üzerine 4.3BSD Unix alt sistemi yerleştirilerek piyasaya sürüldü
    • NeXT, saf mikrokernel yaklaşımı yerine BSD kodunu çekirdek adres alanına entegre etmeyi seçerek performansa öncelik verdi
    • Objective-C tabanlı DriverKit’i de içeriyordu ve bu soy daha sonra Apple’ın XNU çizgisine bağlandı
  • Apple, 1996’da NeXT’i satın aldı ve NeXTSTEP’i yeni Mac OS X için temel olarak seçti
    • Rhapsody projesi başlarken, NeXT’in Mach/BSD hibrit çekirdeği Apple’a taşındı
    • Sonrasında XNU, OSFMK 7.3 tabanlı Mach 3.0 ailesi kodunu ve 4.4BSD ile FreeBSD kodunu bünyesine kattı

Darwin ve Mac OS X’in ilk gelişimi

  • Apple, 1999’da Mac OS X geliştirici önizlemesini sundu ve 2000’de Darwin 1.0’ı yayımlayarak XNU çekirdeği ile temel Unix kullanıcı alanını geliştiricilere açtı
  • Mac OS X 10.0 Cheetah, 2001’de Darwin 1.3.1 tabanlı ticari sürüm olarak çıktı
  • İlk dönemdeki değişimlerin odağı, BSD katmanını, ağı, dosya sistemini ve iş parçacığı performansını güçlendirmekti
    • Mac OS X 10.1 Puma, iş parçacığı yönetimi performansını ve gerçek zamanlı iş parçacığı desteğini iyileştirdi
    • Mac OS X 10.2 Jaguar; IPv6, IPSec, mDNSResponder ve HFS+ journaling içeriyordu
    • Mac OS X 10.3 Panther, FreeBSD 5 çekirdek iyileştirmelerini ve daha ayrıntılı çekirdek kilitlemesini entegre ederek çok işlemcili kullanımını güçlendirdi
  • Mac OS X 10.4 Tiger, UNIX 03 sertifikası aldı, FreeBSD’nin kqueue/kevent yapısını benimsedi ve Intel Mac geçişi için çapraz platform temelini korudu

64 bit ve iPhone OS’un getirdiği mobil ihtiyaçlar

  • Mac OS X 10.5 Leopard, Darwin 9 tabanıyla 64 bit çekirdek çalıştırma, 64 bit sürücüler, ASLR, sandbox ve DTrace sundu
  • 2007’de ilk iPhone OS da Darwin 9 tabanlı olarak yayımlandı ve XNU böylece ARM mobil cihazlara kadar genişledi
    • İlk iPhone’larda RAM sınırlıydı ve swap kullanılamıyordu; bu nedenle düşük bellek durumlarında arka plan uygulamalarını sonlandıran Jetsam mekanizması kullanıldı
    • iPhone OS, üçüncü taraf uygulamaları sandbox içinde çalıştırıyor ve ikili dosyalar için katı kod imzalama şartı getiriyordu
  • Mac OS X 10.6 Snow Leopard, PowerPC desteğini bıraktı ve Intel odaklı 64 bit ile çok çekirdek optimizasyonlarını güçlendirdi
    • Grand Central Dispatch ve libdispatch kullanıcı alanı kütüphaneleri olsa da çekirdeğin iş parçacığı havuzu ve zamanlama desteğinden yararlanıyordu
    • OpenCL de GPU hesaplama için kullanıcı çerçeveleri ile çekirdek sürücülerinin sıkı entegrasyonunu gerektiriyordu
  • iOS 4, arka plan uygulamalarının öncelik ayrımına ve çok çekirdekli ARM SoC desteğine uyum sağlamak için zamanlayıcıyı ayarladı

Modern macOS ve iOS’ta çekirdek özelliklerinin genişlemesi

  • OS X 10.9 Mavericks, sıkıştırılmış bellek ve timer coalescing ekledi
    • Sıkıştırılmış bellek, etkin olmayan sayfaları RAM içinde sıkıştırarak disk swap kullanımını azaltır
    • Timer coalescing, CPU uyandırma zamanlarını hizalayarak güç tüketimini düşürür
  • OS X 10.11 El Capitan, System Integrity Protection yani SIP’i tanıttı
    • SIP, BSD katmanındaki Mandatory Access Control çerçevesi üzerinden çekirdek tarafından zorlanır ve root süreçlerinin bile kritik sistem dosyalarını ve süreçlerini değiştirmesini engeller
  • macOS 10.13 High Sierra, APFS’yi varsayılan dosya sistemi olarak getirdi
    • XNU’nun VFS katmanı, APFS’nin snapshot, cloning ve konteyner düzeyinde şifreleme özelliklerini destekleyecek şekilde genişletildi
    • Aynı dönemde üçüncü taraf kext yüklemeleri için kullanıcı onayı zorunlu hâle geldi
  • macOS 10.15 Catalina, modern DriverKit’i tanıttı
    • DriverKit, birçok sürücüyü çekirdek dışındaki kullanıcı alanı Driver Extension yapısına taşıdı
    • Çekirdek, IPC ve paylaşımlı bellek üzerinden kullanıcı alanı sürücülerine sınırlı donanım erişimi sağlar
    • Catalina ayrıca salt okunur sistem birimini getirerek SIP korumasını güçlendirdi

Apple Silicon döneminde XNU

  • 2020’de çıkan macOS 11 Big Sur ve Darwin 20, Apple Silicon Mac’leri destekleyen ilk sürümdü
  • XNU, iOS sayesinde zaten ARM desteğine sahipti ancak Apple Silicon Mac’lerde heterojen big.LITTLE CPU yapısı da dikkate alınmak zorundaydı
    • Zamanlayıcı, yüksek öncelikli ve ağır iş parçacıklarını performans çekirdeklerine; düşük QoS veya arka plan iş parçacıklarını verimlilik çekirdeklerine yerleştirebilmek için heterojen çekirdeklerin farkındadır
    • QoS sınıfları, Apple Silicon’da çekirdek türü seçiminde de etkili olabilen zamanlama ipuçları olarak kullanılır
  • Apple Silicon’un birleşik bellek mimarisinde, çekirdek bellek yöneticisi ve GPU sürücüleri tampon paylaşımını yönetir
    • Mach VM soyutlaması, kullanıcı alanı ile GPU arasında kopyalama yerine VM yeniden eşleme yoluyla bellek nesnelerini paylaşmaya uygundur
  • ARM64 arka ucu, Pointer Authentication desteği sunar; istisna çerçeveleri ve sistem işaretçileri için PAC anahtarları kullanarak ROP saldırılarının azaltılmasına katkı sağlar
  • XNU; macOS, iOS, watchOS, tvOS, bridgeOS ve visionOS gibi birçok Apple platformunun ortak temeli olmaya devam eder

XNU’nun hibrit çekirdek yapısı

  • XNU’nun Mach ve BSD bileşenleri tek bir çekirdek ikili dosyası olarak bağlanır ve aynı adres alanını paylaşır
    • Mach ile BSD arasında koruma sınırı yoktur; çekirdek içinde etkileşim IPC mesajlarıyla değil, normal fonksiyon çağrılarıyla gerçekleşir
    • read() gibi Unix sistem çağrıları, ayrı bir BSD sunucusuna mesaj göndermek yerine doğrudan çekirdek içindeki BSD dosya sistemi koduna girer
  • Mach, temel çekirdek altyapısından sorumludur
    • Görev ve iş parçacığı oluşturma/sonlandırma, bağlam değiştirme, düşük seviyeli zamanlama, kilitler, zamanlayıcılar ve zamanlama kuyruklarını yönetir
    • Her BSD süreci bir Mach görevine, her iş parçacığı da bir Mach iş parçacığına karşılık gelir
    • Mach VM; sanal adres haritaları, bellek nesneleri, copy-on-write ve IPC tabanlı bellek paylaşımı sağlar
  • BSD, Unix karakterini ve hizmetlerini sağlar
    • PID, kullanıcı kimliği, sinyaller, POSIX iş parçacıkları, dosya sistemleri, ağ, Unix IPC, aygıt G/Ç’si, izinler ve güvenlik çerçevelerini yönetir
    • VFS; HFS+, APFS ve NFS gibi dosya sistemlerini ele alır, bellek eşlemeli dosyalarda ise Mach VM ve vnode pager üzerinden bağlanır
    • Sandbox ve SIP, BSD güvenlik modülleri ile Mach görev portu kısıtlamalarının iş birliğiyle çalışır
  • I/O Kit, XNU’nun üçüncü ayağıdır ve sınırlı C++ biçimiyle yazılmış nesne yönelimli bir sürücü çerçevesidir
    • Aygıtları ve sürücüleri sınıf hiyerarşileri olarak ifade eder, sürücüler çekirdek içinde C++ nesneleri olarak çalışır
    • Kullanıcı alanına, I/O Registry özellikleri ve user client arayüzü üzerinden sınırlı erişim sunar
    • Modern macOS’ta DriverKit gelmeden önce sürücülerin çoğu çekirdek içinde kext olarak çalışıyordu

Mach IPC ve sistem hizmetleri

  • XNU, Unix sistem çağrısı yolunda Mach mesajlarını kullanmaz; ancak kullanıcı alanı servisleri ile çekirdek/süreçler arası iletişimde Mach IPC’den geniş ölçüde yararlanır
  • Mach portları, birçok çekirdek nesnesi için kullanıcı alanı handle’ı olarak kullanılır
    • Her görevin bir görev portu vardır ve yetkili süreçler bunu kullanarak başka görevleri inceleyebilir veya denetleyebilir
  • Olaylar ve bildirimler de Mach mesajlarıyla iletilir
    • WindowServer, kullanıcı giriş olaylarını çekirdekten Mach mesajları olarak alır
    • Grand Central Dispatch, dahili olarak Mach portlarını kullanarak olay bekleyen iş parçacıklarını uykuya alır
    • kqueue/kevent, Mach port mesajları ile dosya tanımlayıcılarını birlikte bekleyebilir
  • Apple’ın XPC çerçevesi, Mach mesajları üzerine kuruludur
    • XPC bağlantıları dahili olarak Mach portlarına dayanır
    • Mach portlarının yetki modeli, Keychain’in securityd servisi gibi yapılarda çağıran tarafın yetkisini doğrulamak için kullanılır
    • Mach mesajları, out-of-line bellek ve port yetkileri taşıyabildiği için yüksek seviyeli RPC kurulumlarında kullanılır
  • MIG yani Mach Interface Generator, çekirdek ile kullanıcı alanı arasındaki arayüz tanımlarını ve mesaj gönderme/alma kodunu üretmek için kullanılır

Zamanlayıcı ve iş parçacığı yönetimi

  • XNU zamanlayıcısı, Mach’ın öncelik tabanlı round-robin zamanlayıcısından doğdu ancak masaüstü ve mobil ihtiyaçlara uyum için büyük ölçüde değiştirildi
  • Mach tarihsel olarak 0–127 aralığında iş parçacığı öncelikleri tanımladı; XNU ise sched_pri ve base_pri gibi değerler kullanır
    • Zaman paylaşımlı iş parçacıklarının önceliği kullanıma göre değişebilir
    • Gerçek zamanlı iş parçacıkları sabit öncelik kullanır
  • XNU, CPU başına çalışma kuyruğu ve zamanlayıcı kesmeleriyle verimlilik ve yük dengelemesini yönetir
  • iOS’taki uygulama sandbox’ı ve arka plan yürütme modeli, iş rolü veya öncelik grubu kavramlarını zamanlayıcıya yansıtır
  • QoS sınıfları, iOS 8 ve OS X 10.10’dan sonra zamanlamaya entegre edildi
    • user-interactive, user-initiated, default, utility ve background gibi sınıflar öncelik bantlarını ve zamanlamayı etkiler
    • Grand Central Dispatch veya NSThread ile oluşturulan iş parçacıkları QoS devralır
    • Apple Silicon’da background QoS iş parçacıkları verimlilik çekirdeklerine yerleştirilebilir
  • Gerçek zamanlı ses ve kritik işler için gerçek zamanlı kuyruklar ile deadline tabanlı zamanlama da desteklenir

Bellek yönetimi ve Mach VM

  • XNU’nun bellek yönetiminin merkezinde Mach VM alt sistemi yer alır
  • Her Mach görevi, VM map ve VM region ile ifade edilen bir sanal adres alanına sahiptir
    • fork(), tüm belleği hemen kopyalamak yerine copy-on-write kullanır
    • Ebeveyn ve çocuk süreçler, yazma gerçekleşene kadar aynı sayfaları paylaşır
  • Mach, bellek nesnesi ve pager kavramlarını kullanır
    • Anonim belleğin varsayılan pager’ı kullanıcı alanındaki dynamic_pager daemon’udur ve gerektiğinde swap dosyalarını yönetir
    • Dosya belleğinde ise çekirdek içindeki BSD katmanında yer alan vnode pager, dosya sistemi koduyla etkileşir
  • Mavericks’in sıkıştırılmış belleği, çekirdek içindeki compression pager eklenerek hayata geçirildi
    • Bellek baskısı yükseldiğinde etkin olmayan sayfalar doğrudan diske gönderilmek yerine RAM içindeki compressor pool’da sıkıştırılarak tutulur
    • Sıkıştırma yetersiz kaldığında disk swap kullanılır
  • Fiziksel bellek yönetiminden, mimariye bağımlı katman olan pmap sorumludur
    • pmap, sayfa tablolarını veya ilgili mimarinin karşılık gelen yapılarını yönetir
    • ARM64’te güvenlik özellikleri ve önbellek ile ilgili konular da pmap ile bağlantılıdır
  • dyld paylaşımlı önbelleği, aynı fiziksel sayfaları birden fazla süreçte salt okunur eşleyerek verimli kullanım sağlar

Sanallaştırma desteği

  • Intel Mac’lerde OS X 10.10’dan itibaren Hypervisor.framework sunularak kullanıcı alanı sanallaştırması desteklendi
    • Intel VT-x kullanarak kullanıcı alanı süreçlerinin bir sanal makine monitörü gibi davranabilmesini sağladı
    • xhyve gibi araçlar ve bazı sanallaştırma uygulamaları bu özelliği kullandı
  • Apple Silicon’da macOS 11’in Virtualization.framework yapısı, ARM64 için çekirdek içi hypervisor üzerinde çalışır
    • Geliştiriciler kullanıcı alanından Linux veya macOS sanal makineleri çalıştırabilir
    • Rastgele üçüncü taraf hypervisor’ları çekirdeğe kabul etmek yerine, erişim Apple çerçeveleri ve yetkileri üzerinden sağlanır
  • Çekirdek açısından hypervisor işlevleri; misafir fiziksel belleğin yönetimi, hassas komutlar için trap-and-emulate ve vCPU arayüzünün açığa çıkarılmasını içerir
  • Mach zamanlayıcısı, ana makine açısından birer iş parçacığı olan vCPU’ları zamanlar; bellek alt sistemi de misafir bellek eşlemelerinde kullanılır
  • iOS’ta da belirli koşullar ve yetkiler altında sanallaştırma mümkündür; jailbreak yapılmış A14 cihazlarda hypervisor etkinleştirilerek Linux VM çalıştırıldığı örnekler vardır

Secure Enclave ve Exclaves

  • macOS, hassas işlemleri ve verileri korumak için Secure Enclave ile exclaves adlı iki yalıtım mekanizması kullanır
  • Secure Enclave, Apple SoC içine entegre edilmiş özel olarak sertleştirilmiş bir alt sistemdir
    • iPhone, iPad, T2 veya Apple Silicon Mac gibi cihazlarda bulunur
    • Kendi mikrokernel tabanlı işletim sistemini çalıştırır ve kriptografik anahtarlar ile biyometrik veriler gibi hassas bilgileri yönetir
    • Ana uygulama işlemcisi ya da çekirdek ele geçirilse bile kritik verileri ayrı tutmayı amaçlar
  • Exclaves, macOS 14.4 ve iOS 17 ile ortaya çıkan daha yeni bir güvenlik yapısıdır
    • Hassas işleri ana XNU çekirdeğiyle aynı yetki alanında tutmak yerine, bazı çekirdek kaynakları ayrı bir “externally located” alanına ayırır
    • Apple ID hizmetleri, ses tamponları, sensör verileri ve gösterge ışığı yönetimi bileşenleri gibi kaynaklar buna dahildir
    • ExclaveKextClient.kext, ExclaveSEPManagerProxy.kext ve ExclavesAudioKext.kext gibi özel kext’ler ile private framework’ler yönetime dâhil olur
  • Bu ayrım, ana çekirdek ele geçirilse bile exclave içindeki işleri yalıtarak ek bir savunma katmanı sağlar

Uzun vadeli tasarım yönü

  • Darwin ve XNU ne tamamen bir mikrokernel ne de tamamen monolitik bir çekirdektir; ikisinin karışımı olan bir tasarımdır
  • Mach tabanlı çekirdek, yeni mimarilere ve sistem işlevlerine uyum sağlamaya yardımcı olurken BSD katmanı POSIX uyumlu ortamı ve Unix araçlarıyla API’lerini sunar
  • Apple, PowerPC’den Intel’e ve ARM’a CPU geçişlerini; ayrıca iPhone, Apple Watch ve Apple Vision Pro gibi yeni cihaz kategorilerini XNU tabanı üzerinde destekledi
  • Çekirdek değişiklikleri başlıca üç yolla ilerledi
    • Yeni özellikler mevcut çekirdeğin üzerine genişletildi
    • Performans açısından kritik bileşenler çekirdeğin içine entegre edildi
    • Yalıtım gerektiren bileşenler Mach IPC ve kullanıcı alanı aracılığıyla ayrıldı
  • Darwin’in açık kaynak sürümleri, araştırmacılara ticari bir hibrit çekirdeği inceleme fırsatı verir; ancak açıklanan kapsam sınırlıdır

1 yorum

 
GN⁺ 2025-04-06
Hacker News yorumları
  • Mach’in sanal bellek sistemi yalnızca 4.4BSD ve FreeBSD’ye değil, NetBSD[0] ve OpenBSD[1]’ye de girmişti; ancak DragonFly BSD[2] için durum böyle görünmüyor
    [0] https://netbsd.org/docs/kernel/uvm.html
    [1] https://man.openbsd.org/OpenBSD-3.0/uvm.9
    [2] https://www.dragonflybsd.org/mailarchive/kernel/2011-04/msg0...

    • Tam olarak öyle değil. 386BSD, FreeBSD ve NetBSD başlangıçta Mach 2.5 tarzı tasarımı miras aldı; ancak FreeBSD kalan Mach VM izlerinin[0] tamamını oldukça hızlı biçimde modern ve performanslı bir VM yeniden yazımıyla değiştirdi
      FreeBSD 4 zamanına gelindiğinde çekirdek kod tabanında orijinal Mach kodu kalmamıştı; bu iş 1990’ların sonlarında zaten bitmişti. Dolayısıyla FreeBSD’yi Mach ile ilişkilendirebileceğimiz nokta, ancak çok erken dönem çatallanma/temel alma aşaması olur
      NetBSD ve OpenBSD de bunu bir süre sürdürdü, ancak Mach tasarımının performans, SMP/ölçeklenebilirlik ve ağ sınırlamalarına takılınca Chuck Cranor’un tasarlayıp öncülük ettiği UVM (Unified Virtual Memory, birleşik sanal bellek) ile tamamen yeniden yazdılar; OpenBSD daha sonra bu uygulamayı alıp kullandı ve bugün de kullanıyor
      Yaşayan BSD’ler[1] arasında Mach’i kullanmaya devam eden tek sistem XNU/Darwin; o da Mach 2.5 değil, Mach 3. Mach 2.5, 3 ve 4 (GNU/Hurd, Mach 4’tür) vardı; ancak uyumlulukları düşük ve esasen yalnızca genel mimari düzeydeki etkileri paylaşıyorlar. Bu yüzden bunları ortak etkilenmiş ayrı tasarımlar olarak görmek daha doğru
      [0] Zaten baştan beri bu izler çok da fazla değildi
      [1] DragonBSD’nin şu an ölü mü canlı mı olduğundan da pek emin değilim
  • Darwin’de çekirdek bileşenlerin radikal biçimde değişme hızı ilginç. Sistem çağrılarında geriye dönük uyumluluktan vazgeçilmesi, zorunlu kod imzalama, dinamik çalıştırılabilir dosya yüklemeyi hızlandırmak için tek tek sistem kütüphanesi dosyalarının kaldırılıp dyld_shared_cache’e geçilmesi gibi örneklerle, nostaljiye ya da dokunulmaz alanlara yer bırakmadan sonuç odaklı tasarlanan bir yaklaşım
    Bu, ancak Apple gibi büyük bir donanım üreticisinin başarabileceği bir yaklaşım gibi görünüyor

  • Yazıda, swap dosyasını yöneten pager daemon’ın kullanıcı alanında çalıştığı ve çekirdek belleğinin de swap edilebildiği söylenmiş; ancak kullanıcı alanındaki bir daemon’ın çekirdek belleğini nasıl swap ettiği açıklanmamış
    Özel daemon için hard-code edilmiş bir istisna mı var, yoksa özel sistem çağrıları mı kullanılıyor merak ediyorum. Kullanıcı alanı bellek yönetiminin ayrıntılarını nereden okuyabilirim?

    • Bu açıklama hatalı ve birkaç şeyi birbirine karıştırıyor. Mach mikroçekirdeği başlangıçta dosya sistemi yerine rastgele bir daemon koymaya dayanan, mmap’e benzeyen gerçek kullanıcı alanı paging desteğine sahipti; arayüzü burada görülebilir:
      https://web.mit.edu/darwin/src/modules/xnu/osfmk/man/memory_...
      Ancak Darwin’in bu özelliği gerçekten kullanıp kullanmadığı kesin değil; en azından yaklaşık son 20 yıldır kullanmadı. dynamic_pager bu arayüzü hiç kullanmadı; XNU swap yetersizliğini bildirdiğinde swap dosyası oluşturup bunları macx_swapon, macx_swapoff sistem çağrılarıyla çekirdeğe veren çok daha sınırlı bir Mach arayüzünü kullandı. Gerçek swapping işlemini çekirdek yapıyordu; eski dynamic_pager kodu burada:
      https://github.com/apple-oss-distributions/system_cmds/blob/...
      Bu özellik de artık çekirdeğe taşındı; güncel dynamic_pager fiilen neredeyse hiçbir şey yapmıyor:
      https://github.com/apple-oss-distributions/system_cmds/blob/...
      Çekirdek belleğinin büyük kısmı wired durumdadır, yani paging’e tabi tutulamaz; ancak çekirdek IOMallocPageable gibi yöntemlerle açıkça sayfalanabilir bellek isteyebilir ve bu bellek diske swap edilebilir. Yine de bu neredeyse hiç kullanılmaz; bu tür kodların deadlock’tan kaçınacak şekilde dikkatli yazılması gerekir. Kullanıcı alanı artık “paging”in kendisine dahil olmasa bile, FSKit veya FUSE tabanlı kullanıcı alanı dosya sistemleri, disk imajı üstündeki dosya sistemleri, kullanıcı alanı ağ uzantılarından geçen NFS/SMB gibi durumlarda bir veya iki katman aşağıda kullanıcı alanının devreye girmesi yaygındır. Ancak son kısım yanlış olabilir. Kullanıcı alanında takılan dosya sistemleri kesinlikle mümkün; fakat böyle bir dosya sistemi üzerine swap koymak desteklenmiyor olabilir
    • https://github.com/apple-oss-distributions/xnu
  • Darwin çekirdeğiyle ilgili bir şey gördüğümde, Apple sadece Linux’u fork’layıp üzerine OS servislerini kursaydı her şey ne kadar farklı olurdu diye merak ediyorum.
    Özellikle Apple’ın Darwin’e ne kadar takıntılı olduğunu görünce, açık kaynağın kaybettikleri ile Apple’ın harcamak zorunda kaldığı zaman ve maliyete karşılık elde ettiği getiri arasında dengesizlik var gibi geliyor ve bu bende iyi bir izlenim bırakmıyor.

    • Apple’ın böyle bir geçiş yapması için uygun bir zaman hiç olmadı. NeXTSTEP, Linux’tan önce ortaya çıktı; Apple Mac OS X’e geçerken, zaten yaptığı diğer tüm işlere ek olarak çekirdeği baştan sona değiştirecek bir projeyi de kaldıramazdı.
      1990’ların sonundaki Linux da açıkça daha iyi bir seçenek değildi; OS X birkaç sürüm geçirip tüketici PC’lerinde en başarılı UNIX türevi OS olarak yerini aldıktan sonra ise Linux tabanına geçmek, kısa vadeli getirisi neredeyse olmayan, maliyeti ve riski büyük bir tercih olurdu.
      Apple klasik MacOS’u 5 yıl daha sürdürmüş olsaydı ya da Linux 5 yıl daha erken olgunlaşsaydı, OS X’e geçiş çok farklı olabilirdi. Ama 2.6 öncesi Linux çekirdeği uğruna XNU’dan vazgeçmek mantıklı değildi.
    • Apple’ın NeXT’i satın aldığı dönemde Linux yoğun geliştirme aşamasındaydı ve henüz iyi oturmamıştı. Linux monolitik bir çekirdek olduğu için Mach’ın sunduğu düzeyde bölümlendirmeyi de sağlayamıyordu.
      Bugünün ölçütleriyle bakıldığında FreeBSD, Darwin’in avantajlarının ve Linux tarzı açık kaynak niteliğinin çoğunu birlikte barındırıyor. Apple’ın giderek güçlenen bağımlılığı olmadan daha güvenli bir ortam istiyorsanız, FreeBSD ve diğer BSD’ler de dağıtım hedefi olarak değerlendirilebilir.
    • İlginç şekilde Apple, 1996’da başlayan MkLinux projesinde Linux’un PowerPC Mac’lere port edilmesine katkıda bulundu. Bu, aynı yılın sonundaki NeXT satın alımından önceydi:
      https://en.m.wikipedia.org/wiki/MkLinux
      Macintosh GUI’sini ve uygulama ekosistemini Linux’a taşıma çalışması yok gibi görünüyor. Ancak NeXT satın alımından önce de Apple, 68k Mac’ler için A/UX ve daha sonra Solaris ile HP-UX için Macintosh Application Environment aracılığıyla Unix üzerinde Macintosh ortamı çalıştırıyordu; ikincisi Mac OS’u bir Unix süreci olarak çalıştırıyordu. Yanlış hatırlamıyorsam Macintosh Application Environment çalışması, Rhapsody’nin Blue Box’ının ve daha sonra Mac OS X Classic ortamının temelini oluşturdu. Teorik olarak Macintosh Application Environment’ı MkLinux’a port etmek de hayal edilebilir. 1996’da BSD ile ilgili dava uzlaşmasının ardından modern özgür açık kaynak BSD’ler de zaten mevcuttu.
      Elbette 1990’ların ortasında klasik Mac OS’u Linux, FreeBSD, BeOS, Windows NT gibi modern OS’lerin üzerinde bir süreç olarak çalıştırmak, tüketici masaüstü stratejisi olarak gerçekçi değildi. İş istasyonu sınıfı kaynaklar gerekiyordu; Apple ise hâlâ 68k Mac’leri destekliyordu ve Mac OS 8 de bazı 68030/68040 cihazlarda çalışıyordu. G3/G4 döneminde bu daha gerçekçi olurdu; 2000’lerde ise her bir klasik Macintosh programını modern bir OS üzerinde ayrı bir Mac OS süreci olarak çalıştırmak da mümkün olabilirdi. Ancak Jobs geri dönmeseydi Apple muhtemelen 1998’i göremezdi. Üstelik NeXT satın alımı Cocoa, IOKit, Quartz (Display PostScript’in halefi) ve bugün çekirdek öneme sahip başka teknolojileri de Mac’e getirdi.
    • Neden daha ağır bir tek kültür istememiz gerektiğini anlamıyorum. Zaten tek sepete fazlasıyla çok yumurta koyduk. Çekirdeklerin daha fazla birleşmesinden ziyade çeşitliliğin artmasını isterim.
      Başka açıdan bakınca, Apple’ın Safari’yi Chromium üzerine taşıması gerektiği önerisine benziyor.
    • XNU yalnızca kısmen açık kaynak. Çekirdek kısmı açık, ancak APFS dosya sistemi gibi önemli parçalar eksik.
      Linux’u fork’lasaydı, yasal olarak tüm çekirdek modüllerini açık kaynak yayımlamak zorunda kalabilirdi. Bu insanlık için büyük olasılıkla olumlu olurdu ama Apple’ın istediği yön bu olmazdı.
  • Bu yazıya çok emek ve sevgi konmuş. Bu tarihin büyük kısmını yaşamış; NeXTSTEP kodunu Windows’a port etmeyi denemiş; GNUStep’in yeniden üretme girişimlerini kurcalamış; YellowBox ve OpenStep’i hatırlayan; iç mimari kitaplarını okumuş ve WWDC içeriklerini düzenli takip etmiş biri olarak, çeşitli sistemlerin nasıl evrildiğine dair kendi hafızamla neredeyse tamamen örtüşüyor.

  • Jobs, Torvalds’ı Mac OS X üzerinde çalışması için işe almaya çalışmış, Linus ise reddetmişti: https://www.macrumors.com/2012/03/22/steve-jobs-tried-to-hir...

    • Üstelik Torvalds’ın bir mikroçekirdek üzerinde çalıştığını hayal etmek zor.
  • I/O Kit’in bu C++ alt kümesiyle yazılmasının yalnızca hız nedeniyle olup olmadığından pek emin değilim. O dönemde bu tartışmalıydı. Çünkü Apple, MacOS X’i duyururken mevcut yazılımlarla uyumlu olmayacağını ve tüm iş ortaklarının Objective-C ile yeniden yazması gerektiğini söylemişti.
    Tepkiler iyi olmayınca Apple geri adım attı ve C++ uygulamaları için bir API katmanı olan Carbon ile Objective-C tabanlı Foundation’ın altyapısı olan Core Foundation’ı devreye aldı. Obj-C++’ın var olma nedeni de bu. İlginç nokta, bellek yönetimini toll-free bridging ile kurmalarıydı. Yani C/C++ dünyasında ayrılmış nesneler, ek yük olmadan Obj-C’ye aktarılabiliyor.

    • IOKit C++ çekirdekte çalıştığı için, sözünü ettiğiniz teknolojilerle pek ilgisi yok. Bunların tamamı yalnızca kullanıcı alanı teknolojileri.
  • Apple, XNU etrafında daha iyi bir özgür açık kaynak topluluğu büyütmeliydi. ARM’ye geçmiş olduğu şu anda bile x64 üzerinde çalışabilen bir dağıtım olmalıydı.

  • Darwin’i bu kadar derinlemesine anlamak istiyordum; iyi bir yazıydı

    • Singh’in Mac OS X Internals kitabı sevdiğim kitaplardan biri. Mac OS X 10.4 dönemini çok derinlemesine ele alan harika bir inceleme kitabı; güncellenmiş bir sürümü gerçekten olsaydı keşke
      Bu yazının sonunda da alıntılanmış. macOS tarihinde uzun süre kalacak bir kaynak
    • Windows NT’yi de bu derinlikte anlamak isterdim. Win32 konusunu atlayıp onun altındaki katmanı ele alacak şekilde. Benim anladığım kadarıyla Win32 yalnızca bir personality; ayrıca Windows XP döneminde Windows Services for UNIX ve Windows Vista’da Subsystem for UNIX-based Applications da vardı
      Temeldeki NT çekirdeği, POSIX uyumluluğuna izin verecek kadar esnek olduğundan, bunları ele alan bir yazı ilginç olurdu
  • Güzel bir tarih özeti, ama Apple işletim sistemlerini Linux veya Windows’tan ayıran mükemmel güvenlik çalışmalarının çoğunu atlamış. Apple’ın bugün güvenlik açısından ne kadar ileride olduğunun yeterince takdir edilmediğini düşünüyorum. Belki bir gün bu algı güçlenir de hassas ortamlarda çalışanlar için CISO’lar Mac kullanımını şart koşar
    İşin özü kod imzalama sistemi. Uygulamalara yetki verebiliyor veya onları sandbox’a alabiliyor ve bu zorlamanın gerçekten sürmesini sağlıyor. Apple, çoğu UNIX gibi ELF kullanmıyor; Mach-O adlı bir format kullanıyor. ELF ile Mach-O arasındaki farkların çoğu önemli değil, ama Mach-O’nun imzalı kod dizinini barındıran ek bir bölümü desteklemesi önemli. Kod dizini, kod sayfalarının hash’lerini içeriyor; kernel bu veri yapısını bir ölçüde anlıyor ve dyld, bir binary veya kütüphane yüklendiğinde bunu bağlayabiliyor. XNU kod dizini imzasını doğruluyor; VMM alt sistemi de kod sayfası gerektiğinde yüklenirken hash hesaplayıp dizindeki imzalı hash ile eşleşip eşleşmediğini doğruluyor. Bu yüzden kod dizini hash’i, Apple ekosistemindeki herhangi bir program için benzersiz tanımlayıcı gibi davranabiliyor. Burada bir bug var: Bu bağlantı Mach vnode yapısına asılı olduğu için, imzalı bir binary’nin üzerine yazıp çalıştırırsanız yeni dosya imzası geçerli olsa bile kernel sinirlenip süreci öldürüyor. Yeni durumu fark ettirmek için dosyanın tamamını gerçekten değiştirmeniz gerekiyor
    Apple bu temelin üzerine kod gereksinimlerini koyuyor. Bunlar, kod imzasının çeşitli özelliklerine ilişkin kısıtları ifade eden küçük bir ifade diliyle yazılmış programlar. “Bu binary Apple tarafından imzalanmış olmalı”, “sertifika otoritesi Y’ye göre kimliği X olan öznenin imzaladığı binary’nin herhangi bir sürümüne izin ver”, “bu binary cdhash Z’ye sahip olmalı”, yani tam olarak o binary olmalı gibi gereksinimler yazılabiliyor. Binary’ler, başka taraflara kendilerinin hangi gereksinimle tanımlanmak istediğini gösteren designated requirement da sunabiliyor. İlk başta abartılı görünüyor, ama programlar evrilirken bile kararlı ve taklit edilemez bir kimlik taşımalarını sağlıyor
    Kernel, bir task’in imza kimliğini portlar üzerinden diğer task’lere açıyor. Kullanıcı alanındaki kütüphane, kısıt dilini yorumlayıp o porta gereksinim uygulayabiliyor. Örneğin bir program sistem keychain’ine bir anahtar kaydettiğinde, kullanıcı alanında uygulanmış keychain daemon’u RPC gönderen programın designated requirement’ını inceliyor ve sonraki anahtar kullanım istekleriyle eşleşip eşleşmediğini kontrol ediyor
    Bu sistem, yetkiler (entitlements) ile soyutlanıyor. Yetkiler, izinleri ifade eden key=value çiftleri. Açık bir sistem olduğu için uygulamalar kendi yetkilerini tanımlayabiliyor, ama çoğunu Apple tanımlıyor. Bazıları tamamen opt-in; sadece isteyince OS otomatik ve sessizce izin veriyor. İlk bakışta işe yaramaz görünüyor, ama App Store’un uygulamanın ne yapacağını önceden açıklayabilmesini ve daha genel olarak uygulamanın ihtiyaç duymadığı şeylere erişemediği en az ayrıcalık yaklaşımını mümkün kılıyor. Bazıları provisioning profile gibi ek kanıt gerektiriyor. Bu, Apple’ın sağladığı imzalı bir CMS veri yapısı; kabaca “designated requirement X’e sahip uygulama kısıtlı yetki Y’yi kullanabilir” anlamına geliyor, dolayısıyla bunu kullanmak için Apple’dan izin almak gerekiyor. Bazıları da fiilen genel amaçlı bir imza bayrağı sistemi gibi kötüye kullanılıyor ve güvenlikle ilgisiz
    Sistem, kullanıcı alanı ile XNU’nun işbirliğiyle daha da genişletiliyor. Binary imzalayabilmek sadece başlangıç; birçok programın veri dosyaları da var. Apple güvenlik sistemi burada biraz yamalı bohça gibi görünüyor. Kernel, veri dosyası bütünlüğü kontrolüne karışmıyor. Bunun yerine, biraz keyfi bundle dizin yapısının özel bir konumunda bir plist bulunuyor; bu plist, bundle içindeki tüm veri dosyalarının dosya bazında hash’lerini içeriyor; plist’in hash’i kod imzasına giriyor ve en sonunda Gatekeeper ilk çalıştırmada her şeyi kontrol ediyor. Kernel, programın çalıştırılmasına izin verip vermeyeceğini Gatekeeper’a soruyor; Gatekeeper da dosyaya eklenmiş ve web tarayıcısı ya da arşiv açma aracı gibi GUI araçlarının yaydığı extended attribute’un varlığına bakarak karar veriyor. Finder gibi kullanıcı alanı OS kodu, program ilk indirildiğinde Gatekeeper’ı çağırıp kontrol ettiriyor; Gatekeeper da bundle içindeki tüm dosyaları hash’leyip binary’de imzalanmış içerikle eşleşip eşleşmediğini denetliyor. Bu yüzden macOS’te ilk çalıştırmada yavaş “Verifying app” iletişim kutusu çıkıyor. Bu, mmap kullanmadan büyük veri dosyaları açan uygulamaların takılmaması için yapılmış gibi görünüyor; ama hızlı ağlarda optimize edilmemiş Gatekeeper doğrulaması indirme işleminin kendisinden yavaş olabildiği için üzücü. Apple, mağaza dışı dağıtımı eski bir teknoloji olarak gördüğü için pek umursamıyor gibi
    Son olarak Seatbelt var. Sandbox kurallarını ifade eden Lisp tabanlı bir programlama dili. Bu dosyalar kullanıcı alanında bir tür bytecode’a derleniyor ve kernel bunları değerlendiriyor. Dil oldukça gelişmiş; tamamı kod imzalama kimliğine dayanarak çeşitli sistem bileşenlerinin nasıl etkileşeceğini ve ne yapabileceğini keyfi kurallarla ifade edebiliyor
    Yukarıdaki şemada, ancak son sürümlerde kapatılan bariz bir delik vardı. Veri dosyalarının kod içerebilmesi ve yalnızca bir kez kontrol edilmesi. Electron veya JVM uygulamaları taşınabilir formatta kod içerdiği için bu gerçekten böyle. Dolayısıyla bir uygulama, veri dosyalarını değiştirerek başka bir uygulamaya kod enjekte edip kod imzalamayı atlatabiliyordu. Yeni macOS’te bunu engellemek için Seatbelt, çalışan tüm uygulamaları sandbox’a alıyor. Bildiğim kadarıyla modern macOS’te sandbox dışında kod yok. Sandbox politikalarından biri, uygulamaların izin olmadan başka uygulamaların veri dosyalarını değiştirmesini engellemek. Politika oldukça gelişmiş: Apple’ın doğruladığı aynı tüzel kişi tarafından imzalanmış uygulamalar birbirini değiştirebiliyor; bir uygulama kod gereksinimlerine uyan başka bir uygulamanın değişiklik yapmasına izin verebiliyor; kullanıcı da gerektiğinde yetki verebiliyor. Bunu kontrol etmek için Settings -> Privacy & Security -> App Management’te Terminal.app yetkisini kapatıp yeniden başlatın, ardından vim /Applications/Google Chrome.app/Contents/Info.plist gibi bir komut çalıştırın. Dosya izinleri rw olsa bile vim bunu salt okunur görür
    Buradan sonrası için Apple’da çalışmadığımdan benim anlayışım da bitiyor. Kernel’in app bundle’larını anlamadığını biliyorum ve open() sistem çağrısını salt okunur hâle getirmeye nasıl karar verdiğinden de emin değilim. Tahminimce varsayılan Seatbelt politikası, kernel’in bundle formatını ve SQLite yetki veritabanını okuyabilen bir güvenlik daemon’una upcall yapmasını sağlıyor; o daemon da açan tarafın designated requirement’ını bundle ve sandbox’ın ifade ettiği politikayla karşılaştırıp karar veriyor

  • Böyle bir özelliğe güvenlik adının uygun olduğunu düşünmüyorum
    Bana göre güvenlik her zaman bilgisayarın sahibinin ya da kullanıcısının emniyetini ifade etmeli
    Apple’ın bu tür özellikleri güvenliği artırmak için kullanılabilir, ancak temel tasarım amacı, bilgisayarı satmış olan satıcının artık kendisine ait olmaması gereken bir cihazın teorik olarak sahibi tarafından nasıl kullanıldığı üzerinde daha güçlü denetim kurmasıdır. Yani son kullanıcının hangi programları çalıştıracağına Apple’ın karar verebilmesini sağlayan bir yöne işaret eder