Saya tahu bahwa Linux tersedia dan telah porting untuk berbagai platform seperti untuk X86, ARM, PowerPC dll.
Namun, dalam hal porting, apa yang dibutuhkan sebenarnya?
Pemahaman saya adalah bahwa Linux adalah perangkat lunak yang ditulis dalam C. Oleh karena itu ketika porting Linux berasal dari X86 ke ARM atau yang lainnya misalnya, bukankah itu hanya masalah mengkompilasi ulang kode dengan kompiler untuk arsitektur target spesifik?
Mengesampingkan driver perangkat untuk periferal yang berbeda, apa lagi yang perlu dilakukan ketika porting Linux ke arsitektur baru. Apakah kompiler tidak mengurus semuanya untuk kita?
Jawaban:
Meskipun sebagian besar kode dalam kernel Linux ditulis dalam C, masih ada banyak bagian dari kode itu yang sangat spesifik untuk platform di mana ia berjalan dan perlu memperhitungkannya.
Salah satu contoh khusus dari ini adalah memori virtual, yang bekerja dengan cara yang serupa di sebagian besar arsitektur (hierarki tabel halaman) tetapi memiliki detail spesifik untuk setiap arsitektur (seperti jumlah level di setiap arsitektur, dan ini telah meningkat bahkan pada x86 dengan pengenalan chip baru yang lebih besar.) Kode kernel Linux memperkenalkan makro untuk menangani melintasi hierarki ini yang dapat dielakkan oleh kompiler pada arsitektur yang memiliki lebih sedikit tingkat tabel halaman (sehingga kode ditulis dalam C, tetapi mengambil rincian arsitektur ke dalam pertimbangan.)
Banyak area lain yang sangat spesifik untuk setiap arsitektur dan perlu ditangani dengan kode khusus lengkung. Sebagian besar dari ini melibatkan kode dalam bahasa assembly. Contohnya adalah:
Pengalihan Konteks : Pengalihan konteks melibatkan penghematan nilai semua register untuk proses yang dihilangkan dan mengembalikan register dari set proses tersimpan yang dijadwalkan ke dalam CPU. Bahkan jumlah dan set register sangat spesifik untuk setiap arsitektur. Kode ini biasanya diimplementasikan dalam perakitan, untuk memungkinkan akses penuh ke register dan juga untuk memastikan itu berjalan secepat mungkin, karena kinerja pengalihan konteks bisa sangat penting untuk sistem.
Panggilan Sistem : Mekanisme di mana kode userspace dapat memicu panggilan sistem biasanya khusus untuk arsitektur (dan kadang-kadang bahkan untuk model CPU tertentu, misalnya Intel dan AMD memperkenalkan instruksi yang berbeda untuk itu, CPU yang lebih tua mungkin kekurangan instruksi tersebut, jadi perinciannya). bagi mereka akan tetap unik.)
Interrupt Handler : Detail tentang cara menangani interupsi (interupsi perangkat keras) biasanya khusus untuk platform dan biasanya memerlukan lem tingkat rakitan untuk menangani konvensi pemanggilan khusus yang digunakan untuk platform. Juga, primitif untuk mengaktifkan / menonaktifkan interupsi biasanya platform-spesifik dan memerlukan kode perakitan juga.
Inisialisasi : Rincian tentang bagaimana inisialisasi harus terjadi juga biasanya mencakup detail yang khusus untuk platform dan sering memerlukan beberapa kode rakitan untuk menangani titik masuk ke kernel. Pada platform yang memiliki banyak CPU (SMP), perincian tentang cara menghadirkan CPU lain secara online biasanya juga berbasis platform.
Locking Primitives : Implementasi primitif penguncian (seperti spinlocks) biasanya melibatkan detail platform spesifik juga, karena beberapa arsitektur menyediakan (atau lebih suka) instruksi CPU yang berbeda untuk mengimplementasikannya secara efisien. Beberapa akan menerapkan operasi atom, beberapa akan memberikan cmpxchg yang dapat menguji / memperbarui (tetapi gagal jika penulis lain masuk terlebih dahulu), yang lain akan menyertakan pengubah "kunci" untuk instruksi CPU. Ini akan sering melibatkan penulisan kode assembly juga.
Mungkin ada area lain di mana kode platform-atau arsitektur-spesifik diperlukan di kernel (atau, khususnya, di kernel Linux.) Melihat pohon sumber kernel, ada sub pohon khusus arsitektur di bawah
arch/
dan di bawah diinclude/arch/
mana Anda dapat menemukan lebih banyak contoh dari ini.Beberapa sebenarnya mengejutkan, misalnya Anda akan melihat bahwa jumlah panggilan sistem yang tersedia pada setiap arsitektur berbeda dan beberapa panggilan sistem akan ada di beberapa arsitektur dan bukan yang lain. (Bahkan pada x86, daftar syscalls berbeda antara kernel 32-bit dan 64-bit.)
Singkatnya, ada banyak kasus yang perlu diperhatikan oleh kernel yang spesifik untuk suatu platform. Kernel Linux mencoba untuk mengabstraksi sebagian besar dari mereka, sehingga algoritma tingkat yang lebih tinggi (seperti bagaimana manajemen memori dan penjadwalan bekerja) dapat diimplementasikan dalam C dan bekerja sama (atau sebagian besar sama) pada semua arsitektur.
sumber
Selain porting kernel Linux, Anda perlu mendefinisikan antarmuka biner aplikasi (ABI) untuk program "ruang pengguna" dan port lapisan paling bawah dari tumpukan perangkat lunak ruang pengguna. Linux biasanya digunakan dengan komponen ruang pengguna tingkat rendah dari proyek GNU, yang mana yang paling kritis adalah:
Banyak perangkat lunak lain memiliki komponen opsional yang bergantung pada platform; misalnya, penjelajahan web akan jauh lebih cepat jika Anda menulis primitif kriptografi yang dioptimalkan untuk NSS dan OpenSSL untuk arsitektur CPU baru Anda, dan kompilasi back-end just-in-time untuk IonMonkey dan V8 . Tetapi ini tidak penting untuk memunculkan platform baru.
sumber
Anda harus memberi tahu kernel tentang perangkat keras yang Anda porting. Pekerjaan kernel adalah untuk langsung berinteraksi dengan perangkat keras, sehingga agar berfungsi dengan baik, kernel perlu tahu tentang CPU, osilator (jam), dan periferal apa pun, seperti berbagai jenis port serial (SPI, CAN, I2C, dll.).
Di masa lalu, Anda akan melakukan ini dengan menulis kode khusus platform yang kemudian akan digunakan driver untuk berfungsi. Hari-hari ini, ini dilakukan dengan menulis definisi Device Tree .
sumber