Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
X
xv6-public
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
统计图
问题
0
问题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
银宸时代
OS Lab Group
奖励实验
xv6-public
提交
14270288
提交
14270288
8月 08, 2017
创建
作者:
Robert Morris
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'master' of g.csail.mit.edu:xv6-dev
上级
aba8423c
825ce074
隐藏空白字符变更
内嵌
并排
正在显示
19 个修改的文件
包含
181 行增加
和
172 行删除
+181
-172
console.c
console.c
+3
-2
defs.h
defs.h
+5
-1
exec.c
exec.c
+9
-7
fs.c
fs.c
+2
-9
ide.c
ide.c
+2
-1
lapic.c
lapic.c
+2
-23
main.c
main.c
+4
-5
mmu.h
mmu.h
+4
-5
pipe.c
pipe.c
+2
-2
proc.c
proc.c
+91
-42
proc.h
proc.h
+1
-15
sleeplock.c
sleeplock.c
+1
-1
spinlock.c
spinlock.c
+7
-7
syscall.c
syscall.c
+17
-11
sysfile.c
sysfile.c
+10
-8
sysproc.c
sysproc.c
+3
-3
trap.c
trap.c
+12
-12
trapasm.S
trapasm.S
+0
-3
vm.c
vm.c
+6
-15
没有找到文件。
console.c
浏览文件 @
14270288
...
...
@@ -111,7 +111,8 @@ panic(char *s)
cli
();
cons
.
locking
=
0
;
cprintf
(
"cpu with apicid %d: panic: "
,
cpu
->
apicid
);
// use lapiccpunum so that we can call panic from mycpu()
cprintf
(
"lapicid %d: panic: "
,
lapicid
());
cprintf
(
s
);
cprintf
(
"
\n
"
);
getcallerpcs
(
&
s
,
pcs
);
...
...
@@ -242,7 +243,7 @@ consoleread(struct inode *ip, char *dst, int n)
acquire
(
&
cons
.
lock
);
while
(
n
>
0
){
while
(
input
.
r
==
input
.
w
){
if
(
proc
->
killed
){
if
(
myproc
()
->
killed
){
release
(
&
cons
.
lock
);
ilock
(
ip
);
return
-
1
;
...
...
defs.h
浏览文件 @
14270288
...
...
@@ -74,7 +74,7 @@ void kbdintr(void);
// lapic.c
void
cmostime
(
struct
rtcdate
*
r
);
int
cpunum
(
void
);
int
lapicid
(
void
);
extern
volatile
uint
*
lapic
;
void
lapiceoi
(
void
);
void
lapicinit
(
void
);
...
...
@@ -103,14 +103,18 @@ int pipewrite(struct pipe*, char*, int);
//PAGEBREAK: 16
// proc.c
int
cpuid
(
void
);
void
exit
(
void
);
int
fork
(
void
);
int
growproc
(
int
);
int
kill
(
int
);
struct
cpu
*
mycpu
(
void
);
struct
proc
*
myproc
();
void
pinit
(
void
);
void
procdump
(
void
);
void
scheduler
(
void
)
__attribute__
((
noreturn
));
void
sched
(
void
);
void
setproc
(
struct
proc
*
);
void
sleep
(
void
*
,
struct
spinlock
*
);
void
userinit
(
void
);
int
wait
(
void
);
...
...
exec.c
浏览文件 @
14270288
...
...
@@ -17,11 +17,13 @@ exec(char *path, char **argv)
struct
inode
*
ip
;
struct
proghdr
ph
;
pde_t
*
pgdir
,
*
oldpgdir
;
struct
proc
*
curproc
=
myproc
();
begin_op
();
if
((
ip
=
namei
(
path
))
==
0
){
end_op
();
cprintf
(
"exec: fail
\n
"
);
return
-
1
;
}
ilock
(
ip
);
...
...
@@ -89,15 +91,15 @@ exec(char *path, char **argv)
for
(
last
=
s
=
path
;
*
s
;
s
++
)
if
(
*
s
==
'/'
)
last
=
s
+
1
;
safestrcpy
(
proc
->
name
,
last
,
sizeof
(
proc
->
name
));
safestrcpy
(
curproc
->
name
,
last
,
sizeof
(
cur
proc
->
name
));
// Commit to the user image.
oldpgdir
=
proc
->
pgdir
;
proc
->
pgdir
=
pgdir
;
proc
->
sz
=
sz
;
proc
->
tf
->
eip
=
elf
.
entry
;
// main
proc
->
tf
->
esp
=
sp
;
switchuvm
(
proc
);
oldpgdir
=
cur
proc
->
pgdir
;
cur
proc
->
pgdir
=
pgdir
;
cur
proc
->
sz
=
sz
;
cur
proc
->
tf
->
eip
=
elf
.
entry
;
// main
cur
proc
->
tf
->
esp
=
sp
;
switchuvm
(
cur
proc
);
freevm
(
oldpgdir
);
return
0
;
...
...
fs.c
浏览文件 @
14270288
...
...
@@ -169,7 +169,7 @@ iinit(int dev)
for
(
i
=
0
;
i
<
NINODE
;
i
++
)
{
initsleeplock
(
&
icache
.
inode
[
i
].
lock
,
"inode"
);
}
readsb
(
dev
,
&
sb
);
cprintf
(
"sb: size %d nblocks %d ninodes %d nlog %d logstart %d\
inodestart %d bmap start %d
\n
"
,
sb
.
size
,
sb
.
nblocks
,
...
...
@@ -451,13 +451,6 @@ readi(struct inode *ip, char *dst, uint off, uint n)
for
(
tot
=
0
;
tot
<
n
;
tot
+=
m
,
off
+=
m
,
dst
+=
m
){
bp
=
bread
(
ip
->
dev
,
bmap
(
ip
,
off
/
BSIZE
));
m
=
min
(
n
-
tot
,
BSIZE
-
off
%
BSIZE
);
/*
cprintf("data off %d:\n", off);
for (int j = 0; j < min(m, 10); j++) {
cprintf("%x ", bp->data[off%BSIZE+j]);
}
cprintf("\n");
*/
memmove
(
dst
,
bp
->
data
+
off
%
BSIZE
,
m
);
brelse
(
bp
);
}
...
...
@@ -617,7 +610,7 @@ namex(char *path, int nameiparent, char *name)
if
(
*
path
==
'/'
)
ip
=
iget
(
ROOTDEV
,
ROOTINO
);
else
ip
=
idup
(
proc
->
cwd
);
ip
=
idup
(
myproc
()
->
cwd
);
while
((
path
=
skipelem
(
path
,
name
))
!=
0
){
ilock
(
ip
);
...
...
ide.c
浏览文件 @
14270288
...
...
@@ -108,9 +108,9 @@ ideintr(void)
// First queued buffer is the active request.
acquire
(
&
idelock
);
if
((
b
=
idequeue
)
==
0
){
release
(
&
idelock
);
// cprintf("spurious IDE interrupt\n");
return
;
}
idequeue
=
b
->
qnext
;
...
...
@@ -164,5 +164,6 @@ iderw(struct buf *b)
sleep
(
b
,
&
idelock
);
}
release
(
&
idelock
);
}
lapic.c
浏览文件 @
14270288
...
...
@@ -9,7 +9,6 @@
#include "traps.h"
#include "mmu.h"
#include "x86.h"
#include "proc.h" // ncpu
// Local APIC registers, divided by 4 for use as uint[] indices.
#define ID (0x0020/4) // ID
...
...
@@ -99,31 +98,11 @@ lapicinit(void)
}
int
cpunum
(
void
)
lapicid
(
void
)
{
int
apicid
,
i
;
// Cannot call cpu when interrupts are enabled:
// result not guaranteed to last long enough to be used!
// Would prefer to panic but even printing is chancy here:
// almost everything, including cprintf and panic, calls cpu,
// often indirectly through acquire and release.
if
(
readeflags
()
&
FL_IF
){
static
int
n
;
if
(
n
++
==
0
)
cprintf
(
"cpu called from %x with interrupts enabled
\n
"
,
__builtin_return_address
(
0
));
}
if
(
!
lapic
)
return
0
;
apicid
=
lapic
[
ID
]
>>
24
;
for
(
i
=
0
;
i
<
ncpu
;
++
i
)
{
if
(
cpus
[
i
].
apicid
==
apicid
)
return
i
;
}
panic
(
"unknown apicid
\n
"
);
return
lapic
[
ID
]
>>
24
;
}
// Acknowledge interrupt.
...
...
main.c
浏览文件 @
14270288
...
...
@@ -22,7 +22,6 @@ main(void)
mpinit
();
// detect other processors
lapicinit
();
// interrupt controller
seginit
();
// segment descriptors
cprintf
(
"
\n
cpu%d: starting xv6
\n\n
"
,
cpunum
());
picinit
();
// another interrupt controller
ioapicinit
();
// another interrupt controller
consoleinit
();
// console hardware
...
...
@@ -31,7 +30,7 @@ main(void)
tvinit
();
// trap vectors
binit
();
// buffer cache
fileinit
();
// file table
ideinit
();
// disk
ideinit
();
// disk
if
(
!
ismp
)
timerinit
();
// uniprocessor timer
startothers
();
// start other processors
...
...
@@ -54,9 +53,9 @@ mpenter(void)
static
void
mpmain
(
void
)
{
cprintf
(
"cpu%d: starting
\n
"
,
cpunum
());
cprintf
(
"cpu%d: starting
%d
\n
"
,
cpuid
(),
cpuid
());
idtinit
();
// load idt register
xchg
(
&
cpu
->
started
,
1
);
// tell startothers() we're up
xchg
(
&
(
mycpu
()
->
started
)
,
1
);
// tell startothers() we're up
scheduler
();
// start running processes
}
...
...
@@ -78,7 +77,7 @@ startothers(void)
memmove
(
code
,
_binary_entryother_start
,
(
uint
)
_binary_entryother_size
);
for
(
c
=
cpus
;
c
<
cpus
+
ncpu
;
c
++
){
if
(
c
==
cpus
+
cpunum
())
// We've started already.
if
(
c
==
mycpu
())
// We've started already.
continue
;
// Tell entryother.S what stack to use, where to enter, and what
...
...
mmu.h
浏览文件 @
14270288
...
...
@@ -42,13 +42,12 @@
// various segment selectors.
#define SEG_KCODE 1 // kernel code
#define SEG_KDATA 2 // kernel data+stack
#define SEG_KCPU 3 // kernel per-cpu data
#define SEG_UCODE 4 // user code
#define SEG_UDATA 5 // user data+stack
#define SEG_TSS 6 // this process's task state
#define SEG_UCODE 3 // user code
#define SEG_UDATA 4 // user data+stack
#define SEG_TSS 5 // this process's task state
// cpu->gdt[NSEGS] holds the above segments.
#define NSEGS
7
#define NSEGS
6
//PAGEBREAK!
#ifndef __ASSEMBLER__
...
...
pipe.c
浏览文件 @
14270288
...
...
@@ -83,7 +83,7 @@ pipewrite(struct pipe *p, char *addr, int n)
acquire
(
&
p
->
lock
);
for
(
i
=
0
;
i
<
n
;
i
++
){
while
(
p
->
nwrite
==
p
->
nread
+
PIPESIZE
){
//DOC: pipewrite-full
if
(
p
->
readopen
==
0
||
proc
->
killed
){
if
(
p
->
readopen
==
0
||
myproc
()
->
killed
){
release
(
&
p
->
lock
);
return
-
1
;
}
...
...
@@ -104,7 +104,7 @@ piperead(struct pipe *p, char *addr, int n)
acquire
(
&
p
->
lock
);
while
(
p
->
nread
==
p
->
nwrite
&&
p
->
writeopen
){
//DOC: pipe-empty
if
(
proc
->
killed
){
if
(
myproc
()
->
killed
){
release
(
&
p
->
lock
);
return
-
1
;
}
...
...
proc.c
浏览文件 @
14270288
...
...
@@ -26,6 +26,45 @@ pinit(void)
initlock
(
&
ptable
.
lock
,
"ptable"
);
}
// Must be called with interrupts disabled
int
cpuid
()
{
return
mycpu
()
-
cpus
;
}
// Must be called with interrupts disabled to avoid the caller being rescheduled
// between reading lapicid and running through the loop.
struct
cpu
*
mycpu
(
void
)
{
int
apicid
,
i
;
if
(
readeflags
()
&
FL_IF
)
panic
(
"mycpu called with interrupts enabled
\n
"
);
apicid
=
lapicid
();
// APIC IDs are not guaranteed to be contiguous. Maybe we should have
// a reverse map, or reserve a register to store &cpus[i].
for
(
i
=
0
;
i
<
ncpu
;
++
i
)
{
if
(
cpus
[
i
].
apicid
==
apicid
)
return
&
cpus
[
i
];
}
panic
(
"unknown apicid
\n
"
);
}
// Disable interrupts so that we are not rescheduled
// while reading proc from the cpu structure
struct
proc
*
myproc
(
void
)
{
struct
cpu
*
c
;
struct
proc
*
p
;
pushcli
();
c
=
mycpu
();
p
=
c
->
proc
;
popcli
();
return
p
;
}
//PAGEBREAK: 32
// Look in the process table for an UNUSED proc.
// If found, change state to EMBRYO and initialize
...
...
@@ -120,17 +159,18 @@ int
growproc
(
int
n
)
{
uint
sz
;
struct
proc
*
curproc
=
myproc
();
sz
=
proc
->
sz
;
sz
=
cur
proc
->
sz
;
if
(
n
>
0
){
if
((
sz
=
allocuvm
(
proc
->
pgdir
,
sz
,
sz
+
n
))
==
0
)
if
((
sz
=
allocuvm
(
cur
proc
->
pgdir
,
sz
,
sz
+
n
))
==
0
)
return
-
1
;
}
else
if
(
n
<
0
){
if
((
sz
=
deallocuvm
(
proc
->
pgdir
,
sz
,
sz
+
n
))
==
0
)
if
((
sz
=
deallocuvm
(
cur
proc
->
pgdir
,
sz
,
sz
+
n
))
==
0
)
return
-
1
;
}
proc
->
sz
=
sz
;
switchuvm
(
proc
);
cur
proc
->
sz
=
sz
;
switchuvm
(
cur
proc
);
return
0
;
}
...
...
@@ -142,32 +182,33 @@ fork(void)
{
int
i
,
pid
;
struct
proc
*
np
;
struct
proc
*
curproc
=
myproc
();
// Allocate process.
if
((
np
=
allocproc
())
==
0
){
return
-
1
;
}
// Copy process state from p.
if
((
np
->
pgdir
=
copyuvm
(
proc
->
pgdir
,
proc
->
sz
))
==
0
){
// Copy process state from p
roc
.
if
((
np
->
pgdir
=
copyuvm
(
curproc
->
pgdir
,
cur
proc
->
sz
))
==
0
){
kfree
(
np
->
kstack
);
np
->
kstack
=
0
;
np
->
state
=
UNUSED
;
return
-
1
;
}
np
->
sz
=
proc
->
sz
;
np
->
parent
=
proc
;
*
np
->
tf
=
*
proc
->
tf
;
np
->
sz
=
cur
proc
->
sz
;
np
->
parent
=
cur
proc
;
*
np
->
tf
=
*
cur
proc
->
tf
;
// Clear %eax so that fork returns 0 in the child.
np
->
tf
->
eax
=
0
;
for
(
i
=
0
;
i
<
NOFILE
;
i
++
)
if
(
proc
->
ofile
[
i
])
np
->
ofile
[
i
]
=
filedup
(
proc
->
ofile
[
i
]);
np
->
cwd
=
idup
(
proc
->
cwd
);
if
(
cur
proc
->
ofile
[
i
])
np
->
ofile
[
i
]
=
filedup
(
cur
proc
->
ofile
[
i
]);
np
->
cwd
=
idup
(
cur
proc
->
cwd
);
safestrcpy
(
np
->
name
,
proc
->
name
,
sizeof
(
proc
->
name
));
safestrcpy
(
np
->
name
,
curproc
->
name
,
sizeof
(
cur
proc
->
name
));
pid
=
np
->
pid
;
...
...
@@ -186,33 +227,34 @@ fork(void)
void
exit
(
void
)
{
struct
proc
*
curproc
=
myproc
();
struct
proc
*
p
;
int
fd
;
if
(
proc
==
initproc
)
if
(
cur
proc
==
initproc
)
panic
(
"init exiting"
);
// Close all open files.
for
(
fd
=
0
;
fd
<
NOFILE
;
fd
++
){
if
(
proc
->
ofile
[
fd
]){
fileclose
(
proc
->
ofile
[
fd
]);
proc
->
ofile
[
fd
]
=
0
;
if
(
cur
proc
->
ofile
[
fd
]){
fileclose
(
cur
proc
->
ofile
[
fd
]);
cur
proc
->
ofile
[
fd
]
=
0
;
}
}
begin_op
();
iput
(
proc
->
cwd
);
iput
(
cur
proc
->
cwd
);
end_op
();
proc
->
cwd
=
0
;
cur
proc
->
cwd
=
0
;
acquire
(
&
ptable
.
lock
);
// Parent might be sleeping in wait().
wakeup1
(
proc
->
parent
);
wakeup1
(
cur
proc
->
parent
);
// Pass abandoned children to init.
for
(
p
=
ptable
.
proc
;
p
<
&
ptable
.
proc
[
NPROC
];
p
++
){
if
(
p
->
parent
==
proc
){
if
(
p
->
parent
==
cur
proc
){
p
->
parent
=
initproc
;
if
(
p
->
state
==
ZOMBIE
)
wakeup1
(
initproc
);
...
...
@@ -220,7 +262,7 @@ exit(void)
}
// Jump into the scheduler, never to return.
proc
->
state
=
ZOMBIE
;
cur
proc
->
state
=
ZOMBIE
;
sched
();
panic
(
"zombie exit"
);
}
...
...
@@ -232,13 +274,14 @@ wait(void)
{
struct
proc
*
p
;
int
havekids
,
pid
;
struct
proc
*
curproc
=
myproc
();
acquire
(
&
ptable
.
lock
);
for
(;;){
// Scan through table looking for exited children.
havekids
=
0
;
for
(
p
=
ptable
.
proc
;
p
<
&
ptable
.
proc
[
NPROC
];
p
++
){
if
(
p
->
parent
!=
proc
)
if
(
p
->
parent
!=
cur
proc
)
continue
;
havekids
=
1
;
if
(
p
->
state
==
ZOMBIE
){
...
...
@@ -258,13 +301,13 @@ wait(void)
}
// No point waiting if we don't have any children.
if
(
!
havekids
||
proc
->
killed
){
if
(
!
havekids
||
cur
proc
->
killed
){
release
(
&
ptable
.
lock
);
return
-
1
;
}
// Wait for children to exit. (See wakeup1 call in proc_exit.)
sleep
(
proc
,
&
ptable
.
lock
);
//DOC: wait-sleep
sleep
(
cur
proc
,
&
ptable
.
lock
);
//DOC: wait-sleep
}
}
...
...
@@ -280,7 +323,9 @@ void
scheduler
(
void
)
{
struct
proc
*
p
;
struct
cpu
*
c
=
mycpu
();
c
->
proc
=
0
;
for
(;;){
// Enable interrupts on this processor.
sti
();
...
...
@@ -294,15 +339,16 @@ scheduler(void)
// Switch to chosen process. It is the process's job
// to release ptable.lock and then reacquire it
// before jumping back to us.
proc
=
p
;
c
->
proc
=
p
;
switchuvm
(
p
);
p
->
state
=
RUNNING
;
swtch
(
&
cpu
->
scheduler
,
p
->
context
);
swtch
(
&
(
c
->
scheduler
),
p
->
context
);
switchkvm
();
// Process is done running for now.
// It should have changed its p->state before coming back.
proc
=
0
;
c
->
proc
=
0
;
}
release
(
&
ptable
.
lock
);
...
...
@@ -320,18 +366,19 @@ void
sched
(
void
)
{
int
intena
;
struct
proc
*
p
=
myproc
();
if
(
!
holding
(
&
ptable
.
lock
))
panic
(
"sched ptable.lock"
);
if
(
cpu
->
ncli
!=
1
)
if
(
mycpu
()
->
ncli
!=
1
)
panic
(
"sched locks"
);
if
(
p
roc
->
state
==
RUNNING
)
if
(
p
->
state
==
RUNNING
)
panic
(
"sched running"
);
if
(
readeflags
()
&
FL_IF
)
panic
(
"sched interruptible"
);
intena
=
cpu
->
intena
;
swtch
(
&
p
roc
->
context
,
cpu
->
scheduler
);
cpu
->
intena
=
intena
;
intena
=
mycpu
()
->
intena
;
swtch
(
&
p
->
context
,
mycpu
()
->
scheduler
);
mycpu
()
->
intena
=
intena
;
}
// Give up the CPU for one scheduling round.
...
...
@@ -339,7 +386,7 @@ void
yield
(
void
)
{
acquire
(
&
ptable
.
lock
);
//DOC: yieldlock
proc
->
state
=
RUNNABLE
;
myproc
()
->
state
=
RUNNABLE
;
sched
();
release
(
&
ptable
.
lock
);
}
...
...
@@ -370,7 +417,9 @@ forkret(void)
void
sleep
(
void
*
chan
,
struct
spinlock
*
lk
)
{
if
(
proc
==
0
)
struct
proc
*
p
=
myproc
();
if
(
p
==
0
)
panic
(
"sleep"
);
if
(
lk
==
0
)
...
...
@@ -386,14 +435,14 @@ sleep(void *chan, struct spinlock *lk)
acquire
(
&
ptable
.
lock
);
//DOC: sleeplock1
release
(
lk
);
}
// Go to sleep.
proc
->
chan
=
chan
;
proc
->
state
=
SLEEPING
;
p
->
chan
=
chan
;
p
->
state
=
SLEEPING
;
sched
();
// Tidy up.
p
roc
->
chan
=
0
;
p
->
chan
=
0
;
// Reacquire original lock.
if
(
lk
!=
&
ptable
.
lock
){
//DOC: sleeplock2
...
...
proc.h
浏览文件 @
14270288
...
...
@@ -7,26 +7,12 @@ struct cpu {
volatile
uint
started
;
// Has the CPU started?
int
ncli
;
// Depth of pushcli nesting.
int
intena
;
// Were interrupts enabled before pushcli?
// Cpu-local storage variables; see below
struct
cpu
*
cpu
;
struct
proc
*
proc
;
// The currently-running process.
struct
proc
*
proc
;
// The process running on this cpu or null
};
extern
struct
cpu
cpus
[
NCPU
];
extern
int
ncpu
;
// Per-CPU variables, holding pointers to the
// current cpu and to the current process.
// The asm suffix tells gcc to use "%gs:0" to refer to cpu
// and "%gs:4" to refer to proc. seginit sets up the
// %gs segment register so that %gs refers to the memory
// holding those two variables in the local cpu's struct cpu.
// This is similar to how thread-local variables are implemented
// in thread libraries such as Linux pthreads.
extern
struct
cpu
*
cpu
asm
(
"%gs:0"
);
// &cpus[cpunum()]
extern
struct
proc
*
proc
asm
(
"%gs:4"
);
// cpus[cpunum()].proc
//PAGEBREAK: 17
// Saved registers for kernel context switches.
// Don't need to save all the segment registers (%cs, etc),
...
...
sleeplock.c
浏览文件 @
14270288
...
...
@@ -27,7 +27,7 @@ acquiresleep(struct sleeplock *lk)
sleep
(
lk
,
&
lk
->
lk
);
}
lk
->
locked
=
1
;
lk
->
pid
=
proc
->
pid
;
lk
->
pid
=
myproc
()
->
pid
;
release
(
&
lk
->
lk
);
}
...
...
spinlock.c
浏览文件 @
14270288
...
...
@@ -38,7 +38,7 @@ acquire(struct spinlock *lk)
__sync_synchronize
();
// Record info about lock acquisition for debugging.
lk
->
cpu
=
cpu
;
lk
->
cpu
=
mycpu
()
;
getcallerpcs
(
&
lk
,
lk
->
pcs
);
}
...
...
@@ -89,7 +89,7 @@ getcallerpcs(void *v, uint pcs[])
int
holding
(
struct
spinlock
*
lock
)
{
return
lock
->
locked
&&
lock
->
cpu
==
cpu
;
return
lock
->
locked
&&
lock
->
cpu
==
mycpu
()
;
}
...
...
@@ -104,9 +104,9 @@ pushcli(void)
eflags
=
readeflags
();
cli
();
if
(
cpu
->
ncli
==
0
)
cpu
->
intena
=
eflags
&
FL_IF
;
cpu
->
ncli
+=
1
;
if
(
mycpu
()
->
ncli
==
0
)
mycpu
()
->
intena
=
eflags
&
FL_IF
;
mycpu
()
->
ncli
+=
1
;
}
void
...
...
@@ -114,9 +114,9 @@ popcli(void)
{
if
(
readeflags
()
&
FL_IF
)
panic
(
"popcli - interruptible"
);
if
(
--
cpu
->
ncli
<
0
)
if
(
--
mycpu
()
->
ncli
<
0
)
panic
(
"popcli"
);
if
(
cpu
->
ncli
==
0
&&
cpu
->
intena
)
if
(
mycpu
()
->
ncli
==
0
&&
mycpu
()
->
intena
)
sti
();
}
syscall.c
浏览文件 @
14270288
...
...
@@ -17,7 +17,9 @@
int
fetchint
(
uint
addr
,
int
*
ip
)
{
if
(
addr
>=
proc
->
sz
||
addr
+
4
>
proc
->
sz
)
struct
proc
*
curproc
=
myproc
();
if
(
addr
>=
curproc
->
sz
||
addr
+
4
>
curproc
->
sz
)
return
-
1
;
*
ip
=
*
(
int
*
)(
addr
);
return
0
;
...
...
@@ -30,14 +32,16 @@ int
fetchstr
(
uint
addr
,
char
**
pp
)
{
char
*
s
,
*
ep
;
struct
proc
*
curproc
=
myproc
();
if
(
addr
>=
proc
->
sz
)
if
(
addr
>=
cur
proc
->
sz
)
return
-
1
;
*
pp
=
(
char
*
)
addr
;
ep
=
(
char
*
)
proc
->
sz
;
for
(
s
=
*
pp
;
s
<
ep
;
s
++
)
ep
=
(
char
*
)
cur
proc
->
sz
;
for
(
s
=
*
pp
;
s
<
ep
;
s
++
)
{
if
(
*
s
==
0
)
return
s
-
*
pp
;
}
return
-
1
;
}
...
...
@@ -45,7 +49,7 @@ fetchstr(uint addr, char **pp)
int
argint
(
int
n
,
int
*
ip
)
{
return
fetchint
(
proc
->
tf
->
esp
+
4
+
4
*
n
,
ip
);
return
fetchint
(
(
myproc
()
->
tf
->
esp
)
+
4
+
4
*
n
,
ip
);
}
// Fetch the nth word-sized system call argument as a pointer
...
...
@@ -55,10 +59,11 @@ int
argptr
(
int
n
,
char
**
pp
,
int
size
)
{
int
i
;
struct
proc
*
curproc
=
myproc
();
if
(
argint
(
n
,
&
i
)
<
0
)
return
-
1
;
if
(
size
<
0
||
(
uint
)
i
>=
proc
->
sz
||
(
uint
)
i
+
size
>
proc
->
sz
)
if
(
size
<
0
||
(
uint
)
i
>=
curproc
->
sz
||
(
uint
)
i
+
size
>
cur
proc
->
sz
)
return
-
1
;
*
pp
=
(
char
*
)
i
;
return
0
;
...
...
@@ -127,13 +132,14 @@ void
syscall
(
void
)
{
int
num
;
struct
proc
*
curproc
=
myproc
();
num
=
proc
->
tf
->
eax
;
num
=
cur
proc
->
tf
->
eax
;
if
(
num
>
0
&&
num
<
NELEM
(
syscalls
)
&&
syscalls
[
num
])
{
proc
->
tf
->
eax
=
syscalls
[
num
]();
cur
proc
->
tf
->
eax
=
syscalls
[
num
]();
}
else
{
cprintf
(
"%d %s: unknown sys call %d
\n
"
,
proc
->
pid
,
proc
->
name
,
num
);
proc
->
tf
->
eax
=
-
1
;
curproc
->
pid
,
cur
proc
->
name
,
num
);
cur
proc
->
tf
->
eax
=
-
1
;
}
}
sysfile.c
浏览文件 @
14270288
...
...
@@ -26,7 +26,7 @@ argfd(int n, int *pfd, struct file **pf)
if
(
argint
(
n
,
&
fd
)
<
0
)
return
-
1
;
if
(
fd
<
0
||
fd
>=
NOFILE
||
(
f
=
proc
->
ofile
[
fd
])
==
0
)
if
(
fd
<
0
||
fd
>=
NOFILE
||
(
f
=
myproc
()
->
ofile
[
fd
])
==
0
)
return
-
1
;
if
(
pfd
)
*
pfd
=
fd
;
...
...
@@ -41,10 +41,11 @@ static int
fdalloc
(
struct
file
*
f
)
{
int
fd
;
struct
proc
*
curproc
=
myproc
();
for
(
fd
=
0
;
fd
<
NOFILE
;
fd
++
){
if
(
proc
->
ofile
[
fd
]
==
0
){
proc
->
ofile
[
fd
]
=
f
;
if
(
cur
proc
->
ofile
[
fd
]
==
0
){
cur
proc
->
ofile
[
fd
]
=
f
;
return
fd
;
}
}
...
...
@@ -97,7 +98,7 @@ sys_close(void)
if
(
argfd
(
0
,
&
fd
,
&
f
)
<
0
)
return
-
1
;
proc
->
ofile
[
fd
]
=
0
;
myproc
()
->
ofile
[
fd
]
=
0
;
fileclose
(
f
);
return
0
;
}
...
...
@@ -373,7 +374,8 @@ sys_chdir(void)
{
char
*
path
;
struct
inode
*
ip
;
struct
proc
*
curproc
=
myproc
();
begin_op
();
if
(
argstr
(
0
,
&
path
)
<
0
||
(
ip
=
namei
(
path
))
==
0
){
end_op
();
...
...
@@ -386,9 +388,9 @@ sys_chdir(void)
return
-
1
;
}
iunlock
(
ip
);
iput
(
proc
->
cwd
);
iput
(
cur
proc
->
cwd
);
end_op
();
proc
->
cwd
=
ip
;
cur
proc
->
cwd
=
ip
;
return
0
;
}
...
...
@@ -432,7 +434,7 @@ sys_pipe(void)
fd0
=
-
1
;
if
((
fd0
=
fdalloc
(
rf
))
<
0
||
(
fd1
=
fdalloc
(
wf
))
<
0
){
if
(
fd0
>=
0
)
proc
->
ofile
[
fd0
]
=
0
;
myproc
()
->
ofile
[
fd0
]
=
0
;
fileclose
(
rf
);
fileclose
(
wf
);
return
-
1
;
...
...
sysproc.c
浏览文件 @
14270288
...
...
@@ -39,7 +39,7 @@ sys_kill(void)
int
sys_getpid
(
void
)
{
return
proc
->
pid
;
return
myproc
()
->
pid
;
}
int
...
...
@@ -50,7 +50,7 @@ sys_sbrk(void)
if
(
argint
(
0
,
&
n
)
<
0
)
return
-
1
;
addr
=
proc
->
sz
;
addr
=
myproc
()
->
sz
;
if
(
growproc
(
n
)
<
0
)
return
-
1
;
return
addr
;
...
...
@@ -67,7 +67,7 @@ sys_sleep(void)
acquire
(
&
tickslock
);
ticks0
=
ticks
;
while
(
ticks
-
ticks0
<
n
){
if
(
proc
->
killed
){
if
(
myproc
()
->
killed
){
release
(
&
tickslock
);
return
-
1
;
}
...
...
trap.c
浏览文件 @
14270288
...
...
@@ -37,18 +37,18 @@ void
trap
(
struct
trapframe
*
tf
)
{
if
(
tf
->
trapno
==
T_SYSCALL
){
if
(
proc
->
killed
)
if
(
myproc
()
->
killed
)
exit
();
proc
->
tf
=
tf
;
myproc
()
->
tf
=
tf
;
syscall
();
if
(
proc
->
killed
)
if
(
myproc
()
->
killed
)
exit
();
return
;
}
switch
(
tf
->
trapno
){
case
T_IRQ0
+
IRQ_TIMER
:
if
(
cpu
num
()
==
0
){
if
(
cpu
id
()
==
0
){
acquire
(
&
tickslock
);
ticks
++
;
wakeup
(
&
ticks
);
...
...
@@ -74,38 +74,38 @@ trap(struct trapframe *tf)
case
T_IRQ0
+
7
:
case
T_IRQ0
+
IRQ_SPURIOUS
:
cprintf
(
"cpu%d: spurious interrupt at %x:%x
\n
"
,
cpu
num
(),
tf
->
cs
,
tf
->
eip
);
cpu
id
(),
tf
->
cs
,
tf
->
eip
);
lapiceoi
();
break
;
//PAGEBREAK: 13
default:
if
(
proc
==
0
||
(
tf
->
cs
&
3
)
==
0
){
if
(
myproc
()
==
0
||
(
tf
->
cs
&
3
)
==
0
){
// In kernel, it must be our mistake.
cprintf
(
"unexpected trap %d from cpu %d eip %x (cr2=0x%x)
\n
"
,
tf
->
trapno
,
cpu
num
(),
tf
->
eip
,
rcr2
());
tf
->
trapno
,
cpu
id
(),
tf
->
eip
,
rcr2
());
panic
(
"trap"
);
}
// In user space, assume process misbehaved.
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
,
cpunum
(),
tf
->
eip
,
myproc
()
->
pid
,
myproc
()
->
name
,
tf
->
trapno
,
tf
->
err
,
cpuid
(),
tf
->
eip
,
rcr2
());
proc
->
killed
=
1
;
myproc
()
->
killed
=
1
;
}
// Force process exit if it has been killed and is in user space.
// (If it is still executing in the kernel, let it keep running
// until it gets to the regular system call return.)
if
(
proc
&&
proc
->
killed
&&
(
tf
->
cs
&
3
)
==
DPL_USER
)
if
(
myproc
()
&&
myproc
()
->
killed
&&
(
tf
->
cs
&
3
)
==
DPL_USER
)
exit
();
// Force process to give up CPU on clock tick.
// If interrupts were on while locks held, would need to check nlock.
if
(
proc
&&
proc
->
state
==
RUNNING
&&
tf
->
trapno
==
T_IRQ0
+
IRQ_TIMER
)
if
(
myproc
()
&&
myproc
()
->
state
==
RUNNING
&&
tf
->
trapno
==
T_IRQ0
+
IRQ_TIMER
)
yield
();
// Check if the process has been killed since we yielded
if
(
proc
&&
proc
->
killed
&&
(
tf
->
cs
&
3
)
==
DPL_USER
)
if
(
myproc
()
&&
myproc
()
->
killed
&&
(
tf
->
cs
&
3
)
==
DPL_USER
)
exit
();
}
trapasm.S
浏览文件 @
14270288
...
...
@@ -14,9 +14,6 @@ alltraps:
movw $(SEG_KDATA<<3), %ax
movw %ax, %ds
movw %ax, %es
movw $(SEG_KCPU<<3), %ax
movw %ax, %fs
movw %ax, %gs
# Call trap(tf), where tf=%esp
pushl %esp
...
...
vm.c
浏览文件 @
14270288
...
...
@@ -21,21 +21,12 @@ seginit(void)
// Cannot share a CODE descriptor for both kernel and user
// because it would have to have DPL_USR, but the CPU forbids
// an interrupt from CPL=0 to DPL=3.
c
=
&
cpus
[
cpu
num
()];
c
=
&
cpus
[
cpu
id
()];
c
->
gdt
[
SEG_KCODE
]
=
SEG
(
STA_X
|
STA_R
,
0
,
0xffffffff
,
0
);
c
->
gdt
[
SEG_KDATA
]
=
SEG
(
STA_W
,
0
,
0xffffffff
,
0
);
c
->
gdt
[
SEG_UCODE
]
=
SEG
(
STA_X
|
STA_R
,
0
,
0xffffffff
,
DPL_USER
);
c
->
gdt
[
SEG_UDATA
]
=
SEG
(
STA_W
,
0
,
0xffffffff
,
DPL_USER
);
// Map cpu and proc -- these are private per cpu.
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
;
}
// Return the address of the PTE in page table pgdir
...
...
@@ -173,13 +164,13 @@ switchuvm(struct proc *p)
panic
(
"switchuvm: no pgdir"
);
pushcli
();
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
)
p
->
kstack
+
KSTACKSIZE
;
mycpu
()
->
gdt
[
SEG_TSS
]
=
SEG16
(
STS_T32A
,
&
mycpu
()
->
ts
,
sizeof
(
mycpu
()
->
ts
)
-
1
,
0
);
mycpu
()
->
gdt
[
SEG_TSS
].
s
=
0
;
mycpu
()
->
ts
.
ss0
=
SEG_KDATA
<<
3
;
mycpu
()
->
ts
.
esp0
=
(
uint
)
p
->
kstack
+
KSTACKSIZE
;
// setting IOPL=0 in eflags *and* iomb beyond the tss segment limit
// forbids I/O instructions (e.g., inb and outb) from user space
cpu
->
ts
.
iomb
=
(
ushort
)
0xFFFF
;
mycpu
()
->
ts
.
iomb
=
(
ushort
)
0xFFFF
;
ltr
(
SEG_TSS
<<
3
);
lcr3
(
V2P
(
p
->
pgdir
));
// switch to process's address space
popcli
();
...
...
编写
预览
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论