Skip to content

Commit

Permalink
spawn judge
Browse files Browse the repository at this point in the history
  • Loading branch information
于纪平 committed May 15, 2018
1 parent 734a058 commit 8b049af
Show file tree
Hide file tree
Showing 73 changed files with 5,002 additions and 69 deletions.
3 changes: 3 additions & 0 deletions GNUmakefile
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ include boot/Makefrag
include kern/Makefrag
include lib/Makefrag
include user/Makefrag
include fs/Makefrag


CPUS ?= 1
Expand All @@ -147,6 +148,8 @@ QEMUOPTS = -drive file=$(OBJDIR)/kern/kernel.img,index=0,media=disk,format=raw -
QEMUOPTS += $(shell if $(QEMU) -nographic -help | grep -q '^-D '; then echo '-D qemu.log'; fi)
IMAGES = $(OBJDIR)/kern/kernel.img
QEMUOPTS += -smp $(CPUS)
QEMUOPTS += -drive file=$(OBJDIR)/fs/fs.img,index=1,media=disk,format=raw
IMAGES += $(OBJDIR)/fs/fs.img
QEMUOPTS += $(QEMUEXTRA)

.gdbinit: .gdbinit.tmpl
Expand Down
4 changes: 2 additions & 2 deletions conf/lab.mk
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
LAB=4
PACKAGEDATE=Wed Oct 12 17:19:29 EDT 2016
LAB=5
PACKAGEDATE=Thu Nov 3 09:15:49 EDT 2016
80 changes: 80 additions & 0 deletions fs/Makefrag
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@

OBJDIRS += fs

FSOFILES := $(OBJDIR)/fs/ide.o \
$(OBJDIR)/fs/bc.o \
$(OBJDIR)/fs/fs.o \
$(OBJDIR)/fs/serv.o \
$(OBJDIR)/fs/test.o \

USERAPPS := $(OBJDIR)/user/init

FSIMGTXTFILES := fs/newmotd \
fs/motd


USERAPPS := $(USERAPPS) \
$(OBJDIR)/user/cat \
$(OBJDIR)/user/echo \
$(OBJDIR)/user/init \
$(OBJDIR)/user/ls \
$(OBJDIR)/user/lsfd \
$(OBJDIR)/user/num \
$(OBJDIR)/user/forktree \
$(OBJDIR)/user/primes \
$(OBJDIR)/user/primespipe \
$(OBJDIR)/user/sh \
$(OBJDIR)/user/spin \
$(OBJDIR)/user/testfdsharing \
$(OBJDIR)/user/testkbd \
$(OBJDIR)/user/testpipe \
$(OBJDIR)/user/testpteshare \
$(OBJDIR)/user/testshell \
$(OBJDIR)/user/hello \
$(OBJDIR)/user/faultio \
$(OBJDIR)/user/arbiter \
$(OBJDIR)/user/sort \

FSIMGTXTFILES := $(FSIMGTXTFILES) \
fs/lorem \
fs/script \
fs/testshell.key \
fs/testshell.sh


FSIMGFILES := $(FSIMGTXTFILES) $(USERAPPS)

$(OBJDIR)/fs/%.o: fs/%.c fs/fs.h inc/lib.h $(OBJDIR)/.vars.USER_CFLAGS
@echo + cc[USER] $<
@mkdir -p $(@D)
$(V)$(CC) -nostdinc $(USER_CFLAGS) -c -o $@ $<

$(OBJDIR)/fs/fs: $(FSOFILES) $(OBJDIR)/lib/entry.o $(OBJDIR)/lib/libjos.a user/user.ld
@echo + ld $@
$(V)mkdir -p $(@D)
$(V)$(LD) -o $@ $(ULDFLAGS) $(LDFLAGS) -nostdlib \
$(OBJDIR)/lib/entry.o $(FSOFILES) \
-L$(OBJDIR)/lib -ljos $(GCC_LIB)
$(V)$(OBJDUMP) -S $@ >$@.asm

# How to build the file system image
$(OBJDIR)/fs/fsformat: fs/fsformat.c
@echo + mk $(OBJDIR)/fs/fsformat
$(V)mkdir -p $(@D)
$(V)$(NCC) $(NATIVE_CFLAGS) -o $(OBJDIR)/fs/fsformat fs/fsformat.c

$(OBJDIR)/fs/clean-fs.img: $(OBJDIR)/fs/fsformat $(FSIMGFILES)
@echo + mk $(OBJDIR)/fs/clean-fs.img
$(V)mkdir -p $(@D)
$(V)$(OBJDIR)/fs/fsformat $(OBJDIR)/fs/clean-fs.img 1024 $(FSIMGFILES)

$(OBJDIR)/fs/fs.img: $(OBJDIR)/fs/clean-fs.img
@echo + cp $(OBJDIR)/fs/clean-fs.img $@
$(V)cp $(OBJDIR)/fs/clean-fs.img $@

all: $(OBJDIR)/fs/fs.img

#all: $(addsuffix .sym, $(USERAPPS))

#all: $(addsuffix .asm, $(USERAPPS))

135 changes: 135 additions & 0 deletions fs/bc.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@

#include "fs.h"

// Return the virtual address of this disk block.
void*
diskaddr(uint32_t blockno)
{
if (blockno == 0 || (super && blockno >= super->s_nblocks))
panic("bad block number %08x in diskaddr", blockno);
return (char*) (DISKMAP + blockno * BLKSIZE);
}

// Is this virtual address mapped?
bool
va_is_mapped(void *va)
{
return (uvpd[PDX(va)] & PTE_P) && (uvpt[PGNUM(va)] & PTE_P);
}

// Is this virtual address dirty?
bool
va_is_dirty(void *va)
{
return (uvpt[PGNUM(va)] & PTE_D) != 0;
}

// Fault any disk block that is read in to memory by
// loading it from disk.
static void
bc_pgfault(struct UTrapframe *utf)
{
void *addr = (void *) utf->utf_fault_va;
uint32_t blockno = ((uint32_t)addr - DISKMAP) / BLKSIZE;
int r;

// Check that the fault was within the block cache region
if (addr < (void*)DISKMAP || addr >= (void*)(DISKMAP + DISKSIZE))
panic("page fault in FS: eip %08x, va %08x, err %04x",
utf->utf_eip, addr, utf->utf_err);

// Sanity check the block number.
if (super && blockno >= super->s_nblocks)
panic("reading non-existent block %08x\n", blockno);

// Allocate a page in the disk map region, read the contents
// of the block from the disk into that page.
// Hint: first round addr to page boundary. fs/ide.c has code to read
// the disk.
//
// LAB 5: you code here:
addr = (void *) ROUNDDOWN(addr, BLKSIZE);
sys_page_alloc(0, addr, PTE_U | PTE_P | PTE_W);
ide_read(((uint32_t) addr - DISKMAP) / SECTSIZE, addr, BLKSECTS);

// Clear the dirty bit for the disk block page since we just read the
// block from disk
if ((r = sys_page_map(0, addr, 0, addr, uvpt[PGNUM(addr)] & PTE_SYSCALL)) < 0)
panic("in bc_pgfault, sys_page_map: %e", r);

// Check that the block we read was allocated. (exercise for
// the reader: why do we do this *after* reading the block
// in?)
if (bitmap && block_is_free(blockno))
panic("reading free block %08x\n", blockno);
}

// Flush the contents of the block containing VA out to disk if
// necessary, then clear the PTE_D bit using sys_page_map.
// If the block is not in the block cache or is not dirty, does
// nothing.
// Hint: Use va_is_mapped, va_is_dirty, and ide_write.
// Hint: Use the PTE_SYSCALL constant when calling sys_page_map.
// Hint: Don't forget to round addr down.
void
flush_block(void *addr)
{
uint32_t blockno = ((uint32_t)addr - DISKMAP) / BLKSIZE;

if (addr < (void*)DISKMAP || addr >= (void*)(DISKMAP + DISKSIZE))
panic("flush_block of bad va %08x", addr);

// LAB 5: Your code here.
int r;

addr = (void *) ROUNDDOWN(addr, BLKSIZE);
if(va_is_mapped(addr) && va_is_dirty(addr))
{
ide_write(blockno * BLKSECTS, addr, BLKSECTS);
if ((r = sys_page_map(0, addr, 0, addr, uvpt[PGNUM(addr)] & PTE_SYSCALL)) < 0)
panic("in flush_block, sys_page_map: %e", r);
}
//panic("flush_block not implemented");
}

// Test that the block cache works, by smashing the superblock and
// reading it back.
static void
check_bc(void)
{
struct Super backup;

// back up super block
memmove(&backup, diskaddr(1), sizeof backup);

// smash it
strcpy(diskaddr(1), "OOPS!\n");
flush_block(diskaddr(1));
assert(va_is_mapped(diskaddr(1)));
assert(!va_is_dirty(diskaddr(1)));

// clear it out
sys_page_unmap(0, diskaddr(1));
assert(!va_is_mapped(diskaddr(1)));

// read it back in
assert(strcmp(diskaddr(1), "OOPS!\n") == 0);

// fix it
memmove(diskaddr(1), &backup, sizeof backup);
flush_block(diskaddr(1));

cprintf("block cache is good\n");
}

void
bc_init(void)
{
struct Super super;
set_pgfault_handler(bc_pgfault);
check_bc();

// cache the super block by reading it once
memmove(&super, diskaddr(1), sizeof super);
}

Loading

0 comments on commit 8b049af

Please sign in to comment.