This shows you the differences between two versions of the page.
sde2:teme:tema_fr_5_rust [2022/06/05 13:24] alexandru.radovici created |
sde2:teme:tema_fr_5_rust [2022/06/05 17:59] (current) alexandru.radovici |
||
---|---|---|---|
Line 6: | Line 6: | ||
Date limite: ** Le 23 iunie, 23h59 ** \\ | Date limite: ** Le 23 iunie, 23h59 ** \\ | ||
Note: ** 2 points ** de la note \\ | Note: ** 2 points ** de la note \\ | ||
- | Lien: [[|Devoir 3]] \\ | + | Lien: [[https://classroom.github.com/a/AFdiJq-3|Devoir 3]] \\ |
</note> | </note> | ||
Line 12: | Line 12: | ||
===== Obiectivele temei ===== | ===== Obiectivele temei ===== | ||
- | * Aprofundarea modului în care un executabil este încărcat și rulat de Sistemul de Operare. | + | * Aprofundarea modului în care se scrie un driver pentru sistemul de operare Tock. |
- | * Obținerea de deprinderi pentru lucrul cu excepții de memorie pe sistemele Linux. | + | * Obținerea de deprinderi pentru a realiza biblioteci pentru un driver. |
- | * Aprofundarea API-ului Linux de lucru cu spațiul de adrese, memorie virtuală și //demand paging//. | + | * Aprofundarea API-ului sistemului de operare Tock. |
===== Recomandări ===== | ===== Recomandări ===== | ||
*Înainte de a începe implementarea temei este recomandată acomodarea cu noțiunile și conceptele specifice, precum: | *Înainte de a începe implementarea temei este recomandată acomodarea cu noțiunile și conceptele specifice, precum: | ||
- | * spațiu de adresă | + | * [[https://elf.cs.pub.ro/so/res/doc/so-books/Radovici-Culic2022_Book_GettingStartedWithSecureEmbedd.pdf#0005253515.INDD%3Ab978-1-4842-7789-8_8%3A429|Syscall Driver]] |
- | * drepturi de acces la pagină | + | * [[https://elf.cs.pub.ro/so/res/doc/so-books/Radovici-Culic2022_Book_GettingStartedWithSecureEmbedd.pdf#0005253516.INDD%3Ab978-1-4842-7789-8_9%3A372|Driver Asincron]] |
- | * formatul fișierelor executabile | + | |
- | * //demand paging// | + | |
- | * //page fault// | + | |
- | * maparea de fișiere în spațu de adresă -- //file mapping// | + | |
- | *Urmăriți resursele descrise în secțiunea [[#resurse_de_suport | Resurse de suport]]. | + | |
===== Enunț ===== | ===== Enunț ===== | ||
- | Să se implementeze un **loader de fișiere executabile** în format [[https://en.wikipedia.org/wiki/Executable_and_Linkable_Format | ELF]] pentru Linux. Loader-ul va încărca fișierul executabil în memorie pagină cu pagină, folosind un mecanism de tipul //demand paging// - o pagină va fi încărcată doar în momentul în care este nevoie de ea. Pentru simplitate, loader-ul va rula doar executabile statice - care nu sunt link-ate cu biblioteci partajate/dinamice. | + | Implmentati un driver pentru a afisa codul morse. Driver-ul va pune la dispozitie aplicatiilor urmatoarele comenzi: |
+ | - afisarea unui litere in codul morse. Driver-ul va primi o litera, si indiferent daca acesta este majuscula sau nu, va afisa pe matricea de LED-uri succesunea de semne pentru litera respectiva | ||
+ | - folosirea buzzer-ului pentru a produce sunetele echivalente coldului morse pentru p litera. Driver-ul va primi o litera, si indiferent daca acesta este majuscula sau nu, va genera sunetele pentru litera respectiva | ||
+ | - comenzile 1 si 2 impreuna | ||
- | Pentru a rula un fișier executabil, loader-ul va executa următorii pași: | + | Scrieti bilioteca pentru folosirea driver-ului. Aesta va expune o singura functie, numita //display// care primeste doi parametrii: |
+ | * litera | ||
+ | * modul de //afisare// | ||
+ | * 1 - LED | ||
+ | * 2 - Buzzer | ||
+ | * 3 - LED si BUZZER | ||
- | * Își va inițializa structurile interne. | ||
- | * Va afisa pe stderr (2) lista de segmente ale fisierului executabil | ||
- | * Va afisa pe stderr (2) //base address// pentru fisierul executabil (adresa de memorie minima la care se incarca segmente) | ||
- | * Va afisa pe stderr (2) //entry point address// | ||
- | * Va parsa fișierul binar - pentru a face asta aveți la dispozitie biblioteca [[https://docs.rs/object/latest/object/|object]]. | ||
- | * Va rula prima instrucțiune a executabilului (//entry point-ul//). | ||
- | * de-a lungul execuției, se va genera câte un //page fault// pentru fiecare acces la o pagină nemapată în memorie; | ||
- | * Va detecta fiecare acces la o pagină nemapată, și va verifica din ce segment al executabilului face parte. | ||
- | * dacă nu se găsește într-un segment, înseamnă că este un acces invalid la memorie -- programul iese cu eroarea -200; | ||
- | * dacă //page fault//-ul este generat într-o pagină deja mapată, atunci se încearcă un acces la memorie nepermis (segmentul respectiv nu are permisiunile necesare) -- la fel, programul iese cu eroarea -200; | ||
- | * dacă pagina se găsește într-un segment, și ea încă nu a fost încă mapată, atunci se mapează la adresa aferentă, cu permisiunile acelui segment; | ||
- | * Veți folosi funcțiile [[http://www.kernel.org/doc/man-pages/online/pages/man2/mmap.2.html | mmap]] (varianta [[https://docs.rs/nix/latest/nix/sys/mman/fn.mmap.html|rust]]. | ||
- | * Pagina trebuie mapată **fix** la adresa indicată în cadrul segmentului. | ||
- | |||
- | |||
- | ==== Formatul afisarii ==== | ||
- | <code> | ||
- | Segments | ||
- | # address size offset length flags | ||
- | 0 0x8048000 1012 0x0 1012 r-x | ||
- | 1 0x804a000 8192 0x1000 8192 rw- | ||
- | Entry point 8048120 | ||
- | Base address 8048000 | ||
- | </code> | ||
- | |||
- | <note> | ||
- | Alinierea campurilor se face cu TAB (\t). Daca alinierea nu este buna, adaugati doua caratere TAB. | ||
- | </note> | ||
- | |||
- | ===== Biblioteca object ===== | ||
- | |||
- | Biblioteca //object// va pune la dispozitie un parser pentru fisiere binare (ELF in Linux). Aveti nevoie de lista de segmente ([[https://docs.rs/object/latest/object/read/struct.File.html|File]]). | ||
- | |||
- | În imaginea de mai jos aveți o reprezentare grafică a unui segment. | ||
- | |||
- | <note> | ||
- | * //mem_size// este reprezentata de campul //size// | ||
- | * //file_size// este reprezentat de una din valorile din tupul //file_range// | ||
- | </note> | ||
- | |||
- | {{:so:teme:so_seg.png|}} | ||
===== Precizări/recomandări pentru implementare ===== | ===== Precizări/recomandări pentru implementare ===== | ||
- | * Implementarea //page fault// handler-ului se realizează prin intermediul unei [[http://www.kernel.org/doc/man-pages/online/pages/man2/sigaction.2.html | rutine pentru tratarea semnalului SIGSEGV]]. | + | * Incepeti prin implementarea unui driver care poate folosi alarma (//Driver<A: Alarm>//) |
- | * Pentru a implementa logica de //demand paging// trebuie să interceptați page fault-urile produse în momentul unui acces nevalid la o zonă de memorie. La interceptarea page fault-urilor, tratați-o corespunzător, în funcție de segmentul din care face parte: | + | * Implementati o comanda temporara in driver (sa spune 1000) care odata apelata, incepe sa afiseaza un text la un anumit interval de timp (folositi //kernel::debug//) |
- | * dacă nu este într-un segment cunoscut, rulați handler-ul default; | + | * Implemnatati bibliteca pentru dirver |
- | * dacă este într-o pagină ne-mapată, mapați-o în memorie, apoi copiați din segmentul din fișier datele; | + | * Implementati comenzile 1 si 2 |
- | * dacă este într-o pagină deja mapată, rulați handler-ul default (întrucât este un acces ne-permis la memorie); | + | * Implementat comanda 3 |
- | * Paginile din două segmente diferite nu se pot suprapune. | + | |
- | * Dimensiunea unui segment nu este aliniată la nivel de pagină; memoria care nu face parte dintr-un segment nu trebuie tratată în niciun fel -- comportamentul unui acces în cadrul acelei zone este nedefinit. | + | |
- | + | ||
- | ===== Precizări ===== | + | |
- | + | ||
- | * Pentru gestiunea memoriei virtuale folosiți funcțiile [[http://www.kernel.org/doc/man-pages/online/pages/man2/mmap.2.html | mmap]], [[http://www.kernel.org/doc/man-pages/online/pages/man2/munmap.2.html | munmap]] și [[http://www.kernel.org/doc/man-pages/online/pages/man2/mprotect.2.html | mprotect]]. | + | |
- | * Pentru interceptarea accesului nevalid la o zonă de memorie va trebui să interceptați semnalul ''SIGSEGV'' folosind apeluri din familia [[http://www.kernel.org/doc/man-pages/online/pages/man2/sigaction.2.html | sigaction]]. | + | |
- | * Veți înregistra un handler în câmpul ''sa_sigaction'' al structurii ''struct sigaction''. | + | |
- | * Pentru a determina adresa care a generat page fault-ul folosiți câmpul ''si_addr'' din cadrul structurii ''siginfo_t''. | + | |
- | * În momentul în care este accesată o pagină nouă din cadrul unui segment, mapați pagina în care s-a generat //page fault//-ul, folosind ''MAP_FIXED'', apoi copiați în pagină datele din executabil | + | |
- | + | ||
- | ===== Resurse de suport ===== | + | |
- | + | ||
- | *Cursuri | + | |
- | *[[sde2::cursuri:07]] | + | |
- | *[[sde2:cursuri:08]] | + | |
- | *Laboratoare | + | |
- | *[[sde2:laboratoare:05_new]] | + | |
- | *[[sde2:laboratoare:08_new]] | + | |
- | *Operating System Concepts -- Chapter 8 -- Main Memory | + | |
- | *Operating System Concepts -- Chapter 9 -- Virtual Memory | + | |
- | + | ||
- | *[[https://en.wikipedia.org/wiki/Executable_and_Linkable_Format| Formatul fișierelor executabile pe Linux (ELF)]] | + | |