Membuat Kernel Sistem Operasi Sendiri dari Nol
(popovicu.com)- Berbagi pengalaman mengimplementasikan kernel prototipe sistem operasi time-sharing pada arsitektur RISC-V
- Menjelaskan konsep dan cara kerja kernel time-sharing dengan pendekatan praktik, serta mengimplementasikannya dengan Zig alih-alih C untuk meningkatkan reproduktibilitas
- Mengadopsi pendekatan unikernel yang menggabungkan kernel dan kode pengguna dalam satu biner, serta memakai layering dengan OpenSBI untuk output konsol dan kontrol timer
- Thread berjalan di mode pengguna (U-mode), sementara kernel melakukan context switch melalui interrupt timer di mode supervisor (S-mode), dan melintasi batas lewat system call
- Inti tekniknya adalah mengganti stack frame yang ditumpuk oleh prolog/epilog interrupt untuk memulihkan himpunan register dan CSR milik thread lain, sehingga alur eksekusi berpindah
- Menyediakan lingkungan belajar yang dapat direproduksi oleh siapa pun berbasis mesin virtual QEMU dan OpenSBI terbaru, serta menghubungkan secara konseptual spektrum virtualisasi seperti thread, proses, container, dan VM, sehingga bernilai sebagai materi dasar untuk tujuan pendidikan dan praktik
Ikhtisar
- Memperkenalkan proses implementasi langsung kernel sistem operasi time-sharing pada arsitektur RISC-V
- Pembaca utamanya adalah pemula sistem perangkat lunak dan arsitektur komputer, mahasiswa, serta engineer yang tertarik memahami prinsip kerja level rendah
- Eksperimen ini menggunakan bahasa Zig alih-alih C untuk meningkatkan reproduktibilitas praktik, sekaligus memudahkan instalasi
- Kode akhirnya dipublikasikan di repositori popovicu/zig-time-sharing-kernel, dan mungkin sedikit berbeda sinkronisasinya dengan isi artikel
- Disarankan menganggap versi repositori sebagai single source of truth dibanding potongan kode di artikel
- Saat praktik, repositori memudahkan penyelarasan lingkungan berdasarkan skrip linker dan opsi build
Bacaan yang direkomendasikan
- Artikel ini mengasumsikan dasar arsitektur komputer seperti register, pengalamatan memori, dan interrupt
- Sebagai bahan awal, disarankan Bare metal on RISC-V, proses boot SBI, dan contoh interrupt timer
- Artikel tentang distribusi Linux mikro juga dapat berguna secara opsional untuk memahami filosofi pemisahan kernel dan ruang pengguna
Unikernel
- Mengadopsi konfigurasi unikernel yang menautkan aplikasi dan kernel OS ke dalam satu berkas eksekusi
- Menghindari kerumitan loader dan linker pada runtime, serta menyederhanakan pemuatan kode pengguna ke memori bersama kernel
- Untuk tujuan pendidikan dan reproduksi, pendekatan ini memberi keuntungan berupa kesederhanaan distribusi dan konsistensi lingkungan
Lapisan SBI
- RISC-V memakai model hak akses mode M/S/U, dan eksperimen ini menempatkan OpenSBI di M-mode sementara kernel berjalan di S-mode
- Output konsol dan kontrol perangkat timer didelegasikan ke SBI untuk memperoleh portabilitas
- Jika SBI tidak tersedia, UART MMIO dipakai sebagai fallback, tetapi untuk praktik disarankan menggunakan OpenSBI terbaru
Tujuan kernel
- Demi penyederhanaan, hanya mendukung thread statis, dan thread disusun sebagai fungsi yang tidak pernah selesai
- Thread berjalan di U-mode dan mengirim system call ke kernel S-mode
- Mengimplementasikan penjadwalan time-sharing berbasis single core agar dapat berpindah ke thread lain pada setiap timer tick
Virtualisasi dan apa sebenarnya thread itu
- Threading time-sharing adalah bentuk virtualisasi yang menjalankan beberapa pekerjaan secara bersamaan pada satu core tanpa mengubah model pemrograman
- Berbeda dari penjadwalan kooperatif, perpindahan terjadi melalui interrupt timer tanpa yield eksplisit
- Setiap thread memiliki himpunan register dan stack yang tidak bisa disentuh pihak lain, sementara memori lainnya dapat dibagikan
Stack dan virtualisasi memori
- Thread harus memiliki stack terpisah; dalam calling convention, ini penting untuk mempertahankan konteks eksekusi seperti variabel lokal dan penyimpanan
ra- Spektrum virtualisasi berlanjut dari thread < proses < container < VM, dengan perbedaan tingkat isolasi dan view
- Di Linux, container diimplementasikan lewat kombinasi mekanisme kernel seperti chroot dan cgroups
Memvirtualisasikan thread
- Target virtualisasi minimum pada eksperimen ini adalah model pemrograman tetap, perlindungan register dan sebagian CSR, serta alokasi stack individual
- Ditekankan bahwa tanpa perlindungan view register, komputasi yang bermakna menjadi mustahil
- Nilai awal seperti a0 di-seed ke stack agar pengiriman argumen saat thread mulai dapat ditangani dengan ringkas
Konteks interrupt
- Interrupt dapat dipahami sebagai model mirip pemanggilan fungsi yang menyimpan/memulihkan register ke stack melalui prolog/epilog
- Kepatuhan terhadap aturan preservasi wajib agar interrupt timer asinkron tidak merusak register
- Assembly contoh menyimpan/memulihkan x0–x31 dan juga CSR seperti sstatus, sepc, scause, stval
Implementasi (tingkat tinggi)
Memanfaatkan konvensi stack interrupt
- Badan rutin interrupt berada di antara prolog dan epilog, dan jika sp diganti ke area memori lain, maka himpunan register dari konteks lain akan dipulihkan
- Ini pada dasarnya adalah context switch, dan merupakan ide inti implementasi time-sharing dalam eksperimen ini
- Interrupt timer campur tangan secara berkala untuk menjalankan alur utama dan alur interrupt secara bergantian
Pemisahan kernel/ruang pengguna
- Menjaga batas kernel S-mode / pengguna U-mode, sementara penanganan interrupt dan system call dilakukan di trap handler S-mode
- Boot berlangsung dalam urutan OpenSBI di M-mode → inisialisasi kernel S-mode → mulai thread U-mode
- Interrupt timer periodik memungkinkan penjadwalan dan perpindahan konteks
Implementasi (kode)
Startup assembly
- Di
startup.S, disusun urutan minimal untuk inisialisasi BSS dan penetapan awal stack pointer, lalu melompat ke main milik Zig- Entry point kernel memakai konvensi
exportagar terhubung dengan C ABI
- Entry point kernel memakai konvensi
Berkas kernel utama dan driver I/O
kernel.zigpadamainterlebih dahulu memeriksa fitur konsol OpenSBI, lalu fallback ke UART MMIO jika gagalsbi.debug_printdipanggil sesuai protokol ECALL dengan mengatur register a0/a1/a6/a7- Setelah timer diatur, handler interrupt S-mode didaftarkan dan tick diaktifkan
Handler S-mode dan context switch
- Handler ditulis dengan konvensi
nakeddi Zig sehingga prolog/epilog penuh termasuk preservasi CSR disusun secara manual- Di badan handler,
handle_kernel(sp)dipanggil dan sp yang dikembalikan dipakai untuk menentukan apakah perpindahan dilakukan scausedigunakan untuk membedakan ECALL U-mode dari interrupt timer lalu bercabang sesuai hasilnya
- Di badan handler,
Thread ruang pengguna
- Kode pengguna dimasukkan bersama kernel dalam satu biner, dan thread contoh mengulangi pola mencetak string → loop penundaan
syscall.debug_printmenaruh nomor system call 64 di a7 serta buffer/panjang di a0/a1, lalu menjalankan ECALL- Saat inisialisasi thread, alamat kembali dan nilai register awal di-seed ke stack sehingga pada return pertama argumen bisa langsung dipakai
Menjalankan kernel
- Build dilakukan dengan
zig build, dan eksekusi dijalankan di QEMU dengan menentukan mesin virt + nographic + OpenSBI fw_dynamic- Saat boot, setelah banner OpenSBI, output periodik berdasarkan ID thread muncul secara bergantian
- Jika dibangun dengan
-Ddebug-logs=true, akan tampil rinci sumber interrupt, stack saat ini, serta log queueing/dequeueing
Kesimpulan
- Eksperimen ini memodernisasi kernel edukatif dengan kombinasi RISC-V + OpenSBI + Zig untuk meningkatkan reproduksibilitas dan keterbacaan
- Ada penyederhanaan seperti penanganan error minimal dan stack yang di-overprovision, tetapi fokusnya tetap pada pembelajaran hakikat context switch dan pemisahan privilese
- Portabilitas ke mesin nyata dimungkinkan dengan asumsi penyesuaian konstanta linker/driver dan tersedianya SBI
Catatan tambahan: ringkasan spektrum virtualisasi
- Threads: berfokus pada virtualisasi register dan stack, dengan kemungkinan besar memori dibagikan
- Process: isolasi memori melalui virtualisasi ruang alamat, dan bisa memuat banyak thread di dalamnya
- Container: unit isolasi yang dibentuk dari kombinasi view lingkungan seperti filesystem dan namespace jaringan
- VM: bertujuan pada virtualisasi penuh atas keseluruhan perangkat keras
Ringkasan poin implementasi inti
- Context switch diwujudkan lewat penggantian stack interrupt
- Trap handler S-mode menyimpan/memulihkan seluruh state termasuk CSR
- Jalur output digandakan dengan pendekatan SBI lebih dulu, fallback UART MMIO
- Penjadwalan sederhana berpusat pada thread statis, single core, dan time slice
- System call berbasis ECALL memperjelas batas U/S
1 komentar
Opini Hacker News
Pekerjaan serupa bisa dialami dalam bentuk "paket" melalui "Operating System in 1000 Lines of Code"; dulu saya pernah mengikutinya dengan Zig (sambil mengonversi cuplikan kode C ke Zig) dan itu sangat menyenangkan, kode dan VOD saya ada di sini https://github.com/kristoff-it/kristos/
Ini adalah kiriman terpisah dari penulis artikelnya sendiri https://news.ycombinator.com/item?id=45236479; penulisnya membuat ulang Tiny OS Kernel sendiri, dan secara khusus ingin bereksperimen di lingkungan RISC-V dan OpenSBI, serta menggunakan Zig alih-alih C tradisional, meski saya rasa bisa diikuti dengan mudah juga memakai C atau Rust; seluruh prosesnya memang agak kasar, tetapi ini merupakan eksperimen dan pengantar untuk langkah pertama mempelajari pengembangan kernel OS dan arsitektur komputer; menurut saya ini proyek yang asyik untuk dicoba sebagai eksperimen akhir pekan, dan tautan walkthrough lengkap serta Github-nya bisa dilihat di atas
Proyek seperti ini benar-benar mengesankan; Linux pada akhirnya juga hanyalah sebuah kernel, tetapi pekerjaan itu membuka jalan agar Unix open source bisa dipasang di miliaran perangkat; menurut saya itu sangat keren
Yang lebih menarik, saat Linux pertama kali dirilis Torvalds menulis di email bahwa itu "hanya hobi, dan tidak akan sebesar serta seprofesional GNU" https://groups.google.com/g/comp.os.minix/c/dlNtH7RRrGA/m/SwRavCzVE7gJ
Saya tidak menganggap proyek seperti ini <i>sangat</i> mengesankan; cara membuat kernel multitasking minimal sudah menjadi jalur yang dikenal selama puluhan tahun; membuat kernel yang bisa boot dan hanya melakukan tugas sederhana adalah hal yang bisa dilakukan siapa pun dengan tingkat kecerdasan dan ketekunan tertentu; di RISC-V memang sedikit lebih rumit daripada x86, tetapi informasi inisialisasi hardware mudah didapat (https://wiki.osdev.org/RISC-V_Meaty_Skeleton_with_QEMU_virt_board lihat di sini), dan dalam hal itu penulis proyek ini sendiri menyatakan bahwa ia "mengulang latihan yang pernah dilakukan di kelas sistem operasi"; menurut saya ini berada pada tingkat yang bisa dicapai siapa saja yang punya gelar rekayasa perangkat lunak; tentu mungkin masih ada bug atau bagian yang belum selesai, tetapi multiproses atau isolasi proses dengan MMU sendiri sekarang bukan lagi hal yang sulit
Sama seperti Linux, ketika Stallman mulai membuat compiler C dan utilitas Unix pada 1984, itu juga membuka jalan agar Unix open source bisa dipasang di miliaran mesin
Zig sangat bagus untuk pengembangan sistem operasi, begitu juga RISC-V; saya juga memulai tugas yang sama dengan x86, tetapi cepat lelah karena terlalu banyak boilerplate legacy; di sisi RISC-V hampir tidak ada hal seperti itu, jadi memulai pengembangannya jauh lebih mudah https://github.com/Fingel/aeros-v
Menurut saya kalau mulai dari x86, boilerplate-nya tidak banyak asalkan memakai bootloader dengan baik; multiboot loader biasanya menangani real mode, dan karena kebanyakan orang ingin protected mode, kita hanya perlu menyiapkan beberapa tabel lalu lompat; kalau ingin mematikan legacy interrupt controller memang ada tambahan yang harus diutak-atik, tetapi ada keuntungan bisa melakukan boot di PC desktop (meski perlu memperhatikan antarmuka konsol); OS hobi saya dulu memakai BIOS boot dan beberapa fitur VGA lalu cukup menderita karena kompatibilitas yang buruk, serial console jauh lebih mudah tetapi komputer zaman sekarang sering tidak punya port serial
Pada dasarnya ini seperti menghidupkan kembali keamanan ala Object Pascal atau Modula-2 lalu membungkusnya ulang dengan sintaks C; C sendiri tidak punya sesuatu yang istimewa selain menyebar luas berkat lisensi UNIX
Saya juga ingin mencoba sendiri, tetapi penasaran kernel RISC-V ini dijalankan di lingkungan seperti apa; apakah hanya memakai Qemu, atau ada hardware nyata yang direkomendasikan? Akan bagus kalau ada saran
Saya rasa ISA RISC-V benar-benar sangat mudah diakses; dokumentasinya bagus, contohnya sangat banyak, emulator-nya juga cukup banyak, dan machine code yang tidak dikompresi pun mudah dibaca; saya sedang menulis buku sendiri untuk anak perempuan saya sambil membuat OS kecil dengan Forth dan timesharing https://punkx.org/projekt0/book/part1/os.html, dan saya rasa saya tidak akan pernah mencoba kalau ini x86; lewat proses ini saya belajar Forth dan assembly RISC-V sekaligus, dan itu sangat menyenangkan; kalau ingin membuat toy OS dari nol, menurut saya sekarang adalah waktu yang tepat (semenarik era 1980-an); beli papan RISC-V murah (rp2350 dan sejenisnya), lalu unggah bagian manual terkait ke AI seperti Claude, itu sangat membantu saat menemui jalan buntu
Upaya seperti ini selalu menyenangkan dan menarik; saya juga ingin mendorong orang untuk mencoba hal-hal sulit lain, bahkan kriptografi buatan sendiri; nasihat "jangan mengimplementasikan kriptografi sendiri" maksudnya adalah jangan memakai sesuatu yang belum terbukti di lingkungan produksi; untuk eksperimen/riset itu tidak berbahaya, jadi silakan saja mencoba; kita butuh lebih banyak sistem operasi dan lebih banyak pilihan
(kutipan putusan Spanyol) Memblokir http saja mungkin masih bisa dimengerti, tapi ini keterlaluan...
Saya dengar di Spanyol Cloudflare (dan mungkin yang lain juga) kadang ikut terblokir secara tidak sengaja karena masalah siaran sepak bola; saya penasaran bagaimana orang-orang menyiasati masalah seperti ini, apakah memakai VPN? Kalau IP penting ikut diblokir, pekerjaan juga pasti kena dampaknya
(dalam putusan itu) Melihat bagian yang menyebut ini dimulai oleh liga sepak bola profesional Spanyol dan Telefónica Audiovisual Digital, saya merasa orang-orang seperti ini adalah kriminal
...apa? Maksudnya organisasi sepak bola Spanyol punya wewenang untuk membatasi akses internet satu negara?
Saya penasaran bagaimana cara mendapatkan hardware RISC murah
Di AliExpress ada board bernama Milk-V Duo S yang dijual seharga $10, belakangan sering muncul di daftar rekomendasi saya; spesifikasi utamanya adalah master SG2000 yang ditingkatkan dengan RAM 512MB, IO lebih luas, WI-FI6/BT5 pada sebagian model (kecuali model 512M-Basic/eMMC), port host USB 2.0, ethernet 100Mbps dengan dukungan PoE, dual MIPI CSI, serta dukungan sakelar perpindahan boot RISC-V dan ARM https://aliexpress.com/w/wholesale-Milk%2525252dV-Duo-S.html
Sudah ada beberapa board, tetapi yang menurut saya menarik hingga saya danai adalah VisionFive 2 Lite https://www.kickstarter.com/projects/starfive/visionfive-2-lite-unlock-risc-v-sbc-at-199/description; saya tidak punya VisionFive2 generasi pertama, tetapi katanya ulasannya bagus dan ekosistemnya terus berkembang; memang masih ada bagian yang belum matang, tetapi saya berharap unitnya segera dikirim; yang saya pakai sendiri adalah PolarFire SoC Discovery Kit, board quad-core RISC-V dengan FPGA; memang agak mahal ($130) dan tidak cocok untuk semua orang, tetapi yang menarik adalah board-nya lebih murah daripada chip-nya sendiri https://www.microchip.com/en-us/development-tool/MPFS-DISCO-KIT; dokumentasi dan toolchain Microchip terasa kuno dan kurang bagus, tetapi setelah terbiasa, menjalankan kode bare-metal RISC-V itu sangat mudah; contoh Linux/bare-metal-nya cukup membantu
Saya sarankan, bahkan tanpa hardware nyata sekalipun, cobalah dulu menjalankannya di emulator pada mesin x86 atau Apple; kecepatan pengembangannya lebih tinggi daripada board fisik, dan dengan QEMU Anda bisa langsung mulai https://www.qemu.org/docs/master/system/target-riscv.html
Raspberry Pi Pico 2 juga mendukung RISC-V jadi cukup bagus https://www.raspberrypi.com/products/raspberry-pi-pico-2/
Terima kasih atas jawaban dari banyak orang; menurut saya orang-orang yang memberi downvote pada pertanyaan ini tidak punya alasan untuk diucapi terima kasih