Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
X
xv6-public
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
统计图
问题
0
问题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
银宸时代
OS Lab Group
奖励实验
xv6-public
提交
5628c3d8
提交
5628c3d8
10月 24, 2011
创建
作者:
Silas Boyd-Wickizer
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
CP -- proc.c and trapasm.S hacking..
上级
54ee87d7
隐藏空白字符变更
内嵌
并排
正在显示
8 个修改的文件
包含
225 行增加
和
18 行删除
+225
-18
fs.c
fs.c
+7
-0
kernel.h
kernel.h
+9
-0
main.c
main.c
+3
-0
proc.c
proc.c
+128
-1
proc.h
proc.h
+6
-0
trapasm.S
trapasm.S
+36
-17
x86.h
x86.h
+35
-0
xv6-mtrace.h
xv6-mtrace.h
+1
-0
没有找到文件。
fs.c
浏览文件 @
5628c3d8
...
...
@@ -8,6 +8,13 @@ namecmp(const char *s, const char *t)
return
strncmp
(
s
,
t
,
DIRSIZ
);
}
struct
inode
*
namei
(
char
*
path
)
{
panic
(
"namei"
);
return
NULL
;
}
#if 0
// File system implementation. Four layers:
// + Blocks: allocator for raw disk blocks.
...
...
kernel.h
浏览文件 @
5628c3d8
...
...
@@ -12,6 +12,8 @@ static inline void *p2v(uptr a) { return (void *) a + KBASE; }
struct
spinlock
;
struct
condvar
;
struct
proc
;
struct
vmnode
;
struct
vmap
;
// bio.c
void
binit
(
void
);
...
...
@@ -34,6 +36,7 @@ void snprintf(char *buf, u32 n, char *fmt, ...);
// fs.c
int
namecmp
(
const
char
*
,
const
char
*
);
struct
inode
*
namei
(
char
*
);
// ide.c
void
ideinit
(
void
);
...
...
@@ -145,3 +148,9 @@ int strcmp(const char *p, const char *q);
// uart.c
void
uartputc
(
char
c
);
// vm.c
struct
vmap
*
vmap_alloc
(
void
);
struct
vmnode
*
vmn_allocpg
(
u64
npg
);
int
vmap_insert
(
struct
vmap
*
,
struct
vmnode
*
n
,
uptr
);
int
copyout
(
struct
vmap
*
,
uptr
,
void
*
,
u64
);
main.c
浏览文件 @
5628c3d8
...
...
@@ -14,6 +14,7 @@ extern void initkalloc(void);
extern
void
initrcu
(
void
);
extern
void
initproc
(
void
);
extern
void
initbio
(
void
);
extern
void
inituser
(
void
);
void
cmain
(
void
)
...
...
@@ -38,6 +39,8 @@ cmain(void)
ideinit(); // disk
#endif
inituser
();
// first user process
cprintf
(
"ncpu %d
\n
"
,
ncpu
);
panic
(
"end"
);
}
proc.c
浏览文件 @
5628c3d8
...
...
@@ -8,10 +8,16 @@
#include "condvar.h"
#include "queue.h"
#include "proc.h"
#include "cpu.h"
#include "bits.h"
#include "xv6-mtrace.h"
extern
void
trapret
(
void
);
int
__mpalign__
idle
[
NCPU
];
struct
ns
*
nspid
__mpalign__
;
struct
ns
*
nsrunq
__mpalign__
;
static
struct
proc
*
bootproc
__mpalign__
;
void
sched
(
void
)
...
...
@@ -25,6 +31,127 @@ addrun(struct proc *p)
panic
(
"addrun"
);
}
// A fork child's very first scheduling by scheduler()
// will swtch here. "Return" to user space.
static
void
forkret
(
void
)
{
// Still holding proc->lock from scheduler.
release
(
&
myproc
()
->
lock
);
// Just for the first process. can't do it earlier
// b/c file system code needs a process context
// in which to call cv_sleep().
if
(
myproc
()
->
cwd
==
0
)
{
mtrace_kstack_start
(
forkret
,
myproc
());
myproc
()
->
cwd
=
namei
(
"/"
);
mtrace_kstack_stop
(
myproc
());
}
// Return to "caller", actually trapret (see allocproc).
}
// Look in the process table for an UNUSED proc.
// If found, change state to EMBRYO and initialize
// state required to run in the kernel.
// Otherwise return 0.
static
struct
proc
*
allocproc
(
void
)
{
struct
proc
*
p
;
char
*
sp
;
p
=
kmalloc
(
sizeof
(
struct
proc
));
if
(
p
==
0
)
return
0
;
memset
(
p
,
0
,
sizeof
(
*
p
));
p
->
state
=
EMBRYO
;
p
->
pid
=
ns_allockey
(
nspid
);
p
->
epoch
=
INF
;
p
->
cpuid
=
mycpu
()
->
id
;
p
->
on_runq
=
-
1
;
p
->
cpu_pin
=
0
;
p
->
mtrace_stacks
.
curr
=
-
1
;
snprintf
(
p
->
lockname
,
sizeof
(
p
->
lockname
),
"cv:proc:%d"
,
p
->
pid
);
initlock
(
&
p
->
lock
,
p
->
lockname
+
3
);
initcondvar
(
&
p
->
cv
,
p
->
lockname
);
if
(
ns_insert
(
nspid
,
KI
(
p
->
pid
),
(
void
*
)
p
)
<
0
)
panic
(
"allocproc: ns_insert"
);
// Allocate kernel stack if possible.
if
((
p
->
kstack
=
kalloc
())
==
0
){
if
(
ns_remove
(
nspid
,
KI
(
p
->
pid
),
p
)
==
0
)
panic
(
"allocproc: ns_remove"
);
rcu_delayed
(
p
,
kmfree
);
return
0
;
}
sp
=
p
->
kstack
+
KSTACKSIZE
;
// Leave room for trap frame.
sp
-=
sizeof
*
p
->
tf
;
p
->
tf
=
(
struct
trapframe
*
)
sp
;
// Set up new context to start executing at forkret,
// which returns to trapret.
sp
-=
8
;
*
(
u64
*
)
sp
=
(
u64
)
trapret
;
sp
-=
sizeof
*
p
->
context
;
p
->
context
=
(
struct
context
*
)
sp
;
memset
(
p
->
context
,
0
,
sizeof
*
p
->
context
);
p
->
context
->
rip
=
(
uptr
)
forkret
;
return
p
;
}
// Set up first user process.
void
inituser
(
void
)
{
struct
proc
*
p
;
extern
char
_binary_initcode_start
[],
_binary_initcode_size
[];
p
=
allocproc
();
bootproc
=
p
;
if
((
p
->
vmap
=
vmap_alloc
())
==
0
)
panic
(
"userinit: out of vmaps?"
);
struct
vmnode
*
vmn
=
vmn_allocpg
(
PGROUNDUP
((
uptr
)
_binary_initcode_size
)
/
PGSIZE
);
if
(
vmn
==
0
)
panic
(
"userinit: vmn_allocpg"
);
if
(
vmap_insert
(
p
->
vmap
,
vmn
,
0
)
<
0
)
panic
(
"userinit: vmap_insert"
);
if
(
copyout
(
p
->
vmap
,
0
,
_binary_initcode_start
,
(
uptr
)
_binary_initcode_size
)
<
0
)
panic
(
"userinit: copyout"
);
memset
(
p
->
tf
,
0
,
sizeof
(
*
p
->
tf
));
p
->
tf
->
rflags
=
FL_IF
;
p
->
tf
->
rsp
=
PGSIZE
;
p
->
tf
->
rip
=
0
;
// beginning of initcode.S
safestrcpy
(
p
->
name
,
"initcode"
,
sizeof
(
p
->
name
));
p
->
cwd
=
0
;
// forkret will fix in the process's context
acquire
(
&
p
->
lock
);
addrun
(
p
);
p
->
state
=
RUNNABLE
;
release
(
&
p
->
lock
);
for
(
u32
c
=
0
;
c
<
NCPU
;
c
++
)
{
struct
proc
*
rcup
=
allocproc
();
rcup
->
vmap
=
vmap_alloc
();
rcup
->
context
->
rip
=
(
u64
)
rcu_gc_worker
;
rcup
->
cwd
=
0
;
rcup
->
cpuid
=
c
;
rcup
->
cpu_pin
=
1
;
acquire
(
&
rcup
->
lock
);
rcup
->
state
=
RUNNABLE
;
addrun
(
rcup
);
release
(
&
rcup
->
lock
);
}
}
void
initproc
(
void
)
{
...
...
@@ -115,7 +242,7 @@ allocproc(void)
// Set up new context to start executing at forkret,
// which returns to trapret.
sp -=
4
;
sp -=
8
;
*(uint*)sp = (uint)trapret;
sp -= sizeof *p->context;
...
...
proc.h
浏览文件 @
5628c3d8
#include "spinlock.h"
// Saved registers for kernel context switches.
struct
context
{
u64
rip
;
};
// Per-process, per-stack meta data for mtrace
#define MTRACE_NSTACKS 16
#define MTRACE_TAGSHIFT 28
...
...
trapasm.S
浏览文件 @
5628c3d8
...
...
@@ -17,26 +17,45 @@
trappush:
pushq $0 // error code
trapcommon:
// TODO(rsc): Do we need to push ds, es, fs, gs?
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %r11
pushq %r10
pushq %r9
pushq %r8
pushq %rdi
pushq %rsi
pushq %rbp
pushq $0 // sp
pushq %rbx
pushq %rdx
pushq %rcx
pushq %rax
pushq %rdi
pushq %rsi
pushq %rdx
pushq %rcx
pushq %rax
pushq %r8
pushq %r9
pushq %r10
pushq %r11
pushq %rbx
pushq %rbp
pushq %r12
pushq %r13
pushq %r14
pushq %r15
movq %rsp, %rdi // first argument to trap
call trap
.globl trapret
.align 8
trapret:
popq %r15
popq %r14
popq %r13
popq %r12
popq %rbp
popq %rbx
popq %r11
popq %r10
popq %r9
popq %r8
popq %rax
popq %rcx
popq %rdx
popq %rsi
popq %rdi
addq $0x12, %rsp // trapno, err
iret
.data
.align 8
.globl trapentry
...
...
x86.h
浏览文件 @
5628c3d8
...
...
@@ -103,3 +103,38 @@ writemsr(u32 msr, u64 val)
u32
hi
=
val
>>
32
;
__asm
volatile
(
"wrmsr"
:
:
"c"
(
msr
),
"a"
(
lo
),
"d"
(
hi
));
}
// Layout of the trap frame built on the stack by the
// hardware and by trapasm.S, and passed to trap().
struct
trapframe
{
u64
r15
;
u64
r14
;
u64
r13
;
u64
r12
;
u64
rbp
;
u64
rbx
;
// amd64 ABI callee saved registers
u64
r11
;
u64
r10
;
u64
r9
;
u64
r8
;
u64
rax
;
u64
rcx
;
u64
rdx
;
u64
rsi
;
u64
rdi
;
u64
trapno
;
// Below here defined by amd64 hardware
u32
err
;
u16
padding2
[
2
];
u64
rip
;
u16
cs
;
u16
padding1
[
3
];
u64
rflags
;
// Unlike 32-bit, amd64 hardware always pushes below
u64
rsp
;
u16
ss
;
u16
padding0
[
3
];
}
__attribute__
((
packed
));
xv6-mtrace.h
浏览文件 @
5628c3d8
...
...
@@ -21,4 +21,5 @@ char* strncpy(char *s, const char *t, int n);
#define mtrace_lock_register(ip, x, name, op, y)
#define mtrace_label_register(t, r, x, y, z, ip)
#define mtrace_kstack_start(x, y)
#define mtrace_kstack_stop(x)
#endif
编写
预览
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论