Q1:kern/env.c 中 [GD_KT >> 3] & [GD_KD>>3] 最后指向的都是1,这样不就被覆盖了吗?
37 struct Segdesc gdt[] =
38 {
39 // 0x0 - unused (always faults -- for trapping NULL far pointers)
40 SEG_NULL,
41
42 // 0x8 - kernel code segment
43 [GD_KT >> 3] = SEG(STA_X | STA_R, 0x0, 0xffffffff, 0),
44
45 // 0x10 - kernel data segment
46 [GD_KD >> 3] = SEG(STA_W, 0x0, 0xffffffff, 0),
47
48 // 0x18 - user code segment
49 [GD_UT >> 3] = SEG(STA_X | STA_R, 0x0, 0xffffffff, 3),
50
51 // 0x20 - user data segment
52 [GD_UD >> 3] = SEG(STA_W, 0x0, 0xffffffff, 3),
53
54 // 0x28 - tss, initialized in trap_init_percpu()
55 [GD_TSS0 >> 3] = SEG_NULL
56 };
A: 结果如下:
gdt[0](type,lim,dpl) = (0,0,0)
gdt[1](type,lim,dpl) = (a,ffff,0)
gdt[2](type,lim,dpl) = (2,ffff,0)
gdt[3](type,lim,dpl) = (a,ffff,3)
gdt[4](type,lim,dpl) = (2,ffff,3)
gdt[5](type,lim,dpl) = (0,0,0)
C是按次序赋值,而非完全按照下标.
Q2: boot_map_region() vs. page_insert() ?
Q3: 在做lab3 exercise 1 load_icode()的时候,每次进入memmove()下面这条指令时就crash:
“rep movsb byte ptr es:[edi], byte ptr ds:[esi]” (具体内容可考察/htjacky/article/details/18651931)
A:查看register,
<bochs:13> r
eax: 0x00200000 2097152
ecx: 0x00003fae 16302
edx: 0x000003d5 981
ebx: 0xf011d378 -267267208
esp: 0xf011af70 -267276432
ebp: 0xf011af78 -267276424
esi: 0xf011e344 -267263164
edi: 0x00200000 2097152
eip: 0xf010522e
用于计算重复次数的ECX= 0x3fae看起来没问题,esi = 0xf011e344,指向的信息如下,看起来也没问题:
<bochs:15> x/16ux 0xf011e344
[bochs]:
0xf011e344 <bogus+ 0>: 0x00200010 0x002028c0 0x002028c10x00203fad
0xf011e354 <bogus+ 16>: 0x00000001 0x03630000 0x000016ec0x00000001
0xf011e364 <bogus+ 32>: 0x00000064 0x00800020 0x000000120x00000084
0xf011e374 <bogus+ 48>: 0x00800020 0x00000000 0x001700440x00800020
而edi指向的是0x200000,用户空间虚拟地址,看起来也是对的,试读一下:
<bochs:16> x/ux 0x200000
[bochs]:
0x00200000 <bogus+ 0>:bx_dbg_read_linear: physical address not available for linear 0x00200000
打印出debug信息发现有个page一直是被重复映射的,原因是它的link地址指向了自己:
page_alloc(), ALLOC_ZERO, page = 0xf019ddc8
pgdir_walk,467, create new page table at 0x3b9007
region_alloc(),293:paddr = 0xf03b9000,p =0xf019ddc8, link =0xf019ddc8
page_alloc(), ALLOC_ZERO, page = 0xf019ddc8
page_insert,(0xf03bb000: 0xf019ddc8, 0x00, 6)!
page_lookup,618, no page mapped at va!
region_alloc(),293:paddr = 0xf03b9000,p =0xf019ddc8, link =0xf019ddc8
page_alloc(), ALLOC_ZERO, page = 0xf019ddc8
最后往上查,发现在page_remove()里的设计出错,把同一个page free了两次。在内核里操作内存要非常的小心啊~~~