C için Raspberry Pi için bir işletim sistemi yazın


19

Baking Pi eğitimlerini zaten buldum , ancak sadece montaj dilini kullanıyorlar . İlk dersleri takip ettim ama onun yerine C'yi nasıl kullanacağımı merak ediyorum. Yani, daha üst düzey diller icat etmelerinin bir nedeni var. Ben sadece bir nesne ( .o) dosyasına C kodunu derleme, derleme çalıştı

.section .init
.globl _start
_start:

bl main

loop$:
b loop$

başka bir nesne dosyasına ve onları birbirine bağlamak ve böylece elde kernel.img. Daha sonra zaten var olan çekirdeği kendi ile değiştirdim, ancak C kodunu yürütmüyor. Yazdığım C kodu sadece OK LED'ini açmalı ve sonra geri dönmelidir (sonra gelir loop$: b loop$). Ancak OK LED'i birkaç kez rastgele yanıp söner ve ardından sönük kalır. İşte benim C kodum:

int main(int argc, char ** argv) {
    volatile unsigned *gpioAddr = (volatile unsigned *)0x20200000;
    *(gpioAddr + 4) = 1 << 18;
    *(gpioAddr + 40) = 1 << 16;
    return 0;
}

Raspberry Pi'de işletim sistemi geliştirmek için C'yi nasıl kullanabilirim?

(Ben sadece bir hobisi olmasına rağmen) kodda bir hata olduğundan şüpheliyim. C kurulumunun karmaşık olabileceğinin farkındayım, ancak bunu yapan ilk kişi ben değilim. AFAIK, şu anda baskın olan tüm işletim sistemleri çoğunlukla C ile yazılmıştır, bu yüzden süreci açıklayan bir makale olmalıdır. Ben de bir adım listesi ile çok mutlu olurdu, bu yüzden bu adımlar için google ve belki biraz daha az geniş bir soru sorabilirsiniz.

Not: Yukarıdaki C kodunun ARM montaj eşdeğeri gayet iyi çalışıyor. LED'i açar (biraz yanıp söndükten sonra). Ahududu Pi'imin iyi olduğunu gösteren (umut) düşünüyorum.


C, Unix için taşınabilir montaj dili olarak tasarlanmıştır. Linux C ile yazılmıştır, nasıl yapıldığına bakarak biraz zaman kazanabilirsiniz.
Thorbjørn Ravn Andersen

1
@ ThorbjørnRavnAndersen Sanırım Linux kaynağını okumaya hazır değilim. Linux bilmek istediğimden çok daha karmaşık, bu yüzden benim için ilginç parçalar gizliyor.
11684

1
Um, birkaç LED'i 'bağla'.
11684

1
Teşekkür ederim, ama çoğu şeyi kendim yapmak istiyorum. Bu bir öğrenme projesi.
11684

1
İtiraf etmeliyim ki, daha önce nasıl bir işletim sistemi yazacağım hakkında bir soru görmedim. Ve bazı ilginç cevaplar var. Sadece çılgınca ...
Piotr Kula

Yanıtlar:


14

Yıllar önce çok basit bir çekirdek yazdım ve 386'da çalıştırdım. Yıllarca çıplak metal programlama yapmadım, ancak geniş anlamda bir montajcı kodu yazmanız gerekiyor:

  • önyükleme işlemi sırasında kesintileri devre dışı bırak
  • Pi'nin bir bellek denetleyicisi varsa, bunu ayarlamanız gerekir.
  • bir kronometre ayarla
  • kesinti denetleyicisini yapılandır
  • C kodu yürütebilmeniz için bir yığın oluşturun

Yığını ayarlamak kolaydır - kullanılmayan bir bellek bulun ve yığının işaretçisi olarak kaydının kullanıldığı adresi yükleyin.

C kodunuzda, bellek havuzları ve iş parçacığı tabloları gibi işletim sistemi veri yapılarını başlatmanız gerekir. C kitaplığı işlevlerini kullanamayacaksınız - bunları kendiniz yazmanız gerekir.

Basit bir çok görevli işletim sistemi yazmak istiyorsanız, CPU kayıtlarını yığına kaydetmek ve başka bir iş parçacığının yığınından farklı bir kayıt değerleri kümesi yüklemek için bazı montajcı rutinleri yazmanız gerekir. Farklı iş parçacıkları oluşturmak için bir API yazmanız gerekir.


1
Bu cevap ile Georges Dupéron'un aralarından seçim yapmak zor. Bunu kabul ettim ve diğerine bir oy verdim.
11684

13

Kodunuza derinlemesine bakmadım, ama bana göre doğru yoldasınız. Emin olun:

  • _startSembol aslında derleme & derleme dosyası ve C dosyasını bağlarken kullanılan biridir (ve bu main()yerine kullanılmaz)
  • Ararken main() , C arama kuralını kullanmanız gerekir:
    • çağrıyı takiben talimatın adresini (telefon tarafından kullanılacak dönüş adresi) return C'deki ifadeyle
    • işlevin bağımsız değişkenlerini itin. Sizin durumunuzda iki adet 32 ​​bit değer (toplam 8 bayt) itebilirsiniz, ancak işleri daha basit hale getirmek için argümanları da kaldırabilir veint main() { ... }
    • belki yığın üzerinde dönüş değeri için biraz yer ayırın
    • Bu şeylerin hangi sırada itilmesi gerektiğini hatırlayamıyorum
    • C fonksiyonunun tam olarak ne beklediğini bilmek için, onu sökün ( objdump -S main.o) ve yığının nasıl işlediğine bakın.
  • Arama kuralına uymuyorsanız, C derleyicisi tarafından oluşturulan montaj kodu yığındaki dönüş adresini değiştirebilir ve sizin durumunuzda bir dönüş adresini bile itmediniz, bu nedenle iade talimatı bir yere atlayacaktır gitmek yerine rastgele loop$.

OSDev wiki çok yararlı bir ressource olacak - bu temelde x86 gelişimi ile ilgilendiği ancak bilgilerin çoğu hala ahududu pi için geçerlidir.

Raspberry-pi osdev'e özgü bazı kaynaklar:


Bu cevap ve Steve'in arasında seçim yapmak zor. Sana bir oy verdim ve diğerini kabul ettim. 5 tekrar farkı pişmanım.
11684

OSDev wiki iyi - ve hatta bazı RasPi şeyler var
wally

2

Karşılaşabileceğiniz temel sorun C kütüphaneleri ve prolog kodudur. Kendi kodunuz yürütülmeye başlanmadan ve yığını, yığını kurmadan ve diğer birçok yararlı şeyi yapmadan önce başlar. Bununla birlikte, çıplak metal için programlamaya çalışırken, altında çalışan herhangi bir işletim sisteminiz yoktur ve bu işlevleri çağırmaktan kaçınmanız daha iyi olur. Bunu yapmak için, C kütüphanelerinin değiştirilmiş sürümlerine ve / veya kendinizle tanımlanmış veya değiştirilmiş bazı global sembollere ihtiyacınız vardır. Bu süreç biraz dahil, bu yüzden 'Pişirme Pi' insanlar eğitimleri için montaj kullanmayı seçti.


Soruma cevap verdiğiniz için teşekkür ederim (ve çok geç cevap verdiğiniz için üzgünüm). Ama (sürpriz!) Biraz düşük seviyeli süreçleri içeren pi öğrenmek için aldım (bunu kişisel dosyaları / postaları / fotoğrafları yok etme riski olan pahalı bir masaüstünde yapmamayı tercih ederim). Yığını nasıl ayarladığımı veya bunu açıklayan bir makaleyi / öğreticiyi / bazı kaynakları ekler misiniz? (Ve C çalıştırmak için başka nelere ihtiyacım olabilir).
11684

2

Bunun yerine şunu deneyin:

http://www.valvers.com/open-software/raspberry-pi/step01-bare-metal-programming-in-cpt1/

Ayrıca, x86 deneyimi biraz farklı. Genel ARM çıplak metal işletim sistemi programlamasına uygulanabilir. Ama Pi için üzgünüm, ilk önce gpu başlangıç ​​ve OS (?) Kodunuzdan biraz önce ayarlanmış.


1
Biraz daha ayrıntı harika olurdu, cevabınızdaki bağlantı koparsa ne olur?
Darth Vader

Hala orada ama sanırım buraya gelenler için, google "vanalar çıplak metal" ve daha iyi OSDEV serisini deneyebilir (mücadele ederken çapraz dev olanı aşmak için forumu okuyun; Ben bir tane gönderebilirim google "OSDEV'i deneyebilirsiniz forum altı ay arası ")
Dennis Ng

Bunun daha eski bir sorunun eski bir cevabı olduğunu biliyorum, ancak sayfa aşağı düşmesi durumunda web.archive.org'da .
anonymoose

1

s-matyukevich/raspberry-pi-os

https://github.com/s-matyukevich/raspberry-pi-os

Bu harika repo, hem C önyükleme yapıyor hem de oldukça karmaşık konulara giriyor.

Ayrıca, Linux çekirdeğinin işleri nasıl yaptığını inceler ve Linux çekirdek kodunu açıklar.

Minimalist bir kurulum için ilk öğreticiye bir göz atın: https://github.com/s-matyukevich/raspberry-pi-os/tree/43f682d406c8fc08736ca3edd08a1c8e477c72b0/src/lesson01/src

Şiddetle tavsiye ederim.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.