Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
X
xv6-public
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
统计图
问题
0
问题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
银宸时代
OS Lab Group
奖励实验
xv6-public
提交
0ca1c040
提交
0ca1c040
9月 27, 2011
创建
作者:
Frans Kaashoek
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'master' of
git+ssh://amsterdam.csail.mit.edu/home/am0/6.828/xv6
上级
9b972c06
1e6f0146
全部展开
隐藏空白字符变更
内嵌
并排
正在显示
10 个修改的文件
包含
94 行增加
和
84 行删除
+94
-84
LucidaSans-Typewriter83
LucidaSans-Typewriter83
+0
-0
bootasm.S
bootasm.S
+3
-3
console.c
console.c
+1
-2
defs.h
defs.h
+3
-4
entry.S
entry.S
+1
-1
kalloc.c
kalloc.c
+31
-24
main.c
main.c
+8
-11
memlayout.h
memlayout.h
+4
-4
runoff
runoff
+9
-3
vm.c
vm.c
+34
-32
没有找到文件。
LucidaSans-Typewriter83
deleted
100644 → 0
浏览文件 @
9b972c06
差异被折叠。
点击展开。
bootasm.S
浏览文件 @
0ca1c040
...
...
@@ -12,8 +12,8 @@
start:
cli # BIOS enabled interrupts; disable
#
Set up the important data segment registers (DS, ES, SS)
.
xorw %ax,%ax # Se
gment number
zero
#
Zero data segment registers DS, ES, and SS
.
xorw %ax,%ax # Se
t %ax to
zero
movw %ax,%ds # -> Data Segment
movw %ax,%es # -> Extra Segment
movw %ax,%ss # -> Stack Segment
...
...
@@ -37,7 +37,7 @@ seta20.2:
outb %al,$0x60
# Switch from real to protected mode. Use a bootstrap GDT that makes
# virtual addresses map di
erctly to
physical addresses so that the
# virtual addresses map di
rectly to
physical addresses so that the
# effective memory map doesn't change during the transition.
lgdt gdtdesc
movl %cr0, %eax
...
...
console.c
浏览文件 @
0ca1c040
...
...
@@ -53,7 +53,7 @@ printint(int xx, int base, int sign)
void
cprintf
(
char
*
fmt
,
...)
{
int
i
,
c
,
state
,
locking
;
int
i
,
c
,
locking
;
uint
*
argp
;
char
*
s
;
...
...
@@ -65,7 +65,6 @@ cprintf(char *fmt, ...)
panic
(
"null fmt"
);
argp
=
(
uint
*
)(
void
*
)(
&
fmt
+
1
);
state
=
0
;
for
(
i
=
0
;
(
c
=
fmt
[
i
]
&
0xff
)
!=
0
;
i
++
){
if
(
c
!=
'%'
){
consputc
(
c
);
...
...
defs.h
浏览文件 @
0ca1c040
...
...
@@ -62,11 +62,10 @@ extern uchar ioapicid;
void
ioapicinit
(
void
);
// kalloc.c
char
*
enter_alloc
(
void
);
char
*
kalloc
(
void
);
void
kfree
(
char
*
);
void
kinit
(
void
);
uint
detect_memory
(
void
);
void
kinit
1
(
void
*
,
void
*
);
void
kinit2
(
void
*
,
void
*
);
// kbd.c
void
kbdintr
(
void
);
...
...
@@ -165,7 +164,7 @@ void uartputc(int);
void
seginit
(
void
);
void
kvmalloc
(
void
);
void
vmenable
(
void
);
pde_t
*
setupkvm
(
char
*
(
*
alloc
)()
);
pde_t
*
setupkvm
();
char
*
uva2ka
(
pde_t
*
,
char
*
);
int
allocuvm
(
pde_t
*
,
uint
,
uint
);
int
deallocuvm
(
pde_t
*
,
uint
,
uint
);
...
...
entry.S
浏览文件 @
0ca1c040
...
...
@@ -36,7 +36,7 @@ multiboot_header:
.globl _start
_start = V2P_WO(entry)
# Entering xv6 on boot processor
. Machine is mostly set up
.
# Entering xv6 on boot processor
, with paging off
.
.globl entry
entry:
# Turn on page size extension for 4Mbyte pages
...
...
kalloc.c
浏览文件 @
0ca1c040
...
...
@@ -9,42 +9,45 @@
#include "mmu.h"
#include "spinlock.h"
void
freerange
(
void
*
vstart
,
void
*
vend
);
extern
char
end
[];
// first address after kernel loaded from ELF file
struct
run
{
struct
run
*
next
;
};
struct
{
struct
spinlock
lock
;
int
use_lock
;
struct
run
*
freelist
;
}
kmem
;
extern
char
end
[];
// first address after kernel loaded from ELF file
static
char
*
newend
;
// A simple page allocator to get off the ground during entry
char
*
enter_alloc
(
void
)
// Initialization happens in two phases.
// 1. main() calls kinit1() while still using entrypgdir to place just
// the pages mapped by entrypgdir on free list.
// 2. main() calls kinit2() with the rest of the physical pages
// after installing a full page table that maps them on all cores.
void
kinit1
(
void
*
vstart
,
void
*
vend
)
{
if
(
newend
==
0
)
newend
=
end
;
initlock
(
&
kmem
.
lock
,
"kmem"
);
kmem
.
use_lock
=
0
;
freerange
(
vstart
,
vend
);
}
if
((
uint
)
newend
>=
KERNBASE
+
0x400000
)
panic
(
"only first 4Mbyte are mapped during entry"
);
void
*
p
=
(
void
*
)
PGROUNDUP
((
uint
)
newend
);
memset
(
p
,
0
,
PGSIZE
);
newend
=
newend
+
PGSIZE
;
return
p
;
void
kinit2
(
void
*
vstart
,
void
*
vend
)
{
freerange
(
vstart
,
vend
);
kmem
.
use_lock
=
1
;
}
// Initialize free list of physical pages.
void
kinit
(
voi
d
)
freerange
(
void
*
vstart
,
void
*
ven
d
)
{
char
*
p
;
initlock
(
&
kmem
.
lock
,
"kmem"
);
p
=
(
char
*
)
PGROUNDUP
((
uint
)
newend
);
for
(;
p
+
PGSIZE
<=
(
char
*
)
p2v
(
PHYSTOP
);
p
+=
PGSIZE
)
p
=
(
char
*
)
PGROUNDUP
((
uint
)
vstart
);
for
(;
p
+
PGSIZE
<=
(
char
*
)
vend
;
p
+=
PGSIZE
)
kfree
(
p
);
}
...
...
@@ -64,11 +67,13 @@ kfree(char *v)
// Fill with junk to catch dangling refs.
memset
(
v
,
1
,
PGSIZE
);
acquire
(
&
kmem
.
lock
);
if
(
kmem
.
use_lock
)
acquire
(
&
kmem
.
lock
);
r
=
(
struct
run
*
)
v
;
r
->
next
=
kmem
.
freelist
;
kmem
.
freelist
=
r
;
release
(
&
kmem
.
lock
);
if
(
kmem
.
use_lock
)
release
(
&
kmem
.
lock
);
}
// Allocate one 4096-byte page of physical memory.
...
...
@@ -79,11 +84,13 @@ kalloc(void)
{
struct
run
*
r
;
acquire
(
&
kmem
.
lock
);
if
(
kmem
.
use_lock
)
acquire
(
&
kmem
.
lock
);
r
=
kmem
.
freelist
;
if
(
r
)
kmem
.
freelist
=
r
->
next
;
release
(
&
kmem
.
lock
);
if
(
kmem
.
use_lock
)
release
(
&
kmem
.
lock
);
return
(
char
*
)
r
;
}
main.c
浏览文件 @
0ca1c040
...
...
@@ -9,6 +9,7 @@
static
void
startothers
(
void
);
static
void
mpmain
(
void
)
__attribute__
((
noreturn
));
extern
pde_t
*
kpgdir
;
extern
char
end
[];
// first address after kernel loaded from ELF file
// Bootstrap processor starts running C code here.
// Allocate a real stack and switch to it, first
...
...
@@ -16,6 +17,7 @@ extern pde_t *kpgdir;
int
main
(
void
)
{
kinit1
(
end
,
P2V
(
4
*
1024
*
1024
));
// phys page allocator
kvmalloc
();
// kernel page table
mpinit
();
// collect info about this machine
lapicinit
(
mpbcpu
());
...
...
@@ -33,9 +35,9 @@ main(void)
ideinit
();
// disk
if
(
!
ismp
)
timerinit
();
// uniprocessor timer
startothers
();
// start other processors (must come before kinit)
kinit
();
// initialize memory allocator
userinit
();
// first user process
(must come after kinit)
startothers
();
// start other processors
kinit
2
(
P2V
(
4
*
1024
*
1024
),
P2V
(
PHYSTOP
));
// must come after startothers()
userinit
();
// first user process
// Finish setting up this processor in mpmain.
mpmain
();
}
...
...
@@ -84,12 +86,7 @@ startothers(void)
// Tell entryother.S what stack to use, where to enter, and what
// pgdir to use. We cannot use kpgdir yet, because the AP processor
// is running in low memory, so we use entrypgdir for the APs too.
// kalloc can return addresses above 4Mbyte (the machine may have
// much more physical memory than 4Mbyte), which aren't mapped by
// entrypgdir, so we must allocate a stack using enter_alloc();
// this introduces the constraint that xv6 cannot use kalloc until
// after these last enter_alloc invocations.
stack
=
enter_alloc
();
stack
=
kalloc
();
*
(
void
**
)(
code
-
4
)
=
stack
+
KSTACKSIZE
;
*
(
void
**
)(
code
-
8
)
=
mpenter
;
*
(
int
**
)(
code
-
12
)
=
(
void
*
)
v2p
(
entrypgdir
);
...
...
@@ -109,9 +106,9 @@ startothers(void)
__attribute__
((
__aligned__
(
PGSIZE
)))
pde_t
entrypgdir
[
NPDENTRIES
]
=
{
// Map VA's [0, 4MB) to PA's [0, 4MB)
[
0
]
=
(
0
)
+
PTE_P
+
PTE_W
+
PTE_PS
,
[
0
]
=
(
0
)
|
PTE_P
|
PTE_W
|
PTE_PS
,
// Map VA's [KERNBASE, KERNBASE+4MB) to PA's [0, 4MB)
[
KERNBASE
>>
PDXSHIFT
]
=
(
0
)
+
PTE_P
+
PTE_W
+
PTE_PS
,
[
KERNBASE
>>
PDXSHIFT
]
=
(
0
)
|
PTE_P
|
PTE_W
|
PTE_PS
,
};
//PAGEBREAK!
...
...
memlayout.h
浏览文件 @
0ca1c040
...
...
@@ -10,13 +10,13 @@
#ifndef __ASSEMBLER__
static
inline
uint
v2p
(
void
*
a
)
{
return
(
uint
)
a
-
KERNBASE
;
}
static
inline
void
*
p2v
(
uint
a
)
{
return
(
void
*
)
a
+
KERNBASE
;
}
static
inline
uint
v2p
(
void
*
a
)
{
return
(
(
uint
)
(
a
))
-
KERNBASE
;
}
static
inline
void
*
p2v
(
uint
a
)
{
return
(
void
*
)
((
a
)
+
KERNBASE
)
;
}
#endif
#define V2P(a) ((
uint) a
- KERNBASE)
#define P2V(a) ((
void *) a
+ KERNBASE)
#define V2P(a) ((
(uint) (a))
- KERNBASE)
#define P2V(a) ((
(void *) (a))
+ KERNBASE)
#define V2P_WO(x) ((x) - KERNBASE) // same as V2P, but without casts
#define P2V_WO(x) ((x) + KERNBASE) // same as V2P, but without casts
runoff
浏览文件 @
0ca1c040
...
...
@@ -223,11 +223,17 @@ awk '
grep
Pages: all.ps
# if we have the nice font, use it
nicefont
=
../LucidaSans-Typewriter83
if
[
-f
$nicefont
]
nicefont
=
LucidaSans-Typewriter83
if
[
!
-f
../
$nicefont
]
then
if
git cat-file blob font:
$nicefont
>
../
$nicefont
~
;
then
mv
../
$nicefont
~ ../
$nicefont
fi
fi
if
[
-f
../
$nicefont
]
then
echo
nicefont
(
sed
1q all.ps
;
cat
$nicefont
;
sed
'1d; s/Courier/LucidaSans-Typewriter83/'
all.ps
)
>
allf.ps
(
sed
1q all.ps
;
cat
../
$nicefont
;
sed
"1d; s/Courier/
$nicefont
/"
all.ps
)
>
allf.ps
else
echo
ugly font!
cp
all.ps allf.ps
...
...
vm.c
浏览文件 @
0ca1c040
...
...
@@ -43,7 +43,7 @@ seginit(void)
// that corresponds to virtual address va. If alloc!=0,
// create any required page table pages.
static
pte_t
*
walkpgdir
(
pde_t
*
pgdir
,
const
void
*
va
,
char
*
(
*
alloc
)(
void
)
)
walkpgdir
(
pde_t
*
pgdir
,
const
void
*
va
,
int
alloc
)
{
pde_t
*
pde
;
pte_t
*
pgtab
;
...
...
@@ -52,7 +52,7 @@ walkpgdir(pde_t *pgdir, const void *va, char* (*alloc)(void))
if
(
*
pde
&
PTE_P
){
pgtab
=
(
pte_t
*
)
p2v
(
PTE_ADDR
(
*
pde
));
}
else
{
if
(
!
alloc
||
(
pgtab
=
(
pte_t
*
)
alloc
())
==
0
)
if
(
!
alloc
||
(
pgtab
=
(
pte_t
*
)
k
alloc
())
==
0
)
return
0
;
// Make sure all those PTE_P bits are zero.
memset
(
pgtab
,
0
,
PGSIZE
);
...
...
@@ -68,8 +68,7 @@ walkpgdir(pde_t *pgdir, const void *va, char* (*alloc)(void))
// physical addresses starting at pa. va and size might not
// be page-aligned.
static
int
mappages
(
pde_t
*
pgdir
,
void
*
va
,
uint
size
,
uint
pa
,
int
perm
,
char
*
(
*
alloc
)(
void
))
mappages
(
pde_t
*
pgdir
,
void
*
va
,
uint
size
,
uint
pa
,
int
perm
)
{
char
*
a
,
*
last
;
pte_t
*
pte
;
...
...
@@ -77,7 +76,7 @@ mappages(pde_t *pgdir, void *va, uint size, uint pa,
a
=
(
char
*
)
PGROUNDDOWN
((
uint
)
va
);
last
=
(
char
*
)
PGROUNDDOWN
(((
uint
)
va
)
+
size
-
1
);
for
(;;){
if
((
pte
=
walkpgdir
(
pgdir
,
a
,
alloc
))
==
0
)
if
((
pte
=
walkpgdir
(
pgdir
,
a
,
1
))
==
0
)
return
-
1
;
if
(
*
pte
&
PTE_P
)
panic
(
"remap"
);
...
...
@@ -90,53 +89,56 @@ mappages(pde_t *pgdir, void *va, uint size, uint pa,
return
0
;
}
// The
mappings from logical to virtual are one to one (i.e.,
//
segmentation doesn't do anything). There is one page table per
//
process, plus one that's used when a CPU is not running any process
//
(kpgdir). A user process uses the same page table as the kernel; the
//
page protection bits prevent it from accessing kernel memory
.
// The
re is one page table per process, plus one that's used when
//
a CPU is not running any process (kpgdir). The kernel uses the
//
current process's page table during system calls and interrupts;
//
page protection bits prevent user code from using the kernel's
//
mappings
.
//
// setupkvm() and exec() set up every page table like this:
// 0..KERNBASE: user memory (text+data+stack+heap), mapped to some free
// phys memory
//
// 0..KERNBASE: user memory (text+data+stack+heap), mapped to
// phys memory allocated by the kernel
// KERNBASE..KERNBASE+EXTMEM: mapped to 0..EXTMEM (for I/O space)
// KERNBASE+EXTMEM..
KERNBASE+end: mapped to EXTMEM..end kernel,
//
w. no write permission
//
KERNBASE+end..KERBASE+PHYSTOP: mapped to end
..PHYSTOP,
// rw data + free memory
// KERNBASE+EXTMEM..
data: mapped to EXTMEM..V2P(data)
//
for the kernel's instructions and r/o data
//
data..KERNBASE+PHYSTOP: mapped to V2P(data)
..PHYSTOP,
// rw data + free
physical
memory
// 0xfe000000..0: mapped direct (devices such as ioapic)
//
// The kernel allocates memory for its heap and for user memory
// between KERNBASE+end and the end of physical memory (PHYSTOP).
// The user program sits in the bottom of the address space, and the
// kernel at the top at KERNBASE.
// The kernel allocates physical memory for its heap and for user memory
// between V2P(end) and the end of physical memory (PHYSTOP)
// (directly addressable from end..P2V(PHYSTOP)).
// This table defines the kernel's mappings, which are present in
// every process's page table.
static
struct
kmap
{
void
*
virt
;
uint
phys_start
;
uint
phys_end
;
int
perm
;
}
kmap
[]
=
{
{
P2V
(
0
),
0
,
1024
*
1024
,
PTE_W
},
// I/O space
{
(
void
*
)
KERNLINK
,
V2P
(
KERNLINK
),
V2P
(
data
),
0
},
// kernel text+rodata
{
data
,
V2P
(
data
),
PHYSTOP
,
PTE_W
},
// kernel data, memory
{
(
void
*
)
DEVSPACE
,
DEVSPACE
,
0
,
PTE_W
},
// more devices
{
(
void
*
)
KERNBASE
,
0
,
EXTMEM
,
PTE_W
},
// I/O space
{
(
void
*
)
KERNLINK
,
V2P
(
KERNLINK
),
V2P
(
data
),
0
},
// kernel text+rodata
{
(
void
*
)
data
,
V2P
(
data
),
PHYSTOP
,
PTE_W
},
// kernel data, memory
{
(
void
*
)
DEVSPACE
,
DEVSPACE
,
0
,
PTE_W
},
// more devices
};
// Set up kernel part of a page table.
pde_t
*
setupkvm
(
char
*
(
*
alloc
)(
void
)
)
setupkvm
()
{
pde_t
*
pgdir
;
struct
kmap
*
k
;
if
((
pgdir
=
(
pde_t
*
)
alloc
())
==
0
)
if
((
pgdir
=
(
pde_t
*
)
k
alloc
())
==
0
)
return
0
;
memset
(
pgdir
,
0
,
PGSIZE
);
if
(
p2v
(
PHYSTOP
)
>
(
void
*
)
DEVSPACE
)
panic
(
"PHYSTOP too high"
);
for
(
k
=
kmap
;
k
<
&
kmap
[
NELEM
(
kmap
)];
k
++
)
if
(
mappages
(
pgdir
,
k
->
virt
,
k
->
phys_end
-
k
->
phys_start
,
(
uint
)
k
->
phys_start
,
k
->
perm
,
alloc
)
<
0
)
(
uint
)
k
->
phys_start
,
k
->
perm
)
<
0
)
return
0
;
return
pgdir
;
}
...
...
@@ -146,7 +148,7 @@ setupkvm(char* (*alloc)(void))
void
kvmalloc
(
void
)
{
kpgdir
=
setupkvm
(
enter_alloc
);
kpgdir
=
setupkvm
();
switchkvm
();
}
...
...
@@ -185,7 +187,7 @@ inituvm(pde_t *pgdir, char *init, uint sz)
panic
(
"inituvm: more than a page"
);
mem
=
kalloc
();
memset
(
mem
,
0
,
PGSIZE
);
mappages
(
pgdir
,
0
,
PGSIZE
,
v2p
(
mem
),
PTE_W
|
PTE_U
,
kalloc
);
mappages
(
pgdir
,
0
,
PGSIZE
,
v2p
(
mem
),
PTE_W
|
PTE_U
);
memmove
(
mem
,
init
,
sz
);
}
...
...
@@ -235,7 +237,7 @@ allocuvm(pde_t *pgdir, uint oldsz, uint newsz)
return
0
;
}
memset
(
mem
,
0
,
PGSIZE
);
mappages
(
pgdir
,
(
char
*
)
a
,
PGSIZE
,
v2p
(
mem
),
PTE_W
|
PTE_U
,
kalloc
);
mappages
(
pgdir
,
(
char
*
)
a
,
PGSIZE
,
v2p
(
mem
),
PTE_W
|
PTE_U
);
}
return
newsz
;
}
...
...
@@ -312,7 +314,7 @@ copyuvm(pde_t *pgdir, uint sz)
uint
pa
,
i
;
char
*
mem
;
if
((
d
=
setupkvm
(
kalloc
))
==
0
)
if
((
d
=
setupkvm
())
==
0
)
return
0
;
for
(
i
=
0
;
i
<
sz
;
i
+=
PGSIZE
){
if
((
pte
=
walkpgdir
(
pgdir
,
(
void
*
)
i
,
0
))
==
0
)
...
...
@@ -323,7 +325,7 @@ copyuvm(pde_t *pgdir, uint sz)
if
((
mem
=
kalloc
())
==
0
)
goto
bad
;
memmove
(
mem
,
(
char
*
)
p2v
(
pa
),
PGSIZE
);
if
(
mappages
(
d
,
(
void
*
)
i
,
PGSIZE
,
v2p
(
mem
),
PTE_W
|
PTE_U
,
kalloc
)
<
0
)
if
(
mappages
(
d
,
(
void
*
)
i
,
PGSIZE
,
v2p
(
mem
),
PTE_W
|
PTE_U
)
<
0
)
goto
bad
;
}
return
d
;
...
...
编写
预览
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论