Tulis OS untuk Raspberry Pi di C

19

Saya sudah menemukan tutorial Baking Pi , tetapi mereka hanya menggunakan bahasa assembly . Saya mengikuti pelajaran pertama, tetapi saya sudah bertanya-tanya bagaimana cara menggunakan C sebagai gantinya. Maksud saya, ada alasan mengapa mereka menciptakan bahasa tingkat tinggi. Saya mencoba mengkompilasi kode C ke .ofile object ( ), mengkompilasi

.section .init
.globl _start
_start:

bl main

loop$:
b loop$

ke file objek lain dan menautkannya bersama sehingga memperoleh kernel.img. Saya kemudian mengganti kernel yang sudah ada dengan kernel saya sendiri, tetapi tidak menjalankan kode C. Kode C yang saya tulis harus menyalakan OK LED dan kemudian kembali (kemudian muncul loop$: b loop$). Tetapi LED OK berkedip secara acak beberapa kali dan kemudian mati. Ini kode C saya:

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

Bagaimana cara saya menggunakan C untuk pengembangan sistem operasi pada Raspberry Pi?

Saya ragu itu adalah kesalahan dalam kode (meskipun saya hanya penggemar). Saya sadar mengatur C mungkin rumit, tetapi saya bukan yang pertama melakukan ini. AFAIK, semua OS yang dominan saat ini kebanyakan ditulis dalam C, jadi harus ada artikel yang menjelaskan prosesnya. Saya akan sangat senang dengan daftar langkah juga, jadi saya bisa google untuk langkah-langkah itu dan mungkin mengajukan pertanyaan yang sedikit kurang luas.

Catatan: rakitan ARM yang setara dengan kode C di atas berfungsi dengan baik. Menyalakan LED (setelah sedikit berkedip). Saya pikir (harapan) yang menunjukkan Raspberry Pi saya baik-baik saja.

11684
sumber
C dirancang untuk menjadi bahasa rakitan portabel untuk Unix. Linux ditulis dalam bahasa C, Anda dapat menghemat sedikit waktu dengan melihat bagaimana hal itu dilakukan.
Thorbjørn Ravn Andersen
1
@ ThorbjørnRavnAndersen Saya pikir saya tidak bisa membaca sumber Linux. Linux jauh lebih kompleks daripada yang saya ingin ketahui, sehingga mengaburkan bagi saya bagian yang menarik.
11684
1
Um, 'pasang' beberapa LED.
11684
1
Terima kasih, tetapi saya ingin melakukan banyak hal sendiri. Ini proyek pembelajaran.
11684
1
Saya harus mengakui bahwa saya tidak pernah melihat pertanyaan sebelumnya tentang cara menulis OS. Dan ada beberapa jawaban yang menarik. Itu hanya gila ...
Piotr Kula

Jawaban:

14

Saya menulis kernel yang sangat sederhana bertahun-tahun yang lalu, dan menjalankannya pada 386. Saya belum pernah melakukan pemrograman bare metal selama bertahun-tahun, tetapi secara umum Anda perlu menulis beberapa kode assembler yang akan:

  • nonaktifkan interupsi selama proses boot
  • jika Pi memiliki pengontrol memori, Anda harus mengaturnya
  • mengatur centang waktu
  • konfigurasikan interrupt controller
  • mengatur tumpukan sehingga Anda dapat mengeksekusi kode C.

Menyiapkan tumpukan itu mudah - temukan beberapa memori yang tidak digunakan, dan muat alamat yang pernah digunakan sebagai penunjuk tumpukan.

Dalam kode C Anda, Anda perlu init struktur data OS seperti kumpulan memori dan tabel utas. Anda tidak akan dapat menggunakan fungsi C library - Anda harus menulis sendiri hal itu.

Jika Anda ingin menulis os multitugas sederhana, Anda harus menulis beberapa rutin assembler untuk menyimpan register CPU di stack, dan memuat serangkaian nilai register yang berbeda dari stack thread lain. Dan Anda harus menulis API untuk membuat utas berbeda.

Steve
sumber
1
Sulit untuk memilih antara jawaban ini dan Georges Dupéron. Saya menerima yang ini dan memberi yang lainnya suara positif.
11684
13

Saya belum melihat kode Anda secara mendalam, tetapi bagi saya Anda berada di jalur yang benar. Pastikan bahwa:

  • The _startsimbol memang yang digunakan saat kompilasi & menghubungkan berkas perakitan dan file C Anda (dan yang main()tidak digunakan sebagai gantinya)
  • Saat menelepon main(), Anda harus menggunakan konvensi pemanggilan C:
    • tekan tumpukan alamat instruksi mengikuti panggilan Anda (alamat kembali, yang akan digunakan oleh returnpernyataan dalam C)
    • dorong argumen untuk fungsi tersebut. Dalam kasus Anda, Anda bisa mendorong dua nilai 32-bit (total 8 byte), tetapi untuk mempermudah, Anda juga bisa menghapus argumen dan hanya perluint main() { ... }
    • mungkin memesan tempat di stack untuk nilai pengembalian
    • Saya tidak ingat bagaimana urutan hal-hal ini harus didorong
    • Untuk mengetahui apa yang diharapkan oleh fungsi C, bongkar ( objdump -S main.o) dan lihat bagaimana ia memanipulasi tumpukan.
  • Jika Anda tidak menghormati konvensi pemanggilan, maka kode rakitan yang dihasilkan oleh kompiler C mungkin merusak alamat pengirim di tumpukan, dan dalam kasus Anda, Anda bahkan tidak mendorong alamat pengirim, sehingga instruksi pengembalian akan melompat ke suatu tempat acak, bukannya pergi ke loop$.

The pengembangan sistem operasi wiki akan menjadi ressource sangat berguna - itu terutama berkaitan dengan pengembangan x86 tetapi informasi yang paling masih berlaku untuk pi raspberry.

Beberapa sumber spesifik raspberry-pi osdev lainnya:

Suzanne Dupéron
sumber
Sulit untuk memilih antara jawaban ini dan jawaban Steve. Saya memberi Anda suara positif dan menerima yang lain. Saya menyesali perbedaan 5 rep.
11684
Wiki OSDev baik - dan bahkan memiliki beberapa hal RasPi khusus
wally
2

Masalah utama yang mungkin Anda temui adalah C library dan kode prolog. Itu dimulai sebelum kode Anda sendiri mulai mengeksekusi dan mengatur tumpukan, tumpukan dan melakukan banyak hal bermanfaat lainnya. Namun, ketika Anda mencoba memprogram untuk bare metal Anda tidak memiliki OS yang berjalan di bawah Anda dan Anda sebaiknya menghindari memanggil fungsi-fungsi ini. Untuk melakukan itu, Anda memerlukan versi perpustakaan C yang dimodifikasi dan / atau beberapa simbol global yang didefinisikan atau diganti dengan milik Anda. Proses ini sedikit melibatkan, itu sebabnya orang 'Baking Pi' memilih untuk menggunakan perakitan untuk tutorial mereka.

lenik
sumber
Terima kasih telah menjawab pertanyaan saya (dan maaf sudah terlambat menanggapi). Tapi (kejutan!) Saya membeli pi saya untuk belajar tentang hal itu, bit yang melibatkan proses tingkat rendah (saya lebih suka tidak melakukannya pada desktop yang mahal dengan risiko menghancurkan file / email / foto pribadi). Bisakah Anda menambahkan bagaimana saya mengatur tumpukan, atau artikel / tutorial / sumber daya yang menjelaskan hal itu? (Dan apa lagi yang saya butuhkan untuk menjalankan C).
11684
2

Coba ini sebagai gantinya:

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

Juga, pengalaman x86 sedikit berbeda. Ini mungkin berlaku untuk pemrograman OS telanjang logam ARM umum. Tapi untuk Pi, maaf itu gpu start dulu dan mengatur sedikit sebelum kode OS (?) Anda.

Dennis Ng
sumber
1
Sedikit lebih detail akan lebih bagus, apa yang terjadi jika tautan di jawaban Anda putus?
Darth Vader
Masih ada di sana tapi saya pikir bagi mereka yang datang ke sini, mungkin google "katup logam kosong" dan lebih baik mencoba seri OSDEV (untuk melewati cross dev ketika saya berjuang, baca forum; saya posting satu Anda dapat mencoba google "OSDEV forum enam bulan lintas ")
Dennis Ng
Saya tahu ini adalah jawaban lama untuk pertanyaan yang lebih lama, tetapi halamannya ada di web.archive.org kalau-kalau turun.
anonim pilih
1

s-matyukevich/raspberry-pi-os

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

Repo yang luar biasa ini melakukan bootstrap C kedua, dan masuk ke topik yang cukup kompleks.

Lebih jauh lagi, ia melihat bagaimana kernel Linux melakukan sesuatu, dan membubuhi keterangan kode kernel Linux.

Lihatlah tutorial pertama untuk pengaturan minimalis: https://github.com/s-matyukevich/raspberry-pi-os/tree/43f682d406c8fc08736ca3edd08a1c8e477c72b0/src/lesson01/src

Saya sangat merekomendasikannya.

Ciro Santilli 新疆 改造 中心 法轮功 六四 事件
sumber