14 poin oleh GN⁺ 2025-05-06 | Belum ada komentar. | Bagikan ke WhatsApp
  • Memperkenalkan cara menggunakan fungsi standar C termasuk printf tanpa sistem operasi dengan memanfaatkan pustaka Newlib
  • Di lingkungan Bare Metal berbasis arsitektur RISC-V, driver UART dan fungsi alokasi memori diimplementasikan langsung lalu dihubungkan ke Newlib
  • Dengan mengimplementasikan fungsi system call minimum seperti _write, _sbrk, _close, fitur tingkat tinggi seperti printf pun dapat digunakan
  • Menjelaskan cara membuat toolchain berbasis Newlib bersama toolchain RISC-V GCC, termasuk build otomatis dan penulisan linker script
  • Hasilnya, berhasil membangun lingkungan printf yang juga mendukung output UART, input scanf, hingga alokasi memori dinamis

Abstraksi perangkat lunak dan pustaka standar C

  • Pada OS umum, saat printf dipanggil, berbagai lapisan abstraksi seperti system call kernel, lapisan terminal, dan font rendering ikut bekerja
  • Di lingkungan Bare Metal, kontrol I/O harus dilakukan langsung tanpa sistem operasi, sehingga implementasi driver secara manual diperlukan
  • Newlib menyediakan susunan yang dapat diperluas dengan hanya mengimplementasikan fungsi minimum, alih-alih seluruh pustaka standar C

Konsep Newlib

  • printf secara internal diimplementasikan berdasarkan fungsi primitif sederhana seperti _write
  • Pada awalnya, Newlib mendefinisikan semua fungsi dalam bentuk dummy, sehingga cukup mengimplementasikan bagian yang diperlukan dan sisanya dapat memakai nilai bawaan
  • Jika pengembang hanya mengimplementasikan fungsi yang dibutuhkan, fitur pustaka C dapat digunakan secara fleksibel

Toolchain cross-compilation

  • Untuk cross-compile dari x86_64/Linux → RISC-V, perlu build langsung dari source GCC
  • Dengan membangun toolchain yang menggunakan Newlib sebagai pustaka C bawaan, sistem dapat dikonfigurasi agar mampu membangun biner untuk RISC-V

Detail toolchain

  • Saat membangun toolchain, digunakan opsi --prefix, --enable-multilib, --disable-gdb, --with-cmodel=medany
  • medany adalah pengaturan di RISC-V yang memungkinkan akses ke area memori beralamat tinggi
  • Setelah build selesai, cross-compiler dan pustaka Newlib dapat digunakan dari path /opt/riscv-newlib

Mengimplementasikan blok penyusun memori dan UART

  • Implementasi kirim-terima karakter dilakukan dengan mengakses langsung alamat hardware 16550A UART di lingkungan QEMU
  • Newlib dihubungkan melalui implementasi fungsi pengganti system call seperti _write, _sbrk, _close
  • _sbrk bekerja dengan cara memperluas memori heap dari titik _end hingga _stack_bottom

Contoh aplikasi: input dan output

  • Di fungsi main, printf dan scanf dapat digunakan, dan nilai input juga diproses dengan benar
  • Echo tidak didukung, tetapi input string dapat diterima dan ditampilkan melalui scanf
  • Runtime terpisah diimplementasikan untuk menginisialisasi stack dan melakukan zero-fill pada section BSS sebelum memanggil main

Linker script

  • Alamat awal eksekusi adalah 0x80000000, dan kode runtime ditempatkan di lokasi tersebut
  • Memori disusun dalam urutan .text, .rodata, .data, .bss, dan heap ditetapkan dari _end hingga sebelum stack
  • Stack memiliki ukuran tetap 64KB, dan alamat paling atasnya adalah 0x80000000 + 64MB
  • Tabrakan antara heap dan stack dicegah melalui pernyataan ASSERT

Momen “gotcha”

  • Saat mengatur toolchain, --with-cmodel=medany harus digunakan agar instruksi machine code yang mampu menangani alamat di atas 0x80000000 dapat dihasilkan
  • Jika model alamat pada pustaka C dan kode aplikasi berbeda, akan terjadi link error

Menjalankan aplikasi

  • Melalui Makefile, cross-compile dan eksekusi QEMU dapat diotomatisasi
  • Opsi -specs=nosys.specs, -nostartfiles, -T link.ld digunakan untuk konfigurasi minimum Newlib dan runtime kustom
  • Saat menjalankan make debug, input dan output melalui UART berfungsi normal di konsol QEMU
  • Jejak instruksi aktual dapat diperiksa melalui qemu_debug.log

Kesimpulan

  • Struktur yang memungkinkan penggunaan printf, scanf, malloc, dan lainnya tanpa sistem operasi berhasil diimplementasikan dengan Newlib
  • Dengan memanfaatkan struktur berbasis building block milik Newlib, strategi kuncinya adalah hanya mengimplementasikan fungsi minimum yang dibutuhkan
  • Ke depannya, fungsi tambahan seperti file system dan manajemen memori juga bisa diimplementasikan, dan tetap dapat digunakan ulang di Bare Metal sambil mempertahankan kompatibilitas pustaka
  • Hasil keseluruhan proyek berukuran sekitar 220KB, sehingga relatif kecil dan efisien

Source GitHub: popovicu/bare-metal-cstdlib

Belum ada komentar.

Belum ada komentar.