Merge branch 'master' of git+ssh://amsterdam.csail.mit.edu/home/am0/6.828/xv6
This commit is contained in:
commit
23c3e52c2f
2
Makefile
2
Makefile
|
@ -159,7 +159,7 @@ clean:
|
||||||
|
|
||||||
# make a printout
|
# make a printout
|
||||||
FILES = $(shell grep -v '^\#' runoff.list)
|
FILES = $(shell grep -v '^\#' runoff.list)
|
||||||
PRINT = runoff.list $(FILES)
|
PRINT = runoff.list runoff.spec $(FILES)
|
||||||
|
|
||||||
xv6.pdf: $(PRINT)
|
xv6.pdf: $(PRINT)
|
||||||
./runoff
|
./runoff
|
||||||
|
|
3
README
3
README
|
@ -20,6 +20,9 @@ The following people made contributions:
|
||||||
Cliff Frey (MP)
|
Cliff Frey (MP)
|
||||||
Xiao Yu (MP)
|
Xiao Yu (MP)
|
||||||
|
|
||||||
|
In addition, we are grateful for the patches submitted by Greg Price,
|
||||||
|
Yandong Mao, and Hitoshi Mitake.
|
||||||
|
|
||||||
The code in the files that constitute xv6 is
|
The code in the files that constitute xv6 is
|
||||||
Copyright 2006-2007 Frans Kaashoek, Robert Morris, and Russ Cox.
|
Copyright 2006-2007 Frans Kaashoek, Robert Morris, and Russ Cox.
|
||||||
|
|
||||||
|
|
1
kalloc.c
1
kalloc.c
|
@ -29,6 +29,7 @@ kinit(void)
|
||||||
kfree(p);
|
kfree(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//PAGEBREAK: 21
|
||||||
// Free the page of physical memory pointed at by v,
|
// Free the page of physical memory pointed at by v,
|
||||||
// which normally should have been returned by a
|
// which normally should have been returned by a
|
||||||
// call to kalloc(). (The exception is when
|
// call to kalloc(). (The exception is when
|
||||||
|
|
33
mmu.h
33
mmu.h
|
@ -24,6 +24,20 @@
|
||||||
#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
|
||||||
|
|
||||||
|
// Control Register flags
|
||||||
|
#define CR0_PE 0x00000001 // Protection Enable
|
||||||
|
#define CR0_MP 0x00000002 // Monitor coProcessor
|
||||||
|
#define CR0_EM 0x00000004 // Emulation
|
||||||
|
#define CR0_TS 0x00000008 // Task Switched
|
||||||
|
#define CR0_ET 0x00000010 // Extension Type
|
||||||
|
#define CR0_NE 0x00000020 // Numeric Errror
|
||||||
|
#define CR0_WP 0x00010000 // Write Protect
|
||||||
|
#define CR0_AM 0x00040000 // Alignment Mask
|
||||||
|
#define CR0_NW 0x20000000 // Not Writethrough
|
||||||
|
#define CR0_CD 0x40000000 // Cache Disable
|
||||||
|
#define CR0_PG 0x80000000 // Paging
|
||||||
|
|
||||||
|
//PAGEBREAK!
|
||||||
// Segment Descriptor
|
// Segment Descriptor
|
||||||
struct segdesc {
|
struct segdesc {
|
||||||
uint lim_15_0 : 16; // Low bits of segment limit
|
uint lim_15_0 : 16; // Low bits of segment limit
|
||||||
|
@ -46,7 +60,6 @@ struct segdesc {
|
||||||
{ ((lim) >> 12) & 0xffff, (uint)(base) & 0xffff, \
|
{ ((lim) >> 12) & 0xffff, (uint)(base) & 0xffff, \
|
||||||
((uint)(base) >> 16) & 0xff, type, 1, dpl, 1, \
|
((uint)(base) >> 16) & 0xff, type, 1, dpl, 1, \
|
||||||
(uint)(lim) >> 28, 0, 0, 1, 1, (uint)(base) >> 24 }
|
(uint)(lim) >> 28, 0, 0, 1, 1, (uint)(base) >> 24 }
|
||||||
|
|
||||||
#define SEG16(type, base, lim, dpl) (struct segdesc) \
|
#define SEG16(type, base, lim, dpl) (struct segdesc) \
|
||||||
{ (lim) & 0xffff, (uint)(base) & 0xffff, \
|
{ (lim) & 0xffff, (uint)(base) & 0xffff, \
|
||||||
((uint)(base) >> 16) & 0xff, type, 1, dpl, 1, \
|
((uint)(base) >> 16) & 0xff, type, 1, dpl, 1, \
|
||||||
|
@ -62,8 +75,6 @@ struct segdesc {
|
||||||
#define STA_R 0x2 // Readable (executable segments)
|
#define STA_R 0x2 // Readable (executable segments)
|
||||||
#define STA_A 0x1 // Accessed
|
#define STA_A 0x1 // Accessed
|
||||||
|
|
||||||
//
|
|
||||||
|
|
||||||
// System segment type bits
|
// System segment type bits
|
||||||
#define STS_T16A 0x1 // Available 16-bit TSS
|
#define STS_T16A 0x1 // Available 16-bit TSS
|
||||||
#define STS_LDT 0x2 // Local Descriptor Table
|
#define STS_LDT 0x2 // Local Descriptor Table
|
||||||
|
@ -78,7 +89,6 @@ 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
|
||||||
|
|
||||||
|
|
||||||
// A linear address 'la' has a three-part structure as follows:
|
// A linear address 'la' has a three-part structure as follows:
|
||||||
//
|
//
|
||||||
// +--------10------+-------10-------+---------12----------+
|
// +--------10------+-------10-------+---------12----------+
|
||||||
|
@ -130,21 +140,6 @@ struct segdesc {
|
||||||
|
|
||||||
typedef uint pte_t;
|
typedef uint pte_t;
|
||||||
|
|
||||||
// Control Register flags
|
|
||||||
#define CR0_PE 0x00000001 // Protection Enable
|
|
||||||
#define CR0_MP 0x00000002 // Monitor coProcessor
|
|
||||||
#define CR0_EM 0x00000004 // Emulation
|
|
||||||
#define CR0_TS 0x00000008 // Task Switched
|
|
||||||
#define CR0_ET 0x00000010 // Extension Type
|
|
||||||
#define CR0_NE 0x00000020 // Numeric Errror
|
|
||||||
#define CR0_WP 0x00010000 // Write Protect
|
|
||||||
#define CR0_AM 0x00040000 // Alignment Mask
|
|
||||||
#define CR0_NW 0x20000000 // Not Writethrough
|
|
||||||
#define CR0_CD 0x40000000 // Cache Disable
|
|
||||||
#define CR0_PG 0x80000000 // Paging
|
|
||||||
|
|
||||||
|
|
||||||
// PAGEBREAK: 40
|
|
||||||
// Task state segment format
|
// Task state segment format
|
||||||
struct taskstate {
|
struct taskstate {
|
||||||
uint link; // Old ts selector
|
uint link; // Old ts selector
|
||||||
|
|
3
proc.c
3
proc.c
|
@ -120,7 +120,8 @@ userinit(void)
|
||||||
panic("userinit: out of memory?");
|
panic("userinit: out of memory?");
|
||||||
if (!allocuvm(p->pgdir, 0x0, (int)_binary_initcode_size))
|
if (!allocuvm(p->pgdir, 0x0, (int)_binary_initcode_size))
|
||||||
panic("userinit: out of memory?");
|
panic("userinit: out of memory?");
|
||||||
inituvm(p->pgdir, 0x0, _binary_initcode_start, (int)_binary_initcode_size);
|
inituvm(p->pgdir, 0x0, _binary_initcode_start,
|
||||||
|
(int)_binary_initcode_size);
|
||||||
p->sz = PGROUNDUP((int)_binary_initcode_size);
|
p->sz = PGROUNDUP((int)_binary_initcode_size);
|
||||||
memset(p->tf, 0, sizeof(*p->tf));
|
memset(p->tf, 0, sizeof(*p->tf));
|
||||||
p->tf->cs = (SEG_UCODE << 3) | DPL_USER;
|
p->tf->cs = (SEG_UCODE << 3) | DPL_USER;
|
||||||
|
|
16
runoff
16
runoff
|
@ -82,23 +82,25 @@ perl -e '
|
||||||
next;
|
next;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(/(left|right): (.*)/){
|
if(/(left|right)(\+?): (.*)/){
|
||||||
$what = $1;
|
$what = $1;
|
||||||
$file = $2;
|
$tens = ($2 eq "+" ? "5" : "0");
|
||||||
|
$file = $3;
|
||||||
if(!defined($toc{$file})){
|
if(!defined($toc{$file})){
|
||||||
print STDERR "Have no toc for $file\n";
|
print STDERR "Have no toc for $file\n";
|
||||||
next;
|
next;
|
||||||
}
|
}
|
||||||
# this assumes that sheet 1 of code is a left page
|
# this assumes that sheet 1 of code is a right page
|
||||||
# double-check the PDF
|
# double-check the PDF. swap the two regexps below
|
||||||
|
# otherwise.
|
||||||
if(!$leftwarn++) {
|
if(!$leftwarn++) {
|
||||||
print STDERR "assuming that sheet 1 is a left page. double-check!\n";
|
print STDERR "assuming that sheet 1 is a right page. double-check!\n";
|
||||||
}
|
}
|
||||||
if($what eq "left" && !($toc{$file} =~ /^\d[13579]0/)){
|
if($what eq "left" && !($toc{$file} =~ /^\d[02468]$tens/)){
|
||||||
print STDERR "$file does not start on a fresh left page [$toc{$file}]\n";
|
print STDERR "$file does not start on a fresh left page [$toc{$file}]\n";
|
||||||
}
|
}
|
||||||
# why does this not work if I inline $x in the if?
|
# why does this not work if I inline $x in the if?
|
||||||
$x = ($toc{$file} =~ /^\d[02468]0/);
|
$x = ($toc{$file} =~ /^\d[13579]$tens/);
|
||||||
if($what eq "right" && !$x){
|
if($what eq "right" && !$x){
|
||||||
print STDERR "$file does not start on a fresh right page [$toc{$file}] [$x]\n";
|
print STDERR "$file does not start on a fresh right page [$toc{$file}] [$x]\n";
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,8 +9,8 @@ elf.h
|
||||||
|
|
||||||
# startup
|
# startup
|
||||||
bootasm.S
|
bootasm.S
|
||||||
bootother.S
|
|
||||||
bootmain.c
|
bootmain.c
|
||||||
|
bootother.S
|
||||||
main.c
|
main.c
|
||||||
|
|
||||||
# locks
|
# locks
|
||||||
|
@ -23,7 +23,6 @@ proc.c
|
||||||
swtch.S
|
swtch.S
|
||||||
kalloc.c
|
kalloc.c
|
||||||
vm.c
|
vm.c
|
||||||
|
|
||||||
# system calls
|
# system calls
|
||||||
traps.h
|
traps.h
|
||||||
vectors.pl
|
vectors.pl
|
||||||
|
@ -46,8 +45,6 @@ file.c
|
||||||
sysfile.c
|
sysfile.c
|
||||||
exec.c
|
exec.c
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# pipes
|
# pipes
|
||||||
pipe.c
|
pipe.c
|
||||||
|
|
||||||
|
@ -73,3 +70,5 @@ init.c
|
||||||
sh.c
|
sh.c
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -16,15 +16,15 @@ even: main.c
|
||||||
# odd: init.c
|
# odd: init.c
|
||||||
|
|
||||||
# spinlock.h either
|
# spinlock.h either
|
||||||
# spinlock.c either
|
right: spinlock.c # mild preference
|
||||||
even: proc.h # mild preference
|
even: proc.h # mild preference
|
||||||
|
|
||||||
# goal is to have two action-packed 2-page spreads,
|
# goal is to have two action-packed 2-page spreads,
|
||||||
# one with
|
# one with
|
||||||
# ksegment usegment allocproc userinit growproc fork
|
# allocproc userinit growproc fork
|
||||||
# and another with
|
# and another with
|
||||||
# scheduler sched yield forkret sleep wakeup1 wakeup
|
# scheduler sched yield forkret sleep wakeup1 wakeup
|
||||||
right: proc.c # VERY important
|
right+: proc.c # VERY important
|
||||||
|
|
||||||
# setjmp.S either
|
# setjmp.S either
|
||||||
# vm.c either
|
# vm.c either
|
||||||
|
|
3
trap.c
3
trap.c
|
@ -83,7 +83,8 @@ trap(struct trapframe *tf)
|
||||||
panic("trap");
|
panic("trap");
|
||||||
}
|
}
|
||||||
// In user space, assume process misbehaved.
|
// In user space, assume process misbehaved.
|
||||||
cprintf("pid %d %s: trap %d err %d on cpu %d eip 0x%x addr 0x%x--kill proc\n",
|
cprintf("pid %d %s: trap %d err %d on cpu %d "
|
||||||
|
"eip 0x%x addr 0x%x--kill proc\n",
|
||||||
proc->pid, proc->name, tf->trapno, tf->err, cpu->id, tf->eip,
|
proc->pid, proc->name, tf->trapno, tf->err, cpu->id, tf->eip,
|
||||||
rcr2());
|
rcr2());
|
||||||
proc->killed = 1;
|
proc->killed = 1;
|
||||||
|
|
93
x86.h
93
x86.h
|
@ -90,25 +90,28 @@ readeflags(void)
|
||||||
return eflags;
|
return eflags;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint
|
|
||||||
xchg(volatile uint *addr, uint newval)
|
|
||||||
{
|
|
||||||
uint result;
|
|
||||||
|
|
||||||
// The + in "+m" denotes a read-modify-write operand.
|
|
||||||
asm volatile("lock; xchgl %0, %1" :
|
|
||||||
"+m" (*addr), "=a" (result) :
|
|
||||||
"1" (newval) :
|
|
||||||
"cc");
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
loadgs(ushort v)
|
loadgs(ushort v)
|
||||||
{
|
{
|
||||||
asm volatile("movw %0, %%gs" : : "r" (v));
|
asm volatile("movw %0, %%gs" : : "r" (v));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline uint
|
||||||
|
rebp(void)
|
||||||
|
{
|
||||||
|
uint val;
|
||||||
|
asm volatile("movl %%ebp,%0" : "=r" (val));
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint
|
||||||
|
resp(void)
|
||||||
|
{
|
||||||
|
uint val;
|
||||||
|
asm volatile("movl %%esp,%0" : "=r" (val));
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
cli(void)
|
cli(void)
|
||||||
{
|
{
|
||||||
|
@ -121,66 +124,62 @@ sti(void)
|
||||||
asm volatile("sti");
|
asm volatile("sti");
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void lcr0(uint val)
|
static inline uint
|
||||||
|
xchg(volatile uint *addr, uint newval)
|
||||||
|
{
|
||||||
|
uint result;
|
||||||
|
|
||||||
|
// The + in "+m" denotes a read-modify-write operand.
|
||||||
|
asm volatile("lock; xchgl %0, %1" :
|
||||||
|
"+m" (*addr), "=a" (result) :
|
||||||
|
"1" (newval) :
|
||||||
|
"cc");
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
nop_pause(void)
|
||||||
|
{
|
||||||
|
asm volatile("pause" : :);
|
||||||
|
}
|
||||||
|
|
||||||
|
//PAGEBREAK!
|
||||||
|
static inline void
|
||||||
|
lcr0(uint val)
|
||||||
{
|
{
|
||||||
asm volatile("movl %0,%%cr0" : : "r" (val));
|
asm volatile("movl %0,%%cr0" : : "r" (val));
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint rcr0(void)
|
static inline uint
|
||||||
|
rcr0(void)
|
||||||
{
|
{
|
||||||
uint val;
|
uint val;
|
||||||
asm volatile("movl %%cr0,%0" : "=r" (val));
|
asm volatile("movl %%cr0,%0" : "=r" (val));
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint rcr2(void)
|
static inline uint
|
||||||
|
rcr2(void)
|
||||||
{
|
{
|
||||||
uint val;
|
uint val;
|
||||||
asm volatile("movl %%cr2,%0" : "=r" (val));
|
asm volatile("movl %%cr2,%0" : "=r" (val));
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void lcr3(uint val)
|
static inline void
|
||||||
|
lcr3(uint val)
|
||||||
{
|
{
|
||||||
asm volatile("movl %0,%%cr3" : : "r" (val));
|
asm volatile("movl %0,%%cr3" : : "r" (val));
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint rcr3(void)
|
static inline uint
|
||||||
|
rcr3(void)
|
||||||
{
|
{
|
||||||
uint val;
|
uint val;
|
||||||
asm volatile("movl %%cr3,%0" : "=r" (val));
|
asm volatile("movl %%cr3,%0" : "=r" (val));
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void lebp(uint val)
|
|
||||||
{
|
|
||||||
asm volatile("movl %0,%%ebp" : : "r" (val));
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uint rebp(void)
|
|
||||||
{
|
|
||||||
uint val;
|
|
||||||
asm volatile("movl %%ebp,%0" : "=r" (val));
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void lesp(uint val)
|
|
||||||
{
|
|
||||||
asm volatile("movl %0,%%esp" : : "r" (val));
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uint resp(void)
|
|
||||||
{
|
|
||||||
uint val;
|
|
||||||
asm volatile("movl %%esp,%0" : "=r" (val));
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void nop_pause(void)
|
|
||||||
{
|
|
||||||
asm volatile("pause" : :);
|
|
||||||
}
|
|
||||||
|
|
||||||
//PAGEBREAK: 36
|
//PAGEBREAK: 36
|
||||||
// Layout of the trap frame built on the stack by the
|
// Layout of the trap frame built on the stack by the
|
||||||
// hardware and by trapasm.S, and passed to trap().
|
// hardware and by trapasm.S, and passed to trap().
|
||||||
|
|
Loading…
Reference in a new issue