Na tomto cvičení se seznámíte s jádrem miniaturního OS NOVA a implementujete do něj systémové volání brk
. NOVA je mikrohypervizor původně vyvíjený na Drážďanské univerzitě, později ve firmě Intel a nyní firmami GENODE labs a Cyberus Technology. Na cvičeních však nebudete pracovat s kompletní verzí jádra NOVA, ale se zjednodušenou verzí pro výuku, která má pouze 2 tisíce řádek kódu.
Pro toto cvičení budete potřebovat následující:
libc6-dev-i386, qemu-system-i386
Ec::syscall_handler
Ptab::insert_mapping
(byla na přednáškách)
Kalloc
ssh -X «login»@postel.felk.cvut.czpřepínač -X umožní spouštět i grafické aplikace (QEMU)
Implementujte systémové volání brk
s prototypem:
void *brk(void *address)
Toto systémové volání nastaví konec datového segmentu v adresním
prostoru procesu (tzv. program break nebo jen break) na adresu
danou parametrem address
. Tím se zvětší nebo zmenší množství
alokované paměti, které může program využívat ke svému běhu. Break je
první adresa za koncem namapovaného datového segmentu.
Vaše řešení by mělo splňovat následující požadavky:
address
. To znamená, že uživatelský program může používat paměť od adresy 0x1000 do o jedna menší než address
. Přístup na stránky začínající na adrese vyšší či rovné address
nebude programu dovolen.
address
rovno NULL (0), nejedná se o chybu a hodnota break se nemění. Toto volání slouží pouze ke zjištění aktuální hodnoty break.
brk
nesmí dojít k “pádu” systému.
Odevzdává se archiv se souborem ec_syscall.cc
obsahující vaši implementaci, ideálně vytvořený pomocí
make hw10.
user/hello.c
můžete nabootovat buď na fyzickém počítači pomocí zavaděče podporujícího specifikaci multiboot (např. GRUB 2), ale pravděpodobně bude efektivnější ho pouštět jako virtuální stroj například v emulátoru Qemu. Pro to stačí spustit příkaz make run.
Ec::root_invoke()
, která připravuje paměť pro spouštěný program. Funkce čte hlavičky z binárky aplikace, které si můžete zobrazit příkazem readelf –program-headers hello
.
Ec::break_min
a Ec::break_current
, které pravděpodobně budete potřebovat ve své implementaci.
readelf –sections hello
)
readelf –sections hello
)
Při vývoji operačního systému nelze používat debugger tak jednoduše,
jak jste zvyklí při vývoji aplikací. Ladit váš kód můžete přidáváním
příkazů printf()
na potřebná místa v kódu. Pokud vám to nestačí
můžete použít parametr -gdb
(případně zkratku -s
) emulátoru
Qemu.
Abychom vám ladění usnadnili, v hlavním Makefile
jsou připravena
pravidla jak pro spouštění Qemu se zmiňovanými parametry, tak pro
spouštění debuggeru gdb
tak, aby šel ladit kód běžící v Qemu:
make rd
, který spustí Qemu, které po startu počká na připojení debuggeru.
make du
či make dk
podle toho, jestli chcete ladit uživatelský program (hello) nebo jádro. Můžete v Makefile změnit argument příkazu break
tak, aby se vykonávání programu zastavilo na funkci (či řádku), který potřebujete odladit.
Užitečné příkazy gdb (většinou se dají zkrátit na první znak):
next
(n), step
(s), continue
©
print
(např. p initialized_var
nebo hexadecimálně: p/x initialized_var
)
x
(např: x/16 0x2000
vypíše 16 slov od adresy 0x200, x/16 &initialized_var
vypíše 16 slov začínající na adrese proměnné initialized_var.
info registers
vypíše hodnoty registrů, info locals
vypíše hodnoty lokálních proměnných atd.
layout src
zobrazí zdrojový kód i příkazové okno, Ctrl-L překreslí obrazovku, tui disable
vypne zobrazování zdrojového kódu.
Pro ladění můžete používat i monitorovací konzoli Qemu, která umožňuje zobrazit stav emulovaného CPU.
Ctrl-Alt-2
v grafickém okně (nebo stiskem Ctrl-a c
pokud používáte přepínač -nographic
)
info mem
nebo info tlb
vypíší informace o mapování virtuálních adres na fyzické (tj. stránkovací tabulku).
info registers
vypíše hodnoty registrů