1 puan yazan GN⁺ 2 시간 전 | 1 yorum | WhatsApp'ta paylaş
  • BusyBox, birden fazla komutu tek bir çalıştırılabilir dosyada sunan bir multicall binary'dir; Alpine'ın varsayılan wgeti de BusyBox üzerinden çalışır
  • Alpine konteynerindeki /usr/bin/wget, gerçek bir ikili dosya değil, /bin/busyboxu işaret eden bir sembolik bağlantıydı
  • BusyBox çalışırken çağrı adını argv[0] içinden okur ve yolun son adını kullanarak çalıştırılacak applet'i belirler
  • Her applet ada göre bulunur ve ilgili main fonksiyonuna girer; wget, wget.c içinde uygulanır ve sonunda wget_main çalışır
  • busybox --list ile derlenmiş komutlar görülebilir; Alpine örneğinde 304 tane listelenir ve her yardımcı araç küçültülmüş bir sürüm gibi görünür

BusyBox'un çalışma şekli

  • BusyBox, birden fazla komutu tek bir çalıştırılabilir dosyada sunan multicall binary yapısını kullanır
  • Alpine konteynerinde /usr/bin/wget, gerçek bir çalıştırılabilir dosya değil, /bin/busyboxu işaret eden bir sembolik bağlantıydı
    docker run --rm -it alpine sh
    / # which wget
    /usr/bin/wget
    / # ls -lah /usr/bin/wget
    lrwxrwxrwx    1 root     root          12 Apr 15 04:51 /usr/bin/wget -> /bin/busybox
    
  • /usr/bin içinde 130'dan fazla çalıştırılabilir dosya, tek bir ikili dosyadan geliyormuş gibi görünür; bu da BusyBox'un multicall binary yapısıyla bağlantılıdır
  • BusyBox çalışırken çağrılan adı argv[0] içinden alır ve yolun yalnızca son adını çıkararak hangi applet'in çalıştırılacağını belirler
    applet_name = argv[0];
    if (applet_name[0] == '-')
      applet_name++;
    applet_name = bb_basename(applet_name);
    
  • busybox ls -1 gibi applet adı açıkça verilse de çalışır; var olmayan bir ad verilirse applet not found çıktısı gösterilir
    / # busybox ls -1
    bin
    dev
    etc
    home
    
    / # busybox meheh
    meheh: applet not found
    

Applet yapısı ve kurulum şekli

  • BusyBox, applet'i ada göre bulduktan sonra o applet'in main fonksiyonunu çalıştırır
    int applet = find_applet_by_name(name);
    // ...
    run_applet_no_and_exit(applet, name, argv);
    // ...
    xfunc_error_retval = applet_main[applet_no](argc, argv);
    
  • Her applet ayrı bir C dosyasına sahiptir; wget, wget.c içinde uygulanmıştır
  • Applet bazlı ayarlar kod yorumları biçiminde tanımlanır; WGET ayarında wget (41 kb), varsayılan olarak etkin olma durumu, HTTP ve FTP sunucularından dosyaları etkileşimsiz olarak indiren bir yardımcı araç olduğuna dair yardım metni ve wget.o derleme hedefi yer alır
    //config:config WGET
    //config:	bool "wget (41 kb)"
    //config:	default y
    //config:	help
    //config:	wget is a utility for non-interactive download of files from HTTP
    //config:	and FTP servers.
    //applet:IF_WGET(APPLET(wget, BB_DIR_USR_BIN, BB_SUID_DROP))
    //kbuild:lib-$(CONFIG_WGET) += wget.o
    
  • Sonuçta wget applet'i wget_main içine girer
    int wget_main(int argc UNUSED_PARAM, char **argv)
    
  • BusyBox hard link'leri de destekler; busybox --install -s içindeki -s, sembolik bağlantı oluşturma anlamına gelir
    busybox --install -s
    
  • Derlemeye dahil edilen komutların listesi busybox --list ile görülebilir; Alpine örnek ortamında 304 tane gösterilir
    / # busybox --list | wc -l
    304
    
  • Alpine'deki birçok komut, BusyBox tabanlı ikili dosyaya yönelik bir arayüz gibi çalışır ve her yardımcı araç, tam kaynak yardımcı araca göre bir miktar kırpılmış bir sürüm gibi görünür

1 yorum

 
GN⁺ 2 시간 전
Lobste.rs görüşleri
  • Alıntılanan sorunun cevabı yeniden uygulamaya daha yakın
    BusyBox tanıtımı https://busybox.net/about.html adresinde, kaynak kodu ise https://github.com/vda-linux/busybox_mirror adresinde

  • Programın gerçekte olduğundan farklı bir admış gibi davranması epey sinir bozucu
    macOS'ta gcc çalıştırdığınızda aslında clang çıkması en kötü örnek; PowerShell de benzer şekilde çalışıyor. Keşke doğrudan farklı bir ad kullansalar

    • Bunun bir nedeni de, birçok geliştiricinin clang'ı bilmediği, test edecek Mac'inin olmadığı ya da pratik bir alternatifin bulunmadığı dönemde başlamış olması
      Nixpkgs'nin https://github.com/NixOS/nixpkgs/… gibi çok sayıda yama yapması gerekiyor ve sqlite gibi ünlü projeler bile istisna değil. Buna karşılık macOS sadece aldatıcı yolu seçmiş gibi görünüyor
    • Birçok yazılımın makefile'ını kullanan kişiler cc'yi bilmiyor olabiliyor
    • Sinir bozuculuğu anlaşılır, ama çoğu build script'ini çalıştıracak kadar yeterince uyumluysa Linux ve çeşitli Unix türevlerinde aynı script'leri bir ölçüde yeniden kullanabilmeyi sağladığı için yayılmış olabilir
    • Bazen pratikte imkânsız oluyor
      gcc'nin sabit kodlandığı çok sayıda makefile vardır ve benzeri başka bağlamlarda da görülür. Örneğin birçok mevcut program doğru çözüm olan terminfo veritabanı yerine TERM ortam değişkenindeki xterm-* değerlerini kontrol ettiği için farklı bir ad seçme yaklaşımı işe yaramıyor
  • Konteynerlerde garip sorunları teşhis ederken sık sık podman cp /usr/bin/busybox-static somecontainer:/bin kullanıyorum

  • toybox da benzer bir yapıya sahip
    Bazı araçlar başka yerlerden alınmış ya da taşınmış gibi görünüyor, ancak önemli bir kısmı BusyBox için sıfırdan uygulanmış ve küçük kalmaları, ayrıca statik bağlama yapıldığında küçük derlenmeleri için sınırlı libc işlevleri kullanmaları hedeflenmiş. Bir başka avantajı da shell script'lerinde bu araçların yerleşik komutlar gibi kullanılabilmesi. Bazıları fork+exec yerine fork+jump ile çalışıyor, bazıları ise fork olmadan normal bir fonksiyon çağrısı olarak bile yürütülebiliyor

    • Bildiğim kadarıyla toybox, GPL lisanslı BusyBox'a BSD lisanslı bir alternatif olarak oluşturuldu
      Ek olarak, Toybox on Wikipedia'ya göre “Toybox, Rob Landley BusyBox'un orijinal yaratıcısı Bruce Perens ile yaşadığı anlaşmazlık nedeniyle BusyBox bakımcılığı görevinden ayrıldıktan sonra 2006'nın başlarında başladı.”
  • Aslında bu bir yeniden uygulama. Yine de lisans izin veriyorsa, orijinal büyük uygulamadan bazı kod parçalarının alınmış olması şaşırtıcı olmaz
    From the 'pedia:'ye göre BusyBox ilk olarak 1995'te Bruce Perens tarafından yazıldı ve 1996'da amaçlanan kullanım için tamamlandığı ilan edildi. İlk hedef, Debian dağıtımının kurtarma diski ve kurulum programı olarak görev yapan, tamamen önyüklenebilir bir sistemi tek bir disketin içine sığdırmaktı. Daha sonra gömülü Linux aygıtları ve Linux dağıtımlarının kurulum programlarında fiilî standart temel kullanıcı alanı araç takımı hâline geldi; ayrıca Linux'taki her çalıştırılabilir dosya birkaç KB ek yük gerektirdiğinden, 200'den fazla programı tek bir dosyada birleştirmek disk alanı ve bellekte büyük tasarruf sağlıyor
    Bununla bağlantılı olarak Toybox da yapı ve felsefe açısından benzer, ancak BSD lisanslı. Baş geliştiricisi Rob Landley'nin, ticari olarak kabul edilmesi daha kolay bir lisans olursa bunun Android cihazlara dahil edilebileceğini ve böylece tüm Android telefon ve tabletlerin Unix benzeri bir geliştirme ortamına dönüşme potansiyeli taşıyacağını düşündüğünü hatırlıyorum. Toybox hâlâ Android'in bir parçası gibi görünüyor, ancak Termux gibi üst katmanda yardımcı araçlar olmadan Android'i Unix gibi kullanmak pek kolay değil

    • Google gibi şirketler için ücretsiz emek vermenin nasıl dönüp dolaşıp kişinin kendi ayağına dolandığını gösteren bundan daha kusursuz bir ders kitabı örneği bulmak zor
      Özellikle de Google'ın yıllardır Termux'u engellemekle tehdit ettiğini düşününce
  • Bir Windows portu da var: https://github.com/rmyorston/busybox-w32
    BusyBox'un küçük boyutu sayesinde böyle portlar daha gerçekçi oluyor. Ancak artık Windows içinde Linux'u doğrudan çalıştırabildiğiniz için bunun önemi biraz azalmış gibi görünüyor