Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
X
xv6-public
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
统计图
问题
0
问题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
银宸时代
OS Lab Group
奖励实验
xv6-public
提交
31085bb4
提交
31085bb4
9月 07, 2006
创建
作者:
rsc
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
more comments
上级
7e019461
隐藏空白字符变更
内嵌
并排
正在显示
13 个修改的文件
包含
151 行增加
和
81 行删除
+151
-81
elf.h
elf.h
+3
-3
fs.h
fs.h
+33
-20
kalloc.c
kalloc.c
+4
-0
mkdir.c
mkdir.c
+1
-0
proc.c
proc.c
+4
-1
proc.h
proc.h
+40
-36
setjmp.S
setjmp.S
+22
-5
spinlock.c
spinlock.c
+15
-1
spinlock.h
spinlock.h
+8
-4
stat.h
stat.h
+5
-5
trap.c
trap.c
+9
-5
traps.h
traps.h
+3
-1
x86.h
x86.h
+4
-0
没有找到文件。
elf.h
浏览文件 @
31085bb4
//
// format of an ELF executable file
//
// Format of an ELF executable file
#define ELF_MAGIC 0x464C457FU // "\x7FELF" in little endian
// File header
struct
elfhdr
{
uint
magic
;
// must equal ELF_MAGIC
uchar
elf
[
12
];
...
...
@@ -22,6 +21,7 @@ struct elfhdr {
ushort
shstrndx
;
};
// Program section header
struct
proghdr
{
uint
type
;
uint
offset
;
...
...
fs.h
浏览文件 @
31085bb4
// on-disk file system format
// On-disk file system format.
// This header is shared between kernel and user space.
// Block 0 is unused.
// Block 1 is super block.
// Inodes start at block 2.
#define BSIZE 512 // block size
//
sector 1 (2nd sector)
struct
superblock
{
uint
size
;
uint
nblocks
;
uint
ninodes
;
//
File system super block
struct
superblock
{
uint
size
;
// Size of file system (bytes???) xxx
uint
nblocks
;
// Number of blocks
uint
ninodes
;
// Number of inodes.
};
#define NADDRS (NDIRECT+1)
...
...
@@ -15,24 +20,31 @@ struct superblock{
#define NINDIRECT (BSIZE / sizeof(uint))
#define MAXFILE (NDIRECT + NINDIRECT)
// On-disk inode structure
struct
dinode
{
short
type
;
short
major
;
short
minor
;
short
nlink
;
uint
size
;
uint
addrs
[
NADDRS
];
short
type
;
// File type
short
major
;
// Major device number (T_DEV only)
short
minor
;
// Minor device number (T_DEV only)
short
nlink
;
// Number of links to inode in file system
uint
size
;
// Size of file (bytes)
uint
addrs
[
NADDRS
];
// Data block addresses
};
#define T_DIR 1
#define T_FILE 2
#define T_DEV 3
#define T_DIR 1 // Directory
#define T_FILE 2 // File
#define T_DEV 3 // Special device
// Inodes per block.
#define IPB (BSIZE / sizeof(struct dinode))
// Block containing inode i
#define IBLOCK(i) ((i) / IPB + 2)
// Bitmap bits per block
#define BPB (BSIZE*8)
// sector 0 is unused, sector 1 is superblock, inodes start at sector 2
#define IPB (BSIZE / sizeof(struct dinode))
#define IBLOCK(inum) (inum / IPB + 2) // start of inode
#define BPB (BSIZE*8)
#define BBLOCK(b,ninodes) (b/BPB + (ninodes/IPB) + 3) // start of bitmap
// Block containing bit for block b
#define BBLOCK(b, ninodes) (b/BPB + (ninodes)/IPB + 3)
#define DIRSIZ 14
...
...
@@ -41,4 +53,5 @@ struct dirent {
char
name
[
DIRSIZ
];
};
extern
uint
rootdev
;
// Device number of root file system
kalloc.c
浏览文件 @
31085bb4
...
...
@@ -40,6 +40,10 @@ kinit(void)
kfree
(
start
,
mem
*
PAGE
);
}
// Free the len bytes of memory pointed at by cp,
// which normally should have been returned by a
// call to kalloc(cp). (The exception is when
// initializing the allocator; see kinit above.)
void
kfree
(
char
*
cp
,
int
len
)
{
...
...
mkdir.c
浏览文件 @
31085bb4
...
...
@@ -2,6 +2,7 @@
#include "stat.h"
#include "user.h"
int
main
(
int
argc
,
char
*
argv
[])
{
int
i
;
...
...
proc.c
浏览文件 @
31085bb4
...
...
@@ -136,7 +136,9 @@ copyproc(struct proc *p)
return
np
;
}
uint
// Grow current process's memory by n bytes.
// Return old size on success, -1 on failure.
int
growproc
(
int
n
)
{
struct
proc
*
cp
=
curproc
[
cpu
()];
...
...
@@ -154,6 +156,7 @@ growproc(int n)
return
cp
->
sz
-
n
;
}
//PAGEBREAK: 42
// Per-CPU process scheduler.
// Each CPU calls scheduler() after setting itself up.
// Scheduler never returns. It loops, doing:
...
...
proc.h
浏览文件 @
31085bb4
//
s
egments in proc->gdt
#define SEG_KCODE 1 // kernel code
#define SEG_KDATA 2 // kernel data+stack
//
S
egments in proc->gdt
#define SEG_KCODE 1
// kernel code
#define SEG_KDATA 2
// kernel data+stack
#define SEG_UCODE 3
#define SEG_UDATA 4
#define SEG_TSS 5
// this process's task state
#define SEG_TSS 5 // this process's task state
#define NSEGS 6
// Saved registers for kernel context switches.
// Don't need to save all the %fs etc. segment registers,
// because they are constant across kernel contexts.
// Save all the regular registers so we don't need to care
// which are caller save.
// Don't save %eax, because that's the return register.
// The layout of jmpbuf is known to setjmp.S.
struct
jmpbuf
{
// saved registers for kernel context switches
// don't need to save all the fs etc. registers because
// they are constant across kernel contexts
// save all the regular registers so we don't care which are caller save
// don't save eax because that's the return register
// layout known to setjmp.S
int
ebx
;
int
ecx
;
int
edx
;
...
...
@@ -25,39 +26,42 @@ struct jmpbuf {
enum
proc_state
{
UNUSED
,
EMBRYO
,
SLEEPING
,
RUNNABLE
,
RUNNING
,
ZOMBIE
};
struct
proc
{
char
*
mem
;
// start of process's memory (a kernel address)
// process memory is laid out contiguously:
// text
// original data and bss
// fixed-size stack
// expandable heap
uint
sz
;
// user memory size
char
*
kstack
;
// kernel stack
enum
proc_state
state
;
int
pid
;
int
ppid
;
void
*
chan
;
// sleep
int
killed
;
struct
file
*
ofile
[
NOFILE
];
struct
inode
*
cwd
;
struct
jmpbuf
jmpbuf
;
struct
trapframe
*
tf
;
// points into kstack, used to find user regs
// Per-process state
struct
proc
{
char
*
mem
;
// Start of process memory (kernel address)
uint
sz
;
// Size of process memory (bytes)
char
*
kstack
;
// Bottom of kernel stack for this process
enum
proc_state
state
;
// Process state
int
pid
;
// Process ID
int
ppid
;
// Parent pid
void
*
chan
;
// If non-zero, sleeping on chan
int
killed
;
// If non-zero, have been killed
struct
file
*
ofile
[
NOFILE
];
// Open files
struct
inode
*
cwd
;
// Current directory
struct
jmpbuf
jmpbuf
;
// Jump here to run process
struct
trapframe
*
tf
;
// Trap frame for current interrupt
};
// Process memory is laid out contiguously:
// text
// original data and bss
// fixed-size stack
// expandable heap
extern
struct
proc
proc
[];
extern
struct
proc
*
curproc
[
NCPU
];
//
can be NULL if no proc running.
extern
struct
proc
*
curproc
[
NCPU
];
//
Current (running) process per CPU
#define MPSTACK 512
// Per-CPU state
struct
cpu
{
uchar
apicid
;
// Local APIC ID
struct
jmpbuf
jmpbuf
;
struct
taskstate
ts
;
// only to give cpu address of kernel stack
struct
segdesc
gdt
[
NSEGS
];
char
mpstack
[
MPSTACK
];
// per-cpu start-
up stack
volatile
int
booted
;
int
nlock
;
// #
of locks currently held
uchar
apicid
;
// Local APIC ID
struct
jmpbuf
jmpbuf
;
// Jump here to enter scheduler
struct
taskstate
ts
;
// Used by x86 to find stack for interrupt
struct
segdesc
gdt
[
NSEGS
];
// x86 global descriptor table
char
mpstack
[
MPSTACK
];
// Per-CPU start
up stack
volatile
int
booted
;
// Has the CPU started?
int
nlock
;
// Number
of locks currently held
};
extern
struct
cpu
cpus
[
NCPU
];
...
...
setjmp.S
浏览文件 @
31085bb4
# int setjmp(struct jmpbuf *jmp);
# void longjmp(struct jmpbuf *jmp);
#
# Setjmp saves its stack environment in jmp
# for later use by longjmp. It returns 0.
#
# Longjmp restores the environment saved by
# the last call of setjmp. It then causes
# execution to continue as if the call of setjmp
# had just returned 1.
#
# The caller of setjmp must not itself have
# returned in the interim. All accessible data
# have values as of the time longjmp was called.
#
# [Description, but not code, borrowed from Plan 9.]
.globl setjmp
setjmp:
movl 4(%esp), %eax
...
...
@@ -9,10 +26,10 @@ setjmp:
movl %edi, 16(%eax)
movl %esp, 20(%eax)
movl %ebp, 24(%eax)
pushl 0(%esp)
/* %eip */
pushl 0(%esp)
# %eip
popl 28(%eax)
movl $0, %eax
/* return value */
movl $0, %eax
# return value
ret
.globl longjmp
...
...
@@ -27,8 +44,8 @@ longjmp:
movl 20(%eax), %esp
movl 24(%eax), %ebp
addl $4, %esp
/* pop %eip into thin air */
pushl 28(%eax)
/* push new %eip */
addl $4, %esp
# pop and discard %eip
pushl 28(%eax)
# push new %eip
movl $1, %eax
/* return value (appears to come from setjmp!) */
movl $1, %eax
# return value (appears to come from setjmp!)
ret
spinlock.c
浏览文件 @
31085bb4
// Mutual exclusion spin locks.
#include "types.h"
#include "defs.h"
#include "x86.h"
...
...
@@ -16,6 +18,7 @@ initlock(struct spinlock *lock, char *name)
lock
->
cpu
=
0xffffffff
;
}
// Record the current call stack in pcs[] by following the %ebp chain.
void
getcallerpcs
(
void
*
v
,
uint
pcs
[])
{
...
...
@@ -31,6 +34,10 @@ getcallerpcs(void *v, uint pcs[])
pcs
[
i
]
=
0
;
}
// Acquire the lock.
// Loops (spins) until the lock is acquired.
// (Because contention is handled by spinning, must not
// go to sleep holding any locks.)
void
acquire
(
struct
spinlock
*
lock
)
{
...
...
@@ -44,10 +51,16 @@ acquire(struct spinlock *lock)
while
(
cmpxchg
(
0
,
1
,
&
lock
->
locked
)
==
1
)
;
cpuid
(
0
,
0
,
0
,
0
,
0
);
// memory barrier
getcallerpcs
(
&
lock
,
lock
->
pcs
);
// Record info about lock acquisition for debugging.
// The +10 is only so that we can tell the difference
// between forgetting to initialize lock->cpu
// and holding a lock on cpu 0.
lock
->
cpu
=
cpu
()
+
10
;
getcallerpcs
(
&
lock
,
lock
->
pcs
);
}
// Release the lock.
void
release
(
struct
spinlock
*
lock
)
{
...
...
@@ -63,6 +76,7 @@ release(struct spinlock *lock)
sti
();
}
// Check whether this cpu is holding the lock.
int
holding
(
struct
spinlock
*
lock
)
{
...
...
spinlock.h
浏览文件 @
31085bb4
// Mutual exclusion lock.
struct
spinlock
{
char
*
name
;
uint
locked
;
int
cpu
;
uint
pcs
[
10
];
uint
locked
;
// Is the lock held?
// For debugging:
char
*
name
;
// Name of lock.
int
cpu
;
// The number of the cpu holding the lock.
uint
pcs
[
10
];
// The call stack (an array of program counters)
// that locked the lock.
};
stat.h
浏览文件 @
31085bb4
struct
stat
{
int
dev
;
uint
ino
;
short
type
;
short
nlink
;
uint
size
;
int
dev
;
// Device number
uint
ino
;
// Inode number on device
short
type
;
// Type of file
short
nlink
;
// Number of links to file
uint
size
;
// Size of file in bytes
};
trap.c
浏览文件 @
31085bb4
...
...
@@ -7,11 +7,11 @@
#include "traps.h"
#include "syscall.h"
// Interrupt descriptor table (shared by all CPUs).
struct
gatedesc
idt
[
256
];
extern
uint
vectors
[];
// in vectors.S: array of 256 entry pointers
extern
void
trapenter
(
void
);
extern
void
trapenter1
(
void
);
void
tvinit
(
void
)
...
...
@@ -65,30 +65,34 @@ trap(struct trapframe *tf)
return
;
}
if
(
v
==
(
IRQ_OFFSET
+
IRQ_IDE
)
){
if
(
v
==
IRQ_OFFSET
+
IRQ_IDE
){
ide_intr
();
cli
();
// prevent a waiting interrupt from overflowing stack
lapic_eoi
();
return
;
}
if
(
v
==
(
IRQ_OFFSET
+
IRQ_KBD
)
){
if
(
v
==
IRQ_OFFSET
+
IRQ_KBD
){
kbd_intr
();
cli
();
// prevent a waiting interrupt from overflowing stack
lapic_eoi
();
return
;
}
if
(
v
==
(
IRQ_OFFSET
+
IRQ_SPURIOUS
)
){
if
(
v
==
IRQ_OFFSET
+
IRQ_SPURIOUS
){
cprintf
(
"spurious interrupt from cpu %d eip %x
\n
"
,
cpu
(),
tf
->
eip
);
return
;
// no eoi for this one.
}
if
(
curproc
[
cpu
()])
{
// assume process caused unexpected trap,
// for example by dividing by zero or dereferencing a bad pointer
cprintf
(
"pid %d: unhandled trap %d on cpu %d eip %x -- kill proc
\n
"
,
curproc
[
cpu
()]
->
pid
,
v
,
cpu
(),
tf
->
eip
);
proc_exit
();
}
// otherwise it's our mistake
cprintf
(
"unexpected trap %d from cpu %d eip %x
\n
"
,
v
,
cpu
(),
tf
->
eip
);
panic
(
"trap"
);
}
traps.h
浏览文件 @
31085bb4
// system defined:
// x86 trap and interrupt constants.
// Processor-defined:
#define T_DIVIDE 0 // divide error
#define T_DEBUG 1 // debug exception
#define T_NMI 2 // non-maskable interrupt
...
...
x86.h
浏览文件 @
31085bb4
// Special assembly routines to access x86-specific
// hardware instructions.
static
__inline
uchar
inb
(
int
port
)
{
...
...
@@ -124,6 +127,7 @@ sti(void)
__asm__
volatile
(
"sti"
);
}
// Layout of the trap frame on the stack upon entry to trap.
struct
trapframe
{
// registers as pushed by pusha
uint
edi
;
...
...
编写
预览
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论