6.828: Operating System Engineering (30)
うにまがの特集 Linux のブートプロセスをみる、とか詳解 Linux カーネルをガン読み。メモリ云々な部分はがっつりスルー状態でしたので勉強になります。
とりあえず整理
以下のみっつのアドレスを区別できなければ、とのこと。
- 論理アドレス
- リニアアドレス
- 物理アドレス
論理アドレスはセグメンテーション回路でリニアアドレスに変換されて、リニアアドレスはページング回路によって物理アドレスに変換されるとのこと。ただし、Linux では_基本フラットモデル_と言われるメモリモデルを採用しているとの記述が Linux のブートプロセスをみる、にありました。pmap.c の gdt の記述が以下。
// Global descriptor table. // // The kernel and user segments are identical (except for the DPL). // To load the SS register, the CPL must equal the DPL. Thus, // we must duplicate the segments for the user and the kernel. // struct Segdesc gdt[] = { // 0x0 - unused (always faults -- for trapping NULL far pointers) SEG_NULL, // 0x8 - kernel code segment [GD_KT >> 3] = SEG(STA_X | STA_R, 0x0, 0xffffffff, 0), // 0x10 - kernel data segment [GD_KD >> 3] = SEG(STA_W, 0x0, 0xffffffff, 0), // 0x18 - user code segment [GD_UT >> 3] = SEG(STA_X | STA_R, 0x0, 0xffffffff, 3), // 0x20 - user data segment [GD_UD >> 3] = SEG(STA_W, 0x0, 0xffffffff, 3), // 0x28 - tss, initialized in idt_init() [GD_TSS >> 3] = SEG_NULL };
で、それを前提に、check_page_pgdir なナニを見るに
// check pages array n = ROUNDUP(npage*sizeof(struct Page), PGSIZE); for (i = 0; i < n; i += PGSIZE) assert(check_va2pa(pgdir, UPAGES + i) == PADDR(pages) + i); // check phys mem for (i = 0; i < npage * PGSIZE; i += PGSIZE) assert(check_va2pa(pgdir, KERNBASE + i) == i); // check kernel stack for (i = 0; i < KSTKSIZE; i += PGSIZE) assert(check_va2pa(pgdir, KSTACKTOP - KSTKSIZE + i) == PADDR(bootstack) + i); assert(check_va2pa(pgdir, KSTACKTOP - PTSIZE) == ~0);
- boot_pgdir を UPAGES で物理アドレスに変換したアドレスは pages 配列の物理アドレスと同値でなければならない
- ええと、KERNBASE は 0 にマップされるの?
- Kernel Stack のてっぺんは bootstack の物理アドレスにマップされる?
- ULIM で変換したら invalid?
うう、ワケワカらん。てか、memlayout.h にある memory map なコメントは_リニアアドレス_なマンガなのだな。
* Virtual memory map: Permissions * kernel/user * * 4 Gig --------> +------------------------------+ * | | RW/-- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * : . : * : . : * : . : * |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~| RW/-- * | | RW/-- * | Remapped Physical Memory | RW/-- * | | RW/-- * KERNBASE -----> +------------------------------+ 0xf0000000
ここが若干謎です。約 250MB になるのかどうなのか。このあたりを前提に pmap.[ch] を確認してみます。