Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
X
xv6-public
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
统计图
问题
0
问题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
银宸时代
OS Lab Group
奖励实验
xv6-public
提交
8b4e2a08
提交
8b4e2a08
7月 01, 2006
创建
作者:
rtm
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
swtch saves callee-saved registers
swtch idles on per-CPU stack, not on calling process's stack fix pipe bugs usertest.c tests pipes, fork, exit, close
上级
f7cea12b
隐藏空白字符变更
内嵌
并排
正在显示
14 个修改的文件
包含
212 行增加
和
55 行删除
+212
-55
Makefile
Makefile
+1
-1
fd.c
fd.c
+17
-13
kalloc.c
kalloc.c
+5
-0
main.c
main.c
+1
-1
mp.c
mp.c
+4
-8
pipe.c
pipe.c
+12
-2
proc.c
proc.c
+27
-17
proc.h
proc.h
+11
-0
syscall.c
syscall.c
+34
-4
syscall.h
syscall.h
+1
-0
trap.c
trap.c
+14
-2
ulib.c
ulib.c
+14
-0
usertests.c
usertests.c
+33
-7
x86.h
x86.h
+38
-0
没有找到文件。
Makefile
浏览文件 @
8b4e2a08
...
...
@@ -5,7 +5,7 @@ CC = i386-jos-elf-gcc
LD
=
i386-jos-elf-ld
OBJCOPY
=
i386-jos-elf-objcopy
OBJDUMP
=
i386-jos-elf-objdump
CFLAGS
=
-nostdinc
-I
.
-O
-Wall
-MD
CFLAGS
=
-nostdinc
-I
.
-O
2
-Wall
-MD
xv6.img
:
bootblock kernel
dd
if
=
/dev/zero
of
=
xv6.img
count
=
10000
...
...
fd.c
浏览文件 @
8b4e2a08
...
...
@@ -37,19 +37,6 @@ fd_alloc()
return
0
;
}
void
fd_close
(
struct
fd
*
fd
)
{
if
(
fd
->
type
==
FD_CLOSED
||
fd
->
count
<=
0
)
panic
(
"fd_close"
);
fd
->
count
-=
1
;
if
(
fd
->
count
==
0
){
if
(
fd
->
type
==
FD_PIPE
)
pipe_close
(
fd
->
pipe
,
fd
->
writeable
);
fd
->
type
=
FD_CLOSED
;
}
}
/*
* addr is a kernel address, pointing into some process's p->mem.
*/
...
...
@@ -78,3 +65,20 @@ fd_read(struct fd *fd, char *addr, int n)
return
-
1
;
}
}
void
fd_close
(
struct
fd
*
fd
)
{
if
(
fd
->
count
<
1
||
fd
->
type
==
FD_CLOSED
)
panic
(
"fd_close"
);
fd
->
count
-=
1
;
if
(
fd
->
count
==
0
){
if
(
fd
->
type
==
FD_PIPE
){
pipe_close
(
fd
->
pipe
,
fd
->
writeable
);
}
else
{
panic
(
"fd_close"
);
}
fd
->
type
=
FD_CLOSED
;
}
}
kalloc.c
浏览文件 @
8b4e2a08
...
...
@@ -45,10 +45,15 @@ kfree(char *cp, int len)
struct
run
**
rr
;
struct
run
*
p
=
(
struct
run
*
)
cp
;
struct
run
*
pend
=
(
struct
run
*
)
(
cp
+
len
);
int
i
;
if
(
len
%
PAGE
)
panic
(
"kfree"
);
// XXX fill with junk to help debug
for
(
i
=
0
;
i
<
len
;
i
++
)
cp
[
i
]
=
1
;
rr
=
&
freelist
;
while
(
*
rr
){
struct
run
*
rend
=
(
struct
run
*
)
((
char
*
)(
*
rr
)
+
(
*
rr
)
->
len
);
...
...
main.c
浏览文件 @
8b4e2a08
...
...
@@ -46,7 +46,7 @@ main()
p
=
&
proc
[
0
];
curproc
[
cpu
()]
=
p
;
p
->
state
=
WAITING
;
p
->
sz
=
PAGE
;
p
->
sz
=
4
*
PAGE
;
p
->
mem
=
kalloc
(
p
->
sz
);
memset
(
p
->
mem
,
0
,
p
->
sz
);
p
->
kstack
=
kalloc
(
KSTACKSIZE
);
...
...
mp.c
浏览文件 @
8b4e2a08
...
...
@@ -6,6 +6,7 @@
#include "x86.h"
#include "traps.h"
#include "mmu.h"
#include "proc.h"
/*
* Credit: Plan 9 sources, Intel MP spec, and Cliff Frey
...
...
@@ -92,16 +93,11 @@ enum { /* LAPIC_TDCR */
};
#define APBOOTCODE 0x7000 // XXX hack
#define MPSTACK 512
static
struct
MP
*
mp
;
// The MP floating point structure
static
uint32_t
*
lapicaddr
;
static
struct
cpu
{
uint8_t
apicid
;
// Local APIC ID
int
lintr
[
2
];
// Local APIC
char
mpstack
[
MPSTACK
];
// per-cpu start-up stack, only used to get into main()
}
cpus
[
NCPU
];
static
int
ncpu
;
struct
cpu
cpus
[
NCPU
];
int
ncpu
;
static
struct
cpu
*
bcpu
;
static
int
...
...
@@ -130,7 +126,7 @@ lapic_timerinit()
void
lapic_timerintr
()
{
cprintf
(
"%d: timer interrupt!
\n
"
,
cpu
());
//
cprintf("%d: timer interrupt!\n", cpu());
lapic_write
(
LAPIC_EOI
,
0
);
}
...
...
pipe.c
浏览文件 @
8b4e2a08
...
...
@@ -28,6 +28,10 @@ pipe_alloc(struct fd **fd1, struct fd **fd2)
goto
oops
;
if
((
p
=
(
struct
pipe
*
)
kalloc
(
PAGE
))
==
0
)
goto
oops
;
p
->
readopen
=
1
;
p
->
writeopen
=
1
;
p
->
writep
=
0
;
p
->
readp
=
0
;
(
*
fd1
)
->
type
=
FD_PIPE
;
(
*
fd1
)
->
readable
=
1
;
(
*
fd1
)
->
writeable
=
0
;
...
...
@@ -54,10 +58,13 @@ pipe_alloc(struct fd **fd1, struct fd **fd2)
void
pipe_close
(
struct
pipe
*
p
,
int
writeable
)
{
if
(
writeable
)
if
(
writeable
)
{
p
->
writeopen
=
0
;
else
wakeup
(
&
p
->
readp
);
}
else
{
p
->
readopen
=
0
;
wakeup
(
&
p
->
writep
);
}
if
(
p
->
readopen
==
0
&&
p
->
writeopen
==
0
)
kfree
((
char
*
)
p
,
PAGE
);
}
...
...
@@ -71,11 +78,13 @@ pipe_write(struct pipe *p, char *addr, int n)
while
(((
p
->
writep
+
1
)
%
PIPESIZE
)
==
p
->
readp
){
if
(
p
->
readopen
==
0
)
return
-
1
;
wakeup
(
&
p
->
readp
);
sleep
(
&
p
->
writep
);
}
p
->
data
[
p
->
writep
]
=
addr
[
i
];
p
->
writep
=
(
p
->
writep
+
1
)
%
PIPESIZE
;
}
wakeup
(
&
p
->
readp
);
return
i
;
}
...
...
@@ -96,5 +105,6 @@ pipe_read(struct pipe *p, char *addr, int n)
addr
[
i
]
=
p
->
data
[
p
->
readp
];
p
->
readp
=
(
p
->
readp
+
1
)
%
PIPESIZE
;
}
wakeup
(
&
p
->
writep
);
return
i
;
}
proc.c
浏览文件 @
8b4e2a08
...
...
@@ -104,37 +104,47 @@ swtch()
{
struct
proc
*
np
;
struct
proc
*
op
=
curproc
[
cpu
()];
unsigned
sp
;
int
i
;
// force push of callee-saved registers
asm
volatile
(
"nop"
:
:
:
"%edi"
,
"%esi"
,
"%ebx"
);
// save calling process's stack pointers
op
->
ebp
=
read_ebp
();
op
->
esp
=
read_esp
();
// don't execute on calling process's stack
sp
=
(
unsigned
)
cpus
[
cpu
()].
mpstack
+
MPSTACK
-
32
;
asm
volatile
(
"movl %0, %%esp"
:
:
"g"
(
sp
));
asm
volatile
(
"movl %0, %%ebp"
:
:
"g"
(
sp
));
// gcc might store op on the stack
np
=
curproc
[
cpu
()];
np
=
np
+
1
;
while
(
1
){
np
=
op
+
1
;
while
(
np
!=
op
){
for
(
i
=
0
;
i
<
NPROC
;
i
++
){
if
(
np
>=
&
proc
[
NPROC
])
np
=
&
proc
[
0
];
if
(
np
->
state
==
RUNNABLE
)
break
;
np
++
;
if
(
np
==
&
proc
[
NPROC
])
np
=
&
proc
[
0
];
}
if
(
np
->
state
==
RUNNABLE
)
if
(
i
<
NPROC
)
break
;
// cprintf("swtch: nothing to run\n");
// cprintf("swtch %d: nothing to run %d %d\n",
// cpu(), proc[1].state, proc[2].state);
release_spinlock
(
&
kernel_lock
);
acquire_spinlock
(
&
kernel_lock
);
np
=
&
proc
[
0
];
}
// XXX this may be too late, should probably save on the way
// in, in case some other CPU decided to run curproc
// before we got here. in fact setting state=WAITING and
// setting these variables had better be atomic w.r.t. other CPUs.
op
->
ebp
=
read_ebp
();
op
->
esp
=
read_esp
();
cprintf
(
"cpu %d swtch %x -> %x
\n
"
,
cpu
(),
op
,
np
);
cprintf
(
"cpu %d swtch %x -> %x
\n
"
,
cpu
(),
curproc
[
cpu
()],
np
);
curproc
[
cpu
()]
=
np
;
np
->
state
=
RUNNING
;
// XXX callee-saved registers?
// h/w sets busy bit in TSS descriptor sometimes, and faults
// if it's set in LTR. so clear tss descriptor busy bit.
np
->
gdt
[
SEG_TSS
].
sd_type
=
STS_T32A
;
...
...
proc.h
浏览文件 @
8b4e2a08
...
...
@@ -37,3 +37,14 @@ struct proc{
extern
struct
proc
proc
[];
extern
struct
proc
*
curproc
[
NCPU
];
#define MPSTACK 512
struct
cpu
{
uint8_t
apicid
;
// Local APIC ID
int
lintr
[
2
];
// Local APIC
char
mpstack
[
MPSTACK
];
// per-cpu start-up stack, only used to get into main()
};
extern
struct
cpu
cpus
[
NCPU
];
extern
int
ncpu
;
syscall.c
浏览文件 @
8b4e2a08
...
...
@@ -91,7 +91,7 @@ sys_pipe()
int
sys_write
()
{
int
fd
,
n
;
int
fd
,
n
,
ret
;
unsigned
addr
;
struct
proc
*
p
=
curproc
[
cpu
()];
...
...
@@ -103,13 +103,14 @@ sys_write()
return
-
1
;
if
(
addr
+
n
>
p
->
sz
)
return
-
1
;
return
fd_write
(
p
->
fds
[
fd
],
p
->
mem
+
addr
,
n
);
ret
=
fd_write
(
p
->
fds
[
fd
],
p
->
mem
+
addr
,
n
);
return
ret
;
}
int
sys_read
()
{
int
fd
,
n
;
int
fd
,
n
,
ret
;
unsigned
addr
;
struct
proc
*
p
=
curproc
[
cpu
()];
...
...
@@ -121,7 +122,25 @@ sys_read()
return
-
1
;
if
(
addr
+
n
>
p
->
sz
)
return
-
1
;
return
fd_read
(
p
->
fds
[
fd
],
p
->
mem
+
addr
,
n
);
ret
=
fd_read
(
p
->
fds
[
fd
],
p
->
mem
+
addr
,
n
);
return
ret
;
}
int
sys_close
()
{
int
fd
;
struct
proc
*
p
=
curproc
[
cpu
()];
if
(
fetcharg
(
0
,
&
fd
)
<
0
)
return
-
1
;
if
(
fd
<
0
||
fd
>=
NOFILE
)
return
-
1
;
if
(
p
->
fds
[
fd
]
==
0
)
return
-
1
;
fd_close
(
p
->
fds
[
fd
]);
p
->
fds
[
fd
]
=
0
;
return
0
;
}
int
...
...
@@ -138,6 +157,14 @@ sys_exit()
{
struct
proc
*
p
;
struct
proc
*
cp
=
curproc
[
cpu
()];
int
fd
;
for
(
fd
=
0
;
fd
<
NOFILE
;
fd
++
){
if
(
cp
->
fds
[
fd
]){
fd_close
(
cp
->
fds
[
fd
]);
cp
->
fds
[
fd
]
=
0
;
}
}
cp
->
state
=
ZOMBIE
;
...
...
@@ -227,6 +254,9 @@ syscall()
case
SYS_read
:
ret
=
sys_read
();
break
;
case
SYS_close
:
ret
=
sys_close
();
break
;
default:
cprintf
(
"unknown sys call %d
\n
"
,
num
);
// XXX fault
...
...
syscall.h
浏览文件 @
8b4e2a08
...
...
@@ -5,3 +5,4 @@
#define SYS_pipe 5
#define SYS_write 6
#define SYS_read 7
#define SYS_close 8
trap.c
浏览文件 @
8b4e2a08
...
...
@@ -35,16 +35,28 @@ trap(struct Trapframe *tf)
{
int
v
=
tf
->
tf_trapno
;
if
(
tf
->
tf_cs
==
0x8
&&
kernel_lock
==
cpu
())
cprintf
(
"cpu %d: trap from %x:%x with lock=%d
\n
"
,
cpu
(),
tf
->
tf_cs
,
tf
->
tf_eip
,
kernel_lock
);
acquire_spinlock
(
&
kernel_lock
);
// released in trapret in trapasm.S
if
(
v
==
T_SYSCALL
){
curproc
[
cpu
()]
->
tf
=
tf
;
struct
proc
*
cp
=
curproc
[
cpu
()];
cp
->
tf
=
tf
;
syscall
();
if
(
cp
!=
curproc
[
cpu
()])
panic
(
"trap ret wrong curproc"
);
if
(
cp
->
state
!=
RUNNING
)
panic
(
"trap ret but not RUNNING"
);
if
(
tf
!=
cp
->
tf
)
panic
(
"trap ret wrong tf"
);
if
(
read_esp
()
<
cp
->
kstack
||
read_esp
()
>=
cp
->
kstack
+
KSTACKSIZE
)
panic
(
"trap ret esp wrong"
);
return
;
}
if
(
v
==
(
IRQ_OFFSET
+
IRQ_TIMER
)){
curproc
[
cpu
()]
->
tf
=
tf
;
lapic_timerintr
();
return
;
}
...
...
ulib.c
浏览文件 @
8b4e2a08
...
...
@@ -5,6 +5,13 @@ fork()
asm
(
"int $48"
);
}
int
exit
()
{
asm
(
"mov $2, %eax"
);
asm
(
"int $48"
);
}
void
cons_putc
(
int
c
)
{
...
...
@@ -42,3 +49,10 @@ write(int fd, char *buf, int n)
asm
(
"mov $6, %eax"
);
asm
(
"int $48"
);
}
int
close
(
int
fd
)
{
asm
(
"mov $8, %eax"
);
asm
(
"int $48"
);
}
usertests.c
浏览文件 @
8b4e2a08
// simple fork and pipe read/write
char
buf
[
32
];
char
buf
[
2048
];
void
pipe1
()
{
int
fds
[
2
],
pid
;
int
seq
=
0
,
i
,
n
,
cc
,
total
;
pipe
(
fds
);
pid
=
pipe
();
pid
=
fork
();
if
(
pid
==
0
){
write
(
fds
[
1
],
"xyz"
,
4
);
close
(
fds
[
0
]);
for
(
n
=
0
;
n
<
5
;
n
++
){
for
(
i
=
0
;
i
<
1033
;
i
++
)
buf
[
i
]
=
seq
++
;
if
(
write
(
fds
[
1
],
buf
,
1033
)
!=
1033
){
puts
(
"pipe1 oops 1
\n
"
);
exit
(
1
);
}
}
exit
(
0
);
}
else
{
read
(
fds
[
0
],
buf
,
sizeof
(
buf
));
if
(
buf
[
0
]
!=
'x'
||
buf
[
1
]
!=
'y'
){
puts
(
"pipe1 oops
\n
"
);
return
;
close
(
fds
[
1
]);
total
=
0
;
cc
=
1
;
while
(
1
){
n
=
read
(
fds
[
0
],
buf
,
cc
);
if
(
n
<
1
)
break
;
for
(
i
=
0
;
i
<
n
;
i
++
){
if
((
buf
[
i
]
&
0xff
)
!=
(
seq
++
&
0xff
)){
puts
(
"pipe1 oops 2
\n
"
);
return
;
}
}
total
+=
n
;
cc
=
cc
*
2
;
if
(
cc
>
sizeof
(
buf
))
cc
=
sizeof
(
buf
);
}
if
(
total
!=
5
*
1033
)
puts
(
"pipe1 oops 3
\n
"
);
close
(
fds
[
0
]);
}
puts
(
"pipe1 ok
\n
"
);
}
...
...
x86.h
浏览文件 @
8b4e2a08
...
...
@@ -244,6 +244,30 @@ read_esp(void)
return
esp
;
}
static
__inline
uint32_t
read_esi
(
void
)
{
uint32_t
esi
;
__asm
__volatile
(
"movl %%esi,%0"
:
"=r"
(
esi
));
return
esi
;
}
static
__inline
uint32_t
read_edi
(
void
)
{
uint32_t
edi
;
__asm
__volatile
(
"movl %%edi,%0"
:
"=r"
(
edi
));
return
edi
;
}
static
__inline
uint32_t
read_ebx
(
void
)
{
uint32_t
ebx
;
__asm
__volatile
(
"movl %%ebx,%0"
:
"=r"
(
ebx
));
return
ebx
;
}
static
__inline
void
cpuid
(
uint32_t
info
,
uint32_t
*
eaxp
,
uint32_t
*
ebxp
,
uint32_t
*
ecxp
,
uint32_t
*
edxp
)
{
...
...
@@ -280,6 +304,20 @@ read_tsc(void)
return
tsc
;
}
// disable interrupts
static
__inline
void
cli
(
void
)
{
__asm
__volatile
(
"cli"
);
}
// enable interrupts
static
__inline
void
sti
(
void
)
{
__asm
__volatile
(
"sti"
);
}
struct
PushRegs
{
/* registers as pushed by pusha */
uint32_t
reg_edi
;
...
...
编写
预览
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论