Sunteți pe pagina 1din 19

1.

Ce este un sistem de operare în timp real?

Definiţi atât sistemul de operare generic, cât şi noţiunea de timp real.

SO reprezintă o componentă de bază a clasei programelor de sistem. SO controlează toate resursele calculatorului şi oferă acces la acestea, programelor utilizator într-un mod convenient şi sigur. Timp real: – răspunsul sistemului pentru evenimentele apărute, ajunge în timp oportun pentru evenimentul respective.

2. Care sunt elementele de bază a unui sistem de operare?

Detaliaţi: planificatorul, managmentul memoriei, sistemul de fişiere.

Planificatorul:

Un proces este un program în execuţie. Procesul cuprinde:

programul executabil

– datele şi stiva programului

registrele de uz general

registrele speciale: program counter, stack pointer

Toate informaţiile despre un proces sunt stocate într-o tabelă administrat de SO. Crearea și terminarea proceselor se realizează prin apeluri sistem:

– apelul sistem trebuie să aibă o durată bine definită Schimbarea între procese (planificarea):

preemptiv

non-preemptiv

Tratarea întreruperilor trebuie să aibă prioritate ridicată. Durata dezactivării întreruperilor (secțiuni critice) trebuie să fie minimă și bine determinabilă. Programele utilizator comunică cu SO pentru a cere anumite servicii SO prin intermediul

apelurilor sistem. Un apel de sistem este o funcţie dintr-o bibliotecă (furnizată de SO). Apelurile sistem pot fi împărţite în:

apeluri non-deterministe ce pot fi apelate din procesele utilizator şi pot fi întrerupte

apeluri real-time - secţiuni critice cu dezactivarea întreruperilor - durate deterministe Managementul memorie

SO poate conţine un Memory Manager (integrat în kernel sau în bibliotecile standard asociate). Fiecare proces trebuie să aibă propria zonă de memorie:

date

– stivă

program

Nu toate arhitecturile oferă sistem de management al memoriei. Sistemul de fişiere SO ascunde dispozitivele hardware de utilizator prin sistemul de fişiere.

Sunt puse la dispoziţie apeluri sistem unitare pentru accesul diferitelor dispozitive:

de stocare

periferice integrate

– de comunicaţie

1

3. Ce este un proces respectiv un thread şi cum se raportează la constrângerile real-time? Descrieţi sumar procesul/threadul şi detaliaţi avantajele şi dezavantajele folosirii lor în sisteme real-time.

Taskul (procesul) constă din:

– copie a programului în memorie (instrucţiuni + constante)

- memoria de program poate fi diferită de memoria de date, caz în care se foloseşte numai o mapare a memoriei

– date + stivă

- în unele cazuri heapul lipseşte: o singură zonă de memorie este alocată stivei şi

datelor

registre

- registre de uz general, registrul de stare, program counter, stack pointer Threaduri = fir de execuţie aparţinând aceluiaşi task. Codul, datele sunt commune. Thread conţine:

stiva

registrele

– mapare a memoriei de program şi de date

4. Ce sunt condiţiile de concurenţă şi cum se poate realiza o cooperare corectă în astfel de condiţii? Definiţi condiţia de concurenţă, criteriile de cooperare şi enumeraţi metodele de excludere mutuală.

Condiţii de concurenţă Condiţii de concurenţă la accesul unor resurse:

– în cazul accesului simultan la date, aceste se pot corupe

Coruperea datelor în cazul condiţiei de concurenţă trebuie evitat:

– excludere mutuală a accesului la datele partajate

Secţiuni critice:

partea dintr-un program unde se realizează accesul la o resursă comună

Condiţii de cooperare corectă

- nu pot exista 2 procese simultan în secţiunea critică

- nu se poate face nici o presupunere asupra vitezei şi numărului de CPU

- nici un proces care rulează cod în afara secţiunii critice nu poate bloca alte procese

- nici un proces nu va aştepta pentru totdeauna să intre în secţiunea critic

Metode de excludere mutual - busy-waiting: procesul aşteaptă într-o buclă până la eliberarea resurselor pentru a intra în secţiunea critică – nu rezolvă complet secţiunea critcă

- dezactivarea întreruperilor

– la intrarea în secţiune critică se dezactivează întreruperile, iar la ieşirea din secţiune se reactivează – planificatorul nu mai poate intervine în interiorul secţiunii critice

- lock variables

- alternare strictă

2

- soluţia lui Peterson

- instrucţiunea TSL

- sleep & wakeup

- wakeup întârziat

5. Cum funcţionează semafoarele de numărare şi binare (mutex)? Exemplificaţi pe

FreeRTOS. Definiţi semafoarele şi detaliaţi funcţionarea primitivelor/funcţiilor corespunzătoare din FreeRTOS.

Semafoare In 1965 Dijkstra a propus folosirea unei variabile pentru controrizarea wakeup-urilor salvate pentru viitoarea utilizare:

semafor

semafor = 0: nici un wakeup nu a fost salvat

semafor = n > 0: n wakeup-uri au fost salvate

● se folosesc două proceduri: down şi up

down

● verifică valoarea semaforului

● dacă semafor > 0, decrementează semaforul şi continuă execuţia procesului

● dacă semafor == 0, execută sleep

● verificarea valorii, modificarea şi executarea sleep (dacă e cazul) formează o operaţie atomică

(o operaţie indivizibilă) => pe durata executării acestei operaţii nici un alt proces nu are acces la semafor

● atomicitate este esenţială pentru evitarea condiţiilor de concurenţă up

● incrementează valoarea semaforului

● dacă unul sau mai multe procese executau sleep determinat de semafor (incapabil să execute down), unul din ele va fi ales de system şi va executa down

după up semaforul poate să rămână 0, dar vor fi mai puţine procese blocate de acel semafor

up este de asemenea o operaţie atomică

up nu poate bloca procesul respective

6.

Care sunt strategiile de planificare întâlnite la sisteme de operare în timp real?

Descrieţi strategiile de bază (preemptive/non-preemptive/cooperative) cu avantajele/dezavantajele în sistemele timp real şi descrieţi detaliat strategiile Round-Robin şi

Priority Scheduling.

Strategii de planificare La fiecare întrerupere de ceas sau la apariţia unui eveniment se rulează schedulerul Strategiile:

preemtive care permit suspendarea temporară a proceselor care rulează

non-preemptive procesele rulează până îşi termină execuţia sau se vor bloca în aşteptarea unei

operaţii IO

– cooperativ procesele îşi asigură (prin programare atentă) de a preda controlul din când în când

3

Round Robin Scheduling Este unul din cele mai vechi şi simpli algoritmi de planificare. Fiecărei proces i se atribuie un interval de timp numit cuantă, în care procesul se poate executa. Dacă procesul nu-si termină execuţia până la expirarea cuantei de timp alocate, el va fi întrerupt iar CPU este alocat altui process. Dacă procesul termină înainte de expirarea cuantei, se va planifica alt proces fără a se astepta expirarea cuantei. Priority scheduling In cazul Round Robin, procesele aveau aceeaşi prioritate. Uneori însă va trebui să ţinem cont de priorităţile în rezolvarea unor problem. Fiecărei proces i se alocă o prioritate. La un moment dat va fi rulat procesul cel mai prioritar. Pentru a previne rularea indefinită a proceselor prioritare schedulerul poate descreşte prioritatea procesului activ la fiecare întrerupere.

7. Care sunt principalele arhitecturi de sisteme de operare în timp real? Detaliaţi executivul timp real, nucleul monolitic şi nucleul mikrokernel cu avantajele/dezavantajele în sisteme de timp real.

Real-time executive

● sisteme RTOS tradiţionale

● sisteme fără MMU

resurse (CPU, memorie) limitate

● kernelul rulează în aceaşi spaţiu de adrese ca şi aplicaţiile

● tot sistemul (kernel + aplicaţii) este compilat într-o singură imagine

● este greu de adăugat aplicaţii în mod dinamic

● nu se pretează pentru software complex Kernel monolitic

● distincţie între user-space şi kernel-space

– aplicaţiile rulează în user-space

– nucleul şi driverele rulează în kernel-space

– între ele există un strat de apeluri sistem

● suportă sistem complexe cu multe aplicaţii

● oferă protecţie între aplicaţii

– dacă o aplicaţie se blochează sau funcţionează incorect atunci nu afectează pe celelate

● poate rula şi pe arhitecturi fără MMU, dar cu protecţie limitată Microkernel

● teoretic cea mai performantă arhitectură de SO

● practic implementaţiile existente prezintă prea multe limitări din cauza complexităţii

● toate funcţiile SO rulează în user-space în afara unui strat foarte subţire de message passing

● sistemul are un overhead mare datorită mulţimii de mesaje ce trebuie să treacă din user-space în kernel-space şi invers

● poate fi folosit numai pe sisteme cu MMU, altfel pierde avantajul protecţiei maxime

4

8. Care sunt principalele componente a sistemului de operare Embedded Linux? Descrieţi sumar planificatorul, managerul de memorie, sistemul de fişiere, subsistemul reţea, subsistemul IO şi metodele IPC.

Planificatorul (scheduler)

● planificatorul permite funcţionarea multitasking a sistemului

– aplicaţiile rulează pseudoparalel

firele executate de scheduler pot fi:

– kernel threads (fire de execuţie în interiorul kernelului fără context)

– user process (fire de execuţie, împreună cu context, date, stivă, heap, text, bss + stivă kernel)

– user threads (fire de execuţie, cu instanţă de execuţie separată, dar heap, code, bss şi data partajată cu alte fire din cadrul aceluiaşi proces) Managerul de memorie

● realizează alocarea dinamică a memoriei pentru componentele SO (scheduler, FS, networking, drivere)

● implementează memoria virtuală pentru aplicaţii (paginare)

– memoria este împărţită în pagini de 4kB (de obicei) şi pot fi alocate independent kernelului sau aplicaţiilor

● separă zonele de memorie alocate diferitelor procese pentru protecţie între ele (segmentare) Sistemul de fişiere

● Linux combină diferitele sisteme de fişiere într-un strat comun Virtual File System

● VFS oferă o interfaţă comună pentru toate dispozitivele din sistem

● Linux are nevoie întotdeauna de un FS (cât de cât minimal):

– programele sunt stocate într-o memorie nevolatilă (HDD, Flash) în forma unor fişiere

accesibile prin intermediul FS

– toate dispozitivele de intrare/ieşire existente în sistem sunt tratate ca fişiere

● sistemul Linux oferă un root file system, care trebuie montat la pornire (dacă nu există kernelul nu va porni)

● pe acest root vor fi montate celelalte sisteme de fişiere:

ext2, ext3, reiserfs (pentru harddiskuri)

romfs (memorie ROM)

ramfs (memorie RAM)

jffs2 (flash)

procfs (informaţii despre sistem /proc)

devfs, udev (dispozitive IO /dev)

Subsistemul IO

● oferă o interfaţă uniformă pentru dispozitivele din sistem

– character devices (dispozitive secvenţiale)

block devices (dispozitive accesibile aleator)

network devices (dispozitive pe reţea)

● accesul dispozitivelor se realizează prin intermediul FS

● controlul dispozitivelor se realizează prin interfaţa IO (ioctl)

Subsistemul de reţea

una din principalele atuuri al sistemului Linux este orientarea spre operare în reţea

● nucleul Linux include implementări complete de stive de reţea, cea mai importantă fiind stiva TCP/IP

5

foarte multe subsisteme Linux se folosesc de modularitate oferită de stivele de reţea pentru realizarea separării şi comunicării între ele IPC

● pentru comunicaţii între procese Linux include:

– semnale (comunicaţie asincronă = întreruperi soft)

pipe (prin intermediul FS)

socket (prin intermediul networking)

System V IPC (metodele IPC definite de POSIX):

semafoare

shared memory

message passing

9. Ce este BSP? Descrieţi pe scurt BSP, implementarea lui în kernelul Linux (subdirectoarele, opţiuni de configurare), enumeraţi principalele periferice pentru care există suport implicit în Linux.

Board Support Package

● software folosit pentru iniţializarea dispozitivelor hardware întâlnite în sistemul încorporat

● implementează rutinele specifice hardware-ului ce vor fi folosite de kernel şi drivere

BSP ascunde toate detaliile legate de processor şi placa în care este încorporată, permitând astfel o portare uşoară a sistemului de operare şi a driverelor aferente

● BSP (μC) = HAL (PC)

Componentele BSP

suport pentru procesor - tratează caracteristicile specifice procesoarelor embedded (MIPS, ARM, PowerPC, etc

suport pentru periferice -bootloader -harta memoriei -timere -PIC (Programmable Interrupt Controller) -RTC (Real Time Clock)

-serială (UART) pentru consolă şi debug -magistrale (ISA, PCI) -DMA

)

-Power management Configurare BSP pentru placa de dezvoltare

● se poate realiza o setare prealabilă a elementelor din configurarea kernelului pentru a placă de dezvoltare aparte

● în arch/XXX/ se inserează un fişier Kconfig (sau config.in în cazul kernelului 2.4) cu opţiunile specifice procesorului XXX

● în fisierul Kconfig se poate adăuga opţiuni specifice unei plăci de dezvoltare, de ex:

ifdef CONFIG_EUREKA LIBS += arch/mips/eureka/eureka.o SUBDIRS += arch/mips/eureka LOADADDR := 0x80000000 Endif

6

Opţiuni de configurare

se pot crea şi opţiuni de configurare specific plăcii dep_bool 'Support for EUREKA board' CONFIG_EUREKA if ["$CONFIG_EUREKA"="y" ]; then choice 'Eureka Clock Speed' \ "75 CONFIG_SYSCLK_75 \ 100 CONFIG_SYSCLK_100" 100

fi

if ["$CONFIG_EUREKA"="y" ]; then define_bool CONFIG_PCI y define_bool CONFIG_ISA y define_bool CONFIG_NONCOHERENT_IO y define_bool CONFIG_NEW_TIME_C y

fi

10. Cum funcţionează bootloaderul? Descrieţi rolul bootloaderului şi detaliaţi fazele principale de la pornirea procesorului până la pornirea sistemului de operare.

Funcţiile bootloaderului

● funcţii obligatorii

– iniţializarea procesorului, a controlerului de memorie şi a dispozitivelor hardware esenţiale pentru încărcarea kernelului (de ex. flash)

– încărcarea kernelului: copiere din dispozitivul de stocare în memorie

● funcţii opţionale

– depind de sistemul încorporat în care este folosit

– poate iniţializa alte dispozitive

poate pasa argumente kernelului pentru o configurare dinamică Secvenţa de bootare (la un sistem încorporat)

bootarea

– bootloaderul porneşte din flash

– se iniţializează registrele de bază şi cache-ul (dacă e cazul)

– se verifică memoria şi dispozitivel hardware de pe placă (POST)

relocatarea

– bootloaderul se autocopiază din flash în RAM (pentru rulare mai rapidă)

– la copiere se poate efectua şi o dezarhivare dacă bootloaderul era comprimat în flash

● iniţializarea dispozitivelor

– se iniţializează dispozitivele de bază necesare pentru interacţiunea cu utilizatorul (consola)

se poate iniţializa şi alte dispozitive necesare pentru preluarea kernelului (flash, USB, Ethernet)

● UI

– se prezintă o interfaţă utilizatorului prin intermediul căreia se poate selecta imaginea de kernel ce trebuie încărcată

● Încărcarea kernelului

se copiază kernelul în memorie (+ initrd)

● prepararea kernelului

7

argumente pot fi pasate kernelului

– se completează argumentele din linia de comandă şi se plasează în adrese fixe cunoscute de kernel

● se bootează kernelul

se va face un salt la punctul de intrarea în kernel

– în mod normal bootloaderul nu mai este folosit, aşa că zona de memorie ocupată de aceasta este eliberată de kernel în timpul mapării memoriei

11. Cum se tratează întreruperile în Linux şi cum ajung acestea la procesele utilizator? Descrieţi implementarea în BSP pentru întreruperi, tratarea întreruperi hardware şi emiterea semnalelor (întreruperilor software) către procese.

Managementul întreruperilor Fiecare sistem tratează întreruperile în mod diferite. De obicei există un controler de întreruperi specific (PIC Programmable Interrupt Controller). Intreruperile hardware sunt tratate mai întâi de PIC, care poate devia întreruperile acordând prioritate hardware şi metode diferite de tratare. Pentru programarea PIC trebuie să există driver special, care însă trebuie mascat prin BSP pentru portare uşoară. Tratarea întreruperilor în Linux Linux tratează toate întreruperile ca întreruperi logice (un număr de obicei 128 sau 256 întreruperi). Driverul pentru PIC va redirecţiona întreruperile hardware către una din aceste întreruperi logice (prin intermediul funcţiei request_irq() ). BSP va realiza interfaţarea între întreruperi hard şi soft prin structurile:

– hw_interrupt_type (pointeri la funcţiile de tratare hardware)

irq_desc_t (pointeri la handlere logice)

Funcţiile BSP pentru tratarea întreruperilor

● initialization: iniţializarea întreruperii

● startup function: funcţia apelată la cerinţa de întrerupere, activează întreruperile

● shutdown: dezactivează întreruperile

enable: activează o întrerupere particulară

● disable: dezactivează o întrerupere particulară

● acknowledgement: apelat la începutul rutinei de tratare (dezactivează întreruperea)

● end of interrupt: marchează sfârşitul unei întreruperi (reactiveaza întreruperea) Alte dispozitive importante tratate de BSP

timere

Programmable Interval Timer: un timer este tot timpul configurat în faza de pornire pentru a fi folosit ca tick-ul sistem

– pentru acest timer BSP trebuie să ofere o interfaţă

UART

folosit cel mai des pe post de consolă

– kernelul aşteaptă întotdeauna prezenţa unei console prin care să interfaţeze cu utilizatorul

(serială, ethernet, etc

)

8

12. Cum funcţionează memoria Flash şi care sunt principalele caracteristici ce trebuie luate în seamă de către sistemul de operare? Descrieţi principiul de funcţionare, cele două tipuri de bază, şi influenţa asupra implementării în sistemul de operare a metodei de adresare şi a duratei de viaţă.

Memorii Flash

● dezvoltat în anii '80 de Toshiba şi Intel

● foloseşte tranzistori MOS cu o poartă de control şi o poartă flotantă

MOS cu o poartă de control şi o poartă flotantă Operaţii asupra celulelor Flash ● poarta

Operaţii asupra celulelor Flash

● poarta flotantă poate fi încărcată sau nu

– încărcarea normală nu este suficient pentru deschiderea canalului DS

fiind complet izolată sarcinile acumulate pe poarta flotantă se păstrează pentru timp îndelungat

citire:

– se aplică o tensiune (jumătate din cea necesară deschiderii canalului) pe poarta de control

– tensiunea aplicată împreună cu sarcinile stocate pe poarta flotantă este suficientă pentru a deschide canalul DS

● scrierea (injecţie de electroni fierbinţi)

– se aplică o tensiune mare pe poarta de control (mult mai mare decât tensiunea de deschidere)

– datorită curentului mare pe canalul DS deschis, electronii „fierbinţi” sar pe poarta flotantă încărcând aceasta

● ştergerea (efectul tunel)

– se aplică o tensiune negativă mare pe poarta de control

– sarcinile stocate pe poarta flotantă se vor extrage prin efectul tunel

Există două tehnologii (denumite după modul de legare a tranzistorilor):

NOR (sau negat cablat)

– NAND (şi negat cablat)

Organizarea în amândouă cazuri este una matricială cu linii de adresă care vor selecta celulele paralele. Flash NOR

● tranzistorii sunt legaţi pe o parte la masă pe cealaltă parte pe coloana corespunzătoare

● dacă unul din tranzistori este deschis se va trage toată coloana la GND

parte pe coloana corespunzătoare ● dacă unul din tranzistori este deschis se va trage toată coloana

9

Celule sunt organizate în blocuri: dimensiunea blocului este de ordinul 64k. Citirea şi scrierea se poate face prin adresare direct: liniile de adrese si date sunt organizate similar cu memoriile statice. Stergerea trebuie făcută pe bloc. Tensiunile de scriere şi ştergere sunt realizate intern prin convertoare boost integrate. Flash NAND

● tranzistorii de pe o coloană sunt legaţi în serie

se activează toate liniile de adresă cu tensiunea normală, mai puţin adresa selectată (pe care se aplică jumătatea de tensiune)

selectată (pe care se aplică jumătatea de tensiune) C elule sunt organizate în pagini, iar paginile

Celule sunt organizate în pagini, iar paginile în blocuri. Paginile trebuie citite şi scrise deodată, ştergerea se face pe blocuri. Conţine buffer SRAM integrat pentru pagina citită care poate fi citit ca un flux de date pe interfaţa externă. Comunicarea externă se bazează pe comenzi către registrele interne. Caracteristici specifice flashurilor

- durata de viaţă (calculată în numărul de ştergeri) este limitată

- pentru a creşte durata de viaţă ştergerile de blocuri ar trebuie echilibrate în tot spaţiul de flash (wear leveling)

- operaţie de rescriere este complicată – modificarea unui bit de 1 în 0 se poate face la nivel de cuvânt (sau pagină) – modificarea unui bit de 0 în 1 necesită ştergerea completă a unui bloc întreg după care vor trebui rescrise şi toate datele nemodificate.

13. Cum se implementează memoriile Flash în Linux? Detaliaţi insuficienţele sistemului de fişiere pentru folosirea Flashului şi arhitectura MTD dedicat pentru soluţionarea acestor probleme.

Folosire flashului în Linux

● modul tradiţional de realizare a driverelor şi a sistemelor de fişiere în Linux nu poate fi adaptat uşor la memoriile flash

acestea pot fi citite pe caractere, dar trebuie scrise pe blocuri

– sistemele de fişiere din Linux nu oferă support specific flashurilor -nu există wear leveling -blocurile din flash sunt de obicei mult mai mari decât sectoarele folosite pe hard-

diskuri

-folosirea cacheului pentru file system trebuie evitat pentru a nu avea probleme la oprirea bruscă a sistemului.

Iniţial flashurile se integrau în Linux printr-un FTL (Flash Translation Layer) care emula un hard-disk:

– nu soluţiona toate problemele legate de caracteristicile flashurilor

10

nu ofera suport pentru alte moduri de operare

– devenea din ce în ce mai complex cu apariţia noilor tipuri de flashuri şi noilor interfeţe

Soluţia era introducerea subsistemului MTD (Memory Technology Devices). MTD a fost conceput special pentru modul de operaţie cu flashuri. Se integrează în Linux atât pe nivelul de driver cât şi pe nivelul de aplicaţii. La nivelul de drivere MTD mapează pentru

fiecare dispozitiv câte un driver de character şi de block device

– character device poate fi folosit în mod obişnuit cu funcţiile open/read/write/ioctl

block device poate fi folosit pentru montarea unui sistem de fişiere classic

Arhitectura MTD

MTD core

– implementează driverele character şi block

drivere flash low-level

– implementează interfeţele pentru flashuri NOR si NAND

BSP pentru flash

– oferă suport pentru modurile de conectare a flashului pe placă

● aplicaţii MTD

– aplicaţii pe nivel kernel care folosesc flash (JFFS2) şi aplicaţii pe nivel de utilizator (upgrade)

14. Descrieţi principalele sisteme de fişiere folosite în sisteme embedded. Descrieţi pe scurt Ramdisk, RAMFS, CRAMFS, NFS şi JFFS2

Ramdisk Este o metodă de emulare a unui hard-disk în memorie. Nu este un sistem de fişiere, ci mai degrabă o tehnologie ce permite crearea sistemului / în memorie, după care în aceste sistem se pot monta alte sisteme de fişiere. De obicei initrd se crează într-o formă de imagine ramdisk, ce poate fi încărcată în memorie de către boot-loadeer. RAMFS Este un sistem de fişiere localizată în întregime în memorie RAM. De multe ori este nevoie de folosirea unor informaţii (interne ale kernelului sau a utilizatorilor) organizate în formă de fişiere pentru un acces comod şi care nu trebuie păstrate după repornirea sistemului, de aceea nu merită a fi încărcate în flash. RAMFS oferă suport pentru stocare a astfel de informaţii într-o zonă de memorie care îşi poate modifica dimensiunea în funcţie de necesităţi. CRAMFS Este un sistem de fişiere read-only cu compresia datelor. Este foarte util pentru stocarea programelor în flash comprimate pentru a minimiza spaţiul folosit. CRAMFS este un sistem de fişiere normal, care comunică prin drivere block folosind un cache în memorie şi algoritmi de compresie din zlib pentru pagini de 4kB.

JFFS2

Sistem de fişiere cu jurnal special destinat pentru flashuri. Realizează wear leveling. Nu foloseşte cache de scriere pentru a evita coruperile de date la oprirea bruscă a sistemului. Foloseşte direct API-ul din MTD fără a trece printr-un nivel de translatare (FTL). Modificarea fişierelor se realizează prin intermediul logurilor:

logurilor conţin datele ce au fost modificate

– numai aceste loguri se salvează

– pentru citirea fişierelor se va citi toate logurile aferente pentru a recrea fişierul

11

Periodic se rulează un garbage collector pentru a şterge logurile inutile: acest garbage collector realizează şi wear leveling prin rearanjarea datelor în zonele mai puţin folosite. NFS

pot fi exportate şi către reţea. Kernelul Linux oferă un

mecanism de montare a astfel de sisteme de fişiere prin reţea. Un sistem NFS poate fi montat chiar şi ca /, permiţând astfel o depanare rapidă a sistemului (prin faptul că aplicaţiile pot fi dezvoltate pe un desktop, iar pentru teste acestea nu trebuie înscrise în flash). Bootloader trebuie să ofere suport pentru conectare la reţea (BOOTP, DHCP).

Sistemele de fişiere desktop (ext2,3,4

)

15. Cum se implementează driverul de serială în Linux? Detaliaţi importanţa interfeţei seriale ca interfaţă de consolă şi descrieţi sumar componentele din subsistemul TTY.

Nivelul TTY este o clasă speciala de dispozitve de tip caracter care se intercalează deasupra driverului de nivel jos. TTY tratează toate dispozitivele seriale indiferent de modul cum este folosit interfaţa. Aplicaţiile nu accesează direct driverul de serială, ci driverele TTY.

accesează direct driverul de serială, ci driverele TTY . Discipline de linie Fiecare dispozitiv de tip

Discipline de linie Fiecare dispozitiv de tip TTY este asociat cu o disciplină de linie, care tratează modul cum sunt transmise datele pe linia serială. Implicit disciplina de linie (integrate in fiecare kernel) este N_TTY, care oferă un terminal simplu pe serială. Pot fi implementate și alte discipline de linie pentru protocoalele mai complicate folosite pe interfețe seriale (X.25, PPP/SLIP). Terminale Fiecare proces in Linux are asociat un terminal de control – procesul asociază intrarea standard (stdin) şi ieşirea standard (stdout) respectiv ieşirea pentru erori (stderr) cu acest terminal de control. Subsistemul TTY impreună cu subsistemul de management a proceselor alocă automat terminalul de control a proceselor. CTTY asociat unui proces poate fi o interfaţă serială, tastatura, monitorul in mod text. Pseudo-terminale Datorită faptului că nu există suficiente interfeţe seriale pentru terminalele de control a tuturor proceselor, subsistemul TTY implementează şi o serie de pseudo-terminale (PTY).

12

Aceste pseudoterminale pot fi folosite şi pentru IPC:

– terminalele PTY pot fi redirecţionate intre procese

procesele pot fi pornite cu terminale de control ascunse (la care utilizatorul nu are acces direct)

de ex.: telnet, ssh. Driverul de serială in Linux Interfaţa UART are un driver in kernelul Linux. Driverul accesează dispozitivul prin intermediul structurilor:

uart_driver :interfaţa comună pentru apeluri sistem

uart_state: fiecare port serial are asociat această structură care conţine starea actuală

uart_port: configuraţia hardware

uart_ops: funcţii low level de acces

16. Ce sunt module kernel şi cum sunt implementate?

Descrieţi sumar funcţionarea modulelor, avantajele folosirii lor şi enumeraţi componentele

din API-ul standard pentru module.

Module kernel Modulele de kernel sunt subsisteme ale kernelului care sunt adăugate dinamic la un kernel aflat in rulare. Folosirea modulelor reduce dimensiunea kernelului, pentru că numai subsistemele ce sunt folosite vor fi incărcate. Modulele oferă un API standard, care permite incărcarea/descărcare lor de către kernel şi extind apelurile sistem standard pentru comunicarea cu aplicaţiile. Module API

Funcţii de intrare şi ieşire

– modulul trebuie să ofere funcţiile module_init() şi module_exit(), care sunt apelate de kernel la

incărcarea respectiv descărcarea modulului

Pasarea parametrilor

– la incărcarea modulelor, acestora pot fi pasate paramteri intr-o manieră similară cu linia de

comandă – parametrii trebuie declaraţi de către modul prin nişte tabele de asociere (nume paramtru

variabilă)

Reference count

– fiecare modul trebuie să stocheze intr-o variabilă numărul de incărcări ai modului respectiv

– cand acest număr cade la 0, modulul poate fi descărcat

pentru a evita referirle la module inexistente toate apelurile către module trebuie să treacă prin referinţe tratate de kernel

Declararea licenţei

– modulele Linux au obligaţia de a declara licenţa la pornire

17. Ce este un OSPL?

Descrieţi pe scurt scopul folosire OSPL în portarea aplicaţiilor real-time către Linux.

Operating System Porting Layer Pentru portarea aplicaţiilor RTOS pe Linux trebuie implementat un OSPL. Minimizează numărul de modificări asupra codului aplicaţiei prin maparea funcţiilor oferite de API-ul RTOS la API-ul Linux:

13

mapare unu-la-unu: unele funcţii oferite de RTOS pot fi mapate la un apel sistem oferit de Linux

#define xTaskHandle int

void vTaskSuspend(xTaskHandle pid)

{

kill(pid, SIGSTOP);

}

mapare unu-la-multe: când o funcţie RTOS nu poate fi realizat de un singur apel sistem

18. Care sunt avantajele/dezavantajele folosirii taskurilor şi a threadurilor în sisteme realtime? Detaliaţi diferenţele principale între taskuri şi threaduri pornind de la implementările pe sisteme real-time executive şi portarea lor către Linux.

Portarea taskurilor pe Linux Fiecare task poate fi transformat într-un thread din cadrul aceluiaşi process

transformat într -un thread din cadrul aceluiaşi process T askurile pot fi grupate în procese diferite

Taskurile pot fi grupate în procese diferite

process T askurile pot fi grupate în procese diferite Strategii de portare a taskurilor  T

Strategii de portare a taskurilor

Taskurile strâns cuplate (prin variabile globale partajate) pot fi puse în threaduri separate din cadrul unui singur process.

– este metoda de portare cea mai directă şi mai uşoară

Taskurile independente sau cuplate prin intermediul IPC oferit de SO se pun în procese diferite.

Taskurile importante (la funcţionalitatea sistemului) ar trebui puse în procese diferite pentru protecţie maximă. Linux implementează threaduri POSIX (pthreads). Pentru portarea taskurilor în pthreaduri, aplicaţiile trebuie adaptate la standardul pthread API.

14

Crearea threadurilor:

int pthread_create(pthread_t* thread_id, pthread_attr_t* thread_attributes, void* (*start_routine)(void*), void* arg);

– se crează un nou fir de execuţie pornind de la funcţia start_routine.

Terminarea threadurilor Pentru a transmite starea de terminare threadul poate apela funcţia void pthread_exit(void* return_val);

– similar cu funcţia exit, dar va termina numai threadul care a apelat

– dacă funcţia asociată thread-ului se termină atunci nu se va transmite stare de terminare Pentru ca un thread sa citească starea de terminare se foloseşte funcţia int pthread_join(pthread_t tid, void** thread_return_val);

– similar cu funcţia wait

Dacă starea de terminare a unui thread nu a fost citit, atunci resursele asociate threadurilor nu vor fi eliberate. In cazul în care un thread nu furnizează starea de terminare atunci aceasta nu poate fi citită, pentru a permite totuşi eliberarea resurselor, threadul trebuie detaşat de threadul care l-a creat. int pthread_detach(pthread_t tid);

Portarea unei aplicaţii în care taskurile îşi încheie rularea la un moment date, necesită şi modificarea codurilor aplicaţiei. Sincronizarea threadurilor pthreads oferă metode robuste pentru sincronizare prin intermediul unui API userspace

mutex

void pthread_mutex_init(pthread_mutex_t* mutex, const pthread_mutexattr_t* mutexattr);

int pthread_mutex_lock(pthread_mutex_t* mutex);

int pthread_mutex_unlock(pthread_mutex_t* mutex);

semafoare

void sem_init(sem_t* sem, int pshared, unsigned int value); int sem_wait(sem_t* sem);

int sem_post(sem_t* sem);

19. Care sunt principalele caracteristici a sistemelor de operare care influenţează capabilităţile real-time? Descrieţi sumar: latenţa întreruperilor, durata rutinei de tratare a întreruperilor, latenţa planificatorului şi durata planificării, respectiv influenţa acestora asupra timpului de răspuns a sistemului.

Latenţa întreruperilor Principale cauze de latenţă mare:

– dezactivarea întreruperilor pentru un timp îndelungat ● porţii din kernel şi din drivere trebuie să se protejeze faţă de rutine de întreruperi ● astfel de secţiuni critice sunt înconjurate de apeluri de tip local_irq_disable sau spin_lock_irq

15

– înregistrarea întreruperilor greşită ● driverele scrise greşit pot să înregistreze ISR-ul în mod greşit ● există două moduri de înregistrare: fast irq şi slow irq, dacă un dispozitiv mai puţin important înregistrează fast irq atunci poate bloca întreruperile mai importante. Durata ISR-urilor Durata ISR-ului este în totalitate lăsată pe seama programatorului de driver. Durata ISR-ului poate fi non-deterministă dacă se foloseşte soft-irq. – ISR poate fi înpărţit în două secţiuni: o parte critic care se execută în interiorul ISR şi nu mai poate fi întrerupt şi o parte care va fi tratat ulterior de kernel şi care poate fi întrerupt de alte irq hardware

soft-irq este de obice tratat de daemonul ksoft-irqd care este non-real-time, astfel folosirea

soft-irq pentru evenimente real-time trebuie evitată. Latenţa planificatorului Latenţa planificatorului (mai ales la versiuni mai vechi) este principalul contributor la timpul de răspuns mare. Kernelul până la 2.4 avea o natură nonpreemptivă:

procesele din user-space puteau fi înlăturate, dar funcţiile kernel apelate din user-space nu

puteau fi întrerupte, astfel se crea şi în interiorul proceselor zone în care procesul nu putea fi interrupt.

– dezactivarea întreruperilor (ce include şi întrerupera timerului asociat cu planificatorul) putea avea impact asupra latenţa planificatorului. Durata planificării

Durata planificării este timpul necesar pentru planificator ca să aleagă procesul care va fi activat, să modifice listele (run, ready) corespunzătoare și să-l schimbe contextul la noul process. Iniţial planificatorul din Linux (pornind cu conceptul de SO de uz general) s-a concentrate pentru a realiza planificare cât mai corectă, de aceea a fost sacrificat durata deterministă a planificării.

– de obicei planificatorul rula în timp O(n) pentru numărul proceselor.

20. Care sunt prevederile standardului POSIX pentru sisteme real-time? Descrieţi sumar: preempţia, latenţa întreruperilor, latenţa planificatorului, metodele IPC şi de sincronizare, alocare dinamică de memorie.

preemption: când un task de prioritate mai mare devine ready, taskul de prioritate mai mică în

rulare trebuie interrupt.

latenţa întreruperilor: RTOS trebuie să aibă o latenţă a întreruperilor (timpul între apariţia

întreruperii şi deservirea acesteia) predictibilă (și cât mai mică).

latenţa planificatorului: timpul între momentul când un task devine rulabil şi până când începe să ruleze trebuie să fie determinist.

IPC şi sincronizare: cea mai populară metodă de IPC în sisteme embedded este message

passing, RTOS trebuie să ofere support pentru transmisia mesajelor în timp constant. RTOS trebuie să ofere suport pentru semafoare şi mutex.

– alocare dinamică de memorie: RTOS trebuie să ofere un mecanism de alocare dinamică

a memoriei într-un timp constant.

16

21. Care sunt extensiile POSIX pentru sistemele real-time? Descrieţi sumar: planificarea cu priorităţi fixe, blocarea memoriei, semnale de timp real, ceasul sistem, timere şi operaţiile asincronre.

Extensii POSIX real-time:

fixed-priority scheduling

memory locking

cozi de mesaje POSIX

● memorie partajată POSIX

semnale real-time

semafoare POSIX

timere POSIX

● operaţii IO asincrone

Planificare cu priorităţi fixe Parametrii asociaţi proceselor (referitor la RT):

clasa de planificare

prioritate

cuanta de timp

Clasa de planificare precizează algoritmul de planificare folosit pentru proces:

– SCHED_FIFO: procesele rulează unul după celălalt în ordinea creării până la terminare sau

blocare

– SCHED_RR: (Round Robin) procesele rulează până la cuanta precizată după care vor fi puse la capătul listei

SCHED_OTHER: planificatorul standard (non-RT)

Blocarea memoriei Aplicaţiile real-time au nevoie de un timp de răspuns determinist ce nu poate fi satisfăcut

dacă se foloseşte paginare. Pentru a realiza timpul de răspuns determinist un proces poate să blocheze o parte (sau chiar toată) memoria alocată procesului, ca această zonă să rămână definitiv în memorie. Soluţii de blocare:

– în timpul rulării cu funcţiile mlock şi mlockall

– în timpul legării prin intermediul ldscript-ului

cu atributul gcc:

Semnale timp real

Sunt folosite pentru notificarea proceselor despre apariţia unui eveniment asincron. Semnalele real-time sunt o extensie a semnalelor native Linux:

– număr mai mare de semnale utilizator

semnale prioritizate

– informaţii ataşate semnalelor

– semnalele sunt salvate într-o coadă Funcţii:

sigaction (definirea unui handler), sigqueue (transmiterea unui semnal) Ceasuri şi timere POSIX Oferă acces mai avansat la ceasul system:

CLOCK_REALTIME: ceasul universal

CLOCK_MONOTONIC: timpul trecut de la pornirea sistemului

section

17

CLOCK_PROCESS_CPUTIME_ID: timpul total a unui proces petrecut în rulare

CLOCK_THREAD_CPUTIME_ID: similar pentru threaduri Accesul la ceas:

clock_settime, clock_gettime, clock_getres, Blocarea procesul pentru o perioadă:

clock_nanosleep

Timere

Folosite pentru temporizare:

timer_create, timer_delete

Pot fi setate pentru o anumită perioadă după care vor genera un semnal ce poate fi tratat:

timer_settime

Rezoluţia standard în Linux este de 1ms.

MontaVista a introdus un timer de înaltă rezoluţie (1μs).

CLOCK_REALTIME_HR

CLOCK_MONOTONIC_HR

Operaţii IO asincrone Operaţiile IO standard sunt blocante (read, write). Pentru un timp de răspuns mai bun poate fi nevoie ca procesul să realizeze alte calcule în timp ce aşteaptă pentru terminarea operaţiei IO.

aio_read (citire), aio_write (scriere), aio_error (starea operaţiei), aio_return (numărul de octeţi

transferaţi), aio_cancel (oprirea operaţiei), aio_suspend (blocarea procesului) Operaţiile nu ţin la curent offsetul în fişier. După terminarea operaţie IO procesul este notificat printr-un semnal.

22. Care sunt paşii necesari pentru compilare kernelului Linux? Descrieţi sumar: mediul de cross-compilare, configurarea kernelului, compilarea surselor, legarea codului, post-procesarea imaginii kernelului şi compilarea modulelor.

Pașii necesari pentru compilarea kernelului:

instalarea unui mediu de cross-compilare

implicit sistemul vine cu un mediu de compilare pentru host (binutils, gcc)

compilarea pentru sistemul embedded are nevoie de un cross-compiler: compilatorul este

executat pe un host, dar creează cod pentru sistemul ţintă (ex: gcc-arm, gcc-mips, etc.)

configurarea kernelului

procesul de selectare a componentelor din kernel ce vor fi compilate

mai multe metode: make [config | menuconfig | xconfig]

● compilarea surselor şi legarea fişierelor obiect

make

se compilează sursele selectate la faza de compilarea si se leagă toate împreună într-o imagine vmlinux

– pe 2.4 este nevoie de crearea dependinţelor de fişiere header (make dep) înainte de comanda make, pe 2.6 nu este necesar

– pe 2.4 dacă comanda make se emite înainte de terminarea comenzii, se intră într-o interfaţă interactivă make config, pe 2.6 se generează un mesaje de eroare ● poate exista o fază de postprocesare a imaginii kernelului dependent de arhitectură și de sistemul de compilare

de obicei inclus în faza make, dar nu e standardizat

18

poate include comprimarea imaginii (vmlinuz), crearea unei imagini de root, cod de bootstrap, etc compilarea modulelor

– dacă kernelul a fost configurat să folosească anumite componente ca module încărcate dinamic, acestea trebuie compilate separat

make modules

19