Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
X
xv6-public
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
统计图
问题
0
问题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
银宸时代
OS Lab Group
奖励实验
xv6-public
提交
c3dcf479
提交
c3dcf479
8月 16, 2011
创建
作者:
Frans Kaashoek
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Clean up memlayout.h
Get rid of last instances of linear address and "la" Get ready for detecting physical memory dynamically
上级
427958cb
显示空白字符变更
内嵌
并排
正在显示
6 个修改的文件
包含
41 行增加
和
27 行删除
+41
-27
defs.h
defs.h
+1
-0
kalloc.c
kalloc.c
+10
-3
lapic.c
lapic.c
+2
-1
memlayout.h
memlayout.h
+3
-8
mmu.h
mmu.h
+8
-6
vm.c
vm.c
+17
-9
没有找到文件。
defs.h
浏览文件 @
c3dcf479
...
...
@@ -66,6 +66,7 @@ char* enter_alloc(void);
char
*
kalloc
(
void
);
void
kfree
(
char
*
);
void
kinit
(
void
);
uint
detect_memory
(
void
);
// kbd.c
void
kbdintr
(
void
);
...
...
kalloc.c
浏览文件 @
c3dcf479
...
...
@@ -19,7 +19,8 @@ struct {
}
kmem
;
extern
char
end
[];
// first address after kernel loaded from ELF file
char
*
newend
;
extern
uint
maxpa
;
// Maximum physical address
static
char
*
newend
;
// simple page allocator to get off the ground during entry
char
*
...
...
@@ -36,6 +37,12 @@ enter_alloc(void)
return
p
;
}
uint
detect_memory
(
void
)
{
return
0xE000000
;
}
// Initialize free list of physical pages.
void
kinit
(
void
)
...
...
@@ -44,7 +51,7 @@ kinit(void)
initlock
(
&
kmem
.
lock
,
"kmem"
);
p
=
(
char
*
)
PGROUNDUP
((
uint
)
newend
);
for
(;
p
+
PGSIZE
<=
(
char
*
)
p2v
(
PHYSTOP
);
p
+=
PGSIZE
)
for
(;
p
+
PGSIZE
<=
(
char
*
)
p2v
(
maxpa
);
p
+=
PGSIZE
)
kfree
(
p
);
}
...
...
@@ -58,7 +65,7 @@ kfree(char *v)
{
struct
run
*
r
;
if
((
uint
)
v
%
PGSIZE
||
v
<
end
||
v2p
(
v
)
>=
PHYSTOP
)
if
((
uint
)
v
%
PGSIZE
||
v
<
end
||
v2p
(
v
)
>=
maxpa
)
panic
(
"kfree"
);
// Fill with junk to catch dangling refs.
...
...
lapic.c
浏览文件 @
c3dcf479
...
...
@@ -135,7 +135,6 @@ microdelay(int us)
// Start additional processor running entry code at addr.
// See Appendix B of MultiProcessor Specification.
void
lapicstartap
(
uchar
apicid
,
uint
addr
)
{
int
i
;
...
...
@@ -169,3 +168,5 @@ lapicstartap(uchar apicid, uint addr)
microdelay
(
200
);
}
}
memlayout.h
浏览文件 @
c3dcf479
// Memory layout
#define PGSIZE 4096 // bytes mapped by a page
#define PGSHIFT 12 // log2(PGSIZE)
#define KSTKSIZE (8*PGSIZE) // size of a kernel stack
#define DEVSPACE 0xFE000000 // other devices are in the top of the phys address space
#define PHYSTOP 0xE000000 // use phys mem up to here as free pool
#define EXTMEM 0x100000 // Start of extended memory
#define DEVSPACE 0xFE000000 // Other devices are at high addresses
// Key addresses for address space layout (see kmap in vm.c for the layout)
#define KERNBASE 0xF0000000 // First kernel virtual address
#define USERTOP (KERNBASE-PGSIZE) // Highest user virtual address
#define KERNLINK
0xF0100000
// Address where kernel is linked
#define KERNLINK
(KERNBASE+EXTMEM)
// Address where kernel is linked
#ifndef __ASSEMBLER__
...
...
mmu.h
浏览文件 @
c3dcf479
...
...
@@ -100,32 +100,34 @@ struct segdesc {
#define STS_IG32 0xE // 32-bit Interrupt Gate
#define STS_TG32 0xF // 32-bit Trap Gate
// A
linear
address 'la' has a three-part structure as follows:
// A
virtual
address 'la' has a three-part structure as follows:
//
// +--------10------+-------10-------+---------12----------+
// | Page Directory | Page Table | Offset within Page |
// | Index | Index | |
// +----------------+----------------+---------------------+
// \--- PDX(
la) --/ \--- PTX(l
a) --/
// \--- PDX(
va) --/ \--- PTX(v
a) --/
// page directory index
#define PDX(
la) (((uint)(l
a) >> PDXSHIFT) & 0x3FF)
#define PDX(
va) (((uint)(v
a) >> PDXSHIFT) & 0x3FF)
// page table index
#define PTX(
la) (((uint)(l
a) >> PTXSHIFT) & 0x3FF)
#define PTX(
va) (((uint)(v
a) >> PTXSHIFT) & 0x3FF)
// construct
linear
address from indexes and offset
// construct
virtual
address from indexes and offset
#define PGADDR(d, t, o) ((uint)((d) << PDXSHIFT | (t) << PTXSHIFT | (o)))
// Page directory and page table constants.
#define NPDENTRIES 1024 // page directory entries per page directory
#define NPTENTRIES 1024 // page table entries per page table
#define PGSIZE 4096 // bytes mapped by a page
#define PGSHIFT 12 // log2(PGSIZE)
#define PTXSHIFT 12 // offset of PTX in a linear address
#define PDXSHIFT 22 // offset of PDX in a linear address
#define PGROUNDUP(sz) (((sz)+PGSIZE-1) & ~(PGSIZE-1))
#define PGROUNDDOWN(a) ((
char*)((((unsigned int)(a)) & ~(PGSIZE-1))
))
#define PGROUNDDOWN(a) ((
(a)) & ~(PGSIZE-1
))
// Page table/directory entry flags.
#define PTE_P 0x001 // Present
...
...
vm.c
浏览文件 @
c3dcf479
...
...
@@ -8,6 +8,7 @@
#include "elf.h"
extern
char
data
[];
// defined in data.S
uint
maxpa
;
// max physical address
pde_t
*
kpgdir
;
// for use in scheduler()
struct
segdesc
gdt
[
NSEGS
];
...
...
@@ -64,8 +65,8 @@ walkpgdir(pde_t *pgdir, const void *va, char* (*alloc)(void))
return
&
pgtab
[
PTX
(
va
)];
}
// Create PTEs for virtual addresses starting at
l
a that refer to
// physical addresses starting at pa.
l
a and size might not
// Create PTEs for virtual addresses starting at
v
a that refer to
// physical addresses starting at pa.
v
a and size might not
// be page-aligned.
static
int
mappages
(
pde_t
*
pgdir
,
void
*
va
,
uint
size
,
uint
pa
,
int
perm
,
char
*
(
*
alloc
)(
void
))
...
...
@@ -73,8 +74,8 @@ mappages(pde_t *pgdir, void *va, uint size, uint pa, int perm, char* (*alloc)(vo
char
*
a
,
*
last
;
pte_t
*
pte
;
a
=
PGROUNDDOWN
(
va
);
last
=
PGROUNDDOWN
(
va
+
size
-
1
);
a
=
(
char
*
)
PGROUNDDOWN
((
uint
)
va
);
last
=
(
char
*
)
PGROUNDDOWN
(((
uint
)
va
)
+
size
-
1
);
for
(;;){
pte
=
walkpgdir
(
pgdir
,
a
,
alloc
);
if
(
pte
==
0
)
...
...
@@ -100,13 +101,13 @@ mappages(pde_t *pgdir, void *va, uint size, uint pa, int perm, char* (*alloc)(vo
//
// setupkvm() and exec() set up every page table like this:
// 0..USERTOP : user memory (text, data, stack, heap), mapped to some unused phys mem
// KERNBASE..KERNBASE+
1M: mapped to 0..1M
// KERNBASE+
1M..KERNBASE+end : mapped to 1
M..end (mapped without write permission)
// KERNBASE+end..KERBASE+
PHYSTOP : mapped to end..PHYSTOP
(rw data + free memory)
// KERNBASE..KERNBASE+
EXTMEM: mapped to 0..EXTMEM (below extended memory)
// KERNBASE+
EXTMEM..KERNBASE+end : mapped to EXTME
M..end (mapped without write permission)
// KERNBASE+end..KERBASE+
maxpa : mapped to end..maxpa
(rw data + free memory)
// 0xfe000000..0 : mapped direct (devices such as ioapic)
//
// The kernel allocates memory for its heap and for user memory
// between kernend and the end of physical memory (
PHYSTOP
).
// between kernend and the end of physical memory (
maxpa
).
// The virtual address space of each user program includes the kernel
// (which is inaccessible in user mode). The user program sits in
// the bottom of the address space, and the kernel at the top at KERNBASE.
...
...
@@ -118,7 +119,7 @@ static struct kmap {
}
kmap
[]
=
{
{
P2V
(
0
),
0
,
1024
*
1024
,
PTE_W
},
// First 1Mbyte contains BIOS and some IO devices
{
(
void
*
)
KERNLINK
,
V2P
(
KERNLINK
),
V2P
(
data
),
0
},
// kernel text, rodata
{
data
,
V2P
(
data
),
PHYSTOP
,
PTE_W
},
// kernel data, memory
{
data
,
V2P
(
data
),
0
,
PTE_W
},
// kernel data, memory
{
(
void
*
)
DEVSPACE
,
DEVSPACE
,
0
,
PTE_W
},
// more devices
};
...
...
@@ -129,6 +130,13 @@ setupkvm(char* (*alloc)(void))
pde_t
*
pgdir
;
struct
kmap
*
k
;
if
(
kmap
[
2
].
phys_end
==
0
)
{
maxpa
=
detect_memory
();
kmap
[
2
].
phys_end
=
maxpa
;
if
(
p2v
(
maxpa
)
>
kmap
[
3
].
virt
)
panic
(
"detect_memory: too much memory"
);
}
if
((
pgdir
=
(
pde_t
*
)
alloc
())
==
0
)
return
0
;
memset
(
pgdir
,
0
,
PGSIZE
);
...
...
编写
预览
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论