Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
X
xv6-public
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
统计图
问题
0
问题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
银宸时代
OS Lab Group
奖励实验
xv6-public
提交
bd71a450
提交
bd71a450
8月 11, 2011
创建
作者:
Frans Kaashoek
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Make AP processors boot using bootpgdir
Remove device mapping from bootpgdir Remove unnecessary vmenable Set CPUS back to 2 in Makefile Passes all usertests
上级
673b739d
显示空白字符变更
内嵌
并排
正在显示
5 个修改的文件
包含
42 行增加
和
65 行删除
+42
-65
Makefile
Makefile
+5
-5
bootother.S
bootother.S
+19
-10
lapic.c
lapic.c
+0
-1
main.c
main.c
+14
-23
vm.c
vm.c
+4
-26
没有找到文件。
Makefile
浏览文件 @
bd71a450
...
@@ -98,10 +98,10 @@ bootblock: bootasm.S bootmain.c
...
@@ -98,10 +98,10 @@ bootblock: bootasm.S bootmain.c
./sign.pl bootblock
./sign.pl bootblock
bootother
:
bootother.S
bootother
:
bootother.S
$(CC)
$(CFLAGS)
-nostdinc
-I
.
-c
bootother.S
$(CC)
$(CFLAGS)
-
fno-pic
-
nostdinc
-I
.
-c
bootother.S
$(LD)
$(LDFLAGS)
-N
-e
start
-Ttext
0x7000
-o
boot
other.out
bootother.o
$(LD)
$(LDFLAGS)
-N
-e
start
-Ttext
0x7000
-o
boot
blockother.o
bootother.o
$(OBJCOPY)
-S
-O
binary
bootother.out
bootother
$(OBJCOPY)
-S
-O
binary
-j
.text bootblockother.o
bootother
$(OBJDUMP)
-S
bootother.o
>
bootother.asm
$(OBJDUMP)
-S
boot
block
other.o
>
bootother.asm
initcode
:
initcode.S
initcode
:
initcode.S
$(CC)
$(CFLAGS)
-nostdinc
-I
.
-c
initcode.S
$(CC)
$(CFLAGS)
-nostdinc
-I
.
-c
initcode.S
...
@@ -199,7 +199,7 @@ QEMUGDB = $(shell if $(QEMU) -help | grep -q '^-gdb'; \
...
@@ -199,7 +199,7 @@ QEMUGDB = $(shell if $(QEMU) -help | grep -q '^-gdb'; \
then
echo
"-gdb tcp::
$(GDBPORT)
"
;
\
then
echo
"-gdb tcp::
$(GDBPORT)
"
;
\
else
echo
"-s -p
$(GDBPORT)
"
;
fi
)
else
echo
"-s -p
$(GDBPORT)
"
;
fi
)
ifndef
CPUS
ifndef
CPUS
CPUS
:=
1
CPUS
:=
2
endif
endif
QEMUOPTS
=
-hdb
fs.img xv6.img
-smp
$(CPUS)
-m
512
QEMUOPTS
=
-hdb
fs.img xv6.img
-smp
$(CPUS)
-m
512
...
...
bootother.S
浏览文件 @
bd71a450
...
@@ -14,12 +14,13 @@
...
@@ -14,12 +14,13 @@
# Bootothers (in main.c) sends the STARTUPs one at a time.
# Bootothers (in main.c) sends the STARTUPs one at a time.
# It copies this code (start) at 0x7000.
# It copies this code (start) at 0x7000.
# It puts the address of a newly allocated per-core stack in start-4,
# It puts the address of a newly allocated per-core stack in start-4,
# and the address of the place to jump to (mpmain) in start-8.
# the address of the place to jump to (mpboot) in start-8, and the physical
# address of bootpgdir in start-12.
#
#
#
# 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, start-8, and start-12
# - it jumps to the address at start-8 instead of calling bootmain
.code16
.code16
.globl start
.globl start
...
@@ -37,7 +38,7 @@ start:
...
@@ -37,7 +38,7 @@ start:
movl %eax, %cr0
movl %eax, %cr0
//PAGEBREAK!
//PAGEBREAK!
ljmpl $(SEG_KCODE<<3), $(start32
+KERNBASE
)
ljmpl $(SEG_KCODE<<3), $(start32)
.code32
.code32
start32:
start32:
...
@@ -49,11 +50,18 @@ start32:
...
@@ -49,11 +50,18 @@ start32:
movw %ax, %fs
movw %ax, %fs
movw %ax, %gs
movw %ax, %gs
# switch to the stack allocated by bootothers()
# Use bootpgdir as our initial page table
movl P2V_WO(start-4), %esp
movl (start-12), %eax
movl %eax, %cr3
# Turn on paging.
movl %cr0, %eax
orl $(CR0_PE|CR0_PG|CR0_WP), %eax
movl %eax, %cr0
# call mpmain()
# Switch to the stack allocated by bootothers()
call *(P2V_WO(start)-8)
movl (start-4), %esp
# Call mpboot()
call *(start-8)
movw $0x8a00, %ax
movw $0x8a00, %ax
movw %ax, %dx
movw %ax, %dx
...
@@ -66,10 +74,11 @@ spin:
...
@@ -66,10 +74,11 @@ spin:
.p2align 2
.p2align 2
gdt:
gdt:
SEG_NULLASM
SEG_NULLASM
SEG_ASM(STA_X|STA_R,
-KERNBASE
, 0xffffffff)
SEG_ASM(STA_X|STA_R,
0
, 0xffffffff)
SEG_ASM(STA_W,
-KERNBASE
, 0xffffffff)
SEG_ASM(STA_W,
0
, 0xffffffff)
gdtdesc:
gdtdesc:
.word (gdtdesc - gdt - 1)
.word (gdtdesc - gdt - 1)
.long gdt
.long gdt
lapic.c
浏览文件 @
bd71a450
...
@@ -52,7 +52,6 @@ lapicw(int index, int value)
...
@@ -52,7 +52,6 @@ lapicw(int index, int value)
void
void
lapicinit
(
int
c
)
lapicinit
(
int
c
)
{
{
cprintf
(
"lapicinit: %d 0x%x
\n
"
,
c
,
lapic
);
if
(
!
lapic
)
if
(
!
lapic
)
return
;
return
;
...
...
main.c
浏览文件 @
bd71a450
...
@@ -8,7 +8,7 @@
...
@@ -8,7 +8,7 @@
static
void
bootothers
(
void
);
static
void
bootothers
(
void
);
static
void
mpmain
(
void
)
__attribute__
((
noreturn
));
static
void
mpmain
(
void
)
__attribute__
((
noreturn
));
static
volatile
int
new
pgdir
;
extern
pde_t
*
k
pgdir
;
// Bootstrap processor starts running C code here.
// Bootstrap processor starts running C code here.
// Allocate a real stack and switch to it, first
// Allocate a real stack and switch to it, first
...
@@ -21,7 +21,6 @@ main(void)
...
@@ -21,7 +21,6 @@ main(void)
lapicinit
(
mpbcpu
());
lapicinit
(
mpbcpu
());
seginit
();
// set up segments
seginit
();
// set up segments
cprintf
(
"
\n
cpu%d: starting xv6
\n\n
"
,
cpu
->
id
);
cprintf
(
"
\n
cpu%d: starting xv6
\n\n
"
,
cpu
->
id
);
kinit
();
// initialize memory allocator
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
...
@@ -34,39 +33,35 @@ main(void)
...
@@ -34,39 +33,35 @@ main(void)
ideinit
();
// disk
ideinit
();
// disk
if
(
!
ismp
)
if
(
!
ismp
)
timerinit
();
// uniprocessor timer
timerinit
();
// uniprocessor timer
userinit
();
// first user process
bootothers
();
// start other processors (must come before kinit; must use boot_alloc)
bootothers
();
// start other processors
kinit
();
// initialize memory allocator
newpgdir
=
1
;
userinit
();
// first user process (must come after kinit)
// Finish setting up this processor in mpmain.
// Finish setting up this processor in mpmain.
mpmain
();
mpmain
();
}
}
// Common CPU setup code.
// Bootstrap CPU comes here from mainc().
// Other CPUs jump here from bootother.S.
// Other CPUs jump here from bootother.S.
static
void
static
void
mpboot
(
void
)
mpboot
(
void
)
{
{
vmenable
();
// turn on paging
switchkvm
();
seginit
();
seginit
();
lapicinit
(
cpunum
());
lapicinit
(
cpunum
());
mpmain
();
mpmain
();
}
}
// Common CPU setup code.
// Common CPU setup code.
// Bootstrap CPU comes here from mainc().
// Other CPUs jump here from bootother.S.
static
void
static
void
mpmain
(
void
)
mpmain
(
void
)
{
{
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
);
// tell bootothers() we're up
xchg
(
&
cpu
->
booted
,
1
);
// tell bootothers() we're up
while
(
!
newpgdir
)
;
// wait until we have new page dir
switchkvm
();
// switch to new page dir
scheduler
();
// start running processes
scheduler
();
// start running processes
}
}
pde_t
bootpgdir
[];
// Start the non-boot processors.
// Start the non-boot processors.
static
void
static
void
bootothers
(
void
)
bootothers
(
void
)
...
@@ -86,41 +81,37 @@ bootothers(void)
...
@@ -86,41 +81,37 @@ bootothers(void)
if
(
c
==
cpus
+
cpunum
())
// We've started already.
if
(
c
==
cpus
+
cpunum
())
// We've started already.
continue
;
continue
;
// Tell bootother.S what stack to use and the address of mpmain;
// Tell bootother.S what stack to use, the address of mpboot and pgdir;
// it expects to find these two addresses stored just before
stack
=
boot_alloc
();
// We need a stack below 4Mbyte with bootpgdir
// its first instruction.
stack
=
kalloc
();
*
(
void
**
)(
code
-
4
)
=
stack
+
KSTACKSIZE
;
*
(
void
**
)(
code
-
4
)
=
stack
+
KSTACKSIZE
;
*
(
void
**
)(
code
-
8
)
=
mpboot
;
*
(
void
**
)(
code
-
8
)
=
mpboot
;
*
(
int
**
)(
code
-
12
)
=
(
void
*
)
v2p
(
bootpgdir
);
lapicstartap
(
c
->
id
,
v2p
(
code
));
lapicstartap
(
c
->
id
,
v2p
(
code
));
//
W
ait for cpu to finish mpmain()
//
w
ait for cpu to finish mpmain()
while
(
c
->
booted
==
0
)
while
(
c
->
booted
==
0
)
;
;
}
}
}
}
// Boot page table used in multiboot.S.
// Boot page table used in multiboot.S
and bootother.S
.
// Page directories (and page tables), must start on a page boundary,
// Page directories (and page tables), must start on a page boundary,
// hence the "__aligned__" attribute. Also, because of restrictions
// hence the "__aligned__" attribute. Also, because of restrictions
// related to linking and static initializers, we use "x + PTE_P"
// related to linking and static initializers, we use "x + PTE_P"
// here, rather than the more standard "x | PTE_P". Everywhere else
// here, rather than the more standard "x | PTE_P". Everywhere else
// you should use "|" to combine flags.
// you should use "|" to combine flags.
pte_t
entry_pgtable
[
NPTENTRIES
];
pte_t
dev_pgtable
[
NPTENTRIES
];
pte_t
dev_pgtable
[
NPTENTRIES
];
pte_t
entry_pgtable
[
NPTENTRIES
];
__attribute__
((
__aligned__
(
PGSIZE
)))
__attribute__
((
__aligned__
(
PGSIZE
)))
pde_t
bootpgdir
[
NPDENTRIES
]
=
{
pde_t
bootpgdir
[
NPDENTRIES
]
=
{
// Map VA's [0, 4MB) to PA's [0, 4MB)
// Map VA's [0, 4MB) to PA's [0, 4MB)
[
0
]
[
0
]
=
((
uint
)
entry_pgtable
-
KERNBASE
)
+
PTE_P
,
=
((
uint
)
entry_pgtable
-
KERNBASE
)
+
PTE_P
+
PTE_W
,
// Map VA's [KERNBASE, KERNBASE+4MB) to PA's [0, 4MB)
// Map VA's [KERNBASE, KERNBASE+4MB) to PA's [0, 4MB)
[
KERNBASE
>>
PDXSHIFT
]
[
KERNBASE
>>
PDXSHIFT
]
=
((
uint
)
entry_pgtable
-
KERNBASE
)
+
PTE_P
+
PTE_W
,
=
((
uint
)
entry_pgtable
-
KERNBASE
)
+
PTE_P
+
PTE_W
,
// Map VA's [DEVSPACE, DEVSPACE+4MB) to PA's [DEVSPACE, 4MB)
[
0xFEE00000
>>
PDXSHIFT
]
=
((
uint
)
dev_pgtable
-
KERNBASE
)
+
PTE_P
+
PTE_W
,
};
};
// XXX switch to super pages
// XXX switch to super pages
...
...
vm.c
浏览文件 @
bd71a450
...
@@ -8,7 +8,7 @@
...
@@ -8,7 +8,7 @@
#include "elf.h"
#include "elf.h"
extern
char
data
[];
// defined in data.S
extern
char
data
[];
// defined in data.S
static
pde_t
*
kpgdir
;
// for use in scheduler()
pde_t
*
kpgdir
;
// for use in scheduler()
struct
segdesc
gdt
[
NSEGS
];
struct
segdesc
gdt
[
NSEGS
];
// Set up CPU's kernel segment descriptors.
// Set up CPU's kernel segment descriptors.
...
@@ -40,7 +40,7 @@ seginit(void)
...
@@ -40,7 +40,7 @@ seginit(void)
}
}
// Return the address of the PTE in page table pgdir
// Return the address of the PTE in page table pgdir
// that corresponds to linear address va. If
create
!=0,
// that corresponds to linear address va. If
alloc
!=0,
// create any required page table pages.
// create any required page table pages.
static
pte_t
*
static
pte_t
*
walkpgdir
(
pde_t
*
pgdir
,
const
void
*
va
,
char
*
(
*
alloc
)(
void
))
walkpgdir
(
pde_t
*
pgdir
,
const
void
*
va
,
char
*
(
*
alloc
)(
void
))
...
@@ -102,8 +102,8 @@ mappages(pde_t *pgdir, void *la, uint size, uint pa, int perm, char* (*alloc)(vo
...
@@ -102,8 +102,8 @@ mappages(pde_t *pgdir, void *la, uint size, uint pa, int perm, char* (*alloc)(vo
// setupkvm() and exec() set up every page table like this:
// setupkvm() and exec() set up every page table like this:
// 0..USERTOP : user memory (text, data, stack, heap), mapped to some unused phys mem
// 0..USERTOP : user memory (text, data, stack, heap), mapped to some unused phys mem
// KERNBASE..KERNBASE+1M: mapped to 0..1M
// KERNBASE..KERNBASE+1M: mapped to 0..1M
// KERNBASE+1M..KERNBASE+end : mapped to 1M..end
// KERNBASE+1M..KERNBASE+end : mapped to 1M..end
(mapped without write permission)
// KERNBASE+end..KERBASE+PHYSTOP : mapped to end..PHYSTOP (free memory)
// KERNBASE+end..KERBASE+PHYSTOP : mapped to end..PHYSTOP (
rw data +
free memory)
// 0xfe000000..0 : mapped direct (devices such as ioapic)
// 0xfe000000..0 : mapped direct (devices such as ioapic)
//
//
// The kernel allocates memory for its heap and for user memory
// The kernel allocates memory for its heap and for user memory
...
@@ -150,28 +150,6 @@ kvmalloc(void)
...
@@ -150,28 +150,6 @@ kvmalloc(void)
switchkvm
();
switchkvm
();
}
}
// Turn on paging.
void
vmenable
(
void
)
{
uint
cr0
;
switchkvm
();
// load kpgdir into cr3
cr0
=
rcr0
();
cr0
|=
CR0_PG
;
lcr0
(
cr0
);
struct
cpu
*
c
=
&
cpus
[
0
];
lgdt
((
void
*
)
v2p
((
void
*
)(
c
->
gdt
)),
sizeof
(
c
->
gdt
));
loadgs
(
SEG_KCPU
<<
3
);
loadfs
(
SEG_KDATA
<<
3
);
loades
(
SEG_KDATA
<<
3
);
loadds
(
SEG_KDATA
<<
3
);
loadss
(
SEG_KDATA
<<
3
);
__asm
volatile
(
"ljmp %0,$1f
\n
1:
\n
"
::
"i"
(
SEG_KCODE
<<
3
));
// reload cs
}
// Switch h/w page table register to the kernel-only page table,
// Switch h/w page table register to the kernel-only page table,
// for when no process is running.
// for when no process is running.
void
void
...
...
编写
预览
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论