C ile boot edilebilir bir uygulama nasıl yazılır ?

Katılım
1 Eyl 2011
Mesajlar
119
Beğeniler
5
Puanları
18
#1
C programlama dili ile boot edilebilir bir uygulama nasıl yazılır ? Yani açılışta windows veya linux yerin benim yazmış olduğum uygulamayı nasıl çalıştırabilirim ?. Bu sıradan bir "Merhaba Dünya" programını çalıştırmak istiyorum.Bir hafta kadar araştırmama rağmen bi türlü kaynak bulmamadım malesef.."Memtest" adında ramleri test eden bir uygulama ve Avast'ın başlangıç tarama özelliği bu şekilde çalışıyor. Nasıl yapılacağını anlatan bir kaynak belirtirseniz çok sevinirim.
 
Katılım
31 Ağu 2015
Mesajlar
3
Beğeniler
3
Puanları
0
#3
Selamlar,

Userspace'te çalışan kod yerine doğrudan işlemciyi programlama işi oldukça farklı.

Elektronikçiler basit boardlar üzerinde basit işlemciler için kod yazmayı okulda öğreniyorlar. Bunun gibi eskiden insanlar hobi için PIC programlama yaparlardı. Doğrudan boot eden program yazmak için bu işlere bir bakmak lazım.

PC için boot eden bir program yazmak ise daha karmaşık. Çünkü birincisi PClerde kullanılan modern işlemciler çok daha karmaşık, işlemciyi iyi tanımak gerekiyor. İkincisi anakart çok daha karmaşık. Üçüncüsü aslında senin yazdığın kod doğrudan çalışmıyor, bilgisayarı boot eden BIOS / UEFI çalıştırıyor senin kodunu (aslında board initin bütün karmaşasını üstlendiği için işini kolaylaştırıyor) o yüzden BIOS / UEFI'nin sana nasıl bir ortam bıraktığını da bilmen gerekiyor.

Son bir konu da kodu nasıl çalıştıracağın ve nasıl debug edeceğin. Normalde anakart + CPU üzerinde doğrudan çalışan kod yazan insanlar board geliştiricilerin sunduğu imkanları kullanırlar. Boarda seri port üzerinden ya da JTAG cihazıyla filan bağlanırlar. Çünkü BIOS senin kodunu çalıştırdığı anda ekrana bir şey yazdırmak için bile yapman gereken hazırlıklar var. Programı boarda atmak için bootp protokolü ile çalışan PXE boot kullanılabilir sanırım, bütün anakartlarda var artık. Öyle harddiske yazmakla filan olmayacağı aşikar.

Bu arada bu iş için ayrı bir bilgisayarın olması gerektiğinin farkındasındır umarım. Öyle Visual Studio'da kodu derleyeyim, reboot edeyim benim koddan açılsın şeklinde çalışmak pratikte mümkün değil.

Özetle board üzerinde çalışan kod yazmak userspace'te çalışan kod yazmaktan bambaşka bir iş. Bunun için işletim sisteminin nasıl boot ettiğini bilmen gerekli. Bazı Linux Kernel kitaplarında bundan bahsediyor, mesela Embedded Linux Primer'da vardı. Ayrıca GitHub'da Linux hakkında dokümantasyon yapan bir eleman var, onun yazdıklarını da okuyabilirsin: https://github.com/0xAX/linux-insides/tree/master/Booting . Bir de OSDev Wiki var, o da bu konularda güzel bir kaynak: Expanded Main Page - OSDev Wiki

Hello World işi için de ben Grub kodunu okumanı öneririm. Sonuçta modüler bir yapısı var ve bu sayede kodu biraz anlayıp değiştirerek kısa sürede çalışan küçük programcıklar yapabilirsin. Eğer PC ile değil de Ardunio, Beagle Bone, Rasp Pi gibi boardlar ile çalışacaksan da u-boot'a bakmalısın.

Unutmaman gereken şey şu, bilgisayarın ve anakartın nasıl çalıştığını, nasıl açıldığını bilmeden çalışan kod yazman çok zor. Bir de boot kodunu yanlış yazıp anakartı yakamazsın belki ama cihazı sık sık boot edilemez hale getireceksin. O yüzden kullanmadığın, üzerinde işe yarar bir bilgi vs. olmayan hatta belki ikinci el alınmış yani expandable bir cihazla çalışmalısın kesinlikle.

- - - Mesaj Güncellendi - - -

Yazmayı unutmuşum, işletim sistemi olmadan çalışmak demek syscall'lar yok demek. Yani kaynaklara kendi çabalarınla ulaşmalısın, input alıyorsan da interruptları kendin yönetmelisin. İşletim sisteminde kullandığın C librarysi çalışmaz yani, printf'i getc'yi filan unut.

- - - Mesaj Güncellendi - - -

Bir de Visual Studio ya da gcc ile userspace'te derlediğin bir binary ile boot edemezsin çünkü bu dosyalar OS kernelin anlayacağı şekilde düzenlenmiştir (Windows exe ya da Linux elf gibi). BIOS bunları çalıştıramaz, BIOS'un çalıştırabileceği binaryler oluşturmalısın. (Linux ile geliştirme yapıyorsan Grub ya da Linux kernel binary (vmlinux) nasıl derleniyor bak Makefile'lardan.)
 

kmurat

Profesör
Katılım
8 Şub 2014
Mesajlar
2,964
Beğeniler
453
Puanları
83
#4
Ek bilgi : vmlinuz bir ELF çalıştırılabilir dosyası değil. Bir PXE dosyası, sanal bir windows uygulaması (veya sanal makine). Pc'lerde Bios sadece Windows'u çalıştırıyor. Linux çekirdeği initrd içinde bulunuyor. vmlinuz, initrd dosyasının PC'lerde çalışabilmesini sağlıyor..
 
Katılım
31 Ağu 2015
Mesajlar
3
Beğeniler
3
Puanları
0
#5
Ben de yanıtımda vmlinux ELF formatında değil yazmıştım ama anlaşılan aslında ELF formatındaymış. Neyse, ben gcc ya da Visual Studio çıktısı olan bir dosya gerekli ayarlamalar yapılmadıysa bilgisayarı boot etmek için kullanılamaz demek istemiştim.

vmlinux'un adı içinde vm geçiyor ama bu bir sanal Windows uygulaması değil tabii ki. Linux çekirdeği de initrd içinde bulunmuyor aslında, çekirdek init olduktan sonra harddisk sürücü, dosya sistemi modülleri filan gibi şeyler için initrd'ye ihtiyaç duyuyor. vmlinux içinde kernel binary + initrd var. vmlinuz da onun sıkıştırılmış ve self extract eden hali. Bu konuda çok da detaylı olmayan bir yazıya linkten ulaşabilirsiniz: https://www.ibm.com/developerworks/...try/anatomy_of_the_initrd_and_vmlinuz?lang=en

Aslında kendi PC'niz için kernel derliyorsanız gerekli şeyleri modül olarak derlemek yerine hepsini kernel imajının içine gömüp initrd kullanmadan boot etmek mümkün.

Ancak Linux kernel'i boot etmek için bootloader gerekiyor gerçekten, onu yanlış yazmışım. BIOS ya da UEFI bootloaderı çalıştırıyor, linux çekirdeği gerekli ortam bootloader tarafından hazırlandıktan sonra başlatılıyor.

Bu arada verdiğim GitHub linkinde ilk bölümde ekrana yazı yazan bir assembly kod parçacığı var. ax'in low byte'ına istediğin char'ı yazıp 0x10 interruptını çağırarak ekrana text modunda yazı yazabiliyorsun. Aslında o örneği geliştirerek "Hello, World!" yazan bir uygulama yapabilirsin hemen.
 

okanr

Asistan
Katılım
1 Eyl 2011
Mesajlar
119
Beğeniler
5
Puanları
18
#6
Anlıyorum yardımlarınız için çok teşekkür ederim memtest programını ve github linkindeki dökümanı inceliyorum şimdi. Yani kısacası C yi ve assembly i adam akıllı öğrenmeden bootloader yazmak kolay değil yazılsa da pek bir faydası olmuyor ancak anlayamdığım C dilinde kullandığım fonksiyonlar makine diline çevrilmesine rağmen neden işletim sistemini aracı olarak kullanıyor ?
 
Katılım
31 Ağu 2015
Mesajlar
3
Beğeniler
3
Puanları
0
#7
Aynen öyle. CPU'nun farklı çalışma modları var güvenlik için. İşletim sistemi ile sein userspace kodların farklı güvenlik modlarında çalışıyorlar. (security ring diye aratırsan bulursun). Sanallaştırmadaki hypervisor olayı gibi aynı.

System call diye bir olay var. Bunun sayesinde senin C programın işletim sistemi kernelinden bir şeyler isteyebiliyor. Syscall yaptığında senin programın çalışmayı bırakıp kontrolü tamamen işletim sistemine bırakıyor, işletim sistemi de mümkünse senin programının istediği şeyleri yapıp senin programını kaldığı yerden tekrar başlatıyor. (Bunun bir örneğini de blocking read nedir diye araştırıp öğrenebilirsin).

Bu iş assembly seviyesinde kernel trap denilen olayla gerçekleşiyor. Kernel trap sayesinde daha üst bir security ringde olmasına rağmen senin programın işletim sistemi kerneline ulaşabiliyor. (Bunu da aratabilirsin.)

Senin yapmak istediğin şeye dönersek: işletim sistemi olmadan çalışırsan, userspace programlarının işletim sisteminden istediği bütün o işleri de senin yapman gerekli :)

- - - Mesaj Güncellendi - - -

Security ring değil protection ringmiş: https://en.wikipedia.org/wiki/Protection_ring

Kernel trap yerine trap kernel diye aratırsan daha doğru sonuçlar çıkıyor: http://stackoverflow.com/questions/3149175/what-is-the-difference-between-trap-and-interrupt
 
Katılım
18 Nis 2017
Mesajlar
1
Beğeniler
0
Puanları
1
Konum
sakarya
#8
Arkadaşlar boot yazmayı bilen birine ihtiyacım var.Bana yardımcı olabilecek biri varmı aranızda acaba.
 

Bu konuyu görüntüleyen üyeler (Toplam:0)

stat counter