Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
X
xv6-public
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
统计图
问题
0
问题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
银宸时代
OS Lab Group
奖励实验
xv6-public
提交
40889627
提交
40889627
7月 02, 2010
创建
作者:
Frans Kaashoek
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Initial version of single-cpu xv6 with page tables
上级
b7a517f2
隐藏空白字符变更
内嵌
并排
正在显示
22 个修改的文件
包含
307 行增加
和
152 行删除
+307
-152
Makefile
Makefile
+3
-2
bootasm.S
bootasm.S
+1
-1
defs.h
defs.h
+19
-3
exec.c
exec.c
+40
-50
file.c
file.c
+0
-1
forktest.c
forktest.c
+5
-3
ide.c
ide.c
+2
-1
kalloc.c
kalloc.c
+25
-11
lapic.c
lapic.c
+1
-0
main.c
main.c
+20
-6
mmu.h
mmu.h
+88
-0
mp.c
mp.c
+1
-0
param.h
param.h
+1
-1
proc.c
proc.c
+15
-57
proc.h
proc.h
+1
-1
sh.c
sh.c
+3
-2
spinlock.c
spinlock.c
+1
-1
swtch.S
swtch.S
+8
-0
syscall.c
syscall.c
+11
-5
sysfile.c
sysfile.c
+2
-3
trap.c
trap.c
+5
-4
x86.h
x86.h
+55
-0
没有找到文件。
Makefile
浏览文件 @
40889627
...
@@ -25,12 +25,13 @@ OBJS = \
...
@@ -25,12 +25,13 @@ OBJS = \
trap.o
\
trap.o
\
uart.o
\
uart.o
\
vectors.o
\
vectors.o
\
vm.o
\
# Cross-compiling (e.g., on Mac OS X)
# Cross-compiling (e.g., on Mac OS X)
#
TOOLPREFIX = i386-jos-elf-
TOOLPREFIX
=
i386-jos-elf-
# Using native tools (e.g., on X86 Linux)
# Using native tools (e.g., on X86 Linux)
TOOLPREFIX
=
#
TOOLPREFIX =
CC
=
$(TOOLPREFIX)
gcc
CC
=
$(TOOLPREFIX)
gcc
AS
=
$(TOOLPREFIX)
gas
AS
=
$(TOOLPREFIX)
gas
...
...
bootasm.S
浏览文件 @
40889627
...
@@ -88,5 +88,5 @@ gdt:
...
@@ -88,5 +88,5 @@ gdt:
SEG_ASM(STA_W, 0x0, 0xffffffff) # data seg
SEG_ASM(STA_W, 0x0, 0xffffffff) # data seg
gdtdesc:
gdtdesc:
.word (gdtdesc - gdt - 1)
# sizeof(gdt) - 1
.word (gdtdesc - gdt - 1) # sizeof(gdt) - 1
.long gdt # address gdt
.long gdt # address gdt
defs.h
浏览文件 @
40889627
...
@@ -60,9 +60,10 @@ extern uchar ioapicid;
...
@@ -60,9 +60,10 @@ extern uchar ioapicid;
void
ioapicinit
(
void
);
void
ioapicinit
(
void
);
// kalloc.c
// kalloc.c
extern
int
nfreemem
;
char
*
kalloc
(
int
);
char
*
kalloc
(
int
);
void
kfree
(
char
*
,
int
);
void
kfree
(
char
*
,
int
);
void
kinit
(
void
);
void
kinit
(
char
*
,
uint
);
// kbd.c
// kbd.c
void
kbdintr
(
void
);
void
kbdintr
(
void
);
...
@@ -101,8 +102,6 @@ int kill(int);
...
@@ -101,8 +102,6 @@ int kill(int);
void
pinit
(
void
);
void
pinit
(
void
);
void
procdump
(
void
);
void
procdump
(
void
);
void
scheduler
(
void
)
__attribute__
((
noreturn
));
void
scheduler
(
void
)
__attribute__
((
noreturn
));
void
ksegment
(
void
);
void
usegment
(
void
);
void
sleep
(
void
*
,
struct
spinlock
*
);
void
sleep
(
void
*
,
struct
spinlock
*
);
void
userinit
(
void
);
void
userinit
(
void
);
int
wait
(
void
);
int
wait
(
void
);
...
@@ -111,6 +110,7 @@ void yield(void);
...
@@ -111,6 +110,7 @@ void yield(void);
// swtch.S
// swtch.S
void
swtch
(
struct
context
**
,
struct
context
*
);
void
swtch
(
struct
context
**
,
struct
context
*
);
void
jstack
(
uint
);
// spinlock.c
// spinlock.c
void
acquire
(
struct
spinlock
*
);
void
acquire
(
struct
spinlock
*
);
...
@@ -152,6 +152,22 @@ void uartinit(void);
...
@@ -152,6 +152,22 @@ void uartinit(void);
void
uartintr
(
void
);
void
uartintr
(
void
);
void
uartputc
(
int
);
void
uartputc
(
int
);
// vm.c
#define PGROUNDUP(sz) ((sz+PGSIZE-1) & ~(PGSIZE-1))
void
pminit
(
void
);
void
swkstack
(
void
);
void
vminit
(
void
);
void
printpgdir
(
uint
*
);
uint
*
setupkvm
(
void
);
// XXX need pde_t*
char
*
uva2ka
(
uint
*
,
char
*
);
int
allocuvm
(
uint
*
,
char
*
,
uint
);
// XXX need pde_t*
void
freevm
(
uint
*
);
void
inituvm
(
uint
*
,
char
*
,
char
*
,
uint
);
int
loaduvm
(
uint
*
,
char
*
,
struct
inode
*
ip
,
uint
,
uint
);
uint
*
copyuvm
(
uint
*
,
uint
);
void
ksegment
(
void
);
void
loadvm
(
struct
proc
*
);
// number of elements in fixed-size array
// number of elements in fixed-size array
#define NELEM(x) (sizeof(x)/sizeof((x)[0]))
#define NELEM(x) (sizeof(x)/sizeof((x)[0]))
exec.c
浏览文件 @
40889627
...
@@ -11,12 +11,13 @@ exec(char *path, char **argv)
...
@@ -11,12 +11,13 @@ exec(char *path, char **argv)
{
{
char
*
mem
,
*
s
,
*
last
;
char
*
mem
,
*
s
,
*
last
;
int
i
,
argc
,
arglen
,
len
,
off
;
int
i
,
argc
,
arglen
,
len
,
off
;
uint
sz
,
sp
,
argp
;
uint
sz
,
sp
,
spoffset
,
argp
;
struct
elfhdr
elf
;
struct
elfhdr
elf
;
struct
inode
*
ip
;
struct
inode
*
ip
;
struct
proghdr
ph
;
struct
proghdr
ph
;
pde_t
*
pgdir
,
*
oldpgdir
;
mem
=
0
;
pgdir
=
0
;
sz
=
0
;
sz
=
0
;
if
((
ip
=
namei
(
path
))
==
0
)
if
((
ip
=
namei
(
path
))
==
0
)
...
@@ -29,37 +30,8 @@ exec(char *path, char **argv)
...
@@ -29,37 +30,8 @@ exec(char *path, char **argv)
if
(
elf
.
magic
!=
ELF_MAGIC
)
if
(
elf
.
magic
!=
ELF_MAGIC
)
goto
bad
;
goto
bad
;
// Compute memory size of new process.
if
(
!
(
pgdir
=
setupkvm
()))
// Program segments.
for
(
i
=
0
,
off
=
elf
.
phoff
;
i
<
elf
.
phnum
;
i
++
,
off
+=
sizeof
(
ph
)){
if
(
readi
(
ip
,
(
char
*
)
&
ph
,
off
,
sizeof
(
ph
))
!=
sizeof
(
ph
))
goto
bad
;
if
(
ph
.
type
!=
ELF_PROG_LOAD
)
continue
;
if
(
ph
.
memsz
<
ph
.
filesz
)
goto
bad
;
sz
+=
ph
.
memsz
;
}
// Arguments.
arglen
=
0
;
for
(
argc
=
0
;
argv
[
argc
];
argc
++
)
arglen
+=
strlen
(
argv
[
argc
])
+
1
;
arglen
=
(
arglen
+
3
)
&
~
3
;
sz
+=
arglen
;
sz
+=
4
*
(
argc
+
1
);
// argv data
sz
+=
4
;
// argv
sz
+=
4
;
// argc
// Stack.
sz
+=
PAGE
;
// Allocate program memory.
sz
=
(
sz
+
PAGE
-
1
)
&
~
(
PAGE
-
1
);
mem
=
kalloc
(
sz
);
if
(
mem
==
0
)
goto
bad
;
goto
bad
;
memset
(
mem
,
0
,
sz
);
// Load program into memory.
// Load program into memory.
for
(
i
=
0
,
off
=
elf
.
phoff
;
i
<
elf
.
phnum
;
i
++
,
off
+=
sizeof
(
ph
)){
for
(
i
=
0
,
off
=
elf
.
phoff
;
i
<
elf
.
phnum
;
i
++
,
off
+=
sizeof
(
ph
)){
...
@@ -67,37 +39,48 @@ exec(char *path, char **argv)
...
@@ -67,37 +39,48 @@ exec(char *path, char **argv)
goto
bad
;
goto
bad
;
if
(
ph
.
type
!=
ELF_PROG_LOAD
)
if
(
ph
.
type
!=
ELF_PROG_LOAD
)
continue
;
continue
;
if
(
ph
.
va
+
ph
.
memsz
<
ph
.
va
||
ph
.
va
+
ph
.
memsz
>
sz
)
goto
bad
;
if
(
ph
.
memsz
<
ph
.
filesz
)
if
(
ph
.
memsz
<
ph
.
filesz
)
goto
bad
;
goto
bad
;
if
(
readi
(
ip
,
mem
+
ph
.
va
,
ph
.
offset
,
ph
.
filesz
)
!=
ph
.
filesz
)
if
(
!
allocuvm
(
pgdir
,
(
char
*
)
ph
.
va
,
ph
.
memsz
))
goto
bad
;
sz
+=
PGROUNDUP
(
ph
.
memsz
);
if
(
!
loaduvm
(
pgdir
,
(
char
*
)
ph
.
va
,
ip
,
ph
.
offset
,
ph
.
filesz
))
goto
bad
;
goto
bad
;
memset
(
mem
+
ph
.
va
+
ph
.
filesz
,
0
,
ph
.
memsz
-
ph
.
filesz
);
}
}
iunlockput
(
ip
);
iunlockput
(
ip
);
// Initialize stack.
// Allocate and initialize stack at sz
if
(
!
allocuvm
(
pgdir
,
(
char
*
)
sz
,
PGSIZE
))
goto
bad
;
mem
=
uva2ka
(
pgdir
,
(
char
*
)
sz
);
spoffset
=
sz
;
sz
+=
PGSIZE
;
arglen
=
0
;
for
(
argc
=
0
;
argv
[
argc
];
argc
++
)
arglen
+=
strlen
(
argv
[
argc
])
+
1
;
arglen
=
(
arglen
+
3
)
&
~
3
;
sp
=
sz
;
sp
=
sz
;
argp
=
sz
-
arglen
-
4
*
(
argc
+
1
);
argp
=
sz
-
arglen
-
4
*
(
argc
+
1
);
// Copy argv strings and pointers to stack.
// Copy argv strings and pointers to stack.
*
(
uint
*
)(
mem
+
argp
+
4
*
argc
)
=
0
;
// argv[argc]
*
(
uint
*
)(
mem
+
argp
-
spoffset
+
4
*
argc
)
=
0
;
// argv[argc]
for
(
i
=
argc
-
1
;
i
>=
0
;
i
--
){
for
(
i
=
argc
-
1
;
i
>=
0
;
i
--
){
len
=
strlen
(
argv
[
i
])
+
1
;
len
=
strlen
(
argv
[
i
])
+
1
;
sp
-=
len
;
sp
-=
len
;
memmove
(
mem
+
sp
,
argv
[
i
],
len
);
memmove
(
mem
+
sp
-
spoffset
,
argv
[
i
],
len
);
*
(
uint
*
)(
mem
+
argp
+
4
*
i
)
=
sp
;
// argv[i]
*
(
uint
*
)(
mem
+
argp
-
spoffset
+
4
*
i
)
=
sp
;
// argv[i]
}
}
// Stack frame for main(argc, argv), below arguments.
// Stack frame for main(argc, argv), below arguments.
sp
=
argp
;
sp
=
argp
;
sp
-=
4
;
sp
-=
4
;
*
(
uint
*
)(
mem
+
sp
)
=
argp
;
*
(
uint
*
)(
mem
+
sp
-
spoffset
)
=
argp
;
sp
-=
4
;
sp
-=
4
;
*
(
uint
*
)(
mem
+
sp
)
=
argc
;
*
(
uint
*
)(
mem
+
sp
-
spoffset
)
=
argc
;
sp
-=
4
;
sp
-=
4
;
*
(
uint
*
)(
mem
+
sp
)
=
0xffffffff
;
// fake return pc
*
(
uint
*
)(
mem
+
sp
-
spoffset
)
=
0xffffffff
;
// fake return pc
// Save program name for debugging.
// Save program name for debugging.
for
(
last
=
s
=
path
;
*
s
;
s
++
)
for
(
last
=
s
=
path
;
*
s
;
s
++
)
...
@@ -105,18 +88,25 @@ exec(char *path, char **argv)
...
@@ -105,18 +88,25 @@ exec(char *path, char **argv)
last
=
s
+
1
;
last
=
s
+
1
;
safestrcpy
(
proc
->
name
,
last
,
sizeof
(
proc
->
name
));
safestrcpy
(
proc
->
name
,
last
,
sizeof
(
proc
->
name
));
// Commit to the
new
image.
// Commit to the
user
image.
kfree
(
proc
->
mem
,
proc
->
sz
)
;
oldpgdir
=
proc
->
pgdir
;
proc
->
mem
=
mem
;
proc
->
pgdir
=
pgdir
;
proc
->
sz
=
sz
;
proc
->
sz
=
sz
;
proc
->
tf
->
eip
=
elf
.
entry
;
// main
proc
->
tf
->
eip
=
elf
.
entry
;
// main
proc
->
tf
->
esp
=
sp
;
proc
->
tf
->
esp
=
sp
;
usegment
();
// printstack();
loadvm
(
proc
);
freevm
(
oldpgdir
);
// printstack();
return
0
;
return
0
;
bad:
bad:
if
(
mem
)
freevm
(
pgdir
);
kfree
(
mem
,
sz
);
iunlockput
(
ip
);
iunlockput
(
ip
);
return
-
1
;
return
-
1
;
}
}
file.c
浏览文件 @
40889627
...
@@ -116,7 +116,6 @@ filewrite(struct file *f, char *addr, int n)
...
@@ -116,7 +116,6 @@ filewrite(struct file *f, char *addr, int n)
return
pipewrite
(
f
->
pipe
,
addr
,
n
);
return
pipewrite
(
f
->
pipe
,
addr
,
n
);
if
(
f
->
type
==
FD_INODE
){
if
(
f
->
type
==
FD_INODE
){
ilock
(
f
->
ip
);
ilock
(
f
->
ip
);
cprintf
(
"filewrite: %d
\n
"
,
n
);
if
((
r
=
writei
(
f
->
ip
,
addr
,
f
->
off
,
n
))
>
0
)
if
((
r
=
writei
(
f
->
ip
,
addr
,
f
->
off
,
n
))
>
0
)
f
->
off
+=
r
;
f
->
off
+=
r
;
iunlock
(
f
->
ip
);
iunlock
(
f
->
ip
);
...
...
forktest.c
浏览文件 @
40889627
...
@@ -5,6 +5,8 @@
...
@@ -5,6 +5,8 @@
#include "stat.h"
#include "stat.h"
#include "user.h"
#include "user.h"
#define N 1000
void
void
printf
(
int
fd
,
char
*
s
,
...)
printf
(
int
fd
,
char
*
s
,
...)
{
{
...
@@ -18,7 +20,7 @@ forktest(void)
...
@@ -18,7 +20,7 @@ forktest(void)
printf
(
1
,
"fork test
\n
"
);
printf
(
1
,
"fork test
\n
"
);
for
(
n
=
0
;
n
<
1000
;
n
++
){
for
(
n
=
0
;
n
<
N
;
n
++
){
pid
=
fork
();
pid
=
fork
();
if
(
pid
<
0
)
if
(
pid
<
0
)
break
;
break
;
...
@@ -26,8 +28,8 @@ forktest(void)
...
@@ -26,8 +28,8 @@ forktest(void)
exit
();
exit
();
}
}
if
(
n
==
1000
){
if
(
n
==
N
){
printf
(
1
,
"fork claimed to work
1000 times!
\n
"
);
printf
(
1
,
"fork claimed to work
N times!
\n
"
,
N
);
exit
();
exit
();
}
}
...
...
ide.c
浏览文件 @
40889627
...
@@ -147,8 +147,9 @@ iderw(struct buf *b)
...
@@ -147,8 +147,9 @@ iderw(struct buf *b)
// Wait for request to finish.
// Wait for request to finish.
// Assuming will not sleep too long: ignore proc->killed.
// Assuming will not sleep too long: ignore proc->killed.
while
((
b
->
flags
&
(
B_VALID
|
B_DIRTY
))
!=
B_VALID
)
while
((
b
->
flags
&
(
B_VALID
|
B_DIRTY
))
!=
B_VALID
)
{
sleep
(
b
,
&
idelock
);
sleep
(
b
,
&
idelock
);
}
release
(
&
idelock
);
release
(
&
idelock
);
}
}
kalloc.c
浏览文件 @
40889627
...
@@ -8,6 +8,7 @@
...
@@ -8,6 +8,7 @@
#include "types.h"
#include "types.h"
#include "defs.h"
#include "defs.h"
#include "param.h"
#include "param.h"
#include "mmu.h"
#include "spinlock.h"
#include "spinlock.h"
struct
run
{
struct
run
{
...
@@ -20,21 +21,28 @@ struct {
...
@@ -20,21 +21,28 @@ struct {
struct
run
*
freelist
;
struct
run
*
freelist
;
}
kmem
;
}
kmem
;
int
nfreemem
;
static
void
printfreelist
(
void
)
{
struct
run
*
r
,
**
rp
;
cprintf
(
"freelist:
\n
"
);
for
(
rp
=&
kmem
.
freelist
;
(
r
=*
rp
)
!=
0
;
rp
=&
r
->
next
){
cprintf
(
"0x%x %d=0x%x
\n
"
,
r
,
r
->
len
,
r
->
len
);
}
}
// Initialize free list of physical pages.
// Initialize free list of physical pages.
// This code cheats by just considering one megabyte of
// This code cheats by just considering one megabyte of
// pages after end. Real systems would determine the
// pages after end. Real systems would determine the
// amount of memory available in the system and use it all.
// amount of memory available in the system and use it all.
void
void
kinit
(
void
)
kinit
(
char
*
p
,
uint
len
)
{
{
extern
char
end
[];
uint
len
;
char
*
p
;
initlock
(
&
kmem
.
lock
,
"kmem"
);
initlock
(
&
kmem
.
lock
,
"kmem"
);
p
=
(
char
*
)(((
uint
)
end
+
PAGE
)
&
~
(
PAGE
-
1
));
cprintf
(
"end 0x%x free = %d(0x%x)
\n
"
,
p
,
len
);
len
=
256
*
PAGE
;
// assume computer has 256 pages of RAM, 1 MB
nfreemem
=
0
;
cprintf
(
"mem = %d
\n
"
,
len
);
kfree
(
p
,
len
);
kfree
(
p
,
len
);
}
}
...
@@ -47,19 +55,23 @@ kfree(char *v, int len)
...
@@ -47,19 +55,23 @@ kfree(char *v, int len)
{
{
struct
run
*
r
,
*
rend
,
**
rp
,
*
p
,
*
pend
;
struct
run
*
r
,
*
rend
,
**
rp
,
*
p
,
*
pend
;
if
(
len
<=
0
||
len
%
P
AG
E
)
if
(
len
<=
0
||
len
%
P
GSIZ
E
)
panic
(
"kfree"
);
panic
(
"kfree"
);
// Fill with junk to catch dangling refs.
// Fill with junk to catch dangling refs.
memset
(
v
,
1
,
len
);
memset
(
v
,
1
,
len
);
acquire
(
&
kmem
.
lock
);
acquire
(
&
kmem
.
lock
);
nfreemem
+=
len
;
p
=
(
struct
run
*
)
v
;
p
=
(
struct
run
*
)
v
;
pend
=
(
struct
run
*
)(
v
+
len
);
pend
=
(
struct
run
*
)(
v
+
len
);
for
(
rp
=&
kmem
.
freelist
;
(
r
=*
rp
)
!=
0
&&
r
<=
pend
;
rp
=&
r
->
next
){
for
(
rp
=&
kmem
.
freelist
;
(
r
=*
rp
)
!=
0
&&
r
<=
pend
;
rp
=&
r
->
next
){
rend
=
(
struct
run
*
)((
char
*
)
r
+
r
->
len
);
rend
=
(
struct
run
*
)((
char
*
)
r
+
r
->
len
);
if
(
r
<=
p
&&
p
<
rend
)
if
(
r
<=
p
&&
p
<
rend
)
{
cprintf
(
"freeing a free page: r = 0x%x p = 0x%x rend = 0x%x
\n
"
,
r
,
p
,
rend
);
panic
(
"freeing free page"
);
panic
(
"freeing free page"
);
}
if
(
rend
==
p
){
// r before p: expand r to include p
if
(
rend
==
p
){
// r before p: expand r to include p
r
->
len
+=
len
;
r
->
len
+=
len
;
if
(
r
->
next
&&
r
->
next
==
pend
){
// r now next to r->next?
if
(
r
->
next
&&
r
->
next
==
pend
){
// r now next to r->next?
...
@@ -93,7 +105,7 @@ kalloc(int n)
...
@@ -93,7 +105,7 @@ kalloc(int n)
char
*
p
;
char
*
p
;
struct
run
*
r
,
**
rp
;
struct
run
*
r
,
**
rp
;
if
(
n
%
P
AG
E
||
n
<=
0
)
if
(
n
%
P
GSIZ
E
||
n
<=
0
)
panic
(
"kalloc"
);
panic
(
"kalloc"
);
acquire
(
&
kmem
.
lock
);
acquire
(
&
kmem
.
lock
);
...
@@ -103,6 +115,7 @@ kalloc(int n)
...
@@ -103,6 +115,7 @@ kalloc(int n)
p
=
(
char
*
)
r
+
r
->
len
;
p
=
(
char
*
)
r
+
r
->
len
;
if
(
r
->
len
==
0
)
if
(
r
->
len
==
0
)
*
rp
=
r
->
next
;
*
rp
=
r
->
next
;
nfreemem
-=
n
;
release
(
&
kmem
.
lock
);
release
(
&
kmem
.
lock
);
return
p
;
return
p
;
}
}
...
@@ -112,3 +125,4 @@ kalloc(int n)
...
@@ -112,3 +125,4 @@ kalloc(int n)
cprintf
(
"kalloc: out of memory
\n
"
);
cprintf
(
"kalloc: out of memory
\n
"
);
return
0
;
return
0
;
}
}
lapic.c
浏览文件 @
40889627
...
@@ -48,6 +48,7 @@ lapicw(int index, int value)
...
@@ -48,6 +48,7 @@ lapicw(int index, int value)
void
void
lapicinit
(
int
c
)
lapicinit
(
int
c
)
{
{
cprintf
(
"lapicinit: %d 0x%x
\n
"
,
c
,
lapic
);
if
(
!
lapic
)
if
(
!
lapic
)
return
;
return
;
...
...
main.c
浏览文件 @
40889627
...
@@ -19,20 +19,27 @@ main(void)
...
@@ -19,20 +19,27 @@ main(void)
ioapicinit
();
// another interrupt controller
ioapicinit
();
// another interrupt controller
consoleinit
();
// I/O devices & their interrupts
consoleinit
();
// I/O devices & their interrupts
uartinit
();
// serial port
uartinit
();
// serial port
cprintf
(
"cpus %p cpu %p
\n
"
,
cpus
,
cpu
);
pminit
();
// physical memory for kernel
cprintf
(
"
\n
cpu%d: starting xv6
\n\n
"
,
cpu
->
id
);
jkstack
();
// Jump to mainc on a proper-allocated kernel stack
}
kinit
();
// physical memory allocator
void
mainc
(
void
)
{
cprintf
(
"cpus %p cpu %p
\n
"
,
cpus
,
cpu
);
cprintf
(
"
\n
cpu%d: starting xv6
\n\n
"
,
cpu
->
id
);
vminit
();
// virtual memory
pinit
();
// process table
pinit
();
// process table
tvinit
();
// trap vectors
tvinit
();
// trap vectors
binit
();
// buffer cache
binit
();
// buffer cache
fileinit
();
// file table
fileinit
();
// file table
iinit
();
// inode cache
iinit
();
// inode cache
ideinit
();
// disk
ideinit
();
// disk
cprintf
(
"ismp: %d
\n
"
,
ismp
);
if
(
!
ismp
)
if
(
!
ismp
)
timerinit
();
// uniprocessor timer
timerinit
();
// uniprocessor timer
userinit
();
// first user process
userinit
();
// first user process
bootothers
();
// start other processors
// bootothers(); // start other processors XXX fix where to boot from
// Finish setting up this processor in mpmain.
// Finish setting up this processor in mpmain.
mpmain
();
mpmain
();
...
@@ -43,9 +50,12 @@ cprintf("cpus %p cpu %p\n", cpus, cpu);
...
@@ -43,9 +50,12 @@ cprintf("cpus %p cpu %p\n", cpus, cpu);
static
void
static
void
mpmain
(
void
)
mpmain
(
void
)
{
{
if
(
cpunum
()
!=
mpbcpu
())
if
(
cpunum
()
!=
mpbcpu
())
{
ksegment
();
cprintf
(
"other cpu
\n
"
);
vminit
();
lapicinit
(
cpunum
());
lapicinit
(
cpunum
());
ksegment
();
}
cprintf
(
"cpu%d: mpmain
\n
"
,
cpu
->
id
);
cprintf
(
"cpu%d: mpmain
\n
"
,
cpu
->
id
);
idtinit
();
idtinit
();
xchg
(
&
cpu
->
booted
,
1
);
xchg
(
&
cpu
->
booted
,
1
);
...
@@ -74,11 +84,15 @@ bootothers(void)
...
@@ -74,11 +84,15 @@ bootothers(void)
stack
=
kalloc
(
KSTACKSIZE
);
stack
=
kalloc
(
KSTACKSIZE
);
*
(
void
**
)(
code
-
4
)
=
stack
+
KSTACKSIZE
;
*
(
void
**
)(
code
-
4
)
=
stack
+
KSTACKSIZE
;
*
(
void
**
)(
code
-
8
)
=
mpmain
;
*
(
void
**
)(
code
-
8
)
=
mpmain
;
cprintf
(
"lapicstartap
\n
"
);
lapicstartap
(
c
->
id
,
(
uint
)
code
);
lapicstartap
(
c
->
id
,
(
uint
)
code
);
cprintf
(
"lapicstartap done
\n
"
);
// Wait for cpu to get through bootstrap.
// Wait for cpu to get through bootstrap.
while
(
c
->
booted
==
0
)
while
(
c
->
booted
==
0
)
;
;
cprintf
(
"lapicstartap booted
\n
"
);
}
}
}
}
mmu.h
浏览文件 @
40889627
...
@@ -62,6 +62,8 @@ struct segdesc {
...
@@ -62,6 +62,8 @@ struct segdesc {
#define STA_R 0x2 // Readable (executable segments)
#define STA_R 0x2 // Readable (executable segments)
#define STA_A 0x1 // Accessed
#define STA_A 0x1 // Accessed
//
// System segment type bits
// System segment type bits
#define STS_T16A 0x1 // Available 16-bit TSS
#define STS_T16A 0x1 // Available 16-bit TSS
#define STS_LDT 0x2 // Local Descriptor Table
#define STS_LDT 0x2 // Local Descriptor Table
...
@@ -76,6 +78,92 @@ struct segdesc {
...
@@ -76,6 +78,92 @@ struct segdesc {
#define STS_IG32 0xE // 32-bit Interrupt Gate
#define STS_IG32 0xE // 32-bit Interrupt Gate
#define STS_TG32 0xF // 32-bit Trap Gate
#define STS_TG32 0xF // 32-bit Trap Gate
// A linear address 'la' has a three-part structure as follows:
//
// +--------10------+-------10-------+---------12----------+
// | Page Directory | Page Table | Offset within Page |
// | Index | Index | |
// +----------------+----------------+---------------------+
// \--- PDX(la) --/ \--- PTX(la) --/ \---- PGOFF(la) ----/
// \----------- PPN(la) -----------/
//
// The PDX, PTX, PGOFF, and PPN macros decompose linear addresses as shown.
// To construct a linear address la from PDX(la), PTX(la), and PGOFF(la),
// use PGADDR(PDX(la), PTX(la), PGOFF(la)).
// page number field of address
#define PPN(la) (((uint) (la)) >> PTXSHIFT)
#define VPN(la) PPN(la) // used to index into vpt[]
// page directory index
#define PDX(la) ((((uint) (la)) >> PDXSHIFT) & 0x3FF)
#define VPD(la) PDX(la) // used to index into vpd[]
// page table index
#define PTX(la) ((((uint) (la)) >> PTXSHIFT) & 0x3FF)
// offset in page
#define PGOFF(la) (((uint) (la)) & 0xFFF)
// construct linear address from indexes and offset
#define PGADDR(d, t, o) ((uint) ((d) << PDXSHIFT | (t) << PTXSHIFT | (o)))
// mapping from physical addresses to virtual addresses is the identity one
// (really linear addresses, but we map linear to physical also directly)
#define PADDR(a) ((uint) a)
// 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 PTSIZE (PGSIZE*NPTENTRIES) // bytes mapped by a page directory entry
#define PTSHIFT 22 // log2(PTSIZE)
#define PTXSHIFT 12 // offset of PTX in a linear address
#define PDXSHIFT 22 // offset of PDX in a linear address
// Page table/directory entry flags.
#define PTE_P 0x001 // Present
#define PTE_W 0x002 // Writeable
#define PTE_U 0x004 // User
#define PTE_PWT 0x008 // Write-Through
#define PTE_PCD 0x010 // Cache-Disable
#define PTE_A 0x020 // Accessed
#define PTE_D 0x040 // Dirty
#define PTE_PS 0x080 // Page Size
#define PTE_MBZ 0x180 // Bits must be zero
// The PTE_AVAIL bits aren't used by the kernel or interpreted by the
// hardware, so user processes are allowed to set them arbitrarily.
#define PTE_AVAIL 0xE00 // Available for software use
// Only flags in PTE_USER may be used in system calls.
#define PTE_USER (PTE_AVAIL | PTE_P | PTE_W | PTE_U)
// Address in page table or page directory entry
#define PTE_ADDR(pte) ((uint) (pte) & ~0xFFF)
typedef
uint
pte_t
;
typedef
uint
pde_t
;
// Control Register flags
#define CR0_PE 0x00000001 // Protection Enable
#define CR0_MP 0x00000002 // Monitor coProcessor
#define CR0_EM 0x00000004 // Emulation
#define CR0_TS 0x00000008 // Task Switched
#define CR0_ET 0x00000010 // Extension Type
#define CR0_NE 0x00000020 // Numeric Errror
#define CR0_WP 0x00010000 // Write Protect
#define CR0_AM 0x00040000 // Alignment Mask
#define CR0_NW 0x20000000 // Not Writethrough
#define CR0_CD 0x40000000 // Cache Disable
#define CR0_PG 0x80000000 // Paging
// PAGEBREAK: 40
// PAGEBREAK: 40
// Task state segment format
// Task state segment format
struct
taskstate
{
struct
taskstate
{
...
...
mp.c
浏览文件 @
40889627
...
@@ -39,6 +39,7 @@ mpsearch1(uchar *addr, int len)
...
@@ -39,6 +39,7 @@ mpsearch1(uchar *addr, int len)
{
{
uchar
*
e
,
*
p
;
uchar
*
e
,
*
p
;
cprintf
(
"mpsearch1 0x%x %d
\n
"
,
addr
,
len
);
e
=
addr
+
len
;
e
=
addr
+
len
;
for
(
p
=
addr
;
p
<
e
;
p
+=
sizeof
(
struct
mp
))
for
(
p
=
addr
;
p
<
e
;
p
+=
sizeof
(
struct
mp
))
if
(
memcmp
(
p
,
"_MP_"
,
4
)
==
0
&&
sum
(
p
,
sizeof
(
struct
mp
))
==
0
)
if
(
memcmp
(
p
,
"_MP_"
,
4
)
==
0
&&
sum
(
p
,
sizeof
(
struct
mp
))
==
0
)
...
...
param.h
浏览文件 @
40889627
#define NPROC 64 // maximum number of processes
#define NPROC 64 // maximum number of processes
#define PAGE 4096 //
granularity of user-space memory allocation
#define PAGE 4096 //
conveniently chosen to be equal to PGSIZE
#define KSTACKSIZE PAGE // size of per-process kernel stack
#define KSTACKSIZE PAGE // size of per-process kernel stack
#define NCPU 8 // maximum number of CPUs
#define NCPU 8 // maximum number of CPUs
#define NOFILE 16 // open files per process
#define NOFILE 16 // open files per process
...
...
proc.c
浏览文件 @
40889627
...
@@ -60,39 +60,6 @@ procdump(void)
...
@@ -60,39 +60,6 @@ procdump(void)
}
}
}
}
// Set up CPU's kernel segment descriptors.
// Run once at boot time on each CPU.
void
ksegment
(
void
)
{
struct
cpu
*
c
;
c
=
&
cpus
[
cpunum
()];
c
->
gdt
[
SEG_KCODE
]
=
SEG
(
STA_X
|
STA_R
,
0
,
0x100000
+
64
*
1024
-
1
,
0
);
c
->
gdt
[
SEG_KDATA
]
=
SEG
(
STA_W
,
0
,
0xffffffff
,
0
);
c
->
gdt
[
SEG_KCPU
]
=
SEG
(
STA_W
,
&
c
->
cpu
,
8
,
0
);
lgdt
(
c
->
gdt
,
sizeof
(
c
->
gdt
));
loadgs
(
SEG_KCPU
<<
3
);
// Initialize cpu-local storage.
cpu
=
c
;
proc
=
0
;
}
// Set up CPU's segment descriptors and current process task state.
void
usegment
(
void
)
{
pushcli
();
cpu
->
gdt
[
SEG_UCODE
]
=
SEG
(
STA_X
|
STA_R
,
proc
->
mem
,
proc
->
sz
-
1
,
DPL_USER
);
cpu
->
gdt
[
SEG_UDATA
]
=
SEG
(
STA_W
,
proc
->
mem
,
proc
->
sz
-
1
,
DPL_USER
);
cpu
->
gdt
[
SEG_TSS
]
=
SEG16
(
STS_T32A
,
&
cpu
->
ts
,
sizeof
(
cpu
->
ts
)
-
1
,
0
);
cpu
->
gdt
[
SEG_TSS
].
s
=
0
;
cpu
->
ts
.
ss0
=
SEG_KDATA
<<
3
;
cpu
->
ts
.
esp0
=
(
uint
)
proc
->
kstack
+
KSTACKSIZE
;
ltr
(
SEG_TSS
<<
3
);
popcli
();
}
//PAGEBREAK: 32
//PAGEBREAK: 32
// Look in the process table for an UNUSED proc.
// Look in the process table for an UNUSED proc.
...
@@ -149,20 +116,19 @@ userinit(void)
...
@@ -149,20 +116,19 @@ userinit(void)
p
=
allocproc
();
p
=
allocproc
();
initproc
=
p
;
initproc
=
p
;
if
(
!
(
p
->
pgdir
=
setupkvm
()))
// Initialize memory from initcode.S
panic
(
"userinit: out of memory?"
);
p
->
sz
=
PAGE
;
if
(
!
allocuvm
(
p
->
pgdir
,
0x0
,
(
int
)
_binary_initcode_size
))
p
->
mem
=
kalloc
(
p
->
sz
);
panic
(
"userinit: out of memory?"
);
memset
(
p
->
mem
,
0
,
p
->
sz
);
inituvm
(
p
->
pgdir
,
0x0
,
_binary_initcode_start
,
(
int
)
_binary_initcode_size
);
memmove
(
p
->
mem
,
_binary_initcode_start
,
(
int
)
_binary_initcode_size
);
p
->
sz
=
PGROUNDUP
((
int
)
_binary_initcode_size
);
memset
(
p
->
tf
,
0
,
sizeof
(
*
p
->
tf
));
memset
(
p
->
tf
,
0
,
sizeof
(
*
p
->
tf
));
p
->
tf
->
cs
=
(
SEG_UCODE
<<
3
)
|
DPL_USER
;
p
->
tf
->
cs
=
(
SEG_UCODE
<<
3
)
|
DPL_USER
;
p
->
tf
->
ds
=
(
SEG_UDATA
<<
3
)
|
DPL_USER
;
p
->
tf
->
ds
=
(
SEG_UDATA
<<
3
)
|
DPL_USER
;
p
->
tf
->
es
=
p
->
tf
->
ds
;
p
->
tf
->
es
=
p
->
tf
->
ds
;
p
->
tf
->
ss
=
p
->
tf
->
ds
;
p
->
tf
->
ss
=
p
->
tf
->
ds
;
p
->
tf
->
eflags
=
FL_IF
;
p
->
tf
->
eflags
=
FL_IF
;
p
->
tf
->
esp
=
p
->
sz
;
p
->
tf
->
esp
=
PGSIZE
;
p
->
tf
->
eip
=
0
;
// beginning of initcode.S
p
->
tf
->
eip
=
0
;
// beginning of initcode.S
safestrcpy
(
p
->
name
,
"initcode"
,
sizeof
(
p
->
name
));
safestrcpy
(
p
->
name
,
"initcode"
,
sizeof
(
p
->
name
));
...
@@ -176,17 +142,10 @@ userinit(void)
...
@@ -176,17 +142,10 @@ userinit(void)
int
int
growproc
(
int
n
)
growproc
(
int
n
)
{
{
char
*
newmem
;
if
(
!
allocuvm
(
proc
->
pgdir
,
(
char
*
)
proc
->
sz
,
n
))
newmem
=
kalloc
(
proc
->
sz
+
n
);
if
(
newmem
==
0
)
return
-
1
;
return
-
1
;
memmove
(
newmem
,
proc
->
mem
,
proc
->
sz
);
memset
(
newmem
+
proc
->
sz
,
0
,
n
);
kfree
(
proc
->
mem
,
proc
->
sz
);
proc
->
mem
=
newmem
;
proc
->
sz
+=
n
;
proc
->
sz
+=
n
;
usegment
(
);
loadvm
(
proc
);
return
0
;
return
0
;
}
}
...
@@ -204,14 +163,13 @@ fork(void)
...
@@ -204,14 +163,13 @@ fork(void)
return
-
1
;
return
-
1
;
// Copy process state from p.
// Copy process state from p.
np
->
sz
=
proc
->
sz
;
if
(
!
(
np
->
pgdir
=
copyuvm
(
proc
->
pgdir
,
proc
->
sz
)))
{
if
((
np
->
mem
=
kalloc
(
np
->
sz
))
==
0
){
kfree
(
np
->
kstack
,
KSTACKSIZE
);
kfree
(
np
->
kstack
,
KSTACKSIZE
);
np
->
kstack
=
0
;
np
->
kstack
=
0
;
np
->
state
=
UNUSED
;
np
->
state
=
UNUSED
;
return
-
1
;
return
-
1
;
}
}
memmove
(
np
->
mem
,
proc
->
mem
,
np
->
sz
)
;
np
->
sz
=
proc
->
sz
;
np
->
parent
=
proc
;
np
->
parent
=
proc
;
*
np
->
tf
=
*
proc
->
tf
;
*
np
->
tf
=
*
proc
->
tf
;
...
@@ -225,7 +183,7 @@ fork(void)
...
@@ -225,7 +183,7 @@ fork(void)
pid
=
np
->
pid
;
pid
=
np
->
pid
;
np
->
state
=
RUNNABLE
;
np
->
state
=
RUNNABLE
;
safestrcpy
(
np
->
name
,
proc
->
name
,
sizeof
(
proc
->
name
));
return
pid
;
return
pid
;
}
}
...
@@ -256,7 +214,7 @@ scheduler(void)
...
@@ -256,7 +214,7 @@ scheduler(void)
// to release ptable.lock and then reacquire it
// to release ptable.lock and then reacquire it
// before jumping back to us.
// before jumping back to us.
proc
=
p
;
proc
=
p
;
usegment
(
);
loadvm
(
p
);
p
->
state
=
RUNNING
;
p
->
state
=
RUNNING
;
swtch
(
&
cpu
->
scheduler
,
proc
->
context
);
swtch
(
&
cpu
->
scheduler
,
proc
->
context
);
...
@@ -284,7 +242,6 @@ sched(void)
...
@@ -284,7 +242,6 @@ sched(void)
panic
(
"sched running"
);
panic
(
"sched running"
);
if
(
readeflags
()
&
FL_IF
)
if
(
readeflags
()
&
FL_IF
)
panic
(
"sched interruptible"
);
panic
(
"sched interruptible"
);
intena
=
cpu
->
intena
;
intena
=
cpu
->
intena
;
swtch
(
&
proc
->
context
,
cpu
->
scheduler
);
swtch
(
&
proc
->
context
,
cpu
->
scheduler
);
cpu
->
intena
=
intena
;
cpu
->
intena
=
intena
;
...
@@ -455,9 +412,10 @@ wait(void)
...
@@ -455,9 +412,10 @@ wait(void)
if
(
p
->
state
==
ZOMBIE
){
if
(
p
->
state
==
ZOMBIE
){
// Found one.
// Found one.
pid
=
p
->
pid
;
pid
=
p
->
pid
;
kfree
(
p
->
mem
,
p
->
sz
);
kfree
(
p
->
kstack
,
KSTACKSIZE
);
kfree
(
p
->
kstack
,
KSTACKSIZE
);
freevm
(
p
->
pgdir
);
p
->
state
=
UNUSED
;
p
->
state
=
UNUSED
;
p
->
kstack
=
0
;
p
->
pid
=
0
;
p
->
pid
=
0
;
p
->
parent
=
0
;
p
->
parent
=
0
;
p
->
name
[
0
]
=
0
;
p
->
name
[
0
]
=
0
;
...
...
proc.h
浏览文件 @
40889627
...
@@ -30,8 +30,8 @@ enum procstate { UNUSED, EMBRYO, SLEEPING, RUNNABLE, RUNNING, ZOMBIE };
...
@@ -30,8 +30,8 @@ enum procstate { UNUSED, EMBRYO, SLEEPING, RUNNABLE, RUNNING, ZOMBIE };
// Per-process state
// Per-process state
struct
proc
{
struct
proc
{
char
*
mem
;
// Start of process memory (kernel address)
uint
sz
;
// Size of process memory (bytes)
uint
sz
;
// Size of process memory (bytes)
pde_t
*
pgdir
;
// linear address of proc's pgdir
char
*
kstack
;
// Bottom of kernel stack for this process
char
*
kstack
;
// Bottom of kernel stack for this process
enum
procstate
state
;
// Process state
enum
procstate
state
;
// Process state
volatile
int
pid
;
// Process ID
volatile
int
pid
;
// Process ID
...
...
sh.c
浏览文件 @
40889627
...
@@ -330,7 +330,7 @@ parsecmd(char *s)
...
@@ -330,7 +330,7 @@ parsecmd(char *s)
{
{
char
*
es
;
char
*
es
;
struct
cmd
*
cmd
;
struct
cmd
*
cmd
;
es
=
s
+
strlen
(
s
);
es
=
s
+
strlen
(
s
);
cmd
=
parseline
(
&
s
,
es
);
cmd
=
parseline
(
&
s
,
es
);
peek
(
&
s
,
es
,
""
);
peek
(
&
s
,
es
,
""
);
...
@@ -363,7 +363,7 @@ struct cmd*
...
@@ -363,7 +363,7 @@ struct cmd*
parsepipe
(
char
**
ps
,
char
*
es
)
parsepipe
(
char
**
ps
,
char
*
es
)
{
{
struct
cmd
*
cmd
;
struct
cmd
*
cmd
;
cmd
=
parseexec
(
ps
,
es
);
cmd
=
parseexec
(
ps
,
es
);
if
(
peek
(
ps
,
es
,
"|"
)){
if
(
peek
(
ps
,
es
,
"|"
)){
gettoken
(
ps
,
es
,
0
,
0
);
gettoken
(
ps
,
es
,
0
,
0
);
...
@@ -420,6 +420,7 @@ parseexec(char **ps, char *es)
...
@@ -420,6 +420,7 @@ parseexec(char **ps, char *es)
int
tok
,
argc
;
int
tok
,
argc
;
struct
execcmd
*
cmd
;
struct
execcmd
*
cmd
;
struct
cmd
*
ret
;
struct
cmd
*
ret
;
int
*
x
=
(
int
*
)
peek
;
if
(
peek
(
ps
,
es
,
"("
))
if
(
peek
(
ps
,
es
,
"("
))
return
parseblock
(
ps
,
es
);
return
parseblock
(
ps
,
es
);
...
...
spinlock.c
浏览文件 @
40889627
...
@@ -71,7 +71,7 @@ getcallerpcs(void *v, uint pcs[])
...
@@ -71,7 +71,7 @@ getcallerpcs(void *v, uint pcs[])
ebp
=
(
uint
*
)
v
-
2
;
ebp
=
(
uint
*
)
v
-
2
;
for
(
i
=
0
;
i
<
10
;
i
++
){
for
(
i
=
0
;
i
<
10
;
i
++
){
if
(
ebp
==
0
||
ebp
==
(
uint
*
)
0xffffffff
)
if
(
ebp
==
0
||
ebp
<
0x100000
||
ebp
==
(
uint
*
)
0xffffffff
)
break
;
break
;
pcs
[
i
]
=
ebp
[
1
];
// saved %eip
pcs
[
i
]
=
ebp
[
1
];
// saved %eip
ebp
=
(
uint
*
)
ebp
[
0
];
// saved %ebp
ebp
=
(
uint
*
)
ebp
[
0
];
// saved %ebp
...
...
swtch.S
浏览文件 @
40889627
...
@@ -26,3 +26,11 @@ swtch:
...
@@ -26,3 +26,11 @@ swtch:
popl %ebx
popl %ebx
popl %ebp
popl %ebp
ret
ret
# Jump on a new stack, fake C calling conventions
.globl jstack
jstack:
movl 4(%esp), %esp
subl $16, %esp # space for arguments
movl $0, %ebp # terminate functions that follow ebp's
call mainc # continue at mainc
syscall.c
浏览文件 @
40889627
...
@@ -18,10 +18,12 @@ fetchint(struct proc *p, uint addr, int *ip)
...
@@ -18,10 +18,12 @@ fetchint(struct proc *p, uint addr, int *ip)
{
{
if
(
addr
>=
p
->
sz
||
addr
+
4
>
p
->
sz
)
if
(
addr
>=
p
->
sz
||
addr
+
4
>
p
->
sz
)
return
-
1
;
return
-
1
;
*
ip
=
*
(
int
*
)(
p
->
mem
+
addr
);
*
ip
=
*
(
int
*
)(
addr
);
return
0
;
return
0
;
}
}
// XXX should we copy the string?
// Fetch the nul-terminated string at addr from process p.
// Fetch the nul-terminated string at addr from process p.
// Doesn't actually copy the string - just sets *pp to point at it.
// Doesn't actually copy the string - just sets *pp to point at it.
// Returns length of string, not including nul.
// Returns length of string, not including nul.
...
@@ -32,8 +34,10 @@ fetchstr(struct proc *p, uint addr, char **pp)
...
@@ -32,8 +34,10 @@ fetchstr(struct proc *p, uint addr, char **pp)
if
(
addr
>=
p
->
sz
)
if
(
addr
>=
p
->
sz
)
return
-
1
;
return
-
1
;
*
pp
=
p
->
mem
+
addr
;
// *pp = p->mem + addr;
ep
=
p
->
mem
+
p
->
sz
;
// ep = p->mem + p->sz;
*
pp
=
(
char
**
)
addr
;
ep
=
p
->
sz
;
for
(
s
=
*
pp
;
s
<
ep
;
s
++
)
for
(
s
=
*
pp
;
s
<
ep
;
s
++
)
if
(
*
s
==
0
)
if
(
*
s
==
0
)
return
s
-
*
pp
;
return
s
-
*
pp
;
...
@@ -44,7 +48,8 @@ fetchstr(struct proc *p, uint addr, char **pp)
...
@@ -44,7 +48,8 @@ fetchstr(struct proc *p, uint addr, char **pp)
int
int
argint
(
int
n
,
int
*
ip
)
argint
(
int
n
,
int
*
ip
)
{
{
return
fetchint
(
proc
,
proc
->
tf
->
esp
+
4
+
4
*
n
,
ip
);
int
x
=
fetchint
(
proc
,
proc
->
tf
->
esp
+
4
+
4
*
n
,
ip
);
return
x
;
}
}
// Fetch the nth word-sized system call argument as a pointer
// Fetch the nth word-sized system call argument as a pointer
...
@@ -59,7 +64,8 @@ argptr(int n, char **pp, int size)
...
@@ -59,7 +64,8 @@ argptr(int n, char **pp, int size)
return
-
1
;
return
-
1
;
if
((
uint
)
i
>=
proc
->
sz
||
(
uint
)
i
+
size
>=
proc
->
sz
)
if
((
uint
)
i
>=
proc
->
sz
||
(
uint
)
i
+
size
>=
proc
->
sz
)
return
-
1
;
return
-
1
;
*
pp
=
proc
->
mem
+
i
;
// *pp = proc->mem + i; // XXXXX
*
pp
=
(
char
*
)
i
;
// XXXXX
return
0
;
return
0
;
}
}
...
...
sysfile.c
浏览文件 @
40889627
...
@@ -264,7 +264,6 @@ sys_open(void)
...
@@ -264,7 +264,6 @@ sys_open(void)
if
(
argstr
(
0
,
&
path
)
<
0
||
argint
(
1
,
&
omode
)
<
0
)
if
(
argstr
(
0
,
&
path
)
<
0
||
argint
(
1
,
&
omode
)
<
0
)
return
-
1
;
return
-
1
;
if
(
omode
&
O_CREATE
){
if
(
omode
&
O_CREATE
){
if
((
ip
=
create
(
path
,
T_FILE
,
0
,
0
))
==
0
)
if
((
ip
=
create
(
path
,
T_FILE
,
0
,
0
))
==
0
)
return
-
1
;
return
-
1
;
...
@@ -291,7 +290,6 @@ sys_open(void)
...
@@ -291,7 +290,6 @@ sys_open(void)
f
->
off
=
0
;
f
->
off
=
0
;
f
->
readable
=
!
(
omode
&
O_WRONLY
);
f
->
readable
=
!
(
omode
&
O_WRONLY
);
f
->
writable
=
(
omode
&
O_WRONLY
)
||
(
omode
&
O_RDWR
);
f
->
writable
=
(
omode
&
O_WRONLY
)
||
(
omode
&
O_RDWR
);
return
fd
;
return
fd
;
}
}
...
@@ -350,8 +348,9 @@ sys_exec(void)
...
@@ -350,8 +348,9 @@ sys_exec(void)
int
i
;
int
i
;
uint
uargv
,
uarg
;
uint
uargv
,
uarg
;
if
(
argstr
(
0
,
&
path
)
<
0
||
argint
(
1
,
(
int
*
)
&
uargv
)
<
0
)
if
(
argstr
(
0
,
&
path
)
<
0
||
argint
(
1
,
(
int
*
)
&
uargv
)
<
0
)
{
return
-
1
;
return
-
1
;
}
memset
(
argv
,
0
,
sizeof
(
argv
));
memset
(
argv
,
0
,
sizeof
(
argv
));
for
(
i
=
0
;;
i
++
){
for
(
i
=
0
;;
i
++
){
if
(
i
>=
NELEM
(
argv
))
if
(
i
>=
NELEM
(
argv
))
...
...
trap.c
浏览文件 @
40889627
...
@@ -78,13 +78,14 @@ trap(struct trapframe *tf)
...
@@ -78,13 +78,14 @@ trap(struct trapframe *tf)
default:
default:
if
(
proc
==
0
||
(
tf
->
cs
&
3
)
==
0
){
if
(
proc
==
0
||
(
tf
->
cs
&
3
)
==
0
){
// In kernel, it must be our mistake.
// In kernel, it must be our mistake.
cprintf
(
"unexpected trap %d from cpu %d eip %x
\n
"
,
cprintf
(
"unexpected trap %d from cpu %d eip %x
(cr2=0x%x)
\n
"
,
tf
->
trapno
,
cpu
->
id
,
tf
->
eip
);
tf
->
trapno
,
cpu
->
id
,
tf
->
eip
,
rcr2
()
);
panic
(
"trap"
);
panic
(
"trap"
);
}
}
// In user space, assume process misbehaved.
// In user space, assume process misbehaved.
cprintf
(
"pid %d %s: trap %d err %d on cpu %d eip %x -- kill proc
\n
"
,
cprintf
(
"pid %d %s: trap %d err %d on cpu %d eip 0x%x addr 0x%x--kill proc
\n
"
,
proc
->
pid
,
proc
->
name
,
tf
->
trapno
,
tf
->
err
,
cpu
->
id
,
tf
->
eip
);
proc
->
pid
,
proc
->
name
,
tf
->
trapno
,
tf
->
err
,
cpu
->
id
,
tf
->
eip
,
rcr2
());
proc
->
killed
=
1
;
proc
->
killed
=
1
;
}
}
...
...
x86.h
浏览文件 @
40889627
...
@@ -121,6 +121,61 @@ sti(void)
...
@@ -121,6 +121,61 @@ sti(void)
asm
volatile
(
"sti"
);
asm
volatile
(
"sti"
);
}
}
static
inline
void
lcr0
(
uint
val
)
{
asm
volatile
(
"movl %0,%%cr0"
:
:
"r"
(
val
));
}
static
inline
uint
rcr0
(
void
)
{
uint
val
;
asm
volatile
(
"movl %%cr0,%0"
:
"=r"
(
val
));
return
val
;
}
static
inline
uint
rcr2
(
void
)
{
uint
val
;
asm
volatile
(
"movl %%cr2,%0"
:
"=r"
(
val
));
return
val
;
}
static
inline
void
lcr3
(
uint
val
)
{
asm
volatile
(
"movl %0,%%cr3"
:
:
"r"
(
val
));
}
static
inline
uint
rcr3
(
void
)
{
uint
val
;
asm
volatile
(
"movl %%cr3,%0"
:
"=r"
(
val
));
return
val
;
}
static
inline
void
lebp
(
uint
val
)
{
asm
volatile
(
"movl %0,%%ebp"
:
:
"r"
(
val
));
}
static
inline
uint
rebp
(
void
)
{
uint
val
;
asm
volatile
(
"movl %%ebp,%0"
:
"=r"
(
val
));
return
val
;
}
static
inline
void
lesp
(
uint
val
)
{
asm
volatile
(
"movl %0,%%esp"
:
:
"r"
(
val
));
}
static
inline
uint
resp
(
void
)
{
uint
val
;
asm
volatile
(
"movl %%esp,%0"
:
"=r"
(
val
));
return
val
;
}
//PAGEBREAK: 36
//PAGEBREAK: 36
// Layout of the trap frame built on the stack by the
// Layout of the trap frame built on the stack by the
// hardware and by trapasm.S, and passed to trap().
// hardware and by trapasm.S, and passed to trap().
...
...
编写
预览
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论