Skip to content

Commit 2d1187a

Browse files
committedSep 12, 2018
Lab 2
1 parent a56269d commit 2d1187a

File tree

9 files changed

+1056
-16
lines changed

9 files changed

+1056
-16
lines changed
 

‎GNUmakefile

+2-1
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ endif
6767
GDBPORT := $(shell expr `id -u` % 5000 + 25000)
6868

6969
CC := $(GCCPREFIX)gcc -pipe
70+
GDB := $(GCCPREFIX)gdb
7071
AS := $(GCCPREFIX)as
7172
AR := $(GCCPREFIX)ar
7273
LD := $(GCCPREFIX)ld
@@ -148,7 +149,7 @@ QEMUOPTS += $(QEMUEXTRA)
148149
sed "s/localhost:1234/localhost:$(GDBPORT)/" < $^ > $@
149150

150151
gdb:
151-
gdb -n -x .gdbinit
152+
$(GDB) -n -x .gdbinit
152153

153154
pre-qemu: .gdbinit
154155

‎conf/lab.mk

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
LAB=1
2-
PACKAGEDATE=Thu Aug 30 15:16:04 EDT 2018
1+
LAB=2
2+
PACKAGEDATE=Wed Sep 12 14:51:29 EDT 2018

‎grade-lab2

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#!/usr/bin/env python
2+
3+
from gradelib import *
4+
5+
r = Runner(save("jos.out"),
6+
stop_breakpoint("readline"))
7+
8+
@test(0, "running JOS")
9+
def test_jos():
10+
r.run_qemu()
11+
12+
@test(20, "Physical page allocator", parent=test_jos)
13+
def test_check_page_alloc():
14+
r.match(r"check_page_alloc\(\) succeeded!")
15+
16+
@test(20, "Page management", parent=test_jos)
17+
def test_check_page():
18+
r.match(r"check_page\(\) succeeded!")
19+
20+
@test(20, "Kernel page directory", parent=test_jos)
21+
def test_check_kern_pgdir():
22+
r.match(r"check_kern_pgdir\(\) succeeded!")
23+
24+
@test(10, "Page management 2", parent=test_jos)
25+
def test_check_page_installed_pgdir():
26+
r.match(r"check_page_installed_pgdir\(\) succeeded!")
27+
28+
run_tests()

‎inc/memlayout.h

+41
Original file line numberDiff line numberDiff line change
@@ -143,5 +143,46 @@
143143
typedef uint32_t pte_t;
144144
typedef uint32_t pde_t;
145145

146+
#if JOS_USER
147+
/*
148+
* The page directory entry corresponding to the virtual address range
149+
* [UVPT, UVPT + PTSIZE) points to the page directory itself. Thus, the page
150+
* directory is treated as a page table as well as a page directory.
151+
*
152+
* One result of treating the page directory as a page table is that all PTEs
153+
* can be accessed through a "virtual page table" at virtual address UVPT (to
154+
* which uvpt is set in lib/entry.S). The PTE for page number N is stored in
155+
* uvpt[N]. (It's worth drawing a diagram of this!)
156+
*
157+
* A second consequence is that the contents of the current page directory
158+
* will always be available at virtual address (UVPT + (UVPT >> PGSHIFT)), to
159+
* which uvpd is set in lib/entry.S.
160+
*/
161+
extern volatile pte_t uvpt[]; // VA of "virtual page table"
162+
extern volatile pde_t uvpd[]; // VA of current page directory
163+
#endif
164+
165+
/*
166+
* Page descriptor structures, mapped at UPAGES.
167+
* Read/write to the kernel, read-only to user programs.
168+
*
169+
* Each struct PageInfo stores metadata for one physical page.
170+
* Is it NOT the physical page itself, but there is a one-to-one
171+
* correspondence between physical pages and struct PageInfo's.
172+
* You can map a struct PageInfo * to the corresponding physical address
173+
* with page2pa() in kern/pmap.h.
174+
*/
175+
struct PageInfo {
176+
// Next page on the free list.
177+
struct PageInfo *pp_link;
178+
179+
// pp_ref is the count of pointers (usually in page table entries)
180+
// to this page, for pages allocated using page_alloc.
181+
// Pages allocated at boot time using pmap.c's
182+
// boot_alloc do not have valid reference count fields.
183+
184+
uint16_t pp_ref;
185+
};
186+
146187
#endif /* !__ASSEMBLER__ */
147188
#endif /* !JOS_INC_MEMLAYOUT_H */

‎kern/init.c

+4-13
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,9 @@
66

77
#include <kern/monitor.h>
88
#include <kern/console.h>
9+
#include <kern/pmap.h>
10+
#include <kern/kclock.h>
911

10-
// Test the stack backtrace function (lab 1 only)
11-
void
12-
test_backtrace(int x)
13-
{
14-
cprintf("entering test_backtrace %d\n", x);
15-
if (x > 0)
16-
test_backtrace(x-1);
17-
else
18-
mon_backtrace(0, 0, 0);
19-
cprintf("leaving test_backtrace %d\n", x);
20-
}
2112

2213
void
2314
i386_init(void)
@@ -35,8 +26,8 @@ i386_init(void)
3526

3627
cprintf("6828 decimal is %o octal!\n", 6828);
3728

38-
// Test the stack backtrace function (lab 1 only)
39-
test_backtrace(5);
29+
// Lab 2 memory management initialization functions
30+
mem_init();
4031

4132
// Drop into the kernel monitor.
4233
while (1)

‎kern/kclock.c

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/* See COPYRIGHT for copyright information. */
2+
3+
/* Support for reading the NVRAM from the real-time clock. */
4+
5+
#include <inc/x86.h>
6+
7+
#include <kern/kclock.h>
8+
9+
10+
unsigned
11+
mc146818_read(unsigned reg)
12+
{
13+
outb(IO_RTC, reg);
14+
return inb(IO_RTC+1);
15+
}
16+
17+
void
18+
mc146818_write(unsigned reg, unsigned datum)
19+
{
20+
outb(IO_RTC, reg);
21+
outb(IO_RTC+1, datum);
22+
}

‎kern/kclock.h

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/* See COPYRIGHT for copyright information. */
2+
3+
#ifndef JOS_KERN_KCLOCK_H
4+
#define JOS_KERN_KCLOCK_H
5+
#ifndef JOS_KERNEL
6+
# error "This is a JOS kernel header; user programs should not #include it"
7+
#endif
8+
9+
#define IO_RTC 0x070 /* RTC port */
10+
11+
#define MC_NVRAM_START 0xe /* start of NVRAM: offset 14 */
12+
#define MC_NVRAM_SIZE 50 /* 50 bytes of NVRAM */
13+
14+
/* NVRAM bytes 7 & 8: base memory size */
15+
#define NVRAM_BASELO (MC_NVRAM_START + 7) /* low byte; RTC off. 0x15 */
16+
#define NVRAM_BASEHI (MC_NVRAM_START + 8) /* high byte; RTC off. 0x16 */
17+
18+
/* NVRAM bytes 9 & 10: extended memory size (between 1MB and 16MB) */
19+
#define NVRAM_EXTLO (MC_NVRAM_START + 9) /* low byte; RTC off. 0x17 */
20+
#define NVRAM_EXTHI (MC_NVRAM_START + 10) /* high byte; RTC off. 0x18 */
21+
22+
/* NVRAM bytes 38 and 39: extended memory size (between 16MB and 4G) */
23+
#define NVRAM_EXT16LO (MC_NVRAM_START + 38) /* low byte; RTC off. 0x34 */
24+
#define NVRAM_EXT16HI (MC_NVRAM_START + 39) /* high byte; RTC off. 0x35 */
25+
26+
unsigned mc146818_read(unsigned reg);
27+
void mc146818_write(unsigned reg, unsigned datum);
28+
29+
#endif // !JOS_KERN_KCLOCK_H

‎kern/pmap.c

+841
Large diffs are not rendered by default.

‎kern/pmap.h

+87
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
/* See COPYRIGHT for copyright information. */
2+
3+
#ifndef JOS_KERN_PMAP_H
4+
#define JOS_KERN_PMAP_H
5+
#ifndef JOS_KERNEL
6+
# error "This is a JOS kernel header; user programs should not #include it"
7+
#endif
8+
9+
#include <inc/memlayout.h>
10+
#include <inc/assert.h>
11+
12+
extern char bootstacktop[], bootstack[];
13+
14+
extern struct PageInfo *pages;
15+
extern size_t npages;
16+
17+
extern pde_t *kern_pgdir;
18+
19+
20+
/* This macro takes a kernel virtual address -- an address that points above
21+
* KERNBASE, where the machine's maximum 256MB of physical memory is mapped --
22+
* and returns the corresponding physical address. It panics if you pass it a
23+
* non-kernel virtual address.
24+
*/
25+
#define PADDR(kva) _paddr(__FILE__, __LINE__, kva)
26+
27+
static inline physaddr_t
28+
_paddr(const char *file, int line, void *kva)
29+
{
30+
if ((uint32_t)kva < KERNBASE)
31+
_panic(file, line, "PADDR called with invalid kva %08lx", kva);
32+
return (physaddr_t)kva - KERNBASE;
33+
}
34+
35+
/* This macro takes a physical address and returns the corresponding kernel
36+
* virtual address. It panics if you pass an invalid physical address. */
37+
#define KADDR(pa) _kaddr(__FILE__, __LINE__, pa)
38+
39+
static inline void*
40+
_kaddr(const char *file, int line, physaddr_t pa)
41+
{
42+
if (PGNUM(pa) >= npages)
43+
_panic(file, line, "KADDR called with invalid pa %08lx", pa);
44+
return (void *)(pa + KERNBASE);
45+
}
46+
47+
48+
enum {
49+
// For page_alloc, zero the returned physical page.
50+
ALLOC_ZERO = 1<<0,
51+
};
52+
53+
void mem_init(void);
54+
55+
void page_init(void);
56+
struct PageInfo *page_alloc(int alloc_flags);
57+
void page_free(struct PageInfo *pp);
58+
int page_insert(pde_t *pgdir, struct PageInfo *pp, void *va, int perm);
59+
void page_remove(pde_t *pgdir, void *va);
60+
struct PageInfo *page_lookup(pde_t *pgdir, void *va, pte_t **pte_store);
61+
void page_decref(struct PageInfo *pp);
62+
63+
void tlb_invalidate(pde_t *pgdir, void *va);
64+
65+
static inline physaddr_t
66+
page2pa(struct PageInfo *pp)
67+
{
68+
return (pp - pages) << PGSHIFT;
69+
}
70+
71+
static inline struct PageInfo*
72+
pa2page(physaddr_t pa)
73+
{
74+
if (PGNUM(pa) >= npages)
75+
panic("pa2page called with invalid pa");
76+
return &pages[PGNUM(pa)];
77+
}
78+
79+
static inline void*
80+
page2kva(struct PageInfo *pp)
81+
{
82+
return KADDR(page2pa(pp));
83+
}
84+
85+
pte_t *pgdir_walk(pde_t *pgdir, const void *va, int create);
86+
87+
#endif /* !JOS_KERN_PMAP_H */

0 commit comments

Comments
 (0)
Please sign in to comment.