This shows you the differences between two versions of the page.
Both sides previous revision Previous revision Next revision | Previous revision | ||
linux-kernel-dev:capitole:capitol-07 [2015/09/05 21:14] razvan |
linux-kernel-dev:capitole:capitol-07 [2015/09/11 10:27] (current) razvan [Afișare mesaj de tastă apasată] |
||
---|---|---|---|
Line 1: | Line 1: | ||
- | ====== Întreruperi. Operații de intrare/ieșire ====== | + | ====== 7. Întreruperi. Operații de intrare/ieșire ====== |
+ | |||
+ | ===== Subiecte abordate ===== | ||
* Interfața hardware-ului cu sistemul de operare: întreruperi, porturi, registre, memorie | * Interfața hardware-ului cu sistemul de operare: întreruperi, porturi, registre, memorie | ||
- | * Întreruperi, nevoia de întreruperi, handler de întrerupere, /proc/interrupts | + | * Rolul întreruperilor |
* Porturi și registre hardware, comunicarea cu registrele hardware | * Porturi și registre hardware, comunicarea cu registrele hardware | ||
- | * Linii de întrerupere, înregistrarea unui handler de întrerupere | + | * API-ul kernel de lucru cu întreruperi și registre I/O |
- | * Înregistrarea unui spațiu de I/O | + | |
- | * Handling la întreruperea de tastatură | + | ===== Resurse utile ===== |
- | * Citirea registrelor de tastatură, un keylogger | + | |
- | * (Opțional) Handling la întreruperea de pe portul serial | + | ===== 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<code> | ||
+ | unzip cap-07-tasks.zip | ||
+ | </code> | ||
+ | ==== 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. | ||
+ | |||
+ | <note tip> | ||
+ | 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()''. | ||
+ | </note> | ||
+ | |||
+ | ==== 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. | ||
+ | |||
+ | <note tip> | ||
+ | Porniți de la [[:linux-kernel-dev:capitole:capitol-04#afisare-pid-uri-curente-inproc|exemplul de folosire a procfs]] din capitolul 4. | ||
+ | </note> |