V tomto cvičení preskúmate tabuľky stránok a upravíte ich za účelom zrýchlenia určitých systémových volaní a detekcie stránok, kuk ktorým proces pristúpil.
Než začnete programovať, prečítajte si kapitolu 3 xv6 knižky a pozrite si príslušné súbory:
Nápomocný môže byť tiež manuál privilegovaných inštrukcií RISC-V.
Najprv sa prepnite do vetvy pgtbl:
1 2 3 |
$ git fetch $ git switch pgtbl # alebo git checkout pgtbl $ make clean |
Riešenia úloh z tohto cvičenia ukladajte do vetvy pgtbl. Túto vetvu budeme kontrolovať v rámci priebežnej kontroly repozitárov. Viac informácií k hodnoteniu repozitárov nájdete na príslušnej stránke.
Niektoré operačné systémy (napr. Linux) zrýchľujú určité systémové volania zdieľaním dát medzi jadrom a užívateľským priestorom v pamäťovej oblasti s prístupom iba na čítanie. Vďaka tomu je možné eliminovať prechody do jadra počas systémových volaní. Aby ste sa naučili, ako fungujú pamäťové mapovania, vašou prvou úlohou je implementovať túto optimizáciu pre systémové volaniegetpid()
v xv6.
USYSCALL
(táto virtuálna adresa je definovaná v súbore memlayout.h). Na začiatku tejto stránky uložte štruktúru struct usyscall
(tiež definovaná v memlayout.h) a inicializujte ju tak, aby v nej bolo uložené PID aktuálneho procesu. Pre tento lab je z užívateľského priestoru k dispozícii funkcia ugetpid()
, ktorá automaticky použije mapovanie USYSCALL
. Za implementáciu tejto úlohy získate plný počet bodov, ak prejdete testom ugetpid v súbore testov pgtbltest.Pomôcky:
allocproc()
. Vhodné je tiež niekam uložiť referenciu na alokovanú stránku, napríklad do štruktúry proc
, podobne ako sa ukladá proc->trapframe
a proc->pagetable
.proc_pagetable()
v súbore kernel/proc.c.
mappages()
sa vám môže hodiť.
freeproc()
a odmapovať v proc_freepagetable()
.
Ktoré iné systémové volania môžu byť urýchlené prostredníctvom tejto zdieľanej stránky? Vysvetlite ako.
Odpovede zapíšte do príslušných súborov podľa testovacieho skriptu.
Po úspešnom dokončení úlohy nezabudnite vytvoriť commit!
Vašou druhou úohou je napísať funkciu, ktorá vypíše obsah tabuľky stránok. Pomôže vám to pri vizualizícii tabuliek stránok v RISC-V a funkciu môžete v budúcnosti použiť pri ladení systému.
vmprint()
. Bude mať jeden argument typu pagetable_t
a vypíše tabuľku stránok vo formáte, ktorý je uvedený nižšie. Funkciu môžete otestovať napríkad tak, že ju zavoláte v súbore exec.c tesne pred return argc
. Aby bola tabuľka vypísaná len pre prvý proces, skontrolujte číso procesu: if(p->pid==1) vmprint(p->pagetable)
. Plný počet bodov za túto úlohu dostanete, ak prejdete testom pte printout.
Keď spustíte xv6, mali by ste vidieť podobný výstup. Ak ste funkciu zavolali vyššie popísaným spôsobom, jedná sa o stav tabuľky prvého procesu (init) tesne pred jeho spustením v systémovom volaní exec
.
1 2 3 4 5 6 7 8 9 10 11 |
page table 0x0000000087f6e000 ..0: pte 0x0000000021fda801 pa 0x0000000087f6a000 .. ..0: pte 0x0000000021fda401 pa 0x0000000087f69000 .. .. ..0: pte 0x0000000021fdac1f pa 0x0000000087f6b000 .. .. ..1: pte 0x0000000021fda00f pa 0x0000000087f68000 .. .. ..2: pte 0x0000000021fd9c1f pa 0x0000000087f67000 ..255: pte 0x0000000021fdb401 pa 0x0000000087f6d000 .. ..511: pte 0x0000000021fdb001 pa 0x0000000087f6c000 .. .. ..509: pte 0x0000000021fdd813 pa 0x0000000087f76000 .. .. ..510: pte 0x0000000021fddc07 pa 0x0000000087f77000 .. .. ..511: pte 0x0000000020001c0b pa 0x0000000080007000 |
V prvom riadku je argument funkcie vmprint
. Potom nasledujú riadky pre každý PTE, vrátane vnorených záznamov. Každý riadok PTE je odsadený znakmi ..
podľa toho, ako hboko v strome sa nachádza. Každý riadok obsahuje index záznamu, bity pte
a fyzickú adresu vytiahnutú z PTE. Nevypisujte neplatné záznamy. V príklade vyššie má tabuľka najvyššej úrovne mapovania pre záznamy 0 a 255. O úroveň nižšie, záznam 0 má namapovaný len index 0. Na najnižšej úrovni má tento index namapované záznamy 0, 1 a 2.
Fyzické adresy na vašom počítači môžu byť odlišné od tých v ukážke výstupu. Počet záznamov a virtuálne adresy by mali byť rovnaké.
Pomôcky:
vmprint()
môžete definovať v kernel/vm.c.
freewalk()
.
vmprint()
dajte do kernel/defs.h, aby ste ju mohi zavoať z exec.c.
%p
na výpis PTE a adries ako 64-bitové hexadecimálne číslo.Vysvetlite výstup funkcie vmprint()
a jeho súvis s obrázkom 3-4 z xv6 knižky. Čo obsahuje stránka 0? Čo je v stránke 2? Keď proces beží v užívateľskom móde, môže prečítať/zapísať pamäť mapovanú stránkou 1? Čo obsahuje tretia stránka od konca?
Odpovede zapíšte do príslušných súborov podľa testovacieho skriptu.
Niektorým garbage collectorom (forma automatickej správy pamäte) môže byť užitočná informácia o tom, ku ktorým stránkam bol v minulosti uskutočnený prístup (čítanie alebo zápis). V tejto časti cvičenia budete implementovať do xv6 novú funkcionalitu, ktorá deteguje a ohlási túto informáciu užívateľskému priestoru preskúmaním prístupových bitov v tabuľke stránok architektúry RISC-V. Hardvér tejto architektúry nastavuje tieto bity v PTE vždy, keď fyzickú adresu stránky nenájde v TLB cache.
pgaccess()
, ktoré oznámi stránky, ku ktorým bol v minulosti vykonaný prístup. Toto systémové volanie má tri argumenty. Prvý je virtuálna adresa začiatku stránky, ktorú má prvú skontrolovať. Druhý je počet stránok, ktoré má skontrolovať. Tretí je užívateľská adresa pamäte, kde bude výsledok zapísaný vo forme bitovej masky (dátová štruktúra, ktorá používa jeden bit na stránku a prvú stránku reprezentuje najmenej významný bit). Za túto úlohu dostanete plný počet bodov, ak prejdete testom pgaccess v súbore testov pgtbltest.
Pomôcky:
sys_pgaccess()
v súbore kernel/sysproc.c.
argaddr()
a argint()
.
copyout()
) potom, ako ho naplníte správnymi bitmi. Nezabudnite skopírovať len toľko dát, koľko si užívateľ vyžiadal (zaokrúhlené na bajty).
walk()
v súbore kernel/vm.c je veľmi užitočná na hľadanie správnych PTE.
PTE_A
musíte definovať v súbore kernel/riscv.h. Nahliadnite do tretej kapitoly xv6 knižky, aby ste zistili jeho hodnotu.
PTE_A
ju nezabudnite vynulovať, ak bola nastavená. V opačnom prípade nebudete vedieť zistiť, či bolo k stránke pristúpené od posledného volania pgaccess()
(inými slovami, bit bude navždy nastavený).
vmprint()
sa vám môže hodiť pri ladení.
Po úspešnom dokončení úlohy nezabudnite vytvoriť commit!
Týmto je cvičenie hotové. Skontrolujte, či vaše riešenie prejde všetkými testami make grade. Aby ste prešli posledným testom time, musíte vytvoriť nový súbor time.txt, v ktorom uvediete počet hodín, ktorý ste strávili nad zadaním ako celé číslo. Na záver nezabudnite aj túto zmenu commitnúť do repozitára.
make grade môže zlyhať aj v prípade, že testy osamote zbehnú v poriadku. Je to spôsobené časovým limitom testov. Môžete ho zvýšiť v príslušnom súbore grade-lab-pgtbl (parametre timeout
). Časový limit zmeňte iba v takom prípade, že viete, že samotný test zbehne v poriadku a nič iné v súbore neupravujte.
Pre úspešné testovanie je potrebné použiť aspoň 3 jadrá vo VirtualBoxe.
PTE_D
.