Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
X
xv6-public
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
统计图
问题
0
问题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
银宸时代
OS Lab Group
奖励实验
xv6-public
提交
7a532024
提交
7a532024
10月 24, 2011
创建
作者:
Silas Boyd-Wickizer
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Boot APs, but panic in mpboot.
上级
fbe2bead
隐藏空白字符变更
内嵌
并排
正在显示
6 个修改的文件
包含
192 行增加
和
132 行删除
+192
-132
Makefile
Makefile
+11
-5
boot.S
boot.S
+80
-64
bootother.S
bootother.S
+39
-58
kernel.h
kernel.h
+1
-0
lapic.c
lapic.c
+4
-4
main.c
main.c
+57
-1
没有找到文件。
Makefile
浏览文件 @
7a532024
...
...
@@ -39,9 +39,9 @@ CFLAGS += $(shell $(CC) -fno-stack-protector -E -x c /dev/null >/dev/null 2>&1 &
ASFLAGS
=
-m64
-gdwarf-2
LDFLAGS
+=
-m
elf_x86_64
kernel
:
boot.o $(OBJS) initcode
kernel
:
boot.o $(OBJS) initcode
bootother
$(LD)
$(LDFLAGS)
-T
kernel.ld
-z
max-page-size
=
4096
-e
start
\
-o
$@
boot.o
$(OBJS)
-b
binary initcode
-o
$@
boot.o
$(OBJS)
-b
binary initcode
bootother
initcode
:
initcode.S
$(CC)
$(CFLAGS)
-nostdinc
-I
.
-c
initcode.S
...
...
@@ -49,6 +49,12 @@ initcode: initcode.S
$(OBJCOPY)
-S
-O
binary initcode.out initcode
$(OBJDUMP)
-S
initcode.o
>
initcode.asm
bootother
:
bootother.S
$(CC)
$(CFLAGS)
-nostdinc
-I
.
-c
bootother.S
$(LD)
$(LDFLAGS)
-N
-e
start
-Ttext
0x7000
-o
bootother.out bootother.o
$(OBJCOPY)
-S
-O
binary bootother.out bootother
$(OBJDUMP)
-S
bootother.out
>
bootother.asm
xv6memfs.img
:
bootblock kernelmemfs
dd
if
=
/dev/zero
of
=
xv6memfs.img
count
=
10000
dd
if
=
bootblock
of
=
xv6memfs.img
conv
=
notrunc
...
...
@@ -59,11 +65,11 @@ xv6memfs.img: bootblock kernelmemfs
.PHONY
:
clean qemu ud0
clean
:
rm
-f
*
.o
*
.d
*
.asm
*
.sym initcode kernel
rm
-f
*
.o
*
.d
*
.asm
*
.sym initcode kernel
bootother
QEMUOPTS
=
-smp
$(CPUS)
-m
512
-nographic
QEMUOPTS
=
-smp
$(CPUS)
-m
512
qemu
:
kernel
$(QEMU)
$(QEMUOPTS)
-kernel
kernel
$(QEMU)
$(QEMUOPTS)
-kernel
kernel
#-S -s
ud0
:
kernel
rsync
-avP
kernel amsterdam.csail.mit.edu:/tftpboot/ud0/kernel.xv6
boot.S
浏览文件 @
7a532024
...
...
@@ -23,7 +23,7 @@
#define DATAMAGIC 0x123456789abcdef0
# STACK is the size of the bootstrap stack.
#define STACK
8192
#define STACK
4096
# CGATEXTMEM is the physical address of the CGA text memory.
#define CGATEXTMEM 0xB8000
...
...
@@ -107,66 +107,23 @@ start:
rep stosb
movl %edx, %edi
# Load GDT.
subl $8, %esp
movl $PADDR(bootgdt), 4(%esp)
movw $(8*NSEGS-1), 2(%esp)
lgdt 2(%esp)
addl $8, %esp
movl $KDSEG, %eax // data segment selector
movw %ax, %ds
movw %ax, %es
movw %ax, %ss
movl $0, %eax // null segment selector
movw %ax, %fs
movw %ax, %gs
call loadgdt
# Enter new 32-bit code segment (already in 32-bit mode).
ljmp $KCSEG32, $PADDR(start32) // code32 segment selector
start32:
# Initialize page table.
call initpagetables
call init32e
# Initialize IA-32e mode. See section 9.8.5 of 253668.pdf.
# Set CR4.PAE and CR4.PSE = 1.
movl %cr4, %eax
orl $0x30, %eax
movl %eax, %cr4
# Load CR3 with physical base address of level 4 page table.
movl $PADDR(kpml4), %eax
movl %eax, %cr3
# Enable IA-32e mode by setting IA32_EFER.LME = 1.
# Also turn on IA32_EFER.SCE (syscall enable).
movl $0xc0000080, %ecx
rdmsr
orl $0x101, %eax
wrmsr
# Enable paging by setting CR0.PG = 1.
movl %cr0, %eax
orl $0x80000000, %eax
movl %eax, %cr0
nop
nop
movl $PADDR(start64), %edi
# Enter 64-bit mode.
ljmp $KCSEG, $PADDR(
start
64) // code64 segment selector
ljmp $KCSEG, $PADDR(
trap
64) // code64 segment selector
.code64
start64:
# The linker thinks we are running at start64, but we're actually
# running at PADDR(start64), so use an explicit calculation to
# load and jump to the correct address.
movq $KBASE, %rax
addq $PADDR(start64hi), %rax
jmp *%rax
start64hi:
# Now executing at the real link address.
# Double-check that data segment is set up correctly.
movq $DATAMAGIC, %rax
...
...
@@ -177,14 +134,42 @@ start64hi:
1:
# Load VA stack pointer
movabsq $(stack+STACK), %rsp
# Kill 1GB identity mapping
movq $0, kpml4
# Clear frame pointer for stack walks, and call into C code.
movq $0, %rbp
call cmain
1: jmp 1b
.code32
.globl apstart
apstart:
call loadgdt
ljmp $KCSEG32, $PADDR(apstart32) // code32 segment selector
apstart32:
call init32e
movl $PADDR(apstart64), %edi
ljmp $KCSEG, $PADDR(trap64) // code64 segment selector
.code64
apstart64:
# Remember (from bootothers), that our kernel stack pointer is
# at the top of our temporary stack.
popq %rax
movq %rax, %rsp
movq $0, %rbp
call mpboot
1: jmp 1b
.code64
trap64:
# The linker thinks we are running at trap64, but we're actually
# running at PADDR(trap64), so use an explicit calculation to
# load and jump to the correct address. %rdi should hold the
# physical address of the jmp target.
addq $KBASE, %rdi
jmp *%rdi
.code32
.globl bootpanic
bootpanic:
# This is 32-bit code but can be called from either
...
...
@@ -248,19 +233,6 @@ setcursor:
popl %edx
ret
# Google color bar: spaces with background colors.
colorbar:
.ascii " \x40 \x40 \x40 \x40 \x40 \x40 \x40 \x40 \x40 \x40"
.ascii " \x40 \x40 \x40 \x40 \x40 \x40 \x40 \x40 \x40 \x40"
.ascii " \x10 \x10 \x10 \x10 \x10 \x10 \x10 \x10 \x10 \x10"
.ascii " \x10 \x10 \x10 \x10 \x10 \x10 \x10 \x10 \x10 \x10"
.ascii " \x20 \x20 \x20 \x20 \x20 \x20 \x20 \x20 \x20 \x20"
.ascii " \x20 \x20 \x20 \x20 \x20 \x20 \x20 \x20 \x20 \x20"
.ascii "\xDB\x0E\xDB\x0E\xDB\x0E\xDB\x0E\xDB\x0E"
.ascii "\xDB\x0E\xDB\x0E\xDB\x0E\xDB\x0E\xDB\x0E"
.ascii "\xDB\x0E\xDB\x0E\xDB\x0E\xDB\x0E\xDB\x0E"
.ascii "\xDB\x0E\xDB\x0E\xDB\x0E\xDB\x0E\xDB\x0E"
# Initial stack
.comm stack, STACK
...
...
@@ -325,6 +297,50 @@ initpagetables:
popl %edi
ret
# Initialize IA-32e mode. See section 9.8.5 of 253668.pdf.
init32e:
# Set CR4.PAE and CR4.PSE = 1.
movl %cr4, %eax
orl $0x30, %eax
movl %eax, %cr4
# Load CR3 with physical base address of level 4 page table.
movl $PADDR(kpml4), %eax
movl %eax, %cr3
# Enable IA-32e mode by setting IA32_EFER.LME = 1.
# Also turn on IA32_EFER.SCE (syscall enable).
movl $0xc0000080, %ecx
rdmsr
orl $0x101, %eax
wrmsr
# Enable paging by setting CR0.PG = 1.
movl %cr0, %eax
orl $0x80000000, %eax
movl %eax, %cr0
nop
nop
ret
loadgdt:
subl $8, %esp
movl $PADDR(bootgdt), 4(%esp)
movw $(8*NSEGS-1), 2(%esp)
lgdt 2(%esp)
addl $8, %esp
movl $KDSEG, %eax // data segment selector
movw %ax, %ds
movw %ax, %es
movw %ax, %ss
movl $0, %eax // null segment selector
movw %ax, %fs
movw %ax, %gs
ret
# For sanity check above.
.data
datamagic:
...
...
bootother.S
浏览文件 @
7a532024
#include "asm.h"
#include "memlayout.h"
# Each non-boot CPU ("AP") is started up in response to a STARTUP
# IPI from the boot CPU. Section B.4.2 of the Multi-Processor
# Specification says that the AP will start in real mode with CS:IP
...
...
@@ -20,66 +17,50 @@
# - it uses the address at start-4 for the %esp
# - it jumps to the address at start-8 instead of calling bootmain
#define SEG_KCODE 1
#define SEG_KDATA 2
#define CR0_PE 1
#define RELOC1(x) ((x) + KERNBASE) // same as V2P, but without casts
#define SEG_ASM(type,base,lim) \
.word (((lim) >> 12) & 0xffff), ((base) & 0xffff); \
.byte (((base) >> 16) & 0xff), (0x90 | (type)), \
(0xC0 | (((lim) >> 28) & 0xf)), (((base) >> 24) & 0xff)
#define PROT_MODE_CSEG 0x8
#define PROT_MODE_DSEG 0x10
#define CR0_PE_ON 0x1
.code16
.globl start
start:
cli
## movw $0xb800, %ax
## movw %ax, %es
## movw $65, %es:(0x0)
xorw %ax,%ax
movw %ax,%ds
movw %ax,%es
movw %ax,%ss
lgdt gdtdesc
movl %cr0, %eax
orl $CR0_PE, %eax
movl %eax, %cr0
ljmpl $(SEG_KCODE<< 3), $(start32+KERNBASE)
cli
cld
lgdt gdtdesc
movl %cr0, %eax
orl $CR0_PE_ON, %eax
movl %eax, %cr0
# Jump to next instruction, but in 32-bit code segment.
# Switches processor into 32-bit mode.
ljmp $PROT_MODE_CSEG, $protcseg
.code32
start32:
# movw $65, 0xb8002
movw $(SEG_KDATA<<3), %ax
movw %ax, %ds
movw %ax, %es
movw %ax, %ss
movw $0, %ax
movw %ax, %fs
movw %ax, %gs
# switch to the stack allocated by bootothers()
movl RELOC1(start-4), %esp
# call mpmain()
call *(RELOC1(start)-8)
movw $0x8a00, %ax
movw %ax, %dx
outw %ax, %dx
movw $0x8ae0, %ax
outw %ax, %dx
spin:
jmp spin
.p2align 2
protcseg:
movw $PROT_MODE_DSEG, %ax
movw %ax, %ds
movw %ax, %es
movw %ax, %fs
movw %ax, %gs
movw %ax, %ss
movl $start-12, %esp
movl start-4, %ecx
jmp *%ecx
.align 4
gdt:
SEG_NULLASM
SEG_ASM(STA_X|STA_R, -KERNBASE, 0xffffffff)
SEG_ASM(STA_W, -KERNBASE, 0xffffffff)
.quad 0 # null seg
SEG_ASM(0xa, 0x0, 0xffffffff) # code seg
SEG_ASM(0x2, 0x0, 0xffffffff) # data seg
.align 16
gdtdesc:
.word (gdtdesc - gdt - 1)
.long gdt
.word 0x17 # sizeof(gdt) - 1
gdtaddr:
.long gdt # address gdt
kernel.h
浏览文件 @
7a532024
...
...
@@ -55,6 +55,7 @@ void kmfree(void*);
// lapic.c
int
cpunum
(
void
);
void
lapicstartap
(
u8
,
u32
addr
);
// mp.c
extern
int
ncpu
;
...
...
lapic.c
浏览文件 @
7a532024
...
...
@@ -167,8 +167,8 @@ void
lapicstartap
(
u8
apicid
,
u32
addr
)
{
int
i
;
u16
*
wrv
;
volatile
u16
*
wrv
;
// "The BSP must initialize CMOS shutdown code to 0AH
// and the warm reset vector (DWORD based at 40:67) to point at
// the AP startup code prior to the [universal startup algorithm]."
...
...
@@ -181,9 +181,9 @@ lapicstartap(u8 apicid, u32 addr)
// "Universal startup algorithm."
// Send INIT (level-triggered) interrupt to reset other CPU.
lapicw
(
ICRHI
,
apicid
<<
24
);
lapicw
(
ICRLO
,
INIT
|
LEVEL
|
ASSERT
);
lapicw
(
ICRLO
,
apicid
|
INIT
|
LEVEL
|
ASSERT
);
microdelay
(
200
);
lapicw
(
ICRLO
,
INIT
|
LEVEL
);
lapicw
(
ICRLO
,
apicid
|
INIT
|
LEVEL
);
microdelay
(
100
);
// should be 10ms, but too slow in Bochs!
// Send startup IPI (twice!) to enter bootstrap code.
...
...
main.c
浏览文件 @
7a532024
#include "types.h"
#include "param.h"
#include "multiboot.h"
#include "kernel.h"
#include "cpu.h"
extern
void
inituart
(
void
);
extern
void
initcga
(
void
);
...
...
@@ -16,10 +18,60 @@ extern void initproc(void);
extern
void
initbio
(
void
);
extern
void
inituser
(
void
);
static
volatile
int
bstate
;
#if 1
// Common CPU setup code.
// Bootstrap CPU comes here from mainc().
// Other CPUs jump here from bootother.S.
void
cmain
(
void
)
mpboot
(
void
)
{
// XXX(sbw) load VA for gdt, etc
panic
(
"mpboot"
);
}
#endif
// Start the non-boot processors.
static
void
bootothers
(
void
)
{
extern
u8
_binary_bootother_start
[],
_binary_bootother_size
[];
extern
void
(
*
apstart
)(
void
);
struct
cpu
*
c
;
char
*
stack
;
u8
*
code
;
// Write bootstrap code to unused memory at 0x7000.
// The linker has placed the image of bootother.S in
// _binary_bootother_start.
code
=
p2v
(
0x7000
);
memmove
(
code
,
_binary_bootother_start
,
(
u64
)
_binary_bootother_size
);
for
(
c
=
cpus
;
c
<
cpus
+
ncpu
;
c
++
){
if
(
c
==
cpus
+
cpunum
())
// We've started already.
continue
;
// Tell bootother.S what stack to use and the address of apstart;
// it expects to find these two addresses stored just before
// its first instruction.
stack
=
kalloc
();
*
(
u32
*
)(
code
-
4
)
=
(
u32
)
v2p
(
&
apstart
);
*
(
u64
*
)(
code
-
12
)
=
(
u64
)
stack
+
KSTACKSIZE
;
bstate
=
0
;
lapicstartap
(
c
->
id
,
v2p
(
code
));
// Wait for cpu to finish mpmain()
while
(
bstate
==
0
)
;
}
}
void
cmain
(
void
)
{
inituart
();
initcga
();
initconsole
();
...
...
@@ -33,6 +85,7 @@ cmain(void)
initrcu
();
// initialize rcu module
initproc
();
// process table
initbio
();
// buffer cache
#if 0
fileinit(); // file table
iinit(); // inode cache
...
...
@@ -40,6 +93,9 @@ cmain(void)
#endif
inituser
();
// first user process
bootothers
();
// start other processors
// XXX(sbw) kill ident. mapping
cprintf
(
"ncpu %d
\n
"
,
ncpu
);
panic
(
"end"
);
...
...
编写
预览
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论