Skip to content

Commit

Permalink
xv6: formatting, cleanup, rev5 (take 2)
Browse files Browse the repository at this point in the history
  • Loading branch information
rsc committed Feb 20, 2011
1 parent 9c4fe7b commit cf4b1ad
Show file tree
Hide file tree
Showing 17 changed files with 193 additions and 197 deletions.
20 changes: 11 additions & 9 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,8 @@ initcode: initcode.S
$(OBJCOPY) -S -O binary initcode.out initcode
$(OBJDUMP) -S initcode.o > initcode.asm

kernel: $(OBJS) multiboot.o bootother initcode
$(LD) $(LDFLAGS) -Ttext 0x100000 -e main -o kernel multiboot.o $(OBJS) -b binary initcode bootother fs.img
kernel: $(OBJS) multiboot.o data.o bootother initcode
$(LD) $(LDFLAGS) -Ttext 0x100000 -e main -o kernel multiboot.o data.o $(OBJS) -b binary initcode bootother
$(OBJDUMP) -S kernel > kernel.asm
$(OBJDUMP) -t kernel | sed '1,/SYMBOL TABLE/d; s/ .* / /; /^$$/d' > kernel.sym

Expand All @@ -119,8 +119,8 @@ kernel: $(OBJS) multiboot.o bootother initcode
# great for testing the kernel on real hardware without
# needing a scratch disk.
MEMFSOBJS = $(filter-out ide.o,$(OBJS)) memide.o
kernelmemfs: $(MEMFSOBJS) multiboot.o bootother initcode fs.img
$(LD) $(LDFLAGS) -Ttext 0x100000 -e main -o kernelmemfs multiboot.o $(MEMFSOBJS) -b binary initcode bootother fs.img
kernelmemfs: $(MEMFSOBJS) multiboot.o data.o bootother initcode fs.img
$(LD) $(LDFLAGS) -Ttext 0x100000 -e main -o kernelmemfs multiboot.o data.o $(MEMFSOBJS) -b binary initcode bootother fs.img
$(OBJDUMP) -S kernelmemfs > kernelmemfs.asm
$(OBJDUMP) -t kernelmemfs | sed '1,/SYMBOL TABLE/d; s/ .* / /; /^$$/d' > kernelmemfs.sym

Expand Down Expand Up @@ -251,14 +251,16 @@ dist-test:
rm -rf dist-test
mkdir dist-test
cp dist/* dist-test
cd dist-test; ../m print
cd dist-test; ../m bochs || true
cd dist-test; ../m qemu
cd dist-test; $(MAKE) print
cd dist-test; $(MAKE) bochs || true
cd dist-test; $(MAKE) qemu

# update this rule (change rev1) when it is time to
# update this rule (change rev#) when it is time to
# make a new revision.
tar:
rm -rf /tmp/xv6
mkdir -p /tmp/xv6
cp dist/* dist/.gdbinit.tmpl /tmp/xv6
(cd /tmp; tar cf - xv6) | gzip >xv6-rev4.tar.gz
(cd /tmp; tar cf - xv6) | gzip >xv6-rev5.tar.gz

.PHONY: dist-test dist
33 changes: 12 additions & 21 deletions bootasm.S
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,16 @@
.code16 # Assemble for 16-bit mode
.globl start
start:
cli # BIOS enabled interrupts ; disable
cli # BIOS enabled interrupts; disable

# 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

# Enable A20:
# For backwards compatibility with the earliest PCs, physical
# address line 20 is tied low, so that addresses higher than
# 1MB wrap around to zero by default. This code undoes this.
# Physical address line A20 is tied to zero so that the first PCs
# with 2 MB would run software that assumed 1 MB. Undo that.
seta20.1:
inb $0x64,%al # Wait for not busy
testb $0x2,%al
Expand All @@ -41,28 +39,21 @@ seta20.2:
movb $0xdf,%al # 0xdf -> port 0x60
outb %al,$0x60

//PAGEBREAK!
# Switch from real to protected mode, using a bootstrap GDT
# and segment translation that makes virtual addresses
# identical to physical addresses, so that the
# effective memory map does not change after subsequent
# loads of segment registers.
# Switch from real to protected mode. Use a bootstrap GDT that makes
# virtual addresses map dierctly to physical addresses so that the
# effective memory map doesn't change during the transition.
lgdt gdtdesc
movl %cr0, %eax
orl $CR0_PE, %eax
movl %eax, %cr0

# This ljmp is how you load the CS (Code Segment) register.
# SEG_ASM produces segment descriptors with the 32-bit mode
# flag set (the D flag), so addresses and word operands will
# default to 32 bits after this jump.
ljmp $(SEG_KCODE<<3), $start32

# tell the assembler to generate 0x66 prefixes for 16-bit
# instructions like movw, and to generate 32-bit immediate
# addresses.
.code32
//PAGEBREAK!
# Complete transition to 32-bit protected mode by using long jmp
# to reload %cs and %eip. The segment registers are set up with no
# translation, so that the mapping is still the identity mapping.
ljmp $(SEG_KCODE<<3), $start32

.code32 # Tell assembler to generate 32-bit code now.
start32:
# Set up the protected-mode data segment registers
movw $(SEG_KDATA<<3), %ax # Our data segment selector
Expand Down
2 changes: 1 addition & 1 deletion bootother.S
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,12 @@ start:
movw %ax,%es
movw %ax,%ss

//PAGEBREAK!
lgdt gdtdesc
movl %cr0, %eax
orl $CR0_PE, %eax
movl %eax, %cr0

//PAGEBREAK!
ljmp $(SEG_KCODE<<3), $start32

.code32
Expand Down
23 changes: 21 additions & 2 deletions data.S
Original file line number Diff line number Diff line change
@@ -1,5 +1,24 @@
# Define "data" symbol to mark beginning of data segment.
# Must be linked before any other data on ld command line.
// The kernel layout is:
//
// text
// rodata
// data
// bss
//
// Conventionally, Unix linkers provide pseudo-symbols
// etext, edata, and end, at the end of the text, data, and bss.
// For the kernel mapping, we need the address at the beginning
// of the data section, but that's not one of the conventional
// symbols, because the convention started before there was a
// read-only rodata section between text and data.
//
// To get the address of the data section, we define a symbol
// named data and make sure this is the first object passed to
// the linker, so that it will be the first symbol in the data section.
//
// Alternative approaches would be to parse our own ELF header
// or to write a linker script, but this is simplest.

.data
.globl data
data:
Expand Down
62 changes: 18 additions & 44 deletions exec.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ int
exec(char *path, char **argv)
{
char *s, *last;
int i, off, argc;
uint sz, sp, strings[MAXARG];
int i, off;
uint argc, sz, sp, ustack[3+MAXARG+1];
struct elfhdr elf;
struct inode *ip;
struct proghdr ph;
Expand Down Expand Up @@ -53,49 +53,25 @@ exec(char *path, char **argv)
if((sz = allocuvm(pgdir, sz, sz + PGSIZE)) == 0)
goto bad;

// initialize stack content:

// "argumentN" -- nul-terminated string
// ...
// "argument0"
// 0 -- argv[argc]
// address of argumentN
// ...
// address of argument0 -- argv[0]
// address of address of argument0 -- argv argument to main()
// argc -- argc argument to main()
// ffffffff -- return PC for main() call

// Push argument strings, prepare rest of stack in ustack.
sp = sz;

// count arguments
for(argc = 0; argv[argc]; argc++)
;
if(argc >= MAXARG)
goto bad;

// push strings and remember where they are
for(i = argc - 1; i >= 0; --i){
sp -= strlen(argv[i]) + 1;
strings[i] = sp;
copyout(pgdir, sp, argv[i], strlen(argv[i]) + 1);
for(argc = 0; argv[argc]; argc++) {
if(argc >= MAXARG)
goto bad;
sp -= strlen(argv[argc]) + 1;
sp &= ~3;
if(copyout(pgdir, sp, argv[argc], strlen(argv[argc]) + 1) < 0)
goto bad;
ustack[3+argc] = sp;
}
ustack[3+argc] = 0;

#define PUSH(x){ int xx = (int)(x); sp -= 4; copyout(pgdir, sp, &xx, 4); }
ustack[0] = 0xffffffff; // fake return PC
ustack[1] = argc;
ustack[2] = sp - (argc+1)*4; // argv pointer

PUSH(0); // argv[argc] is zero

// push argv[] elements
for(i = argc - 1; i >= 0; --i)
PUSH(strings[i]);

PUSH(sp); // argv

PUSH(argc);

PUSH(0xffffffff); // in case main tries to return

if(sp < sz - PGSIZE)
sp -= (3+argc+1) * 4;
if(copyout(pgdir, sp, ustack, (3+argc+1)*4) < 0)
goto bad;

// Save program name for debugging.
Expand All @@ -110,9 +86,7 @@ exec(char *path, char **argv)
proc->sz = sz;
proc->tf->eip = elf.entry; // main
proc->tf->esp = sp;

switchuvm(proc);

switchuvm(proc);
freevm(oldpgdir);

return 0;
Expand Down
1 change: 0 additions & 1 deletion fs.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ struct dinode {
// Block containing bit for block b
#define BBLOCK(b, ninodes) (b/BPB + (ninodes)/IPB + 3)

// PAGEBREAK: 10
// Directory is a file containing a sequence of dirent structures.
#define DIRSIZ 14

Expand Down
2 changes: 1 addition & 1 deletion ide.c
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ ideintr(void)
acquire(&idelock);
if((b = idequeue) == 0){
release(&idelock);
cprintf("Spurious IDE interrupt.\n");
// cprintf("spurious IDE interrupt\n");
return;
}
idequeue = b->qnext;
Expand Down
7 changes: 6 additions & 1 deletion main.c
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,8 @@ bootothers(void)
char *stack;

// Write bootstrap code to unused memory at 0x7000.
// The linker has placed the image of bootother.S in _binary_bootother_start.
// The linker has placed the image of bootother.S in
// _binary_bootother_start.
code = (uchar*)0x7000;
memmove(code, _binary_bootother_start, (uint)_binary_bootother_size);

Expand All @@ -111,3 +112,7 @@ bootothers(void)
;
}
}

//PAGEBREAK!
// Blank page.

2 changes: 0 additions & 2 deletions mp.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ mpsearch1(uchar *addr, int len)
{
uchar *e, *p;

cprintf("mpsearch1 0x%x %d\n", addr, len);
e = addr+len;
for(p = addr; p < e; p += sizeof(struct mp))
if(memcmp(p, "_MP_", 4) == 0 && sum(p, sizeof(struct mp)) == 0)
Expand Down Expand Up @@ -113,7 +112,6 @@ mpinit(void)
switch(*p){
case MPPROC:
proc = (struct mpproc*)p;
cprintf("mpproc %d\n", proc->apicid);
if(ncpu != proc->apicid){
cprintf("mpinit: ncpu=%d apicid=%d\n", ncpu, proc->apicid);
ismp = 0;
Expand Down
76 changes: 38 additions & 38 deletions proc.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,44 +25,6 @@ pinit(void)
initlock(&ptable.lock, "ptable");
}

//PAGEBREAK: 36
// Print a process listing to console. For debugging.
// Runs when user types ^P on console.
// No lock to avoid wedging a stuck machine further.
void
procdump(void)
{
static char *states[] = {
[UNUSED] "unused",
[EMBRYO] "embryo",
[SLEEPING] "sleep ",
[RUNNABLE] "runble",
[RUNNING] "run ",
[ZOMBIE] "zombie"
};
int i;
struct proc *p;
char *state;
uint pc[10];

for(p = ptable.proc; p < &ptable.proc[NPROC]; p++){
if(p->state == UNUSED)
continue;
if(p->state >= 0 && p->state < NELEM(states) && states[p->state])
state = states[p->state];
else
state = "???";
cprintf("%d %s %s", p->pid, state, p->name);
if(p->state == SLEEPING){
getcallerpcs((uint*)p->context->ebp+2, pc);
for(i=0; i<10 && pc[i] != 0; i++)
cprintf(" %p", pc[i]);
}
cprintf("\n");
}
}


//PAGEBREAK: 32
// Look in the process table for an UNUSED proc.
// If found, change state to EMBRYO and initialize
Expand Down Expand Up @@ -447,3 +409,41 @@ kill(int pid)
return -1;
}

//PAGEBREAK: 36
// Print a process listing to console. For debugging.
// Runs when user types ^P on console.
// No lock to avoid wedging a stuck machine further.
void
procdump(void)
{
static char *states[] = {
[UNUSED] "unused",
[EMBRYO] "embryo",
[SLEEPING] "sleep ",
[RUNNABLE] "runble",
[RUNNING] "run ",
[ZOMBIE] "zombie"
};
int i;
struct proc *p;
char *state;
uint pc[10];

for(p = ptable.proc; p < &ptable.proc[NPROC]; p++){
if(p->state == UNUSED)
continue;
if(p->state >= 0 && p->state < NELEM(states) && states[p->state])
state = states[p->state];
else
state = "???";
cprintf("%d %s %s", p->pid, state, p->name);
if(p->state == SLEEPING){
getcallerpcs((uint*)p->context->ebp+2, pc);
for(i=0; i<10 && pc[i] != 0; i++)
cprintf(" %p", pc[i]);
}
cprintf("\n");
}
}


4 changes: 4 additions & 0 deletions runoff.list
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ proc.h
proc.c
swtch.S
kalloc.c
data.S
vm.c
# system calls
traps.h
Expand All @@ -48,6 +49,7 @@ exec.c
# pipes
pipe.c


# string operations
string.c

Expand All @@ -62,6 +64,7 @@ kbd.c
console.c
timer.c
uart.c
multiboot.S

# user-level
initcode.S
Expand All @@ -72,3 +75,4 @@ sh.c




Loading

0 comments on commit cf4b1ad

Please sign in to comment.