Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
X
xv6-public
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
统计图
问题
0
问题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
银宸时代
OS Lab Group
奖励实验
xv6-public
提交
faad047a
提交
faad047a
9月 13, 2010
创建
作者:
Robert Morris
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
change some comments, maybe more informative
delete most comments from bootother.S (since copy of bootasm.S) ksegment() -> seginit() move more stuff from main() to mainc()
上级
124fe7e4
显示空白字符变更
内嵌
并排
正在显示
8 个修改的文件
包含
70 行增加
和
66 行删除
+70
-66
bootasm.S
bootasm.S
+8
-3
bootother.S
bootother.S
+32
-43
defs.h
defs.h
+1
-1
main.c
main.c
+16
-8
proc.c
proc.c
+4
-2
proc.h
proc.h
+7
-7
spinlock.c
spinlock.c
+1
-1
vm.c
vm.c
+1
-1
没有找到文件。
bootasm.S
浏览文件 @
faad047a
...
@@ -13,7 +13,7 @@
...
@@ -13,7 +13,7 @@
.code16 # Assemble for 16-bit mode
.code16 # Assemble for 16-bit mode
.globl start
.globl start
start:
start:
cli #
Disable interrupts
cli #
BIOS enabled interrupts ; disable
# Set up the important data segment registers (DS, ES, SS).
# Set up the important data segment registers (DS, ES, SS).
xorw %ax,%ax # Segment number zero
xorw %ax,%ax # Segment number zero
...
@@ -45,7 +45,8 @@ seta20.2:
...
@@ -45,7 +45,8 @@ seta20.2:
# Switch from real to protected mode, using a bootstrap GDT
# Switch from real to protected mode, using a bootstrap GDT
# and segment translation that makes virtual addresses
# and segment translation that makes virtual addresses
# identical to physical addresses, so that the
# identical to physical addresses, so that the
# effective memory map does not change during the switch.
# effective memory map does not change after subsequent
# loads of segment registers.
lgdt gdtdesc
lgdt gdtdesc
movl %cr0, %eax
movl %cr0, %eax
orl $CR0_PE, %eax
orl $CR0_PE, %eax
...
@@ -57,7 +58,11 @@ seta20.2:
...
@@ -57,7 +58,11 @@ seta20.2:
# default to 32 bits after this jump.
# default to 32 bits after this jump.
ljmp $(SEG_KCODE<<3), $start32
ljmp $(SEG_KCODE<<3), $start32
.code32 # Assemble for 32-bit mode
# tell the assembler to generate 0x66 prefixes for 16-bit
# instructions like movw, and to generate 32-bit immediate
# addresses.
.code32
start32:
start32:
# Set up the protected-mode data segment registers
# Set up the protected-mode data segment registers
movw $(SEG_KDATA<<3), %ax # Our data segment selector
movw $(SEG_KDATA<<3), %ax # Our data segment selector
...
...
bootother.S
浏览文件 @
faad047a
...
@@ -9,80 +9,69 @@
...
@@ -9,80 +9,69 @@
# Because this code sets DS to zero, it must sit
# Because this code sets DS to zero, it must sit
# at an address in the low 2^16 bytes.
# at an address in the low 2^16 bytes.
#
#
# Bootothers (in main.c) sends the STARTUPs
,
one at a time.
# Bootothers (in main.c) sends the STARTUPs one at a time.
# It
put
s this code (start) at 0x7000.
# It
copie
s this code (start) at 0x7000.
# It puts the
correct %esp
in start-4,
# It puts the
address of a newly allocated per-core stack
in start-4,
# and the
place to jump to
in start-8.
# and the
address of the place to jump to (mpmain)
in start-8.
#
#
# This code is identical to bootasm.S except:
# This code is identical to bootasm.S except:
# - it does not need to enable A20
# - it does not need to enable A20
# - it uses the address at start-4 for the %esp
# - it uses the address at start-4 for the %esp
# - it jumps to the address at start-8 instead of calling bootmain
# - it jumps to the address at start-8 instead of calling bootmain
#define SEG_KCODE 1
// kernel code
#define SEG_KCODE 1
#define SEG_KDATA 2
// kernel data+stack
#define SEG_KDATA 2
#define CR0_PE 1
// protected mode enable bit
#define CR0_PE 1
.code16
# Assemble for 16-bit mode
.code16
.globl start
.globl start
start:
start:
cli
# Disable interrupts
cli
# Set up the important data segment registers (DS, ES, SS).
xorw %ax,%ax
xorw %ax,%ax # Segment number zero
movw %ax,%ds
movw %ax,%ds # -> Data Segment
movw %ax,%es
movw %ax,%es # -> Extra Segment
movw %ax,%ss
movw %ax,%ss # -> Stack Segment
//PAGEBREAK!
//PAGEBREAK!
# Switch from real to protected mode, using a bootstrap GDT
# and segment translation that makes virtual addresses
# identical to physical addresses, so that the
# effective memory map does not change during the switch.
lgdt gdtdesc
lgdt gdtdesc
movl %cr0, %eax
movl %cr0, %eax
orl $CR0_PE, %eax
orl $CR0_PE, %eax
movl %eax, %cr0
movl %eax, %cr0
# This ljmp is how you load the CS (Code Segment) register.
# 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
start32:
start32:
# Set up the protected-mode data segment registers
movw $(SEG_KDATA<<3), %ax
movw $(SEG_KDATA<<3), %ax # Our data segment selector
movw %ax, %ds
movw %ax, %ds # -> DS: Data Segment
movw %ax, %es
movw %ax, %es # -> ES: Extra Segment
movw %ax, %ss
movw %ax, %ss # -> SS: Stack Segment
movw $0, %ax
movw $0, %ax # Zero segments not ready for use
movw %ax, %fs
movw %ax, %fs # -> FS
movw %ax, %gs
movw %ax, %gs # -> GS
#
Set up the stack pointer and call into C.
#
switch to the stack allocated by bootothers()
movl start-4, %esp
movl start-4, %esp
# call mpmain()
call *(start-8)
call *(start-8)
# If the call returns (it shouldn't), trigger a Bochs
movw $0x8a00, %ax
# breakpoint if running under Bochs, then loop.
movw $0x8a00, %ax # 0x8a00 -> port 0x8a00
movw %ax, %dx
movw %ax, %dx
outw %ax, %dx
outw %ax, %dx
movw $0x8ae0, %ax
# 0x8ae0 -> port 0x8a00
movw $0x8ae0, %ax
outw %ax, %dx
outw %ax, %dx
spin:
spin:
jmp spin
jmp spin
# Bootstrap GDT
.p2align 2
.p2align 2 # force 4 byte alignment
gdt:
gdt:
SEG_NULLASM
# null seg
SEG_NULLASM
SEG_ASM(STA_X|STA_R, 0x0, 0xffffffff)
# code seg
SEG_ASM(STA_X|STA_R, 0x0, 0xffffffff)
SEG_ASM(STA_W, 0x0, 0xffffffff)
# data seg
SEG_ASM(STA_W, 0x0, 0xffffffff)
gdtdesc:
gdtdesc:
.word (gdtdesc - gdt - 1)
# sizeof(gdt) - 1
.word (gdtdesc - gdt - 1)
.long gdt
# address gdt
.long gdt
defs.h
浏览文件 @
faad047a
...
@@ -152,7 +152,7 @@ void uartintr(void);
...
@@ -152,7 +152,7 @@ void uartintr(void);
void
uartputc
(
int
);
void
uartputc
(
int
);
// vm.c
// vm.c
void
ksegmen
t
(
void
);
void
segini
t
(
void
);
void
kvmalloc
(
void
);
void
kvmalloc
(
void
);
void
vmenable
(
void
);
void
vmenable
(
void
);
pde_t
*
setupkvm
(
void
);
pde_t
*
setupkvm
(
void
);
...
...
main.c
浏览文件 @
faad047a
...
@@ -11,16 +11,14 @@ void jkstack(void) __attribute__((noreturn));
...
@@ -11,16 +11,14 @@ void jkstack(void) __attribute__((noreturn));
void
mainc
(
void
);
void
mainc
(
void
);
// Bootstrap processor starts running C code here.
// Bootstrap processor starts running C code here.
// Allocate a real stack and switch to it, first
// doing some setup required for memory allocator to work.
int
int
main
(
void
)
main
(
void
)
{
{
mpinit
();
// collect info about this machine
mpinit
();
// collect info about this machine
lapicinit
(
mpbcpu
());
lapicinit
(
mpbcpu
());
ksegment
();
// set up segments
seginit
();
// set up segments
picinit
();
// interrupt controller
ioapicinit
();
// another interrupt controller
consoleinit
();
// I/O devices & their interrupts
uartinit
();
// serial port
kinit
();
// initialize memory allocator
kinit
();
// initialize memory allocator
jkstack
();
// call mainc() on a properly-allocated stack
jkstack
();
// call mainc() on a properly-allocated stack
}
}
...
@@ -37,10 +35,16 @@ jkstack(void)
...
@@ -37,10 +35,16 @@ jkstack(void)
panic
(
"jkstack"
);
panic
(
"jkstack"
);
}
}
// Set up hardware and software.
// Runs only on the boostrap processor.
void
void
mainc
(
void
)
mainc
(
void
)
{
{
cprintf
(
"
\n
cpu%d: starting xv6
\n\n
"
,
cpu
->
id
);
cprintf
(
"
\n
cpu%d: starting xv6
\n\n
"
,
cpu
->
id
);
picinit
();
// interrupt controller
ioapicinit
();
// another interrupt controller
consoleinit
();
// I/O devices & their interrupts
uartinit
();
// serial port
kvmalloc
();
// initialize the kernel page table
kvmalloc
();
// initialize the kernel page table
pinit
();
// process table
pinit
();
// process table
tvinit
();
// trap vectors
tvinit
();
// trap vectors
...
@@ -64,16 +68,17 @@ static void
...
@@ -64,16 +68,17 @@ static void
mpmain
(
void
)
mpmain
(
void
)
{
{
if
(
cpunum
()
!=
mpbcpu
())
{
if
(
cpunum
()
!=
mpbcpu
())
{
ksegmen
t
();
segini
t
();
lapicinit
(
cpunum
());
lapicinit
(
cpunum
());
}
}
vmenable
();
// turn on paging
vmenable
();
// turn on paging
cprintf
(
"cpu%d: starting
\n
"
,
cpu
->
id
);
cprintf
(
"cpu%d: starting
\n
"
,
cpu
->
id
);
idtinit
();
// load idt register
idtinit
();
// load idt register
xchg
(
&
cpu
->
booted
,
1
);
xchg
(
&
cpu
->
booted
,
1
);
// tell bootothers() we're up
scheduler
();
// start running processes
scheduler
();
// start running processes
}
}
// Start the non-boot processors.
static
void
static
void
bootothers
(
void
)
bootothers
(
void
)
{
{
...
@@ -91,10 +96,13 @@ bootothers(void)
...
@@ -91,10 +96,13 @@ bootothers(void)
if
(
c
==
cpus
+
cpunum
())
// We've started already.
if
(
c
==
cpus
+
cpunum
())
// We've started already.
continue
;
continue
;
// Fill in %esp, %eip and start code on cpu.
// Tell bootother.S what stack to use and the address of mpmain;
// it expects to find these two addresses stored just before
// its first instruction.
stack
=
kalloc
();
stack
=
kalloc
();
*
(
void
**
)(
code
-
4
)
=
stack
+
KSTACKSIZE
;
*
(
void
**
)(
code
-
4
)
=
stack
+
KSTACKSIZE
;
*
(
void
**
)(
code
-
8
)
=
mpmain
;
*
(
void
**
)(
code
-
8
)
=
mpmain
;
lapicstartap
(
c
->
id
,
(
uint
)
code
);
lapicstartap
(
c
->
id
,
(
uint
)
code
);
// Wait for cpu to finish mpmain()
// Wait for cpu to finish mpmain()
...
...
proc.c
浏览文件 @
faad047a
...
@@ -65,7 +65,8 @@ procdump(void)
...
@@ -65,7 +65,8 @@ procdump(void)
//PAGEBREAK: 32
//PAGEBREAK: 32
// Look in the process table for an UNUSED proc.
// Look in the process table for an UNUSED proc.
// If found, change state to EMBRYO and return it.
// If found, change state to EMBRYO and initialize
// state required to run in the kernel.
// Otherwise return 0.
// Otherwise return 0.
static
struct
proc
*
static
struct
proc
*
allocproc
(
void
)
allocproc
(
void
)
...
@@ -97,7 +98,7 @@ found:
...
@@ -97,7 +98,7 @@ found:
p
->
tf
=
(
struct
trapframe
*
)
sp
;
p
->
tf
=
(
struct
trapframe
*
)
sp
;
// Set up new context to start executing at forkret,
// Set up new context to start executing at forkret,
// which returns to trapret
(see below)
.
// which returns to trapret.
sp
-=
4
;
sp
-=
4
;
*
(
uint
*
)
sp
=
(
uint
)
trapret
;
*
(
uint
*
)
sp
=
(
uint
)
trapret
;
...
@@ -105,6 +106,7 @@ found:
...
@@ -105,6 +106,7 @@ found:
p
->
context
=
(
struct
context
*
)
sp
;
p
->
context
=
(
struct
context
*
)
sp
;
memset
(
p
->
context
,
0
,
sizeof
*
p
->
context
);
memset
(
p
->
context
,
0
,
sizeof
*
p
->
context
);
p
->
context
->
eip
=
(
uint
)
forkret
;
p
->
context
->
eip
=
(
uint
)
forkret
;
return
p
;
return
p
;
}
}
...
...
proc.h
浏览文件 @
faad047a
...
@@ -11,7 +11,7 @@
...
@@ -11,7 +11,7 @@
// Per-CPU state
// Per-CPU state
struct
cpu
{
struct
cpu
{
uchar
id
;
// Local APIC ID; index into cpus[] below
uchar
id
;
// Local APIC ID; index into cpus[] below
struct
context
*
scheduler
;
//
Switch
here to enter scheduler
struct
context
*
scheduler
;
//
swtch()
here to enter scheduler
struct
taskstate
ts
;
// Used by x86 to find stack for interrupt
struct
taskstate
ts
;
// Used by x86 to find stack for interrupt
struct
segdesc
gdt
[
NSEGS
];
// x86 global descriptor table
struct
segdesc
gdt
[
NSEGS
];
// x86 global descriptor table
volatile
uint
booted
;
// Has the CPU started?
volatile
uint
booted
;
// Has the CPU started?
...
@@ -20,7 +20,7 @@ struct cpu {
...
@@ -20,7 +20,7 @@ struct cpu {
// Cpu-local storage variables; see below
// Cpu-local storage variables; see below
struct
cpu
*
cpu
;
struct
cpu
*
cpu
;
struct
proc
*
proc
;
struct
proc
*
proc
;
// The currently-running process.
};
};
extern
struct
cpu
cpus
[
NCPU
];
extern
struct
cpu
cpus
[
NCPU
];
...
@@ -29,13 +29,13 @@ extern int ncpu;
...
@@ -29,13 +29,13 @@ extern int ncpu;
// Per-CPU variables, holding pointers to the
// Per-CPU variables, holding pointers to the
// current cpu and to the current process.
// current cpu and to the current process.
// The asm suffix tells gcc to use "%gs:0" to refer to cpu
// The asm suffix tells gcc to use "%gs:0" to refer to cpu
// and "%gs:4" to refer to proc.
ksegmen
t sets up the
// and "%gs:4" to refer to proc.
segini
t sets up the
// %gs segment register so that %gs refers to the memory
// %gs segment register so that %gs refers to the memory
// holding those two variables in the local cpu's struct cpu.
// holding those two variables in the local cpu's struct cpu.
// This is similar to how thread-local variables are implemented
// This is similar to how thread-local variables are implemented
// in thread libraries such as Linux pthreads.
// in thread libraries such as Linux pthreads.
extern
struct
cpu
*
cpu
asm
(
"%gs:0"
);
//
This cpu.
extern
struct
cpu
*
cpu
asm
(
"%gs:0"
);
//
&cpus[cpunum()]
extern
struct
proc
*
proc
asm
(
"%gs:4"
);
//
Current proc on this cpu.
extern
struct
proc
*
proc
asm
(
"%gs:4"
);
//
cpus[cpunum()].proc
//PAGEBREAK: 17
//PAGEBREAK: 17
// Saved registers for kernel context switches.
// Saved registers for kernel context switches.
...
@@ -61,13 +61,13 @@ enum procstate { UNUSED, EMBRYO, SLEEPING, RUNNABLE, RUNNING, ZOMBIE };
...
@@ -61,13 +61,13 @@ 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
;
//
Linear address of proc's pgdir
pde_t
*
pgdir
;
//
Page table
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
struct
proc
*
parent
;
// Parent process
struct
proc
*
parent
;
// Parent process
struct
trapframe
*
tf
;
// Trap frame for current syscall
struct
trapframe
*
tf
;
// Trap frame for current syscall
struct
context
*
context
;
//
Switch
here to run process
struct
context
*
context
;
//
swtch()
here to run process
void
*
chan
;
// If non-zero, sleeping on chan
void
*
chan
;
// If non-zero, sleeping on chan
int
killed
;
// If non-zero, have been killed
int
killed
;
// If non-zero, have been killed
struct
file
*
ofile
[
NOFILE
];
// Open files
struct
file
*
ofile
[
NOFILE
];
// Open files
...
...
spinlock.c
浏览文件 @
faad047a
...
@@ -23,7 +23,7 @@ initlock(struct spinlock *lk, char *name)
...
@@ -23,7 +23,7 @@ initlock(struct spinlock *lk, char *name)
void
void
acquire
(
struct
spinlock
*
lk
)
acquire
(
struct
spinlock
*
lk
)
{
{
pushcli
();
pushcli
();
// disable interrupts to avoid deadlock.
if
(
holding
(
lk
))
if
(
holding
(
lk
))
panic
(
"acquire"
);
panic
(
"acquire"
);
...
...
vm.c
浏览文件 @
faad047a
...
@@ -13,7 +13,7 @@ static pde_t *kpgdir; // for use in scheduler()
...
@@ -13,7 +13,7 @@ static pde_t *kpgdir; // for use in scheduler()
// Set up CPU's kernel segment descriptors.
// Set up CPU's kernel segment descriptors.
// Run once at boot time on each CPU.
// Run once at boot time on each CPU.
void
void
ksegmen
t
(
void
)
segini
t
(
void
)
{
{
struct
cpu
*
c
;
struct
cpu
*
c
;
...
...
编写
预览
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论