Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
X
xv6-public
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
统计图
问题
0
问题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
银宸时代
OS Lab Group
奖励实验
xv6-public
提交
df5cc916
提交
df5cc916
6月 22, 2006
创建
作者:
rtm
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
compile "user programs"
curproc array
上级
bf49aedb
隐藏空白字符变更
内嵌
并排
正在显示
11 个修改的文件
包含
139 行增加
和
64 行删除
+139
-64
Makefile
Makefile
+7
-3
defs.h
defs.h
+3
-1
main.c
main.c
+47
-7
mp.c
mp.c
+16
-16
proc.c
proc.c
+27
-19
proc.h
proc.h
+2
-2
spinlock.c
spinlock.c
+4
-4
syscall.c
syscall.c
+14
-11
trap.c
trap.c
+4
-1
trapasm.S
trapasm.S
+2
-0
user1.c
user1.c
+13
-0
没有找到文件。
Makefile
浏览文件 @
df5cc916
...
...
@@ -20,18 +20,22 @@ bootblock : bootasm.S bootmain.c
$(OBJCOPY)
-S
-O
binary bootblock.o bootblock
./sign.pl bootblock
kernel
:
$(OBJS) bootother.S
kernel
:
$(OBJS) bootother.S
user1
$(CC)
-nostdinc
-I
.
-c
bootother.S
$(LD)
-N
-e
start
-Ttext
0x7000
-o
bootother.out bootother.o
$(OBJCOPY)
-S
-O
binary bootother.out bootother
$(OBJDUMP)
-S
bootother.o
>
bootother.asm
$(LD)
-Ttext
0x100000
-e
main
-o
kernel
$(OBJS)
-b
binary bootother
$(LD)
-Ttext
0x100000
-e
main
-o
kernel
$(OBJS)
-b
binary bootother
user1
$(OBJDUMP)
-S
kernel
>
kernel.asm
vectors.S
:
vectors.pl
perl vectors.pl
>
vectors.S
user1
:
user1.c
$(CC)
-nostdinc
-I
.
-c
user1.c
$(LD)
-N
-e
main
-Ttext
0
-o
user1 user1.o
-include
*.d
clean
:
rm
-f
*
.o bootblock kernel kernel.asm xv6.img
*
.d
rm
-f
*
.o bootblock kernel kernel.asm xv6.img
*
.d
user1
defs.h
浏览文件 @
df5cc916
...
...
@@ -33,7 +33,7 @@ void pic_init(void);
// mp.c
void
mp_init
(
void
);
int
lapic_cpu_number
(
void
);
int
cpu
(
void
);
int
mp_isbcpu
(
void
);
// spinlock.c
...
...
@@ -42,3 +42,5 @@ void acquire_spinlock(uint32_t* lock);
void
release_spinlock
(
uint32_t
*
lock
);
void
release_grant_spinlock
(
uint32_t
*
lock
,
int
cpu
);
// main.c
void
load_icode
(
struct
proc
*
p
,
uint8_t
*
binary
,
unsigned
size
);
main.c
浏览文件 @
df5cc916
...
...
@@ -6,9 +6,13 @@
#include "x86.h"
#include "traps.h"
#include "syscall.h"
#include "elf.h"
#include "param.h"
extern
char
edata
[],
end
[];
extern
int
acpu
;
extern
char
_binary_user1_start
[];
extern
char
_binary_user1_size
[];
char
buf
[
512
];
...
...
@@ -16,12 +20,14 @@ int
main
()
{
struct
proc
*
p
;
int
i
;
if
(
acpu
)
{
cprintf
(
"an application processor
\n
"
);
release_spinlock
(
&
kernel_lock
);
while
(
1
)
;
acquire_spinlock
(
&
kernel_lock
);
lapic_init
(
cpu
());
curproc
[
cpu
()]
=
&
proc
[
0
];
// XXX
swtch
();
}
acpu
=
1
;
// clear BSS
...
...
@@ -34,11 +40,9 @@ main()
tinit
();
// traps and interrupts
pic_init
();
while
(
1
);
// create fake process zero
p
=
&
proc
[
0
];
curproc
=
p
;
curproc
[
cpu
()]
=
p
;
p
->
state
=
WAITING
;
p
->
sz
=
PAGE
;
p
->
mem
=
kalloc
(
p
->
sz
);
...
...
@@ -54,17 +58,20 @@ main()
setupsegs
(
p
);
// turn on interrupts
irq_setmask_8259A
(
0xff
);
write_eflags
(
read_eflags
()
|
FL_IF
);
irq_setmask_8259A
(
0
);
#if 0
ide_read(0, buf, 1);
cprintf("sec0.0 %x\n", buf[0] & 0xff);
#endif
#if
0
#if
1
p
=
newproc
();
load_icode
(
p
,
_binary_user1_start
,
(
unsigned
)
_binary_user1_size
);
#endif
#if 0
i = 0;
p->mem[i++] = 0x90; // nop
p->mem[i++] = 0xb8; // mov ..., %eax
...
...
@@ -96,3 +103,36 @@ main()
return
0
;
}
void
load_icode
(
struct
proc
*
p
,
uint8_t
*
binary
,
unsigned
size
)
{
int
i
;
struct
Elf
*
elf
;
struct
Proghdr
*
ph
;
// Check magic number on binary
elf
=
(
struct
Elf
*
)
binary
;
cprintf
(
"elf %x magic %x
\n
"
,
elf
,
elf
->
e_magic
);
if
(
elf
->
e_magic
!=
ELF_MAGIC
)
panic
(
"load_icode: not an ELF binary"
);
p
->
tf
->
tf_eip
=
elf
->
e_entry
;
p
->
tf
->
tf_esp
=
p
->
sz
;
// Map and load segments as directed.
ph
=
(
struct
Proghdr
*
)
(
binary
+
elf
->
e_phoff
);
for
(
i
=
0
;
i
<
elf
->
e_phnum
;
i
++
,
ph
++
)
{
if
(
ph
->
p_type
!=
ELF_PROG_LOAD
)
continue
;
cprintf
(
"va %x memsz %d
\n
"
,
ph
->
p_va
,
ph
->
p_memsz
);
if
(
ph
->
p_va
+
ph
->
p_memsz
<
ph
->
p_va
)
panic
(
"load_icode: overflow in elf header segment"
);
if
(
ph
->
p_va
+
ph
->
p_memsz
>=
p
->
sz
)
panic
(
"load_icode: icode wants to be above UTOP"
);
// Load/clear the segment
memcpy
(
p
->
mem
+
ph
->
p_va
,
binary
+
ph
->
p_offset
,
ph
->
p_filesz
);
memset
(
p
->
mem
+
ph
->
p_va
+
ph
->
p_filesz
,
0
,
ph
->
p_memsz
-
ph
->
p_filesz
);
}
}
mp.c
浏览文件 @
df5cc916
...
...
@@ -97,7 +97,7 @@ static uint32_t *lapicaddr;
static
struct
cpu
{
uint8_t
apicid
;
/* Local APIC ID */
int
lintr
[
2
];
/* Local APIC */
}
cpu
[
NCPU
];
}
cpu
s
[
NCPU
];
static
int
ncpu
;
static
struct
cpu
*
bcpu
;
...
...
@@ -113,7 +113,7 @@ lapic_write(int r, int data)
*
(
lapicaddr
+
(
r
/
sizeof
(
*
lapicaddr
)))
=
data
;
}
static
void
void
lapic_init
(
int
c
)
{
uint32_t
r
,
lvt
;
...
...
@@ -131,8 +131,8 @@ lapic_init(int c)
* LINT[01] are set to ExtINT.
* Acknowledge any outstanding interrupts.
*/
lapic_write
(
LAPIC_LINT0
,
cpu
[
c
].
lintr
[
0
]);
lapic_write
(
LAPIC_LINT1
,
cpu
[
c
].
lintr
[
1
]);
lapic_write
(
LAPIC_LINT0
,
cpu
s
[
c
].
lintr
[
0
]);
lapic_write
(
LAPIC_LINT1
,
cpu
s
[
c
].
lintr
[
1
]);
lapic_write
(
LAPIC_EOI
,
0
);
lvt
=
(
lapic_read
(
LAPIC_VER
)
>>
16
)
&
0xFF
;
...
...
@@ -168,7 +168,7 @@ lapic_online(void)
}
int
lapic_cpu_number
(
void
)
cpu
(
void
)
{
return
(
lapic_read
(
LAPIC_ID
)
>>
24
)
&
0xFF
;
}
...
...
@@ -312,12 +312,12 @@ mp_init()
switch
(
*
p
){
case
MPPROCESSOR
:
proc
=
(
struct
MPPE
*
)
p
;
cpu
[
ncpu
].
apicid
=
proc
->
apicid
;
cpu
[
ncpu
].
lintr
[
0
]
=
APIC_IMASK
;
cpu
[
ncpu
].
lintr
[
1
]
=
APIC_IMASK
;
cprintf
(
"a processor %x
\n
"
,
cpu
[
ncpu
].
apicid
);
cpu
s
[
ncpu
].
apicid
=
proc
->
apicid
;
cpu
s
[
ncpu
].
lintr
[
0
]
=
APIC_IMASK
;
cpu
s
[
ncpu
].
lintr
[
1
]
=
APIC_IMASK
;
cprintf
(
"a processor %x
\n
"
,
cpu
s
[
ncpu
].
apicid
);
if
(
proc
->
flags
&
MPBP
)
{
bcpu
=
&
cpu
[
ncpu
];
bcpu
=
&
cpu
s
[
ncpu
];
}
ncpu
++
;
p
+=
sizeof
(
struct
MPPE
);
...
...
@@ -342,8 +342,8 @@ mp_init()
}
}
lapic_init
(
cpu
-
bcpu
);
cprintf
(
"ncpu: %d boot %d
\n
"
,
ncpu
,
cpu
-
bcpu
);
lapic_init
(
bcpu
-
cpus
);
cprintf
(
"ncpu: %d boot %d
\n
"
,
ncpu
,
bcpu
-
cpus
);
lapic_online
();
...
...
@@ -352,12 +352,12 @@ mp_init()
(
uint32_t
)
_binary_bootother_size
);
acquire_spinlock
(
&
kernel_lock
);
for
(
c
=
cpu
;
c
<
&
cpu
[
ncpu
];
c
++
)
{
for
(
c
=
cpu
s
;
c
<
&
cpus
[
ncpu
];
c
++
)
{
if
(
c
==
bcpu
)
continue
;
cprintf
(
"starting processor %d
\n
"
,
c
-
cpu
);
release_grant_spinlock
(
&
kernel_lock
,
c
-
cpu
);
cprintf
(
"starting processor %d
\n
"
,
c
-
cpu
s
);
release_grant_spinlock
(
&
kernel_lock
,
c
-
cpu
s
);
lapic_startap
(
c
,
(
uint32_t
)
KADDR
(
APBOOTCODE
));
acquire_spinlock
(
&
kernel_lock
);
cprintf
(
"done starting processor %d
\n
"
,
c
-
cpu
);
cprintf
(
"done starting processor %d
\n
"
,
c
-
cpu
s
);
}
}
proc.c
浏览文件 @
df5cc916
#include "types.h"
#include "mmu.h"
#include "x86.h"
#include "proc.h"
#include "param.h"
#include "proc.h"
#include "defs.h"
struct
proc
proc
[
NPROC
];
struct
proc
*
curproc
;
struct
proc
*
curproc
[
NCPU
]
;
int
next_pid
=
1
;
/*
...
...
@@ -47,6 +47,7 @@ struct proc *
newproc
()
{
struct
proc
*
np
;
struct
proc
*
op
=
curproc
[
cpu
()];
unsigned
*
sp
;
for
(
np
=
&
proc
[
1
];
np
<
&
proc
[
NPROC
];
np
++
)
...
...
@@ -56,22 +57,22 @@ newproc()
return
0
;
np
->
pid
=
next_pid
++
;
np
->
ppid
=
curproc
->
pid
;
np
->
sz
=
curproc
->
sz
;
np
->
mem
=
kalloc
(
curproc
->
sz
);
np
->
ppid
=
op
->
pid
;
np
->
sz
=
op
->
sz
;
np
->
mem
=
kalloc
(
op
->
sz
);
if
(
np
->
mem
==
0
)
return
0
;
memcpy
(
np
->
mem
,
curproc
->
mem
,
np
->
sz
);
memcpy
(
np
->
mem
,
op
->
mem
,
np
->
sz
);
np
->
kstack
=
kalloc
(
KSTACKSIZE
);
if
(
np
->
kstack
==
0
){
kfree
(
np
->
mem
,
curproc
->
sz
);
kfree
(
np
->
mem
,
op
->
sz
);
return
0
;
}
setupsegs
(
np
);
// set up kernel stack to return to user space
np
->
tf
=
(
struct
Trapframe
*
)
(
np
->
kstack
+
KSTACKSIZE
-
sizeof
(
struct
Trapframe
));
*
(
np
->
tf
)
=
*
(
curproc
->
tf
);
*
(
np
->
tf
)
=
*
(
op
->
tf
);
sp
=
(
unsigned
*
)
np
->
tf
;
*
(
--
sp
)
=
(
unsigned
)
&
trapret
;
// for return from swtch()
*
(
--
sp
)
=
0
;
// previous bp for leave in swtch()
...
...
@@ -92,31 +93,38 @@ void
swtch
()
{
struct
proc
*
np
;
struct
proc
*
op
=
curproc
[
cpu
()];
cprintf
(
"swtch cpu %d op %x proc0 %x
\n
"
,
cpu
(),
op
,
proc
);
while
(
1
){
for
(
np
=
curproc
+
1
;
np
!=
curproc
;
np
++
){
if
(
np
==
&
proc
[
NPROC
])
np
=
&
proc
[
0
];
np
=
op
+
1
;
while
(
np
!=
op
){
if
(
np
->
state
==
RUNNABLE
)
break
;
np
++
;
if
(
np
==
&
proc
[
NPROC
])
np
=
&
proc
[
0
];
}
if
(
np
->
state
==
RUNNABLE
)
break
;
// idle...
cprintf
(
"swtch: nothing to run
\n
"
);
release_spinlock
(
&
kernel_lock
);
acquire_spinlock
(
&
kernel_lock
);
}
curproc
->
ebp
=
read_ebp
();
curproc
->
esp
=
read_esp
();
op
->
ebp
=
read_ebp
();
op
->
esp
=
read_esp
();
cprintf
(
"
swtch %x -> %x
\n
"
,
curproc
,
np
);
cprintf
(
"
cpu %d swtch %x -> %x
\n
"
,
cpu
(),
op
,
np
);
curproc
=
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.
curproc
->
gdt
[
SEG_TSS
].
sd_type
=
STS_T32A
;
np
->
gdt
[
SEG_TSS
].
sd_type
=
STS_T32A
;
// XXX probably ought to lgdt on trap return too, in case
// a system call has moved a program or changed its size.
...
...
@@ -134,8 +142,8 @@ swtch()
void
sleep
(
void
*
chan
)
{
curproc
->
chan
=
chan
;
curproc
->
state
=
WAITING
;
curproc
[
cpu
()]
->
chan
=
chan
;
curproc
[
cpu
()]
->
state
=
WAITING
;
swtch
();
}
...
...
proc.h
浏览文件 @
df5cc916
...
...
@@ -20,7 +20,7 @@ struct proc{
char
*
mem
;
// start of process's physical memory
unsigned
sz
;
// total size of mem, including kernel stack
char
*
kstack
;
// kernel stack, separate from mem so it doesn't move
enum
{
UNUSED
,
RUNNABLE
,
WAITING
,
ZOMBIE
}
state
;
enum
{
UNUSED
,
RUNNABLE
,
WAITING
,
ZOMBIE
,
RUNNING
}
state
;
int
pid
;
int
ppid
;
void
*
chan
;
// sleep
...
...
@@ -35,4 +35,4 @@ struct proc{
};
extern
struct
proc
proc
[];
extern
struct
proc
*
curproc
;
extern
struct
proc
*
curproc
[
NCPU
]
;
spinlock.c
浏览文件 @
df5cc916
...
...
@@ -10,18 +10,18 @@ uint32_t kernel_lock = LOCK_FREE;
void
acquire_spinlock
(
uint32_t
*
lock
)
{
int
cpu_id
=
lapic_cpu_number
();
cprintf
(
"acquire: %d
\n
"
,
cpu_id
);
int
cpu_id
=
cpu
();
if
(
*
lock
==
cpu_id
)
return
;
while
(
cmpxchg
(
LOCK_FREE
,
cpu_id
,
lock
)
!=
cpu_id
)
{
;
}
cprintf
(
"acquired: %d
\n
"
,
cpu_id
);
}
void
release_spinlock
(
uint32_t
*
lock
)
{
int
cpu_id
=
lapic_cpu_number
();
int
cpu_id
=
cpu
();
cprintf
(
"release: %d
\n
"
,
cpu_id
);
if
(
*
lock
!=
cpu_id
)
panic
(
"release_spinlock: releasing a lock that i don't own
\n
"
);
...
...
@@ -31,7 +31,7 @@ release_spinlock(uint32_t* lock)
void
release_grant_spinlock
(
uint32_t
*
lock
,
int
c
)
{
int
cpu_id
=
lapic_cpu_number
();
int
cpu_id
=
cpu
();
cprintf
(
"release_grant: %d -> %d
\n
"
,
cpu_id
,
c
);
if
(
*
lock
!=
cpu_id
)
panic
(
"release_spinlock: releasing a lock that i don't own
\n
"
);
...
...
syscall.c
浏览文件 @
df5cc916
...
...
@@ -25,17 +25,18 @@ void
sys_exit
()
{
struct
proc
*
p
;
struct
proc
*
cp
=
curproc
[
cpu
()];
c
urproc
->
state
=
ZOMBIE
;
c
p
->
state
=
ZOMBIE
;
// wake up parent
for
(
p
=
proc
;
p
<
&
proc
[
NPROC
];
p
++
)
if
(
p
->
pid
==
c
urproc
->
ppid
)
if
(
p
->
pid
==
c
p
->
ppid
)
wakeup
(
p
);
// abandon children
for
(
p
=
proc
;
p
<
&
proc
[
NPROC
];
p
++
)
if
(
p
->
ppid
==
c
urproc
->
pid
)
if
(
p
->
ppid
==
c
p
->
pid
)
p
->
pid
=
1
;
swtch
();
...
...
@@ -45,37 +46,39 @@ void
sys_wait
()
{
struct
proc
*
p
;
struct
proc
*
cp
=
curproc
[
cpu
()];
int
any
;
cprintf
(
"waid pid %d ppid %d
\n
"
,
c
urproc
->
pid
,
curproc
->
ppid
);
cprintf
(
"waid pid %d ppid %d
\n
"
,
c
p
->
pid
,
cp
->
ppid
);
while
(
1
){
any
=
0
;
for
(
p
=
proc
;
p
<
&
proc
[
NPROC
];
p
++
){
if
(
p
->
state
==
ZOMBIE
&&
p
->
ppid
==
c
urproc
->
pid
){
if
(
p
->
state
==
ZOMBIE
&&
p
->
ppid
==
c
p
->
pid
){
kfree
(
p
->
mem
,
p
->
sz
);
kfree
(
p
->
kstack
,
KSTACKSIZE
);
p
->
state
=
UNUSED
;
cprintf
(
"%x collected %x
\n
"
,
c
urproc
,
p
);
cprintf
(
"%x collected %x
\n
"
,
c
p
,
p
);
return
;
}
if
(
p
->
state
!=
UNUSED
&&
p
->
ppid
==
c
urproc
->
pid
)
if
(
p
->
state
!=
UNUSED
&&
p
->
ppid
==
c
p
->
pid
)
any
=
1
;
}
if
(
any
==
0
){
cprintf
(
"%x nothing to wait for
\n
"
,
c
urproc
);
cprintf
(
"%x nothing to wait for
\n
"
,
c
p
);
return
;
}
sleep
(
c
urproc
);
sleep
(
c
p
);
}
}
void
syscall
()
{
int
num
=
curproc
->
tf
->
tf_regs
.
reg_eax
;
struct
proc
*
cp
=
curproc
[
cpu
()];
int
num
=
cp
->
tf
->
tf_regs
.
reg_eax
;
cprintf
(
"%x sys %d
\n
"
,
c
urproc
,
num
);
cprintf
(
"%x sys %d
\n
"
,
c
p
,
num
);
switch
(
num
){
case
SYS_fork
:
sys_fork
();
...
...
trap.c
浏览文件 @
df5cc916
...
...
@@ -29,10 +29,13 @@ void
trap
(
struct
Trapframe
*
tf
)
{
int
v
=
tf
->
tf_trapno
;
acquire_spinlock
(
&
kernel_lock
);
// released in trapret in trapasm.S
cprintf
(
"trap %d eip %x:%x
\n
"
,
tf
->
tf_trapno
,
tf
->
tf_cs
,
tf
->
tf_eip
);
if
(
v
==
T_SYSCALL
){
curproc
->
tf
=
tf
;
curproc
[
cpu
()]
->
tf
=
tf
;
syscall
();
return
;
}
...
...
trapasm.S
浏览文件 @
df5cc916
...
...
@@ -22,6 +22,8 @@ alltraps:
* expects ESP to point to a Trapframe
*/
trapret:
push $kernel_lock
call release_spinlock
popal
popl %es
popl %ds
...
...
user1.c
0 → 100644
浏览文件 @
df5cc916
void
fork
()
{
asm
(
"mov $1, %eax"
);
asm
(
"int $48"
);
}
main
()
{
fork
();
while
(
1
)
;
}
编写
预览
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论