Bedah Anatomi Kernel: Kronologi Eksekusi dan Penjelasan Instruksi Assembly

Setelah berhasil melihat kode berjalan menggunakan GDB, langkah selanjutnya adalah memahami “bahasa” yang digunakan CPU. Tabel berikut ini merinci setiap langkah yang diambil prosesor dari detik pertama menyala (0x8000) hingga LED berhasil berkedip.

Namun sebelum masuk ke kronologi, mari kita pahami dulu kosakata dasar instruksi ARM Assembly yang muncul dalam kode kita.

Kamus Kecil Instruksi ARM (Yang Muncul di Kernel Ini)

  1. MOV (Move)
    • Arti: Salin data.
    • Logika: “Ambil angka X, masukkan ke laci Y.”
    • Catatan: Meski namanya “Move”, data aslinya tidak hilang. Lebih tepat disebut “Copy”.
  2. BL (Branch with Link)
    • Arti: Lompat ke alamat lain (Fungsi), tapi ingat jalan pulang.
    • Logika: “Pergi ke fungsi main, dan catat alamat saya sekarang di saku (Link Register) supaya nanti bisa kembali.”
  3. LDR (Load Register)
    • Arti: Baca data dari Memori (RAM) ke CPU.
    • Logika: “Pergi ke alamat memori sekian, ambil isinya, bawa ke register CPU.”
    • Penting: CPU tidak bisa mengolah data langsung di RAM, harus di-LDR dulu.
  4. STR (Store Register)
    • Arti: Tulis data dari CPU ke Memori (RAM/Hardware).
    • Logika: “Ambil isi register CPU ini, lalu simpan/tulis ke alamat memori sekian.”
    • Penting: Ini instruksi sakti untuk mengendalikan Hardware (menyalakan LED).
  5. SUB (Subtract)
    • Arti: Pengurangan matematika.
    • Logika: A = A - B. Sering dipakai untuk mengatur Stack (karena Stack tumbuh ke bawah/alamat mengecil).
  6. BIC (Bit Clear)
    • Arti: Logika AND NOT (Penghapus Bit).
    • Logika: “Pastikan bit-bit tertentu menjadi 0, sisanya biarkan.” Dipakai untuk mereset konfigurasi pin.
  7. ORR (Logical OR)
    • Arti: Logika OR (Penyala Bit).
    • Logika: “Pastikan bit-bit tertentu menjadi 1.” Dipakai untuk mengaktifkan fitur (misal: Mode Output).
  8. CMP (Compare) & BNE (Branch Not Equal)
    • Arti: Bandingkan lalu Lompat jika Beda.
    • Logika: CMP mengecek “Apakah i sudah 500.000?”. BNE berkata “Kalau belum sama, lompat balik ke atas (ulangi loop).”

Tabel Kronologis Eksekusi Program

Berikut adalah perjalanan data langkah demi langkah di dalam CPU Raspberry Pi (Model BCM2835).

Alamat MemoriInstruksi AssemblyPenjelasan & Apa yang Terjadi
— FASE 1: BOOTLOADER (boot.S) —
0x8000mov sp, #0x8000Menyiapkan Stack (Tumpukan)
CPU menggunakan MOV untuk mengisi Register SP (Stack Pointer) dengan alamat 0x8000. Ini menyiapkan “meja kerja” memori sementara agar kode C nanti bisa menyimpan variabel lokal.
0x8004bl 0x8010 <main>Panggil Fungsi Main
BL (Branch with Link) memerintahkan CPU melompat ke alamat 0x8010 (pintu masuk kode C). Ia juga menyimpan alamat jalan pulang, jaga-jaga jika fungsi main selesai (ret).
— FASE 2: PERSIAPAN C (main.c) —
0x8010mov r12, #65536Siapkan “Angka Saklar”
Angka 65536 adalah desimal dari 1 << 16 (Bit ke-16). CPU menyiapkannya di register r12 sekarang, agar nanti saat loop berjalan cepat, ia tidak perlu menghitung ulang.
0x8014mov r0, #0Reset Penghitung
Mengisi register r0 dengan 0. Ini adalah persiapan awal untuk variabel loop i (untuk delay).
0x8018ldr r1, [pc, #120]Ambil Kunci Kantor GPIO
LDR mengambil data alamat dasar 0x20200000 dari memori dan menyimpannya di r1. Mulai sekarang, r1 adalah remote kontrol utama untuk mengakses semua fitur GPIO.
0x801csub sp, sp, #8Booking Memori Stack
SUB mengurangi nilai Stack Pointer sebanyak 8 byte. Karena stack tumbuh ke bawah (ke alamat lebih kecil), pengurangan ini berarti kita “memesan” ruang kosong untuk variabel lokal.
— FASE 3: KONFIGURASI PIN —
0x8020ldr r3, [r1, #4]Cek Status Pin
LDR membaca konfigurasi saat ini dari register GPFSEL1 (Alamat r1 + offset 4) dan menyalinnya ke r3. Kita wajib membaca dulu sebelum mengubah.
0x80240x802cbic ... lalu str ...Reset Konfigurasi (Bersihkan)
BIC (Bit Clear) menghapus bit 18-20 pada r3 (menjadi 000). Lalu STR menuliskan nilai bersih ini kembali ke hardware. Ini memastikan tidak ada settingan sisa sebelumnya.
0x8030ldr r3, [r1, #4]Baca Ulang (Verifikasi)
Karena variabel didefinisikan sebagai volatile, Compiler memaksa CPU melakukan LDR ulang untuk memastikan data yang diolah adalah data hardware terbaru.
0x8034orr r3, r3, #262144Set Mode Output
ORR mengubah bit ke-18 pada register r3 menjadi 1 (Logika biner 001 = Output). Angka 262144 adalah desimal dari 1 << 18.
0x8038str r3, [r1, #4]Simpan Permanen
STR menuliskan nilai r3 yang sudah dimodifikasi kembali ke alamat hardware. Detik ini juga, Pin 16 resmi menjadi OUTPUT.
— FASE 4: LOOP UTAMA (Start Blinking) —
0x803cstr r12, [r1, #40]NYALAKAN LED! (Momen Kritis)
STR mengirim isi r12 (Bit 16) ke alamat r1 + 40 (Register GPCLR0).
Karena rangkaian bersifat Active Low, mengirim sinyal ke Clear justru akan Menyalakan LED.
cmp, bneDelay (Menunggu)
CPU melakukan CMP (bandingkan) dan BNE (ulang loop) sebanyak 500.000 kali. Tidak ada perubahan hardware di sini, hanya membuang waktu.
0x8064 (Est)str r5, [r1, #28]MATIKAN LED!
STR mengirim bit 16 ke alamat r1 + 28 (Register GPSET0).
Menulis ke register Set akan membuat pin High (mati pada rangkaian Active Low).
cmp, bneDelay (Menunggu)
CPU kembali berputar dalam loop kosong sebelum kembali ke atas untuk menyalakan LED lagi.

Poin Penting untuk Diingat Pembaca:

  1. Peran Register r1: Ia adalah “jangkar” yang memegang alamat dasar 0x20200000. Semua akses GPIO dilakukan dengan menambahkan offset pada r1.
  2. Offset #40 (0x28): Adalah alamat register GPCLR (Clear Output).
  3. Offset #28 (0x1C): Adalah alamat register GPSET (Set Output).
  4. Alamat 0x803c: Adalah baris kode yang paling bersejarah, karena di baris inilah instruksi STR pertama kali mengubah tegangan listrik fisik pada pin prosesor.