Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
X
xv6-public
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
统计图
问题
0
问题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
银宸时代
OS Lab Group
奖励实验
xv6-public
提交
21a88fd4
提交
21a88fd4
6月 22, 2006
创建
作者:
kaashoek
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
checkpoint. booting second processor. stack is messed up, but thanks to cliff
and plan 9 code, at least boots and gets into C code.
上级
7baa34a4
全部展开
显示空白字符变更
内嵌
并排
正在显示
13 个修改的文件
包含
496 行增加
和
142 行删除
+496
-142
Makefile
Makefile
+7
-3
bootasm.S
bootasm.S
+1
-14
bootother.S
bootother.S
+77
-0
defs.h
defs.h
+10
-1
main.c
main.c
+8
-1
mp.c
mp.c
+254
-30
mp.h
mp.h
+50
-84
param.h
param.h
+1
-0
picirq.c
picirq.c
+0
-9
spinlock.c
spinlock.c
+39
-0
string.c
string.c
+20
-0
trapasm.S
trapasm.S
+5
-0
x86.h
x86.h
+24
-0
没有找到文件。
Makefile
浏览文件 @
21a88fd4
OBJS
=
main.o console.o string.o kalloc.o proc.o trapasm.o trap.o vectors.o
\
syscall.o ide.o picirq.o mp.o
syscall.o ide.o picirq.o mp.o
spinlock.o
CC
=
i386-jos-elf-gcc
LD
=
i386-jos-elf-ld
...
...
@@ -20,8 +20,12 @@ bootblock : bootasm.S bootmain.c
$(OBJCOPY)
-S
-O
binary bootblock.o bootblock
./sign.pl bootblock
kernel
:
$(OBJS)
$(LD)
-Ttext
0x100000
-e
main
-o
kernel
$(OBJS)
kernel
:
$(OBJS) bootother.S
$(CC)
-nostdinc
-I
.
-c
bootother.S
$(LD)
-N
-e
start
-Ttext
0x7000
-o
bootother.out bootother.o
$(OBJCOPY)
-S
-O
binary bootother.out bootother
$(OBJDUMP)
-S
bootother.o
>
bootother.asm
$(LD)
-Ttext
0x100000
-e
main
-o
kernel
$(OBJS)
-b
binary bootother
$(OBJDUMP)
-S
kernel
>
kernel.asm
vectors.S
:
vectors.pl
...
...
bootasm.S
浏览文件 @
21a88fd4
#define SEG_NULL \
.word 0, 0; \
.byte 0, 0, 0, 0
#define SEG(type,base,lim) \
.word (((lim) >> 12) & 0xffff), ((base) & 0xffff); \
.byte (((base) >> 16) & 0xff), (0x90 | (type)), \
(0xC0 | (((lim) >> 28) & 0xf)), (((base) >> 24) & 0xff)
#define STA_X 0x8 // Executable segment
#define STA_E 0x4 // Expand down (non-executable segments)
#define STA_C 0x4 // Conforming code segment (executable only)
#define STA_W 0x2 // Writeable (non-executable segments)
#define STA_R 0x2 // Readable (executable segments)
#define STA_A 0x1 // Accessed
#include "asm.h"
.set PROT_MODE_CSEG,0x8 # code segment selector
.set PROT_MODE_DSEG,0x10 # data segment selector
...
...
bootother.S
0 → 100644
浏览文件 @
21a88fd4
#include "asm.h"
/*
* Start an Application Processor. This must be placed on a 4KB boundary
* somewhere in the 1st MB of conventional memory (APBOOTSTRAP). However,
* due to some shortcuts below it's restricted further to within the 1st
* 64KB. The AP starts in real-mode, with
* CS selector set to the startup memory address/16;
* CS base set to startup memory address;
* CS limit set to 64KB;
* CPL and IP set to 0.
*
* Credit: Cliff Frey
*/
.set PROT_MODE_CSEG,0x8 # code segment selector
.set PROT_MODE_DSEG,0x10 # data segment selector
.set CR0_PE_ON,0x1 # protected mode enable flag
.globl start
start: .code16 # This runs in real mode
cli # Disable interrupts
cld # String operations increment
# Set up the important data segment registers (DS, ES, SS).
xorw %ax,%ax # Segment number zero
movw %ax,%ds # -> Data Segment
movw %ax,%es # -> Extra Segment
movw %ax,%ss # -> Stack Segment
# Set up the stack pointer, growing downward from 0x7000.
movw $start,%sp # Stack Pointer
#### Switch from real to protected mode
#### The descriptors in our GDT allow all physical memory to be accessed.
#### Furthermore, the descriptors have base addresses of 0, so that the
#### segment translation is a NOP, ie. virtual addresses are identical to
#### their physical addresses. With this setup, immediately after
#### enabling protected mode it will still appear to this code
#### that it is running directly on physical memory with no translation.
#### This initial NOP-translation setup is required by the processor
#### to ensure that the transition to protected mode occurs smoothly.
lgdt gdtdesc # load GDT -- mandatory in protected mode
movl %cr0, %eax # turn on protected mode
orl $CR0_PE_ON, %eax #
movl %eax, %cr0 #
### CPU magic: jump to relocation, flush prefetch queue, and reload %cs
### Has the effect of just jmp to the next instruction, but simultaneous
### loads CS with $PROT_MODE_CSEG.
ljmp $PROT_MODE_CSEG, $protcseg
#### we are in 32-bit protected mode (hence the .code32)
.code32
protcseg:
# Set up the protected-mode data segment registers
movw $PROT_MODE_DSEG, %ax # Our data segment selector
movw %ax, %ds # -> DS: Data Segment
movw %ax, %es # -> ES: Extra Segment
movw %ax, %fs # -> FS
movw %ax, %gs # -> GS
movw %ax, %ss # -> SS: Stack Segment
# XXX hack
movl 0x10018, %eax # elfhdr->entry (left over in scratch space)
# subl $KERNBASE, %eax
jmp *%eax # this jumps to _start in kern/entry.S
.p2align 2 # force 4 byte alignment
gdt:
SEG_NULL # null seg
SEG(STA_X|STA_R, 0x0, 0xffffffff) # code seg
SEG(STA_W, 0x0, 0xffffffff) # data seg
gdtdesc:
.word 0x17 # sizeof(gdt) - 1
.long gdt # address gdt
defs.h
浏览文件 @
21a88fd4
...
...
@@ -22,6 +22,7 @@ void tinit(void);
void
*
memcpy
(
void
*
dst
,
void
*
src
,
unsigned
n
);
void
*
memset
(
void
*
dst
,
int
c
,
unsigned
n
);
int
memcmp
(
const
void
*
v1
,
const
void
*
v2
,
unsigned
n
);
void
*
memmove
(
void
*
dst
,
const
void
*
src
,
unsigned
n
);
// syscall.c
void
syscall
(
void
);
...
...
@@ -31,5 +32,13 @@ void irq_setmask_8259A(uint16_t mask);
void
pic_init
(
void
);
// mp.c
void
mpinit
(
void
);
void
mp_init
(
void
);
int
lapic_cpu_number
(
void
);
int
mp_isbcpu
(
void
);
// spinlock.c
extern
uint32_t
kernel_lock
;
void
acquire_spinlock
(
uint32_t
*
lock
);
void
release_spinlock
(
uint32_t
*
lock
);
void
release_grant_spinlock
(
uint32_t
*
lock
,
int
cpu
);
main.c
浏览文件 @
21a88fd4
...
...
@@ -8,6 +8,7 @@
#include "syscall.h"
extern
char
edata
[],
end
[];
extern
int
acpu
;
char
buf
[
512
];
...
...
@@ -17,12 +18,18 @@ main()
struct
proc
*
p
;
int
i
;
if
(
acpu
)
{
cprintf
(
"an application processor
\n
"
);
release_spinlock
(
&
kernel_lock
);
while
(
1
)
;
}
acpu
=
1
;
// clear BSS
memset
(
edata
,
0
,
end
-
edata
);
cprintf
(
"
\n
xV6
\n\n
"
);
mpinit
();
// multiprocessor
mp
_
init
();
// multiprocessor
kinit
();
// physical memory allocator
tinit
();
// traps and interrupts
pic_init
();
...
...
mp.c
浏览文件 @
21a88fd4
差异被折叠。
点击展开。
mp.h
浏览文件 @
21a88fd4
/*
* MultiProcessor Specification Version 1.[14].
*
* Credit: Plan 9 sources
*/
struct
_MP_
{
/* floating pointer */
struct
MP
{
/* floating pointer */
uint8_t
signature
[
4
];
/* "_MP_" */
physaddr_t
physaddr
;
/* physical address of MP configuration table */
uint8_t
length
;
/* 1 */
...
...
@@ -12,7 +15,7 @@ struct _MP_ { /* floating pointer */
uint8_t
reserved
[
3
];
};
struct
PCMP
{
/* configuration table header */
struct
MPCTB
{
/* configuration table header */
uint8_t
signature
[
4
];
/* "PCMP" */
uint16_t
length
;
/* total table length */
uint8_t
version
;
/* [14] */
...
...
@@ -21,15 +24,15 @@ struct PCMP { /* configuration table header */
uintptr_t
oemtable
;
/* OEM table pointer */
uint16_t
oemlength
;
/* OEM table length */
uint16_t
entry
;
/* entry count */
uintptr_t
lapic
base
;
/* address of local APIC */
uintptr_t
lapic
addr
;
/* address of local APIC */
uint16_t
xlength
;
/* extended table length */
uint8_t
xchecksum
;
/* extended table checksum */
uint8_t
reserved
;
};
struct
PCMPprocessor
{
/* processor table entry */
struct
MPPE
{
/* processor table entry */
uint8_t
type
;
/* entry type (0) */
uint8_t
apic
no
;
/* local APIC id */
uint8_t
apic
id
;
/* local APIC id */
uint8_t
version
;
/* local APIC verison */
uint8_t
flags
;
/* CPU flags */
uint8_t
signature
[
4
];
/* CPU signature */
...
...
@@ -37,13 +40,13 @@ struct PCMPprocessor { /* processor table entry */
uint8_t
reserved
[
8
];
};
struct
PCMPbus
{
/* bus table entry */
struct
MPBE
{
/* bus table entry */
uint8_t
type
;
/* entry type (1) */
uint8_t
busno
;
/* bus id */
char
string
[
6
];
/* bus type string */
};
struct
PCMPioapic
{
/* I/O APIC table entry */
struct
MPIOAPIC
{
/* I/O APIC table entry */
uint8_t
type
;
/* entry type (2) */
uint8_t
apicno
;
/* I/O APIC id */
uint8_t
version
;
/* I/O APIC version */
...
...
@@ -51,7 +54,7 @@ struct PCMPioapic { /* I/O APIC table entry */
uintptr_t
addr
;
/* I/O APIC address */
};
struct
PCMPintr
{
/* interrupt table entry */
struct
MPIE
{
/* interrupt table entry */
uint8_t
type
;
/* entry type ([34]) */
uint8_t
intr
;
/* interrupt type */
uint16_t
flags
;
/* interrupt flag */
...
...
@@ -61,71 +64,34 @@ struct PCMPintr { /* interrupt table entry */
uint8_t
intin
;
/* destination APIC [L]INTIN# */
};
struct
PCMPsasm
{
/* system address space mapping entry */
uint8_t
type
;
/* entry type (128) */
uint8_t
length
;
/* of this entry (20) */
uint8_t
busno
;
/* bus id */
uint8_t
addrtype
;
uintptr_t
addrbase
[
2
];
uint32_t
addrlength
[
2
];
};
struct
PCMPhierarchy
{
/* bus hierarchy descriptor entry */
uint8_t
type
;
/* entry type (129) */
uint8_t
length
;
/* of this entry (8) */
uint8_t
busno
;
/* bus id */
uint8_t
info
;
/* bus info */
uint8_t
parent
;
/* parent bus */
uint8_t
reserved
[
3
];
};
struct
PCMPcbasm
{
/* compatibility bus address space modifier entry */
uint8_t
type
;
/* entry type (130) */
uint8_t
length
;
/* of this entry (8) */
uint8_t
busno
;
/* bus id */
uint8_t
modifier
;
/* address modifier */
uint32_t
range
;
/* predefined range list */
};
enum
{
/* table entry types */
Pcmp
PROCESSOR
=
0x00
,
/* one entry per processor */
PcmpBUS
=
0x01
,
/* one entry per bus */
Pcmp
IOAPIC
=
0x02
,
/* one entry per I/O APIC */
Pcmp
IOINTR
=
0x03
,
/* one entry per bus interrupt source */
Pcmp
LINTR
=
0x04
,
/* one entry per system interrupt source */
MP
PROCESSOR
=
0x00
,
/* one entry per processor */
MPBUS
=
0x01
,
/* one entry per bus */
MP
IOAPIC
=
0x02
,
/* one entry per I/O APIC */
MP
IOINTR
=
0x03
,
/* one entry per bus interrupt source */
MP
LINTR
=
0x04
,
/* one entry per system interrupt source */
Pcmp
SASM
=
0x80
,
Pcmp
HIERARCHY
=
0x81
,
Pcmp
CBASM
=
0x82
,
MP
SASM
=
0x80
,
MP
HIERARCHY
=
0x81
,
MP
CBASM
=
0x82
,
/* PCMPprocessor and PCMPioapic flags */
PcmpEN
=
0x01
,
/* enabled */
PcmpBP
=
0x02
,
/* bootstrap processor */
MPEN
=
0x01
,
/* enabled */
MPBP
=
0x02
,
/* bootstrap processor */
/* PCMPiointr and PCMPlintr flags */
Pcmp
POMASK
=
0x03
,
/* polarity conforms to specifications of bus */
Pcmp
HIGH
=
0x01
,
/* active high */
Pcmp
LOW
=
0x03
,
/* active low */
Pcmp
ELMASK
=
0x0C
,
/* trigger mode of APIC input signals */
Pcmp
EDGE
=
0x04
,
/* edge-triggered */
Pcmp
LEVEL
=
0x0C
,
/* level-triggered */
MP
POMASK
=
0x03
,
/* polarity conforms to specifications of bus */
MP
HIGH
=
0x01
,
/* active high */
MP
LOW
=
0x03
,
/* active low */
MP
ELMASK
=
0x0C
,
/* trigger mode of APIC input signals */
MP
EDGE
=
0x04
,
/* edge-triggered */
MP
LEVEL
=
0x0C
,
/* level-triggered */
/* PCMPiointr and PCMPlintr interrupt type */
PcmpINT
=
0x00
,
/* vectored interrupt from APIC Rdt */
PcmpNMI
=
0x01
,
/* non-maskable interrupt */
PcmpSMI
=
0x02
,
/* system management interrupt */
PcmpExtINT
=
0x03
,
/* vectored interrupt from external PIC */
/* PCMPsasm addrtype */
PcmpIOADDR
=
0x00
,
/* I/O address */
PcmpMADDR
=
0x01
,
/* memory address */
PcmpPADDR
=
0x02
,
/* prefetch address */
/* PCMPhierarchy info */
PcmpSD
=
0x01
,
/* subtractive decode bus */
/* PCMPcbasm modifier */
PcmpPR
=
0x01
,
/* predefined range list */
MPINT
=
0x00
,
/* vectored interrupt from APIC Rdt */
MPNMI
=
0x01
,
/* non-maskable interrupt */
MPSMI
=
0x02
,
/* system management interrupt */
MPExtINT
=
0x03
,
/* vectored interrupt from external PIC */
};
/*
...
...
@@ -136,23 +102,23 @@ enum { /* table entry types */
* Local APIC Timer Vector Table.
*/
enum
{
A
pic
FIXED
=
0x00000000
,
/* [10:8] Delivery Mode */
A
pic
LOWEST
=
0x00000100
,
/* Lowest priority */
A
pic
SMI
=
0x00000200
,
/* System Management Interrupt */
A
pic
RR
=
0x00000300
,
/* Remote Read */
A
pic
NMI
=
0x00000400
,
A
pic
INIT
=
0x00000500
,
/* INIT/RESET */
A
pic
STARTUP
=
0x00000600
,
/* Startup IPI */
A
pic
ExtINT
=
0x00000700
,
A
pic
PHYSICAL
=
0x00000000
,
/* [11] Destination Mode (RW) */
A
pic
LOGICAL
=
0x00000800
,
A
pic
DELIVS
=
0x00001000
,
/* [12] Delivery Status (RO) */
A
pic
HIGH
=
0x00000000
,
/* [13] Interrupt Input Pin Polarity (RW) */
A
pic
LOW
=
0x00002000
,
A
pic
RemoteIRR
=
0x00004000
,
/* [14] Remote IRR (RO) */
A
pic
EDGE
=
0x00000000
,
/* [15] Trigger Mode (RW) */
A
pic
LEVEL
=
0x00008000
,
A
pic
IMASK
=
0x00010000
,
/* [16] Interrupt Mask */
A
PIC_
FIXED
=
0x00000000
,
/* [10:8] Delivery Mode */
A
PIC_
LOWEST
=
0x00000100
,
/* Lowest priority */
A
PIC_
SMI
=
0x00000200
,
/* System Management Interrupt */
A
PIC_
RR
=
0x00000300
,
/* Remote Read */
A
PIC_
NMI
=
0x00000400
,
A
PIC_
INIT
=
0x00000500
,
/* INIT/RESET */
A
PIC_
STARTUP
=
0x00000600
,
/* Startup IPI */
A
PIC_
ExtINT
=
0x00000700
,
A
PIC_
PHYSICAL
=
0x00000000
,
/* [11] Destination Mode (RW) */
A
PIC_
LOGICAL
=
0x00000800
,
A
PIC_
DELIVS
=
0x00001000
,
/* [12] Delivery Status (RO) */
A
PIC_
HIGH
=
0x00000000
,
/* [13] Interrupt Input Pin Polarity (RW) */
A
PIC_
LOW
=
0x00002000
,
A
PIC_
RemoteIRR
=
0x00004000
,
/* [14] Remote IRR (RO) */
A
PIC_
EDGE
=
0x00000000
,
/* [15] Trigger Mode (RW) */
A
PIC_
LEVEL
=
0x00008000
,
A
PIC_
IMASK
=
0x00010000
,
/* [16] Interrupt Mask */
};
param.h
浏览文件 @
21a88fd4
#define NPROC 64
#define PAGE 4096
#define KSTACKSIZE PAGE
#define NCPU 8
picirq.c
浏览文件 @
21a88fd4
...
...
@@ -4,15 +4,6 @@
#include "x86.h"
#include "defs.h"
#define MAX_IRQS 16 // Number of IRQs
// I/O Addresses of the two 8259A programmable interrupt controllers
#define IO_PIC1 0x20 // Master (IRQs 0-7)
#define IO_PIC2 0xA0 // Slave (IRQs 8-15)
#define IRQ_SLAVE 2 // IRQ at which slave connects to master
#define IRQ_OFFSET 32 // IRQ 0 corresponds to int IRQ_OFFSET
// Current IRQ mask.
// Initial IRQ mask has interrupt 2 enabled (for slave 8259A).
uint16_t
irq_mask_8259A
=
0xFFFF
&
~
(
1
<<
IRQ_SLAVE
);
...
...
spinlock.c
0 → 100644
浏览文件 @
21a88fd4
#include "types.h"
#include "defs.h"
#include "x86.h"
#define LOCK_FREE -1
uint32_t
kernel_lock
=
LOCK_FREE
;
// lock = LOCK_FREE if free, else = cpu_id of owner CPU
void
acquire_spinlock
(
uint32_t
*
lock
)
{
int
cpu_id
=
lapic_cpu_number
();
cprintf
(
"acquire: %d
\n
"
,
cpu_id
);
if
(
*
lock
==
cpu_id
)
return
;
while
(
cmpxchg
(
LOCK_FREE
,
cpu_id
,
lock
)
!=
cpu_id
)
{
;
}
}
void
release_spinlock
(
uint32_t
*
lock
)
{
int
cpu_id
=
lapic_cpu_number
();
cprintf
(
"release: %d
\n
"
,
cpu_id
);
if
(
*
lock
!=
cpu_id
)
panic
(
"release_spinlock: releasing a lock that i don't own
\n
"
);
*
lock
=
LOCK_FREE
;
}
void
release_grant_spinlock
(
uint32_t
*
lock
,
int
c
)
{
int
cpu_id
=
lapic_cpu_number
();
cprintf
(
"release_grant: %d -> %d
\n
"
,
cpu_id
,
c
);
if
(
*
lock
!=
cpu_id
)
panic
(
"release_spinlock: releasing a lock that i don't own
\n
"
);
*
lock
=
c
;
}
string.c
浏览文件 @
21a88fd4
...
...
@@ -38,3 +38,23 @@ memcmp(const void *v1, const void *v2, unsigned n)
return
0
;
}
void
*
memmove
(
void
*
dst
,
const
void
*
src
,
unsigned
n
)
{
const
char
*
s
;
char
*
d
;
s
=
src
;
d
=
dst
;
if
(
s
<
d
&&
s
+
n
>
d
)
{
s
+=
n
;
d
+=
n
;
while
(
n
--
>
0
)
*--
d
=
*--
s
;
}
else
while
(
n
--
>
0
)
*
d
++
=
*
s
++
;
return
dst
;
}
trapasm.S
浏览文件 @
21a88fd4
...
...
@@ -27,3 +27,8 @@ trapret:
popl %ds
addl $0x8, %esp /* trapno and errcode */
iret
.globl acpu
acpu:
.long 0
x86.h
浏览文件 @
21a88fd4
...
...
@@ -261,6 +261,17 @@ cpuid(uint32_t info, uint32_t *eaxp, uint32_t *ebxp, uint32_t *ecxp, uint32_t *e
*
edxp
=
edx
;
}
static
__inline
uint32_t
cmpxchg
(
uint32_t
oldval
,
uint32_t
newval
,
volatile
uint32_t
*
lock_addr
)
{
uint32_t
result
;
__asm__
__volatile__
(
"lock; cmpxchgl %2, %0"
:
"+m"
(
*
lock_addr
),
"=a"
(
result
)
:
"r"
(
newval
),
"1"
(
oldval
)
:
"cc"
);
return
result
;
}
static
__inline
uint64_t
read_tsc
(
void
)
{
...
...
@@ -299,3 +310,16 @@ struct Trapframe {
uint16_t
tf_ss
;
uint16_t
tf_padding4
;
};
#define MAX_IRQS 16 // Number of IRQs
// I/O Addresses of the two 8259A programmable interrupt controllers
#define IO_PIC1 0x20 // Master (IRQs 0-7)
#define IO_PIC2 0xA0 // Slave (IRQs 8-15)
#define IRQ_SLAVE 2 // IRQ at which slave connects to master
#define IRQ_OFFSET 32 // IRQ 0 corresponds to int IRQ_OFFSET
#define IRQ_ERROR 19
#define IRQ_SPURIOUS 31
编写
预览
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论