Exercise 4.In the file kern/pmap.c,you must implement code for the following functions.
当使用80x86处理器时,必须区分三个地址
逻辑地址(Logical address):每个逻辑地址包括一个段和偏移,偏移指从段起始地址到实际地址的偏移。
线性地址(Linear address)(也称虚拟地址):一个32位无符号整数,可以用来表示高达4GB的地址,通常用十六进制表示,范围从0x00000000到0xffffffff
物理地址(physical address):用于在内存芯片上寻址内存单元。与从CPU地址引脚发送到内存总线的电信号相对应。
MMU通过一种称为分段单元(segmentation unit)的硬件电路吧逻辑地址转换成线性地址,接着分页单元(paging uni)的硬件电路把线性地址转换成一个物理地址。
Exercise 4的几个函数都是基于线性地址到物理地址的转换,具体的转换可以参考i386手册中关于paging的部分。pgdir_walk()
416 pte_t *result = NULL;
417 pde_t *pdt = pgdir + PDX(va);
419 struct Page* newpta = NULL;
421 cprintf("%s(0x%x, 0x%x, %d, pdt = %x,*pdt = %x),\n",__func__,pgdir,va,create,pdt, *pdt);
423 if (!(*pdt & PTE_P)) { // the page table entry not present yet
424 if(create) {
425 newpta = page_alloc(PGSIZE);
427 if(newpta == NULL) {
429 return NULL;
430 } else {
431 memset(page2kva(newpta), 0, PGSIZE);
432 newpta->pp_ref++;
433 *pdt = PADDR(page2kva(newpta))|PTE_U|PTE_W|PTE_P;
435 }
436 } else {
438 return NULL;
439 }
440 }
441 result = (pte_t *)KADDR(PTE_ADDR(*pdt)) + PTX(va);
boot_map_region()
469 int n = ROUNDUP(size, PGSIZE) / PGSIZE;
470 int i;
471 pte_t *pte = NULL;
472 for(i = 0; i < n; i++) {
473 pte = pgdir_walk(pgdir, (void *)(va + i*PGSIZE), 1);
474 *pte = (pa + i*PGSIZE)|perm|PTE_P;
475 }
page_lookup()
554 pte_t *pte = pgdir_walk(pgdir, va, 0);
556 if(pte_store != NULL) {
557 *pte_store = pte;
559 }
560 if ((pte == NULL) || ((*pte & PTE_P) == 0)) {
562 return NULL;
563 }
565 return pa2page(PTE_ADDR(*pte));
page_remove()
587 pte_t *pte;
588 struct Page *pa = page_lookup(pgdir, va, &pte);
589 if(!pa) {
591 return;
592 }
593 page_decref(pa);
594 *pte = 0;
595 if (!pa->pp_ref) {
596 page_free(pa);
597 }
598 tlb_invalidate(pgdir,va);
page_insert()
507 pte_t *pte = pgdir_walk(pgdir, va, 1);
508 if (!pte)
509 return -E_NO_MEM;
510 if(PTE_ADDR(*pte) != page2pa(pp)) {
512 page_remove(pgdir, va);
513 pte = pgdir_walk(pgdir, va, 1);
515 pp->pp_ref++;
516 }
517 *pte = page2pa(pp)|perm|PTE_P;
518 return 0;

本文介绍80x86处理器上的内存管理机制,包括逻辑地址、线性地址及物理地址的概念,并详细解析了MMU如何进行地址转换。文中还深入探讨了几个关键函数的实现,如pgdir_walk()、boot_map_region()等。

7750

被折叠的 条评论
为什么被折叠?



