Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
X
xv6-public
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
统计图
问题
0
问题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
银宸时代
OS Lab Group
奖励实验
xv6-public
提交
d55b2fac
提交
d55b2fac
8月 26, 2010
创建
作者:
Frans Kaashoek
浏览文件
操作
浏览文件
下载
差异文件
Merge commit 'origin/page' into page
上级
d87f51c5
789b508d
全部展开
隐藏空白字符变更
内嵌
并排
正在显示
21 个修改的文件
包含
351 行增加
和
167 行删除
+351
-167
Makefile
Makefile
+1
-1
asm.h
asm.h
+2
-0
bootasm.S
bootasm.S
+4
-2
bootother.S
bootother.S
+4
-2
defs.h
defs.h
+4
-8
exec.c
exec.c
+5
-2
kalloc.c
kalloc.c
+2
-7
main.c
main.c
+27
-15
mmu.h
mmu.h
+7
-26
proc.c
proc.c
+12
-7
proc.h
proc.h
+5
-4
runoff.list
runoff.list
+1
-0
sh.c
sh.c
+0
-1
swtch.S
swtch.S
+0
-8
syscall.c
syscall.c
+2
-0
syscall.h
syscall.h
+1
-0
sysproc.c
sysproc.c
+15
-1
trap.c
trap.c
+1
-1
usertests.c
usertests.c
+136
-1
usys.S
usys.S
+1
-0
vm.c
vm.c
+121
-81
没有找到文件。
Makefile
浏览文件 @
d55b2fac
...
@@ -38,7 +38,7 @@ AS = $(TOOLPREFIX)gas
...
@@ -38,7 +38,7 @@ AS = $(TOOLPREFIX)gas
LD
=
$(TOOLPREFIX)
ld
LD
=
$(TOOLPREFIX)
ld
OBJCOPY
=
$(TOOLPREFIX)
objcopy
OBJCOPY
=
$(TOOLPREFIX)
objcopy
OBJDUMP
=
$(TOOLPREFIX)
objdump
OBJDUMP
=
$(TOOLPREFIX)
objdump
CFLAGS
=
-fno-pic
-static
-fno-builtin
-fno-strict-aliasing
-O2
-Wall
-MD
-ggdb
-m32
CFLAGS
=
-fno-pic
-static
-fno-builtin
-fno-strict-aliasing
-O2
-Wall
-MD
-ggdb
-m32
-Werror
CFLAGS
+=
$(
shell
$(CC)
-fno-stack-protector
-E
-x
c /dev/null
>
/dev/null 2>&1
&&
echo
-fno-stack-protector
)
CFLAGS
+=
$(
shell
$(CC)
-fno-stack-protector
-E
-x
c /dev/null
>
/dev/null 2>&1
&&
echo
-fno-stack-protector
)
ASFLAGS
=
-m32
-gdwarf-2
ASFLAGS
=
-m32
-gdwarf-2
# FreeBSD ld wants ``elf_i386_fbsd''
# FreeBSD ld wants ``elf_i386_fbsd''
...
...
asm.h
浏览文件 @
d55b2fac
...
@@ -6,6 +6,8 @@
...
@@ -6,6 +6,8 @@
.word 0, 0; \
.word 0, 0; \
.byte 0, 0, 0, 0
.byte 0, 0, 0, 0
// The 0xC0 means the limit is in 4096-byte units
// and (for executable segments) 32-bit mode.
#define SEG_ASM(type,base,lim) \
#define SEG_ASM(type,base,lim) \
.word (((lim) >> 12) & 0xffff), ((base) & 0xffff); \
.word (((lim) >> 12) & 0xffff), ((base) & 0xffff); \
.byte (((base) >> 16) & 0xff), (0x90 | (type)), \
.byte (((base) >> 16) & 0xff), (0x90 | (type)), \
...
...
bootasm.S
浏览文件 @
d55b2fac
...
@@ -51,8 +51,10 @@ seta20.2:
...
@@ -51,8 +51,10 @@ seta20.2:
orl $CR0_PE, %eax
orl $CR0_PE, %eax
movl %eax, %cr0
movl %eax, %cr0
# Jump to next instruction, but in 32-bit code segment.
# This ljmp is how you load the CS (Code Segment) register.
# Switches processor into 32-bit mode.
# SEG_ASM produces segment descriptors with the 32-bit mode
# flag set (the D flag), so addresses and word operands will
# default to 32 bits after this jump.
ljmp $(SEG_KCODE<<3), $start32
ljmp $(SEG_KCODE<<3), $start32
.code32 # Assemble for 32-bit mode
.code32 # Assemble for 32-bit mode
...
...
bootother.S
浏览文件 @
d55b2fac
...
@@ -45,8 +45,10 @@ start:
...
@@ -45,8 +45,10 @@ start:
orl $CR0_PE, %eax
orl $CR0_PE, %eax
movl %eax, %cr0
movl %eax, %cr0
# Jump to next instruction, but in 32-bit code segment.
# This ljmp is how you load the CS (Code Segment) register.
# Switches processor into 32-bit mode.
# SEG_ASM produces segment descriptors with the 32-bit mode
# flag set (the D flag), so addresses and word operands will
# default to 32 bits after this jump.
ljmp $(SEG_KCODE<<3), $start32
ljmp $(SEG_KCODE<<3), $start32
.code32 # Assemble for 32-bit mode
.code32 # Assemble for 32-bit mode
...
...
defs.h
浏览文件 @
d55b2fac
...
@@ -110,7 +110,6 @@ void yield(void);
...
@@ -110,7 +110,6 @@ 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
*
);
...
@@ -143,7 +142,7 @@ void timerinit(void);
...
@@ -143,7 +142,7 @@ void timerinit(void);
// trap.c
// trap.c
void
idtinit
(
void
);
void
idtinit
(
void
);
extern
int
ticks
;
extern
uint
ticks
;
void
tvinit
(
void
);
void
tvinit
(
void
);
extern
struct
spinlock
tickslock
;
extern
struct
spinlock
tickslock
;
...
@@ -153,23 +152,20 @@ void uartintr(void);
...
@@ -153,23 +152,20 @@ void uartintr(void);
void
uartputc
(
int
);
void
uartputc
(
int
);
// vm.c
// vm.c
#define PGROUNDUP(sz) ((sz+PGSIZE-1) & ~(PGSIZE-1))
extern
pde_t
*
kpgdir
;
void
pminit
(
void
);
void
pminit
(
void
);
void
ksegment
(
void
);
void
ksegment
(
void
);
void
kvmalloc
(
void
);
void
kvmalloc
(
void
);
void
vminit
(
void
);
void
vminit
(
void
);
void
jkstack
();
void
printstack
(
void
);
void
printpgdir
(
pde_t
*
);
pde_t
*
setupkvm
(
void
);
pde_t
*
setupkvm
(
void
);
char
*
uva2ka
(
pde_t
*
,
char
*
);
char
*
uva2ka
(
pde_t
*
,
char
*
);
int
allocuvm
(
pde_t
*
,
char
*
,
uint
);
int
allocuvm
(
pde_t
*
,
char
*
,
uint
);
int
deallocuvm
(
pde_t
*
pgdir
,
char
*
addr
,
uint
sz
);
void
freevm
(
pde_t
*
);
void
freevm
(
pde_t
*
);
void
inituvm
(
pde_t
*
,
char
*
,
char
*
,
uint
);
void
inituvm
(
pde_t
*
,
char
*
,
char
*
,
uint
);
int
loaduvm
(
pde_t
*
,
char
*
,
struct
inode
*
ip
,
uint
,
uint
);
int
loaduvm
(
pde_t
*
,
char
*
,
struct
inode
*
ip
,
uint
,
uint
);
pde_t
*
copyuvm
(
pde_t
*
,
uint
);
pde_t
*
copyuvm
(
pde_t
*
,
uint
);
void
loadvm
(
struct
proc
*
);
void
switchuvm
(
struct
proc
*
);
void
switchkvm
();
// 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
浏览文件 @
d55b2fac
...
@@ -43,13 +43,16 @@ exec(char *path, char **argv)
...
@@ -43,13 +43,16 @@ exec(char *path, char **argv)
goto
bad
;
goto
bad
;
if
(
!
allocuvm
(
pgdir
,
(
char
*
)
ph
.
va
,
ph
.
memsz
))
if
(
!
allocuvm
(
pgdir
,
(
char
*
)
ph
.
va
,
ph
.
memsz
))
goto
bad
;
goto
bad
;
sz
+=
PGROUNDUP
(
ph
.
memsz
);
if
(
ph
.
va
+
ph
.
memsz
>
sz
)
sz
=
ph
.
va
+
ph
.
memsz
;
if
(
!
loaduvm
(
pgdir
,
(
char
*
)
ph
.
va
,
ip
,
ph
.
offset
,
ph
.
filesz
))
if
(
!
loaduvm
(
pgdir
,
(
char
*
)
ph
.
va
,
ip
,
ph
.
offset
,
ph
.
filesz
))
goto
bad
;
goto
bad
;
}
}
iunlockput
(
ip
);
iunlockput
(
ip
);
// Allocate and initialize stack at sz
// Allocate and initialize stack at sz
sz
=
PGROUNDUP
(
sz
);
sz
+=
PGSIZE
;
// leave an invalid page
if
(
!
allocuvm
(
pgdir
,
(
char
*
)
sz
,
PGSIZE
))
if
(
!
allocuvm
(
pgdir
,
(
char
*
)
sz
,
PGSIZE
))
goto
bad
;
goto
bad
;
mem
=
uva2ka
(
pgdir
,
(
char
*
)
sz
);
mem
=
uva2ka
(
pgdir
,
(
char
*
)
sz
);
...
@@ -95,7 +98,7 @@ exec(char *path, char **argv)
...
@@ -95,7 +98,7 @@ exec(char *path, char **argv)
proc
->
tf
->
eip
=
elf
.
entry
;
// main
proc
->
tf
->
eip
=
elf
.
entry
;
// main
proc
->
tf
->
esp
=
sp
;
proc
->
tf
->
esp
=
sp
;
load
vm
(
proc
);
switchu
vm
(
proc
);
freevm
(
oldpgdir
);
freevm
(
oldpgdir
);
...
...
kalloc.c
浏览文件 @
d55b2fac
// Physical memory allocator, intended to allocate
// Physical memory allocator, intended to allocate
// memory for user processes. Allocates in 4096-byte
"pages"
.
// memory for user processes. Allocates in 4096-byte
pages
.
// Free list is kept sorted and combines adjacent pages into
// Free list is kept sorted and combines adjacent pages into
// long runs, to make it easier to allocate big segments.
// long runs, to make it easier to allocate big segments.
// One reason the page size is 4k is that the x86 segment size
// This combining is not useful now that xv6 uses paging.
// granularity is 4k.
#include "types.h"
#include "types.h"
#include "defs.h"
#include "defs.h"
...
@@ -24,14 +23,10 @@ struct {
...
@@ -24,14 +23,10 @@ struct {
int
nfreemem
;
int
nfreemem
;
// Initialize free list of physical pages.
// Initialize free list of physical pages.
// This code cheats by just considering one megabyte of
// pages after end. Real systems would determine the
// amount of memory available in the system and use it all.
void
void
kinit
(
char
*
p
,
uint
len
)
kinit
(
char
*
p
,
uint
len
)
{
{
initlock
(
&
kmem
.
lock
,
"kmem"
);
initlock
(
&
kmem
.
lock
,
"kmem"
);
cprintf
(
"end 0x%x free = %d(0x%x)
\n
"
,
p
,
len
);
nfreemem
=
0
;
nfreemem
=
0
;
kfree
(
p
,
len
);
kfree
(
p
,
len
);
}
}
...
...
main.c
浏览文件 @
d55b2fac
...
@@ -7,7 +7,8 @@
...
@@ -7,7 +7,8 @@
static
void
bootothers
(
void
);
static
void
bootothers
(
void
);
static
void
mpmain
(
void
);
static
void
mpmain
(
void
);
void
jkstack
(
void
)
__attribute__
((
noreturn
));
void
jkstack
(
void
)
__attribute__
((
noreturn
));
void
mainc
(
void
);
// Bootstrap processor starts running C code here.
// Bootstrap processor starts running C code here.
int
int
...
@@ -15,21 +16,32 @@ main(void)
...
@@ -15,21 +16,32 @@ main(void)
{
{
mpinit
();
// collect info about this machine
mpinit
();
// collect info about this machine
lapicinit
(
mpbcpu
());
lapicinit
(
mpbcpu
());
ksegment
();
ksegment
();
// set up segments
picinit
();
// interrupt controller
picinit
();
// interrupt controller
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
pminit
();
// physical memory for kernel
pminit
();
// discover how much memory there is
jkstack
();
// Jump to mainc on a proper-allocated kernel stack
jkstack
();
// call mainc() on a properly-allocated stack
}
void
jkstack
(
void
)
{
char
*
kstack
=
kalloc
(
PGSIZE
);
if
(
!
kstack
)
panic
(
"jkstack
\n
"
);
char
*
top
=
kstack
+
PGSIZE
;
asm
volatile
(
"movl %0,%%esp"
:
:
"r"
(
top
));
asm
volatile
(
"call mainc"
);
panic
(
"jkstack"
);
}
}
void
void
mainc
(
void
)
mainc
(
void
)
{
{
cprintf
(
"cpus %p cpu %p
\n
"
,
cpus
,
cpu
);
cprintf
(
"
\n
cpu%d: starting xv6
\n\n
"
,
cpu
->
id
);
cprintf
(
"
\n
cpu%d: starting xv6
\n\n
"
,
cpu
->
id
);
kvmalloc
();
//
allocat
e the kernel page table
kvmalloc
();
//
initialz
e the kernel page table
pinit
();
// process table
pinit
();
// process table
tvinit
();
// trap vectors
tvinit
();
// trap vectors
binit
();
// buffer cache
binit
();
// buffer cache
...
@@ -45,22 +57,21 @@ mainc(void)
...
@@ -45,22 +57,21 @@ mainc(void)
mpmain
();
mpmain
();
}
}
// Bootstrap processor gets here after setting up the hardware.
// Common CPU setup code.
// Additional processors start here.
// Bootstrap CPU comes here from mainc().
// Other CPUs jump here from bootother.S.
static
void
static
void
mpmain
(
void
)
mpmain
(
void
)
{
{
if
(
cpunum
()
!=
mpbcpu
())
{
if
(
cpunum
()
!=
mpbcpu
())
{
ksegment
();
ksegment
();
cprintf
(
"other cpu
\n
"
);
lapicinit
(
cpunum
());
lapicinit
(
cpunum
());
}
}
vminit
();
//
Run with paging on each processor
vminit
();
//
turn on paging
cprintf
(
"cpu%d:
mpmain
\n
"
,
cpu
->
id
);
cprintf
(
"cpu%d:
starting
\n
"
,
cpu
->
id
);
idtinit
();
idtinit
();
// load idt register
xchg
(
&
cpu
->
booted
,
1
);
xchg
(
&
cpu
->
booted
,
1
);
cprintf
(
"cpu%d: scheduling
\n
"
,
cpu
->
id
);
scheduler
();
// start running processes
scheduler
();
}
}
static
void
static
void
...
@@ -75,6 +86,7 @@ bootothers(void)
...
@@ -75,6 +86,7 @@ bootothers(void)
// placed the start of bootother.S there.
// placed the start of bootother.S there.
code
=
(
uchar
*
)
0x7000
;
code
=
(
uchar
*
)
0x7000
;
memmove
(
code
,
_binary_bootother_start
,
(
uint
)
_binary_bootother_size
);
memmove
(
code
,
_binary_bootother_start
,
(
uint
)
_binary_bootother_size
);
for
(
c
=
cpus
;
c
<
cpus
+
ncpu
;
c
++
){
for
(
c
=
cpus
;
c
<
cpus
+
ncpu
;
c
++
){
if
(
c
==
cpus
+
cpunum
())
// We've started already.
if
(
c
==
cpus
+
cpunum
())
// We've started already.
continue
;
continue
;
...
@@ -85,7 +97,7 @@ bootothers(void)
...
@@ -85,7 +97,7 @@ bootothers(void)
*
(
void
**
)(
code
-
8
)
=
mpmain
;
*
(
void
**
)(
code
-
8
)
=
mpmain
;
lapicstartap
(
c
->
id
,
(
uint
)
code
);
lapicstartap
(
c
->
id
,
(
uint
)
code
);
// Wait for cpu to
get through bootstrap.
// Wait for cpu to
finish mpmain()
while
(
c
->
booted
==
0
)
while
(
c
->
booted
==
0
)
;
;
}
}
...
...
mmu.h
浏览文件 @
d55b2fac
...
@@ -85,32 +85,20 @@ struct segdesc {
...
@@ -85,32 +85,20 @@ struct segdesc {
// | Page Directory | Page Table | Offset within Page |
// | Page Directory | Page Table | Offset within Page |
// | Index | Index | |
// | Index | Index | |
// +----------------+----------------+---------------------+
// +----------------+----------------+---------------------+
// \--- PDX(la) --/ \--- PTX(la) --/ \---- PGOFF(la) ----/
// \--- PDX(la) --/ \--- PTX(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
// page directory index
#define PDX(la) ((((uint) (la)) >> PDXSHIFT) & 0x3FF)
#define PDX(la) ((((uint) (la)) >> PDXSHIFT) & 0x3FF)
#define VPD(la) PDX(la) // used to index into vpd[]
// page table index
// page table index
#define PTX(la) ((((uint) (la)) >> PTXSHIFT) & 0x3FF)
#define PTX(la) ((((uint) (la)) >> PTXSHIFT) & 0x3FF)
// offset in page
#define PGOFF(la) (((uint) (la)) & 0xFFF)
// construct linear address from indexes and offset
// construct linear address from indexes and offset
#define PGADDR(d, t, o) ((uint) ((d) << PDXSHIFT | (t) << PTXSHIFT | (o)))
#define PGADDR(d, t, o) ((uint) ((d) << PDXSHIFT | (t) << PTXSHIFT | (o)))
// mapping from physical addresses to virtual addresses is the identity one
// turn a kernel linear address into a physical address.
// (really linear addresses, but we map linear to physical also directly)
// all of the kernel data structures have linear and
// physical addresses that are equal.
#define PADDR(a) ((uint) a)
#define PADDR(a) ((uint) a)
// Page directory and page table constants.
// Page directory and page table constants.
...
@@ -120,12 +108,12 @@ struct segdesc {
...
@@ -120,12 +108,12 @@ struct segdesc {
#define PGSIZE 4096 // bytes mapped by a page
#define PGSIZE 4096 // bytes mapped by a page
#define PGSHIFT 12 // log2(PGSIZE)
#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 PTXSHIFT 12 // offset of PTX in a linear address
#define PDXSHIFT 22 // offset of PDX in a linear address
#define PDXSHIFT 22 // offset of PDX in a linear address
#define PGROUNDUP(sz) (((sz)+PGSIZE-1) & ~(PGSIZE-1))
#define PGROUNDDOWN(a) ((char*)((((unsigned int)a) & ~(PGSIZE-1))))
// Page table/directory entry flags.
// Page table/directory entry flags.
#define PTE_P 0x001 // Present
#define PTE_P 0x001 // Present
#define PTE_W 0x002 // Writeable
#define PTE_W 0x002 // Writeable
...
@@ -137,13 +125,6 @@ struct segdesc {
...
@@ -137,13 +125,6 @@ struct segdesc {
#define PTE_PS 0x080 // Page Size
#define PTE_PS 0x080 // Page Size
#define PTE_MBZ 0x180 // Bits must be zero
#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
// Address in page table or page directory entry
#define PTE_ADDR(pte) ((uint) (pte) & ~0xFFF)
#define PTE_ADDR(pte) ((uint) (pte) & ~0xFFF)
...
...
proc.c
浏览文件 @
d55b2fac
...
@@ -142,10 +142,15 @@ userinit(void)
...
@@ -142,10 +142,15 @@ userinit(void)
int
int
growproc
(
int
n
)
growproc
(
int
n
)
{
{
if
(
!
allocuvm
(
proc
->
pgdir
,
(
char
*
)
proc
->
sz
,
n
))
if
(
n
>
0
){
return
-
1
;
if
(
!
allocuvm
(
proc
->
pgdir
,
(
char
*
)
proc
->
sz
,
n
))
return
-
1
;
}
else
if
(
n
<
0
){
if
(
!
deallocuvm
(
proc
->
pgdir
,
(
char
*
)(
proc
->
sz
+
n
),
0
-
n
))
return
-
1
;
}
proc
->
sz
+=
n
;
proc
->
sz
+=
n
;
load
vm
(
proc
);
switchu
vm
(
proc
);
return
0
;
return
0
;
}
}
...
@@ -214,9 +219,10 @@ scheduler(void)
...
@@ -214,9 +219,10 @@ 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
;
load
vm
(
p
);
switchu
vm
(
p
);
p
->
state
=
RUNNING
;
p
->
state
=
RUNNING
;
swtch
(
&
cpu
->
scheduler
,
proc
->
context
);
swtch
(
&
cpu
->
scheduler
,
proc
->
context
);
switchkvm
();
// Process is done running for now.
// Process is done running for now.
// It should have changed its p->state before coming back.
// It should have changed its p->state before coming back.
...
@@ -242,7 +248,6 @@ sched(void)
...
@@ -242,7 +248,6 @@ sched(void)
panic
(
"sched running"
);
panic
(
"sched running"
);
if
(
readeflags
()
&
FL_IF
)
if
(
readeflags
()
&
FL_IF
)
panic
(
"sched interruptible"
);
panic
(
"sched interruptible"
);
lcr3
(
PADDR
(
kpgdir
));
// Switch to the kernel page table
intena
=
cpu
->
intena
;
intena
=
cpu
->
intena
;
swtch
(
&
proc
->
context
,
cpu
->
scheduler
);
swtch
(
&
proc
->
context
,
cpu
->
scheduler
);
cpu
->
intena
=
intena
;
cpu
->
intena
=
intena
;
...
@@ -414,9 +419,9 @@ wait(void)
...
@@ -414,9 +419,9 @@ wait(void)
// Found one.
// Found one.
pid
=
p
->
pid
;
pid
=
p
->
pid
;
kfree
(
p
->
kstack
,
KSTACKSIZE
);
kfree
(
p
->
kstack
,
KSTACKSIZE
);
freevm
(
p
->
pgdir
);
p
->
kstack
=
0
;
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
浏览文件 @
d55b2fac
...
@@ -3,8 +3,8 @@
...
@@ -3,8 +3,8 @@
#define SEG_KCODE 1 // kernel code
#define SEG_KCODE 1 // kernel code
#define SEG_KDATA 2 // kernel data+stack
#define SEG_KDATA 2 // kernel data+stack
#define SEG_KCPU 3 // kernel per-cpu data
#define SEG_KCPU 3 // kernel per-cpu data
#define SEG_UCODE 4
#define SEG_UCODE 4
// user code
#define SEG_UDATA 5
#define SEG_UDATA 5
// user data+stack
#define SEG_TSS 6 // this process's task state
#define SEG_TSS 6 // this process's task state
#define NSEGS 7
#define NSEGS 7
...
@@ -16,7 +16,7 @@
...
@@ -16,7 +16,7 @@
// Contexts are stored at the bottom of the stack they
// Contexts are stored at the bottom of the stack they
// describe; the stack pointer is the address of the context.
// describe; the stack pointer is the address of the context.
// The layout of the context matches the layout of the stack in swtch.S
// The layout of the context matches the layout of the stack in swtch.S
// at
"Switch stacks" comment. Switch itself
doesn't save eip explicitly,
// at
the "Switch stacks" comment. Switch
doesn't save eip explicitly,
// but it is on the stack and allocproc() manipulates it.
// but it is on the stack and allocproc() manipulates it.
struct
context
{
struct
context
{
uint
edi
;
uint
edi
;
...
@@ -31,7 +31,7 @@ enum procstate { UNUSED, EMBRYO, SLEEPING, RUNNABLE, RUNNING, ZOMBIE };
...
@@ -31,7 +31,7 @@ enum procstate { UNUSED, EMBRYO, SLEEPING, RUNNABLE, RUNNING, ZOMBIE };
// Per-process state
// Per-process state
struct
proc
{
struct
proc
{
uint
sz
;
// Size of process memory (bytes)
uint
sz
;
// Size of process memory (bytes)
pde_t
*
pgdir
;
//
l
inear address of proc's pgdir
pde_t
*
pgdir
;
//
L
inear 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
...
@@ -48,6 +48,7 @@ struct proc {
...
@@ -48,6 +48,7 @@ struct proc {
// Process memory is laid out contiguously, low addresses first:
// Process memory is laid out contiguously, low addresses first:
// text
// text
// original data and bss
// original data and bss
// invalid page
// fixed-size stack
// fixed-size stack
// expandable heap
// expandable heap
...
...
runoff.list
浏览文件 @
d55b2fac
...
@@ -23,6 +23,7 @@ proc.c
...
@@ -23,6 +23,7 @@ proc.c
swtch.S
swtch.S
vm.c
vm.c
kalloc.c
kalloc.c
vm.c
# system calls
# system calls
traps.h
traps.h
...
...
sh.c
浏览文件 @
d55b2fac
...
@@ -420,7 +420,6 @@ parseexec(char **ps, char *es)
...
@@ -420,7 +420,6 @@ 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
);
...
...
swtch.S
浏览文件 @
d55b2fac
...
@@ -26,11 +26,3 @@ swtch:
...
@@ -26,11 +26,3 @@ 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
浏览文件 @
d55b2fac
...
@@ -100,6 +100,7 @@ extern int sys_sleep(void);
...
@@ -100,6 +100,7 @@ extern int sys_sleep(void);
extern
int
sys_unlink
(
void
);
extern
int
sys_unlink
(
void
);
extern
int
sys_wait
(
void
);
extern
int
sys_wait
(
void
);
extern
int
sys_write
(
void
);
extern
int
sys_write
(
void
);
extern
int
sys_uptime
(
void
);
static
int
(
*
syscalls
[])(
void
)
=
{
static
int
(
*
syscalls
[])(
void
)
=
{
[
SYS_chdir
]
sys_chdir
,
[
SYS_chdir
]
sys_chdir
,
...
@@ -122,6 +123,7 @@ static int (*syscalls[])(void) = {
...
@@ -122,6 +123,7 @@ static int (*syscalls[])(void) = {
[
SYS_unlink
]
sys_unlink
,
[
SYS_unlink
]
sys_unlink
,
[
SYS_wait
]
sys_wait
,
[
SYS_wait
]
sys_wait
,
[
SYS_write
]
sys_write
,
[
SYS_write
]
sys_write
,
[
SYS_uptime
]
sys_uptime
,
};
};
void
void
...
...
syscall.h
浏览文件 @
d55b2fac
...
@@ -19,3 +19,4 @@
...
@@ -19,3 +19,4 @@
#define SYS_getpid 18
#define SYS_getpid 18
#define SYS_sbrk 19
#define SYS_sbrk 19
#define SYS_sleep 20
#define SYS_sleep 20
#define SYS_uptime 21
sysproc.c
浏览文件 @
d55b2fac
...
@@ -57,7 +57,8 @@ sys_sbrk(void)
...
@@ -57,7 +57,8 @@ sys_sbrk(void)
int
int
sys_sleep
(
void
)
sys_sleep
(
void
)
{
{
int
n
,
ticks0
;
int
n
;
uint
ticks0
;
if
(
argint
(
0
,
&
n
)
<
0
)
if
(
argint
(
0
,
&
n
)
<
0
)
return
-
1
;
return
-
1
;
...
@@ -73,3 +74,16 @@ sys_sleep(void)
...
@@ -73,3 +74,16 @@ sys_sleep(void)
release
(
&
tickslock
);
release
(
&
tickslock
);
return
0
;
return
0
;
}
}
// return how many clock tick interrupts have occurred
// since boot.
int
sys_uptime
(
void
)
{
uint
xticks
;
acquire
(
&
tickslock
);
xticks
=
ticks
;
release
(
&
tickslock
);
return
xticks
;
}
trap.c
浏览文件 @
d55b2fac
...
@@ -11,7 +11,7 @@
...
@@ -11,7 +11,7 @@
struct
gatedesc
idt
[
256
];
struct
gatedesc
idt
[
256
];
extern
uint
vectors
[];
// in vectors.S: array of 256 entry pointers
extern
uint
vectors
[];
// in vectors.S: array of 256 entry pointers
struct
spinlock
tickslock
;
struct
spinlock
tickslock
;
int
ticks
;
u
int
ticks
;
void
void
tvinit
(
void
)
tvinit
(
void
)
...
...
usertests.c
浏览文件 @
d55b2fac
...
@@ -322,8 +322,9 @@ void
...
@@ -322,8 +322,9 @@ void
mem
(
void
)
mem
(
void
)
{
{
void
*
m1
,
*
m2
;
void
*
m1
,
*
m2
;
int
pid
;
int
pid
,
ppid
;
ppid
=
getpid
();
if
((
pid
=
fork
())
==
0
){
if
((
pid
=
fork
())
==
0
){
m1
=
0
;
m1
=
0
;
while
((
m2
=
malloc
(
10001
))
!=
0
)
{
while
((
m2
=
malloc
(
10001
))
!=
0
)
{
...
@@ -338,6 +339,7 @@ mem(void)
...
@@ -338,6 +339,7 @@ mem(void)
m1
=
malloc
(
1024
*
20
);
m1
=
malloc
(
1024
*
20
);
if
(
m1
==
0
)
{
if
(
m1
==
0
)
{
printf
(
1
,
"couldn't allocate mem?!!
\n
"
);
printf
(
1
,
"couldn't allocate mem?!!
\n
"
);
kill
(
ppid
);
exit
();
exit
();
}
}
free
(
m1
);
free
(
m1
);
...
@@ -1229,6 +1231,136 @@ forktest(void)
...
@@ -1229,6 +1231,136 @@ forktest(void)
printf
(
1
,
"fork test OK
\n
"
);
printf
(
1
,
"fork test OK
\n
"
);
}
}
void
sbrktest
(
void
)
{
int
pid
;
char
*
oldbrk
=
sbrk
(
0
);
printf
(
stdout
,
"sbrk test
\n
"
);
// can one sbrk() less than a page?
char
*
a
=
sbrk
(
0
);
int
i
;
for
(
i
=
0
;
i
<
5000
;
i
++
){
char
*
b
=
sbrk
(
1
);
if
(
b
!=
a
){
printf
(
stdout
,
"sbrk test failed %d %x %x
\n
"
,
i
,
a
,
b
);
exit
();
}
*
b
=
1
;
a
=
b
+
1
;
}
pid
=
fork
();
if
(
pid
<
0
){
printf
(
stdout
,
"sbrk test fork failed
\n
"
);
exit
();
}
char
*
c
=
sbrk
(
1
);
c
=
sbrk
(
1
);
if
(
c
!=
a
+
1
){
printf
(
stdout
,
"sbrk test failed post-fork
\n
"
);
exit
();
}
if
(
pid
==
0
)
exit
();
wait
();
// can one allocate the full 640K?
a
=
sbrk
(
0
);
uint
amt
=
(
640
*
1024
)
-
(
uint
)
a
;
char
*
p
=
sbrk
(
amt
);
if
(
p
!=
a
){
printf
(
stdout
,
"sbrk test failed 640K test, p %x a %x
\n
"
,
p
,
a
);
exit
();
}
char
*
lastaddr
=
(
char
*
)(
640
*
1024
-
1
);
*
lastaddr
=
99
;
// is one forbidden from allocating more than 640K?
c
=
sbrk
(
4096
);
if
(
c
!=
(
char
*
)
0xffffffff
){
printf
(
stdout
,
"sbrk allocated more than 640K, c %x
\n
"
,
c
);
exit
();
}
// can one de-allocate?
a
=
sbrk
(
0
);
c
=
sbrk
(
-
4096
);
if
(
c
==
(
char
*
)
0xffffffff
){
printf
(
stdout
,
"sbrk could not deallocate
\n
"
);
exit
();
}
c
=
sbrk
(
0
);
if
(
c
!=
a
-
4096
){
printf
(
stdout
,
"sbrk deallocation produced wrong address, a %x c %x
\n
"
,
a
,
c
);
exit
();
}
// can one re-allocate that page?
a
=
sbrk
(
0
);
c
=
sbrk
(
4096
);
if
(
c
!=
a
||
sbrk
(
0
)
!=
a
+
4096
){
printf
(
stdout
,
"sbrk re-allocation failed, a %x c %x
\n
"
,
a
,
c
);
exit
();
}
if
(
*
lastaddr
==
99
){
// should be zero
printf
(
stdout
,
"sbrk de-allocation didn't really deallocate
\n
"
);
exit
();
}
c
=
sbrk
(
4096
);
if
(
c
!=
(
char
*
)
0xffffffff
){
printf
(
stdout
,
"sbrk was able to re-allocate beyond 640K, c %x
\n
"
,
c
);
exit
();
}
// can we read the kernel's memory?
for
(
a
=
(
char
*
)(
640
*
1024
);
a
<
(
char
*
)
2000000
;
a
+=
50000
){
int
ppid
=
getpid
();
int
pid
=
fork
();
if
(
pid
<
0
){
printf
(
stdout
,
"fork failed
\n
"
);
exit
();
}
if
(
pid
==
0
){
printf
(
stdout
,
"oops could read %x = %x
\n
"
,
a
,
*
a
);
kill
(
ppid
);
exit
();
}
wait
();
}
if
(
sbrk
(
0
)
>
oldbrk
)
sbrk
(
-
(
sbrk
(
0
)
-
oldbrk
));
printf
(
stdout
,
"sbrk test OK
\n
"
);
}
void
stacktest
(
void
)
{
printf
(
stdout
,
"stack test
\n
"
);
char
dummy
=
1
;
char
*
p
=
&
dummy
;
int
ppid
=
getpid
();
int
pid
=
fork
();
if
(
pid
<
0
){
printf
(
stdout
,
"fork failed
\n
"
);
exit
();
}
if
(
pid
==
0
){
// should cause a trap:
p
[
-
4096
]
=
'z'
;
kill
(
ppid
);
printf
(
stdout
,
"stack test failed: page before stack was writeable
\n
"
);
exit
();
}
wait
();
printf
(
stdout
,
"stack test OK
\n
"
);
}
int
int
main
(
int
argc
,
char
*
argv
[])
main
(
int
argc
,
char
*
argv
[])
{
{
...
@@ -1240,6 +1372,9 @@ main(int argc, char *argv[])
...
@@ -1240,6 +1372,9 @@ main(int argc, char *argv[])
}
}
close
(
open
(
"usertests.ran"
,
O_CREATE
));
close
(
open
(
"usertests.ran"
,
O_CREATE
));
stacktest
();
sbrktest
();
opentest
();
opentest
();
writetest
();
writetest
();
writetest1
();
writetest1
();
...
...
usys.S
浏览文件 @
d55b2fac
...
@@ -28,3 +28,4 @@ SYSCALL(dup)
...
@@ -28,3 +28,4 @@ SYSCALL(dup)
SYSCALL(getpid)
SYSCALL(getpid)
SYSCALL(sbrk)
SYSCALL(sbrk)
SYSCALL(sleep)
SYSCALL(sleep)
SYSCALL(uptime)
vm.c
浏览文件 @
d55b2fac
差异被折叠。
点击展开。
编写
预览
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论