Ketika sebuah interupsi terjadi, prosesor akan memproses terlebih dahulu proses saat ini dan memanggil kode kernel untuk menangani interupsi tersebut. Bagaimana cara prosesor tahu di mana harus memasukkan kernel?
Saya mengerti bahwa ada penangan interupsi yang dapat diinstal untuk setiap jalur interupsi. Tetapi karena prosesor hanya mengeksekusi 'logika bawaan', harus ada beberapa tempat yang telah ditentukan yang menunjuk ke salah satu penangan interupsi itu sendiri, atau beberapa kode yang dijalankan sebelum penangan (karena dapat ada banyak penangan untuk satu jalur interupsi, saya berasumsi bahwa terakhir).
sumber
Ya, ada tempat yang telah ditentukan yang berisi alamat kode untuk melompat ke: vektor interupsi . Bergantung pada prosesor, ini dapat berupa lokasi spesifik dalam memori fisik (8088), lokasi spesifik dalam memori virtual, register prosesor, lokasi dalam memori yang ditunjukkan oleh register (ARM, 386), ...
Detail bervariasi pada prosesor yang berbeda, tetapi elemen umum utama untuk menangani interupsi dalam prosesor adalah:
sumber
Dua jawaban lainnya (pada saat penulisan) berbicara tentang interupsi dan IDT. Namun ini benar, pada CPU Intel-esque modern, tidak kurang dari tiga cara untuk memanggil kernel.
Metode # 1: Mengganggu.
Ini dijelaskan di atas. Anda mengatur entri dalam tabel deskriptor interupsi / vektor interupsi, dan kemudian jalankan interupsi perangkat lunak untuk masuk ke kernel.
Keuntungan utama dari metode ini adalah bahwa kernel tipikal perlu dapat menangani interupsi, dan itu bekerja pada perangkat keras kuno.
Metode # 2: Panggil gerbang.
Gerbang panggilan adalah jenis khusus pemilih segmen. Target panggilan harus dimuat dalam tabel deskriptor segmen global atau lokal (masing-masing GDT dan LDT). Jika Anda kemudian melakukan instruksi panggilan jauh menggunakan gerbang panggilan sebagai segmen (offset panggilan diabaikan), ini memungkinkan Anda untuk memanggil kode yang lebih istimewa. Gerbang panggilan sangat fleksibel; arsitektur IA-32 memiliki empat level privilege, dan gerbang panggilan memungkinkan Anda memanggil level apa pun.
Saya tidak percaya bahwa Linux pernah menggunakan gerbang panggilan, tetapi Windows 95 melakukannya. Layanan kernel Win95 (
krnl386.exe
dankernel.dll
) benar-benar berjalan dalam mode pengguna (dering 3). Level privilege tertinggi (ring 0) hanya digunakan untuk driver dan microkernel yang hanya melakukan proses switching. Memanggil ke driver dilakukan menggunakan gerbang panggilan. Ini memungkinkan kode 16-bit lama (yang banyak!) Untuk menggunakan driver Win95 hanya menggunakan panggilan jarak jauh standar, seperti yang selalu mereka lakukan.Perlindungan tabel deskriptor global yang tidak memadai adalah penyebab dari beberapa eksploitasi Windows 95, yang berhasil memasang gerbang panggilan sendiri dengan menulis lebih dari memori.
Metode # 3: SYSCALL / SYSRET dan SYSENTER / SYSEXIT
Ini adalah dua set instruksi, yang diciptakan secara independen oleh AMD dan Intel, tetapi pada dasarnya mereka melakukan hal yang sama. SYSCALL / SYSRET yang lebih dulu dan hanya AMD, SYSENTER / SYSEXIT adalah Intel, tetapi AMD mengimplementasikannya sekarang. Jadi saya akan menjelaskan SYSENTER / SYSEXIT.
Tidak seperti gerbang panggilan, SYSENTER hanya dapat digunakan untuk mentransfer ke dering 0, dan hanya dapat mentransfer ke satu lokasi. Namun, ini memiliki keuntungan menjadi latensi sangat rendah karena tidak seperti panggilan atau interupsi, ia tidak menyentuh tumpukan.
Lokasi transfer diatur menggunakan tiga register khusus model: satu untuk informasi segmen, dan masing-masing untuk penunjuk instruksi dan penumpukan penunjuk kode kernel. Karena tidak ada yang "didorong" ke stack, kode mode pengguna bertanggung jawab untuk memberi tahu kernel ke mana harus kembali dengan melewatkan pointer instruksi pengembalian dan stack pointer dalam register. Kernel bertanggung jawab untuk mengembalikan stack pointer, dan instruksi SYSEXIT mengembalikan pointer instruksi.
Informasi lebih lanjut tentang instruksi SYSENTER dan SYSEXIT.
sumber