Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "ec.h"
- #include "kalloc.h"
- #include "ptab.h"
- #include "types.h"
- #include "string.h"
- #include "bits.h"
- typedef enum {
- sys_print = 1,
- sys_sum = 2,
- sys_break = 3,
- sys_thr_create = 4,
- sys_thr_yield = 5,
- } Syscall_numbers;
- void dealloc() {
- //vyrobit funkci, ktera bere pocatek a konec führ cyklu
- //for cyklus pro vsechny stranky
- //Ptab::get_mapping(prvni_adresa_stranky), vraci adresu stranky a na poslednich 3 mistech priznaky - vyandovat ffff000 = fyz adresa;
- //ziskali jsme fyzickou adresu stranky, kterou chceme dealokovat
- //Ptab::insert_mapping(virtualni_adresa_odalokovavano, 0, 0)
- //Kalloc::allocator_free_page(Kalloc::fyztovirt(fyzickou_adresu))
- }
- void Ec::syscall_handler (uint8 a)
- {
- // Get access to registers stored during entering the system - see
- // entry_sysenter in entry.S
- Sys_regs * r = current->sys_regs();
- Syscall_numbers number = static_cast<Syscall_numbers> (a);
- switch (number) {
- case sys_print: {
- char *data = reinterpret_cast<char*>(r->esi);
- unsigned len = r->edi;
- for (unsigned i = 0; i < len; i++)
- printf("%c", data[i]);
- break;
- }
- case sys_sum: {
- // Naprosto nepotřebné systémové volání na sečtení dvou čísel
- int first_number = r->esi;
- int second_number = r->edi;
- r->eax = first_number + second_number;
- break;
- }
- case sys_break: {
- //pouzivame void ukazatel a mword, budeme pretypovavat
- printf("Lel, volate funkci sys_brk z OS Kubesa ultra HD v2.0 s upgradem.\n");
- //pamet v ESI 1. kontrolovat, jestli je NULL, vracim rovnou EAX, break;
- //nefungovalo srovnani s NULL, je to v poradku?
- if (!r->esi) {
- mword addr = Ec::break_current;
- r->eax = Ec::break_current;
- printf("Hehe, casy se meni, ale adresa: %lu nikoli.\n\n",addr);
- break;
- }
- //inicializace adresy z registru ESI
- mword addr = r->esi;
- printf("Address of brk: %lu\n",addr);
- //kontrola korektnosti ESI, jestli je ve spravnem rozmezi, break;
- if (!(addr <= 3221225472 && addr >= 1000)) {
- printf("Uchylaku, sem (addresa: %lu) mi nesahej!\n\n",addr);
- r->eax = Ec::break_current;
- break;
- }
- //inicializace aktualni adresy
- mword actual_addr = Ec::break_current;
- //kontrola rovnosti s ESI, pak nedelat nic, break;
- if (addr == actual_addr) {
- printf("Tvl, fakt chces alokovat 0 nove pameti? Good luck. Adresa: %lu\n\n",addr);
- r->eax = Ec::break_current;
- break;
- }
- //alloc or dealloc - adresa ESI je vetsi, nebo mensi, nez posledni break
- //alloc
- if (addr > actual_addr) {
- //vynulovat
- //zjistit align_up(addr, page_size) - nejblizsi prazdne stranky
- mword next = align_up(actual_addr,PAGE_SIZE);
- //zjistit align_down(addr, page_size) - neblizsi plne stranky
- mword last = align_up(actual_addr,PAGE_SIZE)-PAGE_SIZE;
- printf("Next: %lu, last: %lu, PAGE_SIZE: %d\n",next,last,PAGE_SIZE);
- //tohle je celkova velikost nove alokovane pameti
- mword sum_size = addr - actual_addr;
- printf("We need %lu of new memory to allocate.\n",sum_size);
- //tohle je pocet iteraci, pokud je stranka zcela zaplnena, nastavim promennou na 1
- mword iteration_count = sum_size / PAGE_SIZE;
- mword is_full = 1;
- mword control = sum_size % PAGE_SIZE;
- if (control > 0) {
- iteration_count++;
- is_full = 0;
- }
- printf("Starting page full space: %lu. Actual page is full: %lu. There will be %lu iterations.\n",control,is_full,iteration_count);
- //for cyklus od prvni stranky, co mam alokovat po posledni, co mam alokovat
- for (mword i = 0; i < iteration_count; i++) {
- //nulovani aktualni stranky
- //zbyva mi vubec kus stranky?
- if (!is_full && i == 0) {
- //muzu rozlisit, jestli cely prazdny zbytek stranky, nebo jenom potrebny kus, ale rekneme, ze to vynuluju cele
- //RIZIKO CHYBY VE VYPOCTU ADRESY
- mword phys_dirty = Ptab::get_mapping(next-PAGE_SIZE);
- mword phys = phys_dirty&0xfffff000;
- //memset(pocatecni_addresa-stary_break_void_ukazatel, cim_to_chceme_vyplnit, velikost_prostoru_co_budeme_vyplnovat)
- memset(Kalloc::phys2virt(phys+actual_addr-next-PAGE_SIZE),0x0,next-actual_addr);
- continue;
- } else {
- //naalokovat stranku - volat Kalloc::allocator.alloc_page(pocet_stranek=1,jakymi hodnotami vyplnit=0)
- //tato vec vraci void ukazatel - virtualni adresu
- void * next_page_virt = Kalloc::allocator.alloc_page(1,Kalloc::FILL_0);
- //okopirovano +- ze ec.cc, misto panic dealokace (ale zbavit se i aktualni stranky)
- if (!next_page_virt) {
- //kontrola, zda page neni NULL, pokud je, dealokovat
- dealloc(); //DODELAT!!!
- //poznamka ke zbavovani se aktualni stranky, dealloc na predchozi cykly
- //VRATIT NA ZACATEK!!!
- printf("Chyba v alokaci stranky.\n");
- continue;
- }
- //pokud se to povedlo, Ptab::insert_mapping(adresa_od_programu_pro_ktery_alokujeme, Kalloc::virttofyz(virtualni_adresa), znaky)
- if (!Ptab::insert_mapping (next, Kalloc::virt2phys (next_page_virt), Ptab::PRESENT | Ptab::RW | Ptab::USER)) {
- dealloc(); //DODELAT!!!
- printf("Chyba v insert mapping.\n");
- //VRATIT NA ZACATEK!!!
- //poznamka ke zbavovani se aktualni stranky, dealloc na predchozi cykly
- }
- next = align_up(next+1,PAGE_SIZE);
- printf("Jsem tu: %lu\n",next);
- }
- }
- r->eax = Ec::break_current;
- Ec::break_current = addr;
- printf("Koncim: %lu\n",r->eax);
- }
- //dealloc
- if (addr < actual_addr) {
- dealloc();
- }
- break;
- }
- default:
- printf ("unknown syscall %d\n", number);
- break;
- };
- ret_user_sysexit();
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement