prune unneeded panics and debug output
This commit is contained in:
parent
d7ce6545e7
commit
dfcc5b997c
2
Makefile
2
Makefile
|
@ -70,7 +70,7 @@ PRINT = \
|
||||||
string.c\
|
string.c\
|
||||||
|
|
||||||
print: $(PRINT)
|
print: $(PRINT)
|
||||||
// ~/src/lgrind/source/lgrind -d ~/src/lgrind/lgrindef $(PRINT) > xv6.tex
|
//~/src/lgrind/source/lgrind -d ~/src/lgrind/lgrindef $(PRINT) > xv6.tex
|
||||||
lgrind $(PRINT) > xv6.tex
|
lgrind $(PRINT) > xv6.tex
|
||||||
latex xv6.tex
|
latex xv6.tex
|
||||||
dvips -o xv61.ps xv6.dvi
|
dvips -o xv61.ps xv6.dvi
|
||||||
|
|
5
asm.h
5
asm.h
|
@ -1,3 +1,8 @@
|
||||||
|
//
|
||||||
|
// macros to create x86 segments from assembler
|
||||||
|
// from JOS
|
||||||
|
//
|
||||||
|
|
||||||
#define SEG_NULL \
|
#define SEG_NULL \
|
||||||
.word 0, 0; \
|
.word 0, 0; \
|
||||||
.byte 0, 0, 0, 0
|
.byte 0, 0, 0, 0
|
||||||
|
|
|
@ -1,3 +1,7 @@
|
||||||
|
#
|
||||||
|
# from JOS
|
||||||
|
#
|
||||||
|
|
||||||
#include "asm.h"
|
#include "asm.h"
|
||||||
|
|
||||||
.set PROT_MODE_CSEG,0x8 # code segment selector
|
.set PROT_MODE_CSEG,0x8 # code segment selector
|
||||||
|
|
5
elf.h
5
elf.h
|
@ -1,3 +1,8 @@
|
||||||
|
//
|
||||||
|
// format of an ELF executable file
|
||||||
|
// from JOS
|
||||||
|
//
|
||||||
|
|
||||||
#define ELF_MAGIC 0x464C457FU /* "\x7FELF" in little endian */
|
#define ELF_MAGIC 0x464C457FU /* "\x7FELF" in little endian */
|
||||||
|
|
||||||
struct elfhdr {
|
struct elfhdr {
|
||||||
|
|
19
init.c
19
init.c
|
@ -13,20 +13,25 @@ main(void)
|
||||||
{
|
{
|
||||||
int pid;
|
int pid;
|
||||||
|
|
||||||
if(open("console", 0) < 0){
|
if(open("console", O_RDWR) < 0){
|
||||||
mknod("console", T_DEV, 1, 1);
|
mknod("console", T_DEV, 1, 1);
|
||||||
open("console", 0);
|
open("console", O_RDWR);
|
||||||
}
|
}
|
||||||
open("console", 1);
|
dup(0);
|
||||||
open("console", 1);
|
dup(0);
|
||||||
|
|
||||||
while(1){
|
while(1){
|
||||||
pid = fork();
|
pid = fork();
|
||||||
if(pid == 0){
|
if(pid < 0){
|
||||||
exec("sh", sh_args);
|
puts("init: fork failed\n");
|
||||||
exit();
|
exit();
|
||||||
}
|
}
|
||||||
if(pid > 0)
|
if(pid == 0){
|
||||||
|
exec("sh", sh_args);
|
||||||
|
puts("init: exec sh failed\n");
|
||||||
|
exit();
|
||||||
|
} else {
|
||||||
wait();
|
wait();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
7
lapic.c
7
lapic.c
|
@ -110,7 +110,6 @@ lapic_write(int r, int data)
|
||||||
void
|
void
|
||||||
lapic_timerinit(void)
|
lapic_timerinit(void)
|
||||||
{
|
{
|
||||||
cprintf("cpu%d: init timer\n", cpu());
|
|
||||||
lapic_write(LAPIC_TDCR, LAPIC_X1);
|
lapic_write(LAPIC_TDCR, LAPIC_X1);
|
||||||
lapic_write(LAPIC_TIMER, LAPIC_CLKIN | LAPIC_PERIODIC | (IRQ_OFFSET + IRQ_TIMER));
|
lapic_write(LAPIC_TIMER, LAPIC_CLKIN | LAPIC_PERIODIC | (IRQ_OFFSET + IRQ_TIMER));
|
||||||
lapic_write(LAPIC_TCCR, 10000000);
|
lapic_write(LAPIC_TCCR, 10000000);
|
||||||
|
@ -129,8 +128,6 @@ lapic_init(int c)
|
||||||
{
|
{
|
||||||
uint r, lvt;
|
uint r, lvt;
|
||||||
|
|
||||||
cprintf("cpu%d: lapic_init %d\n", c);
|
|
||||||
|
|
||||||
lapic_write(LAPIC_DFR, 0xFFFFFFFF); // set destination format register
|
lapic_write(LAPIC_DFR, 0xFFFFFFFF); // set destination format register
|
||||||
r = (lapic_read(LAPIC_ID)>>24) & 0xFF; // read APIC ID
|
r = (lapic_read(LAPIC_ID)>>24) & 0xFF; // read APIC ID
|
||||||
lapic_write(LAPIC_LDR, (1<<r)<<24); // set logical destination register to r
|
lapic_write(LAPIC_LDR, (1<<r)<<24); // set logical destination register to r
|
||||||
|
@ -157,8 +154,6 @@ lapic_init(int c)
|
||||||
lapic_write(LAPIC_ICRLO, LAPIC_ALLINC|APIC_LEVEL|LAPIC_DEASSERT|APIC_INIT);
|
lapic_write(LAPIC_ICRLO, LAPIC_ALLINC|APIC_LEVEL|LAPIC_DEASSERT|APIC_INIT);
|
||||||
while(lapic_read(LAPIC_ICRLO) & APIC_DELIVS)
|
while(lapic_read(LAPIC_ICRLO) & APIC_DELIVS)
|
||||||
;
|
;
|
||||||
|
|
||||||
cprintf("cpu%d: apic init done\n", cpu());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -204,7 +199,7 @@ lapic_startap(uchar apicid, int v)
|
||||||
// in p9 code, this was i < 2, which is what the spec says on page B-3
|
// in p9 code, this was i < 2, which is what the spec says on page B-3
|
||||||
for(i = 0; i < 1; i++){
|
for(i = 0; i < 1; i++){
|
||||||
lapic_write(LAPIC_ICRHI, crhi);
|
lapic_write(LAPIC_ICRHI, crhi);
|
||||||
lapic_write(LAPIC_ICRLO, LAPIC_FIELD|APIC_EDGE|APIC_STARTUP|(v/PGSIZE));
|
lapic_write(LAPIC_ICRLO, LAPIC_FIELD|APIC_EDGE|APIC_STARTUP|(v/4096));
|
||||||
while (j++ < 100000) {;}
|
while (j++ < 100000) {;}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
45
main.c
45
main.c
|
@ -13,7 +13,7 @@
|
||||||
extern char edata[], end[];
|
extern char edata[], end[];
|
||||||
extern uchar _binary_init_start[], _binary_init_size[];
|
extern uchar _binary_init_start[], _binary_init_size[];
|
||||||
|
|
||||||
void main00();
|
void process0();
|
||||||
|
|
||||||
// CPU 0 starts running C code here.
|
// CPU 0 starts running C code here.
|
||||||
// This is called main0 not main so that it can have
|
// This is called main0 not main so that it can have
|
||||||
|
@ -32,43 +32,33 @@ main0(void)
|
||||||
asm volatile("movl %0, %%esp" : : "r" (cpus[0].mpstack + MPSTACK - 32));
|
asm volatile("movl %0, %%esp" : : "r" (cpus[0].mpstack + MPSTACK - 32));
|
||||||
asm volatile("movl %0, %%ebp" : : "r" (cpus[0].mpstack + MPSTACK));
|
asm volatile("movl %0, %%ebp" : : "r" (cpus[0].mpstack + MPSTACK));
|
||||||
|
|
||||||
// Make sure interrupts stay disabled on all processors
|
// Prevent release() from enabling interrupts.
|
||||||
// until each signals it is ready, by pretending to hold
|
for(i=0; i<NCPU; i++)
|
||||||
// an extra lock.
|
cpus[i].nlock = 1;
|
||||||
// xxx maybe replace w/ acquire remembering if FL_IF was already clear
|
|
||||||
for(i=0; i<NCPU; i++){
|
|
||||||
cpus[i].nlock++;
|
|
||||||
cpus[i].guard1 = 0xdeadbeef;
|
|
||||||
cpus[i].guard2 = 0xdeadbeef;
|
|
||||||
}
|
|
||||||
|
|
||||||
mp_init(); // collect info about this machine
|
mp_init(); // collect info about this machine
|
||||||
|
|
||||||
lapic_init(mp_bcpu());
|
lapic_init(mp_bcpu());
|
||||||
|
|
||||||
cprintf("\n\ncpu%d: booting xv6\n\n", cpu());
|
cprintf("\ncpu%d: starting xv6\n\n", cpu());
|
||||||
|
|
||||||
pinit();
|
pinit(); // process table
|
||||||
binit();
|
binit(); // buffer cache
|
||||||
pic_init(); // initialize PIC
|
pic_init();
|
||||||
ioapic_init();
|
ioapic_init();
|
||||||
kinit(); // physical memory allocator
|
kinit(); // physical memory allocator
|
||||||
tvinit(); // trap vectors
|
tvinit(); // trap vectors
|
||||||
idtinit(); // this CPU's idt register
|
idtinit(); // this CPU's interrupt descriptor table
|
||||||
fd_init();
|
fd_init();
|
||||||
iinit();
|
iinit(); // i-node table
|
||||||
|
|
||||||
// initialize process 0
|
// initialize process 0
|
||||||
p = &proc[0];
|
p = &proc[0];
|
||||||
p->state = RUNNABLE;
|
p->state = RUNNABLE;
|
||||||
p->sz = 4 * PAGE;
|
|
||||||
p->mem = kalloc(p->sz);
|
|
||||||
memset(p->mem, 0, p->sz);
|
|
||||||
p->kstack = kalloc(KSTACKSIZE);
|
p->kstack = kalloc(KSTACKSIZE);
|
||||||
|
|
||||||
// cause proc[0] to start in kernel at main00
|
// cause proc[0] to start in kernel at process0
|
||||||
memset(&p->jmpbuf, 0, sizeof p->jmpbuf);
|
p->jmpbuf.eip = (uint) process0;
|
||||||
p->jmpbuf.eip = (uint)main00;
|
|
||||||
p->jmpbuf.esp = (uint) (p->kstack + KSTACKSIZE - 4);
|
p->jmpbuf.esp = (uint) (p->kstack + KSTACKSIZE - 4);
|
||||||
|
|
||||||
// make sure there's a TSS
|
// make sure there's a TSS
|
||||||
|
@ -78,6 +68,7 @@ main0(void)
|
||||||
console_init();
|
console_init();
|
||||||
ide_init();
|
ide_init();
|
||||||
|
|
||||||
|
// start other CPUs
|
||||||
mp_startthem();
|
mp_startthem();
|
||||||
|
|
||||||
// turn on timer and enable interrupts on the local APIC
|
// turn on timer and enable interrupts on the local APIC
|
||||||
|
@ -118,7 +109,7 @@ mpmain(void)
|
||||||
|
|
||||||
// proc[0] starts here, called by scheduler() in the ordinary way.
|
// proc[0] starts here, called by scheduler() in the ordinary way.
|
||||||
void
|
void
|
||||||
main00()
|
process0()
|
||||||
{
|
{
|
||||||
struct proc *p0 = &proc[0];
|
struct proc *p0 = &proc[0];
|
||||||
struct proc *p1;
|
struct proc *p1;
|
||||||
|
@ -130,10 +121,13 @@ main00()
|
||||||
p0->cwd = iget(rootdev, 1);
|
p0->cwd = iget(rootdev, 1);
|
||||||
iunlock(p0->cwd);
|
iunlock(p0->cwd);
|
||||||
|
|
||||||
|
// dummy user memory to make copyproc() happy
|
||||||
|
p0->sz = 4 * PAGE;
|
||||||
|
p0->mem = kalloc(p0->sz);
|
||||||
|
|
||||||
// fake a trap frame as if a user process had made a system
|
// fake a trap frame as if a user process had made a system
|
||||||
// call, so that copyproc will have a place for the new
|
// call, so that copyproc will have a place for the new
|
||||||
// process to return to.
|
// process to return to.
|
||||||
p0 = &proc[0];
|
|
||||||
p0->tf = &tf;
|
p0->tf = &tf;
|
||||||
memset(p0->tf, 0, sizeof(struct trapframe));
|
memset(p0->tf, 0, sizeof(struct trapframe));
|
||||||
p0->tf->es = p0->tf->ds = p0->tf->ss = (SEG_UDATA << 3) | 3;
|
p0->tf->es = p0->tf->ds = p0->tf->ss = (SEG_UDATA << 3) | 3;
|
||||||
|
@ -141,7 +135,7 @@ main00()
|
||||||
p0->tf->eflags = FL_IF;
|
p0->tf->eflags = FL_IF;
|
||||||
p0->tf->esp = p0->sz;
|
p0->tf->esp = p0->sz;
|
||||||
|
|
||||||
p1 = copyproc(&proc[0]);
|
p1 = copyproc(p0);
|
||||||
|
|
||||||
load_icode(p1, _binary_init_start, (uint) _binary_init_size);
|
load_icode(p1, _binary_init_start, (uint) _binary_init_size);
|
||||||
p1->state = RUNNABLE;
|
p1->state = RUNNABLE;
|
||||||
|
@ -157,7 +151,6 @@ load_icode(struct proc *p, uchar *binary, uint size)
|
||||||
struct elfhdr *elf;
|
struct elfhdr *elf;
|
||||||
struct proghdr *ph;
|
struct proghdr *ph;
|
||||||
|
|
||||||
// Check magic number on binary
|
|
||||||
elf = (struct elfhdr*) binary;
|
elf = (struct elfhdr*) binary;
|
||||||
if (elf->magic != ELF_MAGIC)
|
if (elf->magic != ELF_MAGIC)
|
||||||
panic("load_icode: not an ELF binary");
|
panic("load_icode: not an ELF binary");
|
||||||
|
|
73
mmu.h
73
mmu.h
|
@ -1,15 +1,8 @@
|
||||||
/*
|
/*
|
||||||
* This file contains definitions for the x86 memory management unit (MMU),
|
* This file contains definitions for the x86 memory management unit (MMU).
|
||||||
* including paging- and segmentation-related data structures and constants,
|
* from JOS.
|
||||||
* the %cr0, %cr4, and %eflags registers, and traps.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
|
||||||
* Register flags and fundamental constants.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define PGSIZE 4096 // bytes mapped by a page
|
|
||||||
|
|
||||||
// Eflags register
|
// Eflags register
|
||||||
#define FL_CF 0x00000001 // Carry Flag
|
#define FL_CF 0x00000001 // Carry Flag
|
||||||
#define FL_PF 0x00000004 // Parity Flag
|
#define FL_PF 0x00000004 // Parity Flag
|
||||||
|
@ -33,33 +26,7 @@
|
||||||
#define FL_VIP 0x00100000 // Virtual Interrupt Pending
|
#define FL_VIP 0x00100000 // Virtual Interrupt Pending
|
||||||
#define FL_ID 0x00200000 // ID flag
|
#define FL_ID 0x00200000 // ID flag
|
||||||
|
|
||||||
// Page fault error codes
|
// Segment Descriptor
|
||||||
#define FEC_PR 0x1 // Page fault caused by protection violation
|
|
||||||
#define FEC_WR 0x2 // Page fault caused by a write
|
|
||||||
#define FEC_U 0x4 // Page fault occured while in user mode
|
|
||||||
|
|
||||||
/*
|
|
||||||
*
|
|
||||||
* Segmentation data structures and constants.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef __ASSEMBLER__
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Macros to build GDT entries in assembly.
|
|
||||||
*/
|
|
||||||
#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)
|
|
||||||
|
|
||||||
#else // not __ASSEMBLER__
|
|
||||||
|
|
||||||
// Segment Descriptors
|
|
||||||
struct segdesc {
|
struct segdesc {
|
||||||
uint lim_15_0 : 16; // Low bits of segment limit
|
uint lim_15_0 : 16; // Low bits of segment limit
|
||||||
uint base_15_0 : 16; // Low bits of segment base address
|
uint base_15_0 : 16; // Low bits of segment base address
|
||||||
|
@ -75,22 +42,21 @@ struct segdesc {
|
||||||
uint g : 1; // Granularity: limit scaled by 4K when set
|
uint g : 1; // Granularity: limit scaled by 4K when set
|
||||||
uint base_31_24 : 8; // High bits of segment base address
|
uint base_31_24 : 8; // High bits of segment base address
|
||||||
};
|
};
|
||||||
|
|
||||||
// Null segment
|
// Null segment
|
||||||
#define SEG_NULL (struct segdesc){ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
|
#define SEG_NULL (struct segdesc){ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
|
||||||
// Segment that is loadable but faults when used
|
|
||||||
#define SEG_FAULT (struct segdesc){ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0 }
|
|
||||||
// Normal segment
|
// Normal segment
|
||||||
#define SEG(type, base, lim, dpl) (struct segdesc) \
|
#define SEG(type, base, lim, dpl) (struct segdesc) \
|
||||||
{ ((lim) >> 12) & 0xffff, (base) & 0xffff, ((base) >> 16) & 0xff, \
|
{ ((lim) >> 12) & 0xffff, (base) & 0xffff, ((base) >> 16) & 0xff, \
|
||||||
type, 1, dpl, 1, (uint) (lim) >> 28, 0, 0, 1, 1, \
|
type, 1, dpl, 1, (uint) (lim) >> 28, 0, 0, 1, 1, \
|
||||||
(uint) (base) >> 24 }
|
(uint) (base) >> 24 }
|
||||||
|
|
||||||
#define SEG16(type, base, lim, dpl) (struct segdesc) \
|
#define SEG16(type, base, lim, dpl) (struct segdesc) \
|
||||||
{ (lim) & 0xffff, (base) & 0xffff, ((base) >> 16) & 0xff, \
|
{ (lim) & 0xffff, (base) & 0xffff, ((base) >> 16) & 0xff, \
|
||||||
type, 1, dpl, 1, (uint) (lim) >> 16, 0, 0, 1, 0, \
|
type, 1, dpl, 1, (uint) (lim) >> 16, 0, 0, 1, 0, \
|
||||||
(uint) (base) >> 24 }
|
(uint) (base) >> 24 }
|
||||||
|
|
||||||
#endif /* !__ASSEMBLER__ */
|
|
||||||
|
|
||||||
// Application segment type bits
|
// Application segment type bits
|
||||||
#define STA_X 0x8 // Executable segment
|
#define STA_X 0x8 // Executable segment
|
||||||
#define STA_E 0x4 // Expand down (non-executable segments)
|
#define STA_E 0x4 // Expand down (non-executable segments)
|
||||||
|
@ -113,16 +79,7 @@ struct segdesc {
|
||||||
#define STS_IG32 0xE // 32-bit Interrupt Gate
|
#define STS_IG32 0xE // 32-bit Interrupt Gate
|
||||||
#define STS_TG32 0xF // 32-bit Trap Gate
|
#define STS_TG32 0xF // 32-bit Trap Gate
|
||||||
|
|
||||||
|
// Task state segment format
|
||||||
/*
|
|
||||||
*
|
|
||||||
* Traps.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __ASSEMBLER__
|
|
||||||
|
|
||||||
// Task state segment format (as described by the Pentium architecture book)
|
|
||||||
struct taskstate {
|
struct taskstate {
|
||||||
uint link; // Old ts selector
|
uint link; // Old ts selector
|
||||||
uint esp0; // Stack pointers and segment selectors
|
uint esp0; // Stack pointers and segment selectors
|
||||||
|
@ -197,19 +154,3 @@ struct gatedesc {
|
||||||
(gate).off_31_16 = (uint) (off) >> 16; \
|
(gate).off_31_16 = (uint) (off) >> 16; \
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set up a call gate descriptor.
|
|
||||||
#define SETCALLGATE(gate, ss, off, d) \
|
|
||||||
{ \
|
|
||||||
(gate).off_15_0 = (uint) (off) & 0xffff; \
|
|
||||||
(gate).ss = (ss); \
|
|
||||||
(gate).args = 0; \
|
|
||||||
(gate).rsv1 = 0; \
|
|
||||||
(gate).type = STS_CG32; \
|
|
||||||
(gate).s = 0; \
|
|
||||||
(gate).dpl = (d); \
|
|
||||||
(gate).p = 1; \
|
|
||||||
(gate).off_31_16 = (uint) (off) >> 16; \
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* !__ASSEMBLER__ */
|
|
||||||
|
|
||||||
|
|
11
mp.c
11
mp.c
|
@ -42,7 +42,6 @@ mp_scan(uchar *addr, int len)
|
||||||
uchar *e, *p, sum;
|
uchar *e, *p, sum;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
cprintf("scanning: 0x%x\n", (uint)addr);
|
|
||||||
e = addr+len;
|
e = addr+len;
|
||||||
for(p = addr; p < e; p += sizeof(struct mp)){
|
for(p = addr; p < e; p += sizeof(struct mp)){
|
||||||
if(memcmp(p, "_MP_", 4))
|
if(memcmp(p, "_MP_", 4))
|
||||||
|
@ -131,8 +130,6 @@ mp_init(void)
|
||||||
ncpu = 0;
|
ncpu = 0;
|
||||||
if ((r = mp_detect()) != 0) return;
|
if ((r = mp_detect()) != 0) return;
|
||||||
|
|
||||||
cprintf("Mp spec rev #: %x imcrp 0x%x\n", mp->specrev, mp->imcrp);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Run through the table saving information needed for starting
|
* Run through the table saving information needed for starting
|
||||||
* application processors and initialising any I/O APICs. The table
|
* application processors and initialising any I/O APICs. The table
|
||||||
|
@ -140,7 +137,6 @@ mp_init(void)
|
||||||
*/
|
*/
|
||||||
mpctb = (struct mpctb *) mp->physaddr;
|
mpctb = (struct mpctb *) mp->physaddr;
|
||||||
lapicaddr = (uint *) mpctb->lapicaddr;
|
lapicaddr = (uint *) mpctb->lapicaddr;
|
||||||
cprintf("apicaddr: %x\n", lapicaddr);
|
|
||||||
p = ((uchar*)mpctb)+sizeof(struct mpctb);
|
p = ((uchar*)mpctb)+sizeof(struct mpctb);
|
||||||
e = ((uchar*)mpctb)+mpctb->length;
|
e = ((uchar*)mpctb)+mpctb->length;
|
||||||
|
|
||||||
|
@ -149,7 +145,6 @@ mp_init(void)
|
||||||
case MPPROCESSOR:
|
case MPPROCESSOR:
|
||||||
proc = (struct mppe *) p;
|
proc = (struct mppe *) p;
|
||||||
cpus[ncpu].apicid = proc->apicid;
|
cpus[ncpu].apicid = proc->apicid;
|
||||||
cprintf("a processor %x\n", cpus[ncpu].apicid);
|
|
||||||
if (proc->flags & MPBP) {
|
if (proc->flags & MPBP) {
|
||||||
bcpu = &cpus[ncpu];
|
bcpu = &cpus[ncpu];
|
||||||
}
|
}
|
||||||
|
@ -162,18 +157,15 @@ mp_init(void)
|
||||||
if(strncmp(buses[i], bus->string, sizeof(bus->string)) == 0)
|
if(strncmp(buses[i], bus->string, sizeof(bus->string)) == 0)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
cprintf("a bus %d\n", i);
|
|
||||||
p += sizeof(struct mpbe);
|
p += sizeof(struct mpbe);
|
||||||
continue;
|
continue;
|
||||||
case MPIOAPIC:
|
case MPIOAPIC:
|
||||||
ioapic = (struct mpioapic *) p;
|
ioapic = (struct mpioapic *) p;
|
||||||
cprintf("an I/O APIC: id %d %x\n", ioapic->apicno, ioapic->flags);
|
|
||||||
ioapic_id = ioapic->apicno;
|
ioapic_id = ioapic->apicno;
|
||||||
p += sizeof(struct mpioapic);
|
p += sizeof(struct mpioapic);
|
||||||
continue;
|
continue;
|
||||||
case MPIOINTR:
|
case MPIOINTR:
|
||||||
intr = (struct mpie *) p;
|
intr = (struct mpie *) p;
|
||||||
// cprintf("an I/O intr: type %d flags 0x%x bus %d souce bus irq %d dest ioapic id %d dest ioapic intin %d\n", intr->intr, intr->flags, intr->busno, intr->irq, intr->apicno, intr->intin);
|
|
||||||
p += sizeof(struct mpie);
|
p += sizeof(struct mpie);
|
||||||
continue;
|
continue;
|
||||||
default:
|
default:
|
||||||
|
@ -192,8 +184,6 @@ mp_init(void)
|
||||||
byte |= 0x01; /* mask external INTR */
|
byte |= 0x01; /* mask external INTR */
|
||||||
outb(0x23, byte); /* disconnect 8259s/NMI */
|
outb(0x23, byte); /* disconnect 8259s/NMI */
|
||||||
}
|
}
|
||||||
|
|
||||||
cprintf("ncpu: %d boot %d\n", ncpu, bcpu-cpus);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -219,7 +209,6 @@ mp_startthem(void)
|
||||||
|
|
||||||
for(c = 0; c < ncpu; c++){
|
for(c = 0; c < ncpu; c++){
|
||||||
if (c == cpu()) continue;
|
if (c == cpu()) continue;
|
||||||
cprintf ("cpu%d: starting processor %d\n", cpu(), c);
|
|
||||||
*(uint *)(APBOOTCODE-4) = (uint) (cpus[c].mpstack) + MPSTACK; // tell it what to use for %esp
|
*(uint *)(APBOOTCODE-4) = (uint) (cpus[c].mpstack) + MPSTACK; // tell it what to use for %esp
|
||||||
*(uint *)(APBOOTCODE-8) = (uint)mpmain; // tell it where to jump to
|
*(uint *)(APBOOTCODE-8) = (uint)mpmain; // tell it where to jump to
|
||||||
lapic_startap(cpus[c].apicid, (uint) APBOOTCODE);
|
lapic_startap(cpus[c].apicid, (uint) APBOOTCODE);
|
||||||
|
|
29
proc.c
29
proc.c
|
@ -169,18 +169,11 @@ scheduler(void)
|
||||||
struct proc *p;
|
struct proc *p;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if(cpus[cpu()].nlock != 0){
|
|
||||||
cprintf("la %x lr %x\n", cpus[cpu()].lastacquire, cpus[cpu()].lastrelease );
|
|
||||||
panic("holding locks at first entry to scheduler");
|
|
||||||
}
|
|
||||||
|
|
||||||
for(;;){
|
for(;;){
|
||||||
// Loop over process table looking for process to run.
|
// Loop over process table looking for process to run.
|
||||||
acquire(&proc_table_lock);
|
acquire(&proc_table_lock);
|
||||||
|
|
||||||
for(i = 0; i < NPROC; i++){
|
for(i = 0; i < NPROC; i++){
|
||||||
if(cpus[cpu()].guard1 != 0xdeadbeef ||
|
|
||||||
cpus[cpu()].guard2 != 0xdeadbeef)
|
|
||||||
panic("cpu guard");
|
|
||||||
p = &proc[i];
|
p = &proc[i];
|
||||||
if(p->state != RUNNABLE)
|
if(p->state != RUNNABLE)
|
||||||
continue;
|
continue;
|
||||||
|
@ -198,31 +191,11 @@ scheduler(void)
|
||||||
// Process is done running for now.
|
// Process is done running for now.
|
||||||
// It should have changed its p->state before coming back.
|
// It should have changed its p->state before coming back.
|
||||||
curproc[cpu()] = 0;
|
curproc[cpu()] = 0;
|
||||||
if(p->state == RUNNING)
|
|
||||||
panic("swtch to scheduler with state=RUNNING");
|
|
||||||
|
|
||||||
if(!holding(&proc_table_lock)){
|
|
||||||
cprintf("back to scheduler without proc_table_lock (pid=%d state=%d)", p->pid, p->state);
|
|
||||||
panic("scheduler lock");
|
|
||||||
}
|
|
||||||
if(cpus[cpu()].nlock != 1){
|
|
||||||
cprintf("holding %d locks in scheduler (pid=%d state=%d)\n", cpus[cpu()].nlock, p->pid, p->state);
|
|
||||||
panic("scheduler lock");
|
|
||||||
}
|
|
||||||
|
|
||||||
setupsegs(0);
|
setupsegs(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
release(&proc_table_lock);
|
release(&proc_table_lock);
|
||||||
|
|
||||||
if(cpus[cpu()].nlock != 0)
|
|
||||||
panic("holding locks in scheduler");
|
|
||||||
|
|
||||||
// With proc_table_lock released, there are no
|
|
||||||
// locks held on this cpu, so interrupts are enabled.
|
|
||||||
// Hardware interrupts can happen here.
|
|
||||||
// Also, releasing the lock here lets the other CPUs
|
|
||||||
// look for runnable processes too.
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
4
proc.h
4
proc.h
|
@ -66,13 +66,9 @@ struct cpu {
|
||||||
struct jmpbuf jmpbuf;
|
struct jmpbuf jmpbuf;
|
||||||
struct taskstate ts; // only to give cpu address of kernel stack
|
struct taskstate ts; // only to give cpu address of kernel stack
|
||||||
struct segdesc gdt[NSEGS];
|
struct segdesc gdt[NSEGS];
|
||||||
int guard1;
|
|
||||||
char mpstack[MPSTACK]; // per-cpu start-up stack
|
char mpstack[MPSTACK]; // per-cpu start-up stack
|
||||||
int guard2;
|
|
||||||
volatile int booted;
|
volatile int booted;
|
||||||
int nlock; // # of locks currently held
|
int nlock; // # of locks currently held
|
||||||
struct spinlock *lastacquire; // xxx debug
|
|
||||||
struct spinlock *lastrelease; // xxx debug
|
|
||||||
};
|
};
|
||||||
|
|
||||||
extern struct cpu cpus[NCPU];
|
extern struct cpu cpus[NCPU];
|
||||||
|
|
|
@ -43,7 +43,6 @@ acquire(struct spinlock * lock)
|
||||||
cpuid(0, 0, 0, 0, 0); // memory barrier
|
cpuid(0, 0, 0, 0, 0); // memory barrier
|
||||||
getcallerpcs(&lock, lock->pcs);
|
getcallerpcs(&lock, lock->pcs);
|
||||||
lock->cpu = cpu() + 10;
|
lock->cpu = cpu() + 10;
|
||||||
cpus[cpu()].lastacquire = lock;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -53,7 +52,6 @@ release(struct spinlock * lock)
|
||||||
if(!holding(lock))
|
if(!holding(lock))
|
||||||
panic("release");
|
panic("release");
|
||||||
|
|
||||||
cpus[cpu()].lastrelease = lock;
|
|
||||||
lock->pcs[0] = 0;
|
lock->pcs[0] = 0;
|
||||||
lock->cpu = 0xffffffff;
|
lock->cpu = 0xffffffff;
|
||||||
cpuid(0, 0, 0, 0, 0); // memory barrier
|
cpuid(0, 0, 0, 0, 0); // memory barrier
|
||||||
|
|
|
@ -473,7 +473,7 @@ sys_getpid(void)
|
||||||
int
|
int
|
||||||
sys_sbrk(void)
|
sys_sbrk(void)
|
||||||
{
|
{
|
||||||
unsigned addr;
|
uint addr;
|
||||||
int n;
|
int n;
|
||||||
struct proc *cp = curproc[cpu()];
|
struct proc *cp = curproc[cpu()];
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
#include "mmu.h"
|
|
||||||
|
|
||||||
.text
|
.text
|
||||||
.globl trap
|
.globl trap
|
||||||
.globl trapret1
|
.globl trapret1
|
||||||
|
|
48
usertests.c
48
usertests.c
|
@ -13,7 +13,10 @@ pipe1(void)
|
||||||
int fds[2], pid;
|
int fds[2], pid;
|
||||||
int seq = 0, i, n, cc, total;
|
int seq = 0, i, n, cc, total;
|
||||||
|
|
||||||
pipe(fds);
|
if(pipe(fds) != 0){
|
||||||
|
puts("pipe() failed\n");
|
||||||
|
exit();
|
||||||
|
}
|
||||||
pid = fork();
|
pid = fork();
|
||||||
if(pid == 0){
|
if(pid == 0){
|
||||||
close(fds[0]);
|
close(fds[0]);
|
||||||
|
@ -26,7 +29,7 @@ pipe1(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
exit();
|
exit();
|
||||||
} else {
|
} else if(pid > 0){
|
||||||
close(fds[1]);
|
close(fds[1]);
|
||||||
total = 0;
|
total = 0;
|
||||||
cc = 1;
|
cc = 1;
|
||||||
|
@ -43,9 +46,12 @@ pipe1(void)
|
||||||
cc = sizeof(buf);
|
cc = sizeof(buf);
|
||||||
}
|
}
|
||||||
if(total != 5 * 1033)
|
if(total != 5 * 1033)
|
||||||
printf(1, "pipe1 oops 3\n");
|
printf(1, "pipe1 oops 3 total %d\n", total);
|
||||||
close(fds[0]);
|
close(fds[0]);
|
||||||
wait();
|
wait();
|
||||||
|
} else {
|
||||||
|
puts("fork() failed\n");
|
||||||
|
exit();
|
||||||
}
|
}
|
||||||
puts("pipe1 ok\n");
|
puts("pipe1 ok\n");
|
||||||
}
|
}
|
||||||
|
@ -121,26 +127,30 @@ void
|
||||||
mem(void)
|
mem(void)
|
||||||
{
|
{
|
||||||
void *m1, *m2;
|
void *m1, *m2;
|
||||||
|
int pid;
|
||||||
|
|
||||||
m1 = 0;
|
if((pid = fork()) == 0){
|
||||||
while ((m2 = malloc(1024)) != 0) {
|
m1 = 0;
|
||||||
printf(1, "malloc %x\n", m2);
|
while ((m2 = malloc(10001)) != 0) {
|
||||||
*(char **) m2 = m1;
|
*(char **) m2 = m1;
|
||||||
m1 = m2;
|
m1 = m2;
|
||||||
}
|
}
|
||||||
while (m1) {
|
while (m1) {
|
||||||
m2 = *(char **)m1;
|
m2 = *(char **)m1;
|
||||||
|
free(m1);
|
||||||
|
m1 = m2;
|
||||||
|
}
|
||||||
|
m1 = malloc(1024*20);
|
||||||
|
if (m1 == 0) {
|
||||||
|
puts("couldn't allocate mem?!!\n");
|
||||||
|
exit();
|
||||||
|
}
|
||||||
free(m1);
|
free(m1);
|
||||||
m1 = m2;
|
printf(1, "mem ok\n");
|
||||||
}
|
|
||||||
m1 = malloc(1024*20);
|
|
||||||
if (m1 == 0) {
|
|
||||||
puts("couldn't allocate mem?!!\n");
|
|
||||||
exit();
|
exit();
|
||||||
|
} else {
|
||||||
|
wait();
|
||||||
}
|
}
|
||||||
free(m1);
|
|
||||||
|
|
||||||
printf(1, "mem ok\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
|
Loading…
Reference in a new issue