Virtual Page Addresses and Attic Page Details

pages in the attic relative page numbers n.w
1 / 15
Embed
Share

Explore the concept of virtual page addresses and attic pages in the system architecture. Learn about relative page numbers, physical page addresses, and the allocation of free pages. Dive into the contents of the first attic page, including virtual addresses for different elements such as the keyboard buffer and interrupt vector. Delve into the detailed manifest outlining parameters and offsets for various components within the system. Understand the functioning of the user stack page table and how it interacts with physical and virtual pages. Discover the implementation of a new page fault handler for improved system performance.

  • System Architecture
  • Virtual Addresses
  • Attic Pages
  • Page Allocation
  • Interrupt Vector

Uploaded on | 0 Views


Download Presentation

Please find below an Image/Link to download the presentation.

The content on the website is provided AS IS for your information and personal use only. It may not be sold, licensed, or shared on other websites without obtaining consent from the author. If you encounter any issues during the download, it is possible that the publisher has removed the file from their server.

You are allowed to download the files provided on this website for personal or commercial use, subject to the condition that they are used lawfully. All files are the property of their respective owners.

The content on the website is provided AS IS for your information and personal use only. It may not be sold, licensed, or shared on other websites without obtaining consent from the author.

E N D

Presentation Transcript


  1. Pages in the attic, relative page numbers and virtual page addresses: 3 C0001800: second page of physical free page addresses 2 C0001000: first page of physical free page addresses 1 C0000800: second appearance of user stack page table 0 C0000000: general purpose first attic page

  2. Contents of first attic page, virtual addresses: C0000038: last word of keyboard buffer to (the keyboard buffer will not stay here) C0000019: first word of keyboard buffer C0000018: last word of interrupt vector to C0000002: first word of interrupt vector C0000001: number of allocated pages C0000000: number of free pages

  3. manifest { kbbuff_len_words = 32, kbbuff_max_chars = kbbuff_len_words * 4 - 1, OSAPT_first_page_offset = 0, OSAPT_usr_stack_pt_offset = 1, OSAPT_free_pages_offset = 2, first_attic_page_VA = 0xC0000000 + (OSAPT_first_page_offset << 11), usr_stack_pt_VA = 0xC0000000 + (OSAPT_usr_stack_pt_offset << 11), free_list_VA = 0xC0000000 + (OSAPT_free_pages_offset << 11), OSA_num_free_pages_offset = 0, OSA_num_allocated_pages_offset = 1, OSA_intvec_offset = 2, OSA_kbbuff_offset = 2 + sizeof$intvec, OSA____use_this_slot_next = 2 + sizeof$intvec + kbbuff_len_words, num_free_pages_VA = first_attic_page_VA + OSA_num_free_pages_offset, num_allocated_pages_VA = first_attic_page_VA + OSA_num_allocated_pages_offset, intvec_VA = first_attic_page_VA + OSA_intvec_offset, kbbuff_VA = first_attic_page_VA + OSA_kbbuff_offset }

  4. How it works: USR_stack_PT := get_free_page(); ... $clear_physical_page(USR_stack_PT); ... PD_addr ! 511 := USR_stack_PT bitor page$validmask; ... OS_stack_PT ! 2047 := get_free_page() bitor page$validmask; ... OS_attic_PT ! OSAPT_usr_stack_pt_offset := USR_stack_PT bitor page$validmask;

  5. The new, slightly improved page fault handler: let handler pfint(a, b, fault_address, d) be { let p, pn, ptn; ptn := page$tablenumsel from fault_address; if ptn <> 511 then { out("\npage fault address %08X not in acceptable range\n", fault_address); assembly { halt } } pn := page$pageintablesel from fault_address; out("page fault for %08X, page number = %d\n", fault_address, pn); p := free_list_VA ! ! num_allocated_pages_VA; ! num_allocated_pages_VA +:= 1; ! num_free_pages_VA -:= 1; usr_stack_pt_VA ! pn := p bitor page$validmask }

  6. The new "user program": let compute() be { let x = 0; // print num free pages and num allocated pages local_outno(free_list_VA ! ! num_allocated_pages_VA); assembly { type '\n' } local_outno(double(2500)); until stop do { for i = 1 to 500000 do assembly { pause } assembly { type '.' } } assembly { type '\n' type '!' type '\n' halt } }

  7. some preparation and run_user: let stop = false; let usr_stop_addr = @ stop; let run_user() be { out("jumping to %08X\n", 0x200 + compute - local_outno); $set_special_register(sr$usrsp, 0x80000000); $set_special_register(sr$usrfp, 0x80000000); $set_special_register(sr$syssp, 0xC0000000); $set_special_register(sr$sysfp, 0xC0000000); $set_special_register(sr$timer, 25000000); kbbuff := kbbuff_VA; kbbs := 0; kbbe := 0; kbbn := 0; kbbmax := kbbuff_len_words * 4 - 1; kbblines := 0 } usr_stop_addr := 0x200 + @ stop - local_outno; $set_flag(flag$sys, 0); (0x200 + compute - local_outno)() }

  8. The set-up for run_user let local_outno(n) be { ... } let double(b) be { if n = 0 then resultis 0; resultis 2 + double(n - 1) } let compute() be { ... } let after_compute() be { } ... code_addr := get_free_page(); $memory_move(code_addr + 0x200, local_outno, after_compute - local_outno); USR_code_PT ! 0 := code_addr bitor page$validmask;

  9. The keyboard interrupt handler: let handler kbint() be { let c; devctl(dc$termin, 1, @ c); test c = 'H'-64 then { if kbbunadd() then assembly { type 8 type ' ' type 8 } } else test c = 'X'-64 then ! usr_stop_addr := true else { if kbbadd(c) then assembly { type [<c>] } } }

  10. Keyboard buffer and related things: let kbbuff = vec(kbbuff_len_words), kbbs = 0, kbbe = 0, kbbn = 0, kbbmax = kbbuff_max_chars, kbblines = 0; let kbbadd(c) be // called when an ordinary character is typed { if kbbn >= kbbmax then resultis 0; byte kbbe of kbbuff := c; if c = '\n' then kbblines +:= 1; kbbn +:= 1; kbbe +:= 1; if kbbe > kbbmax then kbbe := 0; resultis 1 } let kbbunadd() be { ... } // called when a backspace is typed let kbbremove() be { ... } // how the program gets a character let kbbackch() be { ... } // the reverse of that let minch() be { let c = 0; while true do { c := kbbremove(); if c <> 0 then resultis c; assembly { pause } } }

  11. Two more interrupt handlers: let handler haltint(flags) be { flags bitor:= flag$masksys; ! (@ flags - 2) := back_to_os } let back_to_os() be { out("\nThe OS is in charge again, but there is nothing for it to do\n"); assembly { halt } } let handler timint() be { outs("\nBoo!\n"); $set_special_register(sr$timer, 25000000); }

  12. The set-up and enabling virtual memory: intvec := OS_attic_first_page + OSA_intvec_offset; for i = 0 to sizeof$intvec - 1 do intvec ! i := 0; intvec ! int$pagefault := 0x80000000 + pfint; intvec ! int$halt := 0x80000000 + haltint; intvec ! int$keybd := 0x80000000 + kbint; intvec ! int$timer := 0x80000000 + timint; $set_special_register(sr$intvec, intvec); $set_flag(flag$int, 1); $set_special_register(sr$pdbr, PD_addr); flags := $get_special_register(sr$flags) bitor flag$maskvm; $set_flags_and_jump(flags, run_user + 0x80000000); outs("attempt to start failed\n") }

  13. Part Two

  14. New bits in iosb: iosb_ioblock = 8; let readblock_tape(iosb, buff) be { let r; if buff = nil then buff := iosb ! iosb_buffer; r := devctl(dc$taperead, iosb ! iosb_unit, buff); if r >= 0 then zero_remainder(buff, r, 128); resultis r } let writeblock_tape(iosb, buff, num) be { let r; if buff = nil then buff := iosb ! iosb_buffer; r := devctl(dc$tapewrite, iosb ! iosb_unit, buff, num); resultis r }

  15. Corresponding parts in the shell: let readblock_disc(iosb, buff) be { ... } let writeblock_disc(iosb, buff, num) be { ... } let fast_create_file_from_file(tof, fromf) be { let r, num, buff = vec(128); if tof = tty \/ fromf = tty then { ... resultis err$software } while true do { num := readblock(fromf, buff); if num < 0 then resultis num; r := writeblock(tof, buff, num); if r < 0 then resultis r; if num < 512 then break } resultis 1 }

Related


More Related Content