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] を確認してみます。