====== 7. Întreruperi. Operații de intrare/ieșire ======
===== Subiecte abordate =====
* Interfața hardware-ului cu sistemul de operare: întreruperi, porturi, registre, memorie
* Rolul întreruperilor
* Porturi și registre hardware, comunicarea cu registrele hardware
* API-ul kernel de lucru cu întreruperi și registre I/O
===== Resurse utile =====
===== Exerciții =====
Arhiva de suport pentru exerciții se găsește [[http://koala.cs.pub.ro/training/res/linux-kernel-dev/arc/cap-07-tasks.zip|aici]]. Descărcați arhiva și apoi decomprimați-o folosind comanda
unzip cap-07-tasks.zip
==== Captură de tastatură ====
Una din liniile de întrerupere cu care lucrăm cel mai ușor este linia de întrerupere ''1'' corespunzătoare întreruperii, de obicei conectată la controller-ul de întrerupere ''i8042''. Vom urmări un driver care va afișa un mesaj ori de câte ori este activată acea linie de întrerupere: adică la fiecare apasare (//pres//) respectiv ridicare (//release//) de tastă.
În directorul ''keyboard-hook/'' din arhiva de suport a capitolului se găsește implementarea unui astfel de driver. Driver-ul se înregistrează la linia de întrerupere a tastaturii și afișează un mesaj pentru fiecare tastă apăsată.
Testați acest driver prin compilarea acestuia și apoi copierea modulului de kernel în mașina virtuală QEMU și apoi încărcarea sa în kernel.
==== Afișare mesaj de tastă apasată ====
Actualizați driverul de la punctul anterior pentru a afișa în mesaj tasta care a fost apăsată, în măsura în care este afișabilă (ASCII). Va trebui să folosiți cele portul de date al tastaturii (''0x60'') și să folosiți funcția ''inb()'' pentru a citi informațiile. În portul/registrul de stare puteți vedea dacă este vorba de o tastă apăsată iar în registrul de date aveți codificare tastei.
Va trebui să implementați funcția ''i8042_read_data()'' pentru a citi valoarea din registrul de date al tastaturii.
În handler-ul de întrerupere (adică în funcția ''kbd_interrupt_handle()'') va trebui să rețineți valoarea citită cu ajutorul funcției ''i8042_read_data()'' și apoi să apelați funcția ''is_key_press()'' și ''get_ascii()''.
Este important să rețineți valoarea registrului într-o variabilă și să **nu** apelați de două sau mai multe ori funcția ''i8042_read_data()''.
==== Stocare taste apăsate ====
Implementați o funcționalitate de tipul keylogger a driverului și rețineți într-un buffer din kernel tastele apăsate. Datele (tastele apăsate) se scriu în continuare în buffer; când bufferul este plin, nu se mai scrie nimic.
Prin intermediul unei intrări în ''/proc'' (''/proc/keylogger'') datele din buffer pot fi citite. În momentul citirii din ''/proc/keylogger'' buffer-ul este resetat și se scrie de la începutul bufferului la noi taste apăsate.
Porniți de la [[:linux-kernel-dev:capitole:capitol-04#afisare-pid-uri-curente-inproc|exemplul de folosire a procfs]] din capitolul 4.