6.828: Operating System Engineering (72)

久々のエントリ投入です。LEC5 の Homework です。

ええと、lab2 のソースで色々確認せい、とのこと。順に確認します。
てか、lab なソース見たらまだ commit してない模様。

それはスルーとして

kern/pmap.c の i386_vm_init 手続きの _Try to understand from the code what page mappings are being constructed._ とのこと。
よく考えたらこの手続きを通しで確認、ってしてないな。
順に見ていきます。

    pde_t* pgdir;
    uint32_t cr0;
    size_t n;

    // Delete this line:
//    panic("i386_vm_init: This function is not finished\n");

    //////////////////////////////////////////////////////////////////////
    // create initial page directory.
    pgdir = boot_alloc(PGSIZE, PGSIZE);
    memset(pgdir, 0, PGSIZE);
    boot_pgdir = pgdir;
    boot_cr3 = PADDR(pgdir);

4KB な領域を確保して初期化して

pde_t* boot_pgdir;        // Virtual address of boot time page directory
physaddr_t boot_cr3;        // Physical address of boot time page directory

な領域にアドレス保存。次の以下をちゃんと確認してない気がします。

    //////////////////////////////////////////////////////////////////////
    // Recursively insert PD in itself as a page table, to form
    // a virtual page table at virtual address VPT.
    // (For now, you don't have understand the greater purpose of the
    // following two lines.)

    // Permissions: kernel RW, user NONE
    pgdir[PDX(VPT)] = PADDR(pgdir)|PTE_W|PTE_P;

    // same for UVPT
    // Permissions: kernel R, user R 
    pgdir[PDX(UVPT)] = PADDR(pgdir)|PTE_U|PTE_P;

以下なあたりに関する権限設定か。

 *    KERNBASE ----->  +------------------------------+ 0xf0000000
 *                     |  Cur. Page Table (Kern. RW)  | RW/--  PTSIZE
 *    VPT,KSTACKTOP--> +------------------------------+ 0xefc00000      --+
 *                     |         Kernel Stack         | RW/--  KSTKSIZE   |
 *                     | - - - - - - - - - - - - - - -|                 PTSIZE
 *                     |      Invalid Memory (*)      | --/--             |
 *    ULIM     ------> +------------------------------+ 0xef800000      --+
 *                     |  Cur. Page Table (User R-)   | R-/R-  PTSIZE
 *    UVPT      ---->  +------------------------------+ 0xef400000

ここも inc/memlayout.h の上記のコメント見て、そーゆーことなのか、って思ってただけなんですが、コメントにある_For now, you don't have understand the greater purpose of the following two lines._というナニを見て完全スルーだったのですが。
次は何だったか。

    //////////////////////////////////////////////////////////////////////
    // Allocate an array of npage 'struct Page's and store it in 'pages'.
    // The kernel uses this array to keep track of physical pages: for
    // each physical page, there is a corresponding struct Page in this
    // array.  'npage' is the number of physical pages in memory.
    // User-level programs will get read-only access to the array as well.
    // Your code goes here:
    pages = boot_alloc(npage*sizeof(struct Page), PGSIZE);

ペイジディスクリプタな領域確保、なのかな。もう全然覚えてないので、以前のエントリを確認した方が良さげな勢いだったりします。
そして以下三点の手続きは課題だったような気がしてます。

    //////////////////////////////////////////////////////////////////////
    // Now that we've allocated the initial kernel data structures, we set
    // up the list of free physical pages. Once we've done so, all further
    // memory management will go through the page_* functions. In
    // particular, we can now map memory using boot_map_segment or page_insert
    page_init();

    check_page_alloc();

    page_check();

page_init は何をしてるかというと直前で領域を確保した pages な領域の初期化か。

  • 0 ページは使えない
  • IO hole も使えない
    • 0x0A0000 番地から 0x100000 番地まで

inc/memlayout.h によれば以下な記述。

// At IOPHYSMEM (640K) there is a 384K hole for I/O.  From the kernel,
// IOPHYSMEM can be addressed at KERNBASE + IOPHYSMEM.  The hole ends
// at physical address EXTPHYSMEM.

実装としては

  • 空きページのリストを初期化
  • 0 ページと IO hole は pp_ref 属性に 1 をセット
  • それ以外は pp_ref 属性に 0 をセットして空きページリストにアドレスを追加

という形になっている模様。
で、次の check_page_alloc と page_check という手続きで assert なチェックしてます。ある意味ここまでの実装の仕様はここに記述されている assert なナニ、と言っても過言では無いですね。
特に page_check については相当てこずった記憶があるので、別途 assert なナニについて纏めておいた方が良いと思ってますが、今日はそろそろ限界。
来週はこちら対応の時間が確保できれば良いのですが。