Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
X
xv6-public
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
统计图
问题
0
问题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
银宸时代
OS Lab Group
奖励实验
xv6-public
提交
1afc9d3f
提交
1afc9d3f
8月 05, 2010
创建
作者:
Robert Morris
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
add some comments
find out the hard way why user and kernel must have separate segment descriptors
上级
c9959978
隐藏空白字符变更
内嵌
并排
正在显示
6 个修改的文件
包含
30 行增加
和
19 行删除
+30
-19
asm.h
asm.h
+2
-0
bootasm.S
bootasm.S
+4
-2
bootother.S
bootother.S
+4
-2
main.c
main.c
+12
-10
proc.h
proc.h
+2
-2
vm.c
vm.c
+6
-3
没有找到文件。
asm.h
浏览文件 @
1afc9d3f
...
...
@@ -6,6 +6,8 @@
.word 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) \
.word (((lim) >> 12) & 0xffff), ((base) & 0xffff); \
.byte (((base) >> 16) & 0xff), (0x90 | (type)), \
...
...
bootasm.S
浏览文件 @
1afc9d3f
...
...
@@ -51,8 +51,10 @@ seta20.2:
orl $CR0_PE, %eax
movl %eax, %cr0
# Jump to next instruction, but in 32-bit code segment.
# Switches processor into 32-bit mode.
# 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
.code32 # Assemble for 32-bit mode
...
...
bootother.S
浏览文件 @
1afc9d3f
...
...
@@ -45,8 +45,10 @@ start:
orl $CR0_PE, %eax
movl %eax, %cr0
# Jump to next instruction, but in 32-bit code segment.
# Switches processor into 32-bit mode.
# 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
.code32 # Assemble for 32-bit mode
...
...
main.c
浏览文件 @
1afc9d3f
...
...
@@ -16,13 +16,13 @@ main(void)
{
mpinit
();
// collect info about this machine
lapicinit
(
mpbcpu
());
ksegment
();
ksegment
();
// set up segments
picinit
();
// interrupt controller
ioapicinit
();
// another interrupt controller
consoleinit
();
// I/O devices & their interrupts
uartinit
();
// serial port
pminit
();
//
physical memory for kernel
jkstack
();
//
Jump to mainc
on a properly-allocated stack
pminit
();
//
discover how much memory there is
jkstack
();
//
call mainc()
on a properly-allocated stack
}
void
...
...
@@ -41,7 +41,7 @@ void
mainc
(
void
)
{
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
tvinit
();
// trap vectors
binit
();
// buffer cache
...
...
@@ -57,8 +57,9 @@ mainc(void)
mpmain
();
}
// Bootstrap processor gets here after setting up the hardware.
// Additional processors start here.
// Common CPU setup code.
// Bootstrap CPU comes here from mainc().
// Other CPUs jump here from bootother.S.
static
void
mpmain
(
void
)
{
...
...
@@ -66,11 +67,11 @@ mpmain(void)
ksegment
();
lapicinit
(
cpunum
());
}
vminit
();
//
Run with paging on each processor
vminit
();
//
turn on paging
cprintf
(
"cpu%d: starting
\n
"
,
cpu
->
id
);
idtinit
();
idtinit
();
// load idt register
xchg
(
&
cpu
->
booted
,
1
);
scheduler
();
scheduler
();
// start running processes
}
static
void
...
...
@@ -85,6 +86,7 @@ bootothers(void)
// placed the start of bootother.S there.
code
=
(
uchar
*
)
0x7000
;
memmove
(
code
,
_binary_bootother_start
,
(
uint
)
_binary_bootother_size
);
for
(
c
=
cpus
;
c
<
cpus
+
ncpu
;
c
++
){
if
(
c
==
cpus
+
cpunum
())
// We've started already.
continue
;
...
...
@@ -95,7 +97,7 @@ bootothers(void)
*
(
void
**
)(
code
-
8
)
=
mpmain
;
lapicstartap
(
c
->
id
,
(
uint
)
code
);
// Wait for cpu to
get through bootstrap.
// Wait for cpu to
finish mpmain()
while
(
c
->
booted
==
0
)
;
}
...
...
proc.h
浏览文件 @
1afc9d3f
...
...
@@ -3,8 +3,8 @@
#define SEG_KCODE 1 // kernel code
#define SEG_KDATA 2 // kernel data+stack
#define SEG_KCPU 3 // kernel per-cpu data
#define SEG_UCODE 4
#define SEG_UDATA 5
#define SEG_UCODE 4
// user code
#define SEG_UDATA 5
// user data+stack
#define SEG_TSS 6 // this process's task state
#define NSEGS 7
...
...
vm.c
浏览文件 @
1afc9d3f
...
...
@@ -93,12 +93,15 @@ ksegment(void)
{
struct
cpu
*
c
;
// Map once virtual addresses to linear addresses using identity map
// Map virtual addresses to linear addresses using identity map.
// Cannot share a CODE descriptor for both kernel and user
// because it would have to have DPL_USR, but the CPU forbids
// an interrupt from CPL=0 to DPL=3.
c
=
&
cpus
[
cpunum
()];
c
->
gdt
[
SEG_KCODE
]
=
SEG
(
STA_X
|
STA_R
,
0
,
0xffffffff
,
0
);
c
->
gdt
[
SEG_KDATA
]
=
SEG
(
STA_W
,
0
,
0xffffffff
,
0
);
c
->
gdt
[
SEG_UCODE
]
=
SEG
(
STA_X
|
STA_R
,
0
x0
,
0xffffffff
,
DPL_USER
);
c
->
gdt
[
SEG_UDATA
]
=
SEG
(
STA_W
,
0
x0
,
0xffffffff
,
DPL_USER
);
c
->
gdt
[
SEG_UCODE
]
=
SEG
(
STA_X
|
STA_R
,
0
,
0xffffffff
,
DPL_USER
);
c
->
gdt
[
SEG_UDATA
]
=
SEG
(
STA_W
,
0
,
0xffffffff
,
DPL_USER
);
// map cpu, and curproc
c
->
gdt
[
SEG_KCPU
]
=
SEG
(
STA_W
,
&
c
->
cpu
,
8
,
0
);
...
...
编写
预览
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论