mirror of
https://github.com/SmallPond/MIT6.828_OS.git
synced 2026-02-03 11:03:16 +08:00
all homework are done
This commit is contained in:
@@ -188,6 +188,7 @@ UPROGS=\
|
||||
_date\
|
||||
_alarmtest\
|
||||
_uthread\
|
||||
_big\
|
||||
|
||||
fs.img: mkfs README $(UPROGS)
|
||||
./mkfs fs.img README $(UPROGS)
|
||||
@@ -224,10 +225,12 @@ QEMUGDB = $(shell if $(QEMU) -help | grep -q '^-gdb'; \
|
||||
then echo "-gdb tcp::$(GDBPORT)"; \
|
||||
else echo "-s -p $(GDBPORT)"; fi)
|
||||
ifndef CPUS
|
||||
CPUS := 2
|
||||
CPUS := 1
|
||||
endif
|
||||
# QEMUEXTRA = -snapshot
|
||||
QEMUOPTS = -drive file=fs.img,index=1,media=disk,format=raw -drive file=xv6.img,index=0,media=disk,format=raw -smp $(CPUS) -m 512 $(QEMUEXTRA)
|
||||
|
||||
|
||||
gdb:
|
||||
gdb -x .gdbinit
|
||||
|
||||
|
||||
BIN
xv6-public/big
Normal file
BIN
xv6-public/big
Normal file
Binary file not shown.
53
xv6-public/big.c
Normal file
53
xv6-public/big.c
Normal file
@@ -0,0 +1,53 @@
|
||||
#include "types.h"
|
||||
#include "stat.h"
|
||||
#include "user.h"
|
||||
#include "fcntl.h"
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
char buf[512];
|
||||
int fd, i, sectors;
|
||||
|
||||
fd = open("big.file", O_CREATE | O_WRONLY);
|
||||
if(fd < 0){
|
||||
printf(2, "big: cannot open big.file for writing\n");
|
||||
exit();
|
||||
}
|
||||
|
||||
sectors = 0;
|
||||
while(1){
|
||||
*(int*)buf = sectors;
|
||||
int cc = write(fd, buf, sizeof(buf));
|
||||
if(cc <= 0)
|
||||
break;
|
||||
sectors++;
|
||||
if (sectors % 100 == 0)
|
||||
printf(2, ".");
|
||||
}
|
||||
|
||||
printf(1, "\nwrote %d sectors\n", sectors);
|
||||
|
||||
close(fd);
|
||||
fd = open("big.file", O_RDONLY);
|
||||
if(fd < 0){
|
||||
printf(2, "big: cannot re-open big.file for reading\n");
|
||||
exit();
|
||||
}
|
||||
for(i = 0; i < sectors; i++){
|
||||
int cc = read(fd, buf, sizeof(buf));
|
||||
if(cc <= 0){
|
||||
printf(2, "big: read error at sector %d\n", i);
|
||||
exit();
|
||||
}
|
||||
if(*(int*)buf != i){
|
||||
printf(2, "big: read the wrong data (%d) for sector %d\n",
|
||||
*(int*)buf, i);
|
||||
exit();
|
||||
}
|
||||
}
|
||||
|
||||
printf(1, "done; ok\n");
|
||||
|
||||
exit();
|
||||
}
|
||||
@@ -22,7 +22,7 @@ struct inode {
|
||||
short minor;
|
||||
short nlink;
|
||||
uint size;
|
||||
uint addrs[NDIRECT+1];
|
||||
uint addrs[NDIRECT+2];
|
||||
};
|
||||
|
||||
// table mapping major device number to
|
||||
|
||||
@@ -375,18 +375,23 @@ bmap(struct inode *ip, uint bn)
|
||||
{
|
||||
uint addr, *a;
|
||||
struct buf *bp;
|
||||
|
||||
struct buf *bp2;
|
||||
// 直接索引结点数目 bn= 0~10
|
||||
if(bn < NDIRECT){
|
||||
// 创建直接索引
|
||||
if((addr = ip->addrs[bn]) == 0)
|
||||
ip->addrs[bn] = addr = balloc(ip->dev);
|
||||
return addr;
|
||||
}
|
||||
bn -= NDIRECT;
|
||||
|
||||
|
||||
// #define NINDIRECT (BSIZE / sizeof(uint)) BSIZE = 512
|
||||
if(bn < NINDIRECT){
|
||||
// 一级索引
|
||||
// Load indirect block, allocating if necessary.
|
||||
if((addr = ip->addrs[NDIRECT]) == 0)
|
||||
ip->addrs[NDIRECT] = addr = balloc(ip->dev);
|
||||
|
||||
bp = bread(ip->dev, addr);
|
||||
a = (uint*)bp->data;
|
||||
if((addr = a[bn]) == 0){
|
||||
@@ -397,6 +402,37 @@ bmap(struct inode *ip, uint bn)
|
||||
return addr;
|
||||
}
|
||||
|
||||
|
||||
bn -= NINDIRECT;
|
||||
// 二级索引
|
||||
if (bn < NDINDIRECT) {
|
||||
// 根结点
|
||||
if((addr = ip->addrs[NDIRECT+1]) == 0)
|
||||
ip->addrs[NDIRECT+1] = addr = balloc(ip->dev);
|
||||
|
||||
bp = bread(ip->dev, addr);
|
||||
// 指向一级索引
|
||||
a = (uint *)bp->data;
|
||||
if ((addr = a[bn/NINDIRECT]) == 0) {
|
||||
a[bn/NINDIRECT] = addr = balloc(ip->dev);
|
||||
log_write(bp);
|
||||
}
|
||||
|
||||
bp2 = bread(ip->dev, addr);
|
||||
// 二级页表
|
||||
a = (uint *)bp2->data;
|
||||
if ((addr = a[bn%NINDIRECT]) == 0) {
|
||||
a[bn%NINDIRECT] = addr = balloc(ip->dev);
|
||||
log_write(bp2);
|
||||
}
|
||||
|
||||
brelse(bp2);
|
||||
brelse(bp);
|
||||
return addr;
|
||||
//
|
||||
}
|
||||
|
||||
|
||||
panic("bmap: out of range");
|
||||
}
|
||||
|
||||
|
||||
@@ -21,9 +21,11 @@ struct superblock {
|
||||
uint bmapstart; // Block number of first free map block
|
||||
};
|
||||
|
||||
#define NDIRECT 12
|
||||
#define NDIRECT 11
|
||||
#define NINDIRECT (BSIZE / sizeof(uint))
|
||||
#define MAXFILE (NDIRECT + NINDIRECT)
|
||||
// DOUBLE INDIRECT
|
||||
#define NDINDIRECT (NINDIRECT * NINDIRECT)
|
||||
#define MAXFILE (NDIRECT + NINDIRECT + NDINDIRECT)
|
||||
|
||||
// On-disk inode structure
|
||||
struct dinode {
|
||||
@@ -32,7 +34,7 @@ struct dinode {
|
||||
short minor; // Minor device number (T_DEV only)
|
||||
short nlink; // Number of links to inode in file system
|
||||
uint size; // Size of file (bytes)
|
||||
uint addrs[NDIRECT+1]; // Data block addresses
|
||||
uint addrs[NDIRECT+2]; // Data block addresses
|
||||
};
|
||||
|
||||
// Inodes per block.
|
||||
|
||||
@@ -5,6 +5,10 @@
|
||||
#include "sleeplock.h"
|
||||
#include "fs.h"
|
||||
#include "buf.h"
|
||||
// -------------- hw11 crash added
|
||||
#include "mmu.h"
|
||||
#include "proc.h"
|
||||
|
||||
|
||||
// Simple logging that allows concurrent FS system calls.
|
||||
//
|
||||
@@ -72,11 +76,11 @@ install_trans(void)
|
||||
int tail;
|
||||
|
||||
for (tail = 0; tail < log.lh.n; tail++) {
|
||||
struct buf *lbuf = bread(log.dev, log.start+tail+1); // read log block
|
||||
// struct buf *lbuf = bread(log.dev, log.start+tail+1); // read log block
|
||||
struct buf *dbuf = bread(log.dev, log.lh.block[tail]); // read dst
|
||||
memmove(dbuf->data, lbuf->data, BSIZE); // copy block to dst
|
||||
// memmove(dbuf->data, lbuf->data, BSIZE); // copy block to dst
|
||||
bwrite(dbuf); // write dst to disk
|
||||
brelse(lbuf);
|
||||
// brelse(lbuf);
|
||||
brelse(dbuf);
|
||||
}
|
||||
}
|
||||
@@ -115,12 +119,14 @@ write_head(void)
|
||||
static void
|
||||
recover_from_log(void)
|
||||
{
|
||||
read_head();
|
||||
install_trans(); // if committed, copy from log to disk
|
||||
read_head();
|
||||
cprintf("recovery: n=%d but ignoring\n", log.lh.n);
|
||||
install_trans();
|
||||
log.lh.n = 0;
|
||||
write_head(); // clear the log
|
||||
write_head();
|
||||
}
|
||||
|
||||
|
||||
// called at the start of each FS system call.
|
||||
void
|
||||
begin_op(void)
|
||||
@@ -189,6 +195,26 @@ write_log(void)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
void
|
||||
commit(void)
|
||||
{
|
||||
int pid = myproc()->pid;
|
||||
if (log.lh.n > 0) {
|
||||
write_log();
|
||||
write_head();
|
||||
if(pid > 1) // AAA
|
||||
log.lh.block[0] = 0; // BBB
|
||||
install_trans();
|
||||
if(pid > 1) // AAA
|
||||
panic("commit mimicking crash"); // CCC
|
||||
log.lh.n = 0;
|
||||
write_head();
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
static void
|
||||
commit()
|
||||
{
|
||||
|
||||
@@ -10,5 +10,5 @@
|
||||
#define MAXOPBLOCKS 10 // max # of blocks any FS op writes
|
||||
#define LOGSIZE (MAXOPBLOCKS*3) // max data blocks in on-disk log
|
||||
#define NBUF (MAXOPBLOCKS*3) // size of disk block cache
|
||||
#define FSSIZE 1000 // size of file system in blocks
|
||||
#define FSSIZE 20000 // size of file system in blocks
|
||||
|
||||
|
||||
297
xv6-public/xv6.si4project/Backup/Makefile(3731)
Normal file
297
xv6-public/xv6.si4project/Backup/Makefile(3731)
Normal file
@@ -0,0 +1,297 @@
|
||||
OBJS = \
|
||||
bio.o\
|
||||
console.o\
|
||||
exec.o\
|
||||
file.o\
|
||||
fs.o\
|
||||
ide.o\
|
||||
ioapic.o\
|
||||
kalloc.o\
|
||||
kbd.o\
|
||||
lapic.o\
|
||||
log.o\
|
||||
main.o\
|
||||
mp.o\
|
||||
picirq.o\
|
||||
pipe.o\
|
||||
proc.o\
|
||||
sleeplock.o\
|
||||
spinlock.o\
|
||||
string.o\
|
||||
swtch.o\
|
||||
syscall.o\
|
||||
sysfile.o\
|
||||
sysproc.o\
|
||||
trapasm.o\
|
||||
trap.o\
|
||||
uart.o\
|
||||
vectors.o\
|
||||
vm.o\
|
||||
|
||||
# Cross-compiling (e.g., on Mac OS X)
|
||||
# TOOLPREFIX = i386-jos-elf
|
||||
|
||||
# Using native tools (e.g., on X86 Linux)
|
||||
#TOOLPREFIX =
|
||||
|
||||
# Try to infer the correct TOOLPREFIX if not set
|
||||
ifndef TOOLPREFIX
|
||||
TOOLPREFIX := $(shell if i386-jos-elf-objdump -i 2>&1 | grep '^elf32-i386$$' >/dev/null 2>&1; \
|
||||
then echo 'i386-jos-elf-'; \
|
||||
elif objdump -i 2>&1 | grep 'elf32-i386' >/dev/null 2>&1; \
|
||||
then echo ''; \
|
||||
else echo "***" 1>&2; \
|
||||
echo "*** Error: Couldn't find an i386-*-elf version of GCC/binutils." 1>&2; \
|
||||
echo "*** Is the directory with i386-jos-elf-gcc in your PATH?" 1>&2; \
|
||||
echo "*** If your i386-*-elf toolchain is installed with a command" 1>&2; \
|
||||
echo "*** prefix other than 'i386-jos-elf-', set your TOOLPREFIX" 1>&2; \
|
||||
echo "*** environment variable to that prefix and run 'make' again." 1>&2; \
|
||||
echo "*** To turn off this error, run 'gmake TOOLPREFIX= ...'." 1>&2; \
|
||||
echo "***" 1>&2; exit 1; fi)
|
||||
endif
|
||||
|
||||
# If the makefile can't find QEMU, specify its path here
|
||||
# QEMU = qemu-system-i386
|
||||
|
||||
# Try to infer the correct QEMU
|
||||
ifndef QEMU
|
||||
QEMU = $(shell if which qemu > /dev/null; \
|
||||
then echo qemu; exit; \
|
||||
elif which qemu-system-i386 > /dev/null; \
|
||||
then echo qemu-system-i386; exit; \
|
||||
elif which qemu-system-x86_64 > /dev/null; \
|
||||
then echo qemu-system-x86_64; exit; \
|
||||
else \
|
||||
qemu=/Applications/Q.app/Contents/MacOS/i386-softmmu.app/Contents/MacOS/i386-softmmu; \
|
||||
if test -x $$qemu; then echo $$qemu; exit; fi; fi; \
|
||||
echo "***" 1>&2; \
|
||||
echo "*** Error: Couldn't find a working QEMU executable." 1>&2; \
|
||||
echo "*** Is the directory containing the qemu binary in your PATH" 1>&2; \
|
||||
echo "*** or have you tried setting the QEMU variable in Makefile?" 1>&2; \
|
||||
echo "***" 1>&2; exit 1)
|
||||
endif
|
||||
|
||||
CC = $(TOOLPREFIX)gcc
|
||||
AS = $(TOOLPREFIX)gas
|
||||
LD = $(TOOLPREFIX)ld
|
||||
OBJCOPY = $(TOOLPREFIX)objcopy
|
||||
OBJDUMP = $(TOOLPREFIX)objdump
|
||||
CFLAGS = -fno-pic -static -fno-builtin -fno-strict-aliasing -O2 -Wall -MD -ggdb -m32 -Werror -fno-omit-frame-pointer
|
||||
CFLAGS += $(shell $(CC) -fno-stack-protector -E -x c /dev/null >/dev/null 2>&1 && echo -fno-stack-protector)
|
||||
ASFLAGS = -m32 -gdwarf-2 -Wa,-divide
|
||||
# FreeBSD ld wants ``elf_i386_fbsd''
|
||||
LDFLAGS += -m $(shell $(LD) -V | grep elf_i386 2>/dev/null | head -n 1)
|
||||
|
||||
# Disable PIE when possible (for Ubuntu 16.10 toolchain)
|
||||
ifneq ($(shell $(CC) -dumpspecs 2>/dev/null | grep -e '[^f]no-pie'),)
|
||||
CFLAGS += -fno-pie -no-pie
|
||||
endif
|
||||
ifneq ($(shell $(CC) -dumpspecs 2>/dev/null | grep -e '[^f]nopie'),)
|
||||
CFLAGS += -fno-pie -nopie
|
||||
endif
|
||||
|
||||
xv6.img: bootblock kernel
|
||||
dd if=/dev/zero of=xv6.img count=10000
|
||||
dd if=bootblock of=xv6.img conv=notrunc
|
||||
dd if=kernel of=xv6.img seek=1 conv=notrunc
|
||||
|
||||
xv6memfs.img: bootblock kernelmemfs
|
||||
dd if=/dev/zero of=xv6memfs.img count=10000
|
||||
dd if=bootblock of=xv6memfs.img conv=notrunc
|
||||
dd if=kernelmemfs of=xv6memfs.img seek=1 conv=notrunc
|
||||
|
||||
bootblock: bootasm.S bootmain.c
|
||||
$(CC) $(CFLAGS) -fno-pic -O -nostdinc -I. -c bootmain.c
|
||||
$(CC) $(CFLAGS) -fno-pic -nostdinc -I. -c bootasm.S
|
||||
$(LD) $(LDFLAGS) -N -e start -Ttext 0x7C00 -o bootblock.o bootasm.o bootmain.o
|
||||
$(OBJDUMP) -S bootblock.o > bootblock.asm
|
||||
$(OBJCOPY) -S -O binary -j .text bootblock.o bootblock
|
||||
./sign.pl bootblock
|
||||
|
||||
entryother: entryother.S
|
||||
$(CC) $(CFLAGS) -fno-pic -nostdinc -I. -c entryother.S
|
||||
$(LD) $(LDFLAGS) -N -e start -Ttext 0x7000 -o bootblockother.o entryother.o
|
||||
$(OBJCOPY) -S -O binary -j .text bootblockother.o entryother
|
||||
$(OBJDUMP) -S bootblockother.o > entryother.asm
|
||||
|
||||
initcode: initcode.S
|
||||
$(CC) $(CFLAGS) -nostdinc -I. -c initcode.S
|
||||
$(LD) $(LDFLAGS) -N -e start -Ttext 0 -o initcode.out initcode.o
|
||||
$(OBJCOPY) -S -O binary initcode.out initcode
|
||||
$(OBJDUMP) -S initcode.o > initcode.asm
|
||||
|
||||
kernel: $(OBJS) entry.o entryother initcode kernel.ld
|
||||
$(LD) $(LDFLAGS) -T kernel.ld -o kernel entry.o $(OBJS) -b binary initcode entryother
|
||||
$(OBJDUMP) -S kernel > kernel.asm
|
||||
$(OBJDUMP) -t kernel | sed '1,/SYMBOL TABLE/d; s/ .* / /; /^$$/d' > kernel.sym
|
||||
|
||||
_uthread: uthread.o uthread_switch.o
|
||||
$(LD) $(LDFLAGS) -N -e main -Ttext 0 -o _uthread uthread.o uthread_switch.o $(ULIB)
|
||||
$(OBJDUMP) -S _uthread > uthread.asm
|
||||
|
||||
# kernelmemfs is a copy of kernel that maintains the
|
||||
# disk image in memory instead of writing to a disk.
|
||||
# This is not so useful for testing persistent storage or
|
||||
# exploring disk buffering implementations, but it is
|
||||
# great for testing the kernel on real hardware without
|
||||
# needing a scratch disk.
|
||||
MEMFSOBJS = $(filter-out ide.o,$(OBJS)) memide.o
|
||||
kernelmemfs: $(MEMFSOBJS) entry.o entryother initcode kernel.ld fs.img
|
||||
$(LD) $(LDFLAGS) -T kernel.ld -o kernelmemfs entry.o $(MEMFSOBJS) -b binary initcode entryother fs.img
|
||||
$(OBJDUMP) -S kernelmemfs > kernelmemfs.asm
|
||||
$(OBJDUMP) -t kernelmemfs | sed '1,/SYMBOL TABLE/d; s/ .* / /; /^$$/d' > kernelmemfs.sym
|
||||
|
||||
tags: $(OBJS) entryother.S _init
|
||||
etags *.S *.c
|
||||
|
||||
vectors.S: vectors.pl
|
||||
./vectors.pl > vectors.S
|
||||
|
||||
ULIB = ulib.o usys.o printf.o umalloc.o
|
||||
|
||||
_%: %.o $(ULIB)
|
||||
$(LD) $(LDFLAGS) -N -e main -Ttext 0 -o $@ $^
|
||||
$(OBJDUMP) -S $@ > $*.asm
|
||||
$(OBJDUMP) -t $@ | sed '1,/SYMBOL TABLE/d; s/ .* / /; /^$$/d' > $*.sym
|
||||
|
||||
_forktest: forktest.o $(ULIB)
|
||||
# forktest has less library code linked in - needs to be small
|
||||
# in order to be able to max out the proc table.
|
||||
$(LD) $(LDFLAGS) -N -e main -Ttext 0 -o _forktest forktest.o ulib.o usys.o
|
||||
$(OBJDUMP) -S _forktest > forktest.asm
|
||||
|
||||
mkfs: mkfs.c fs.h
|
||||
gcc -Werror -Wall -o mkfs mkfs.c
|
||||
|
||||
# Prevent deletion of intermediate files, e.g. cat.o, after first build, so
|
||||
# that disk image changes after first build are persistent until clean. More
|
||||
# details:
|
||||
# http://www.gnu.org/software/make/manual/html_node/Chained-Rules.html
|
||||
.PRECIOUS: %.o
|
||||
|
||||
UPROGS=\
|
||||
_cat\
|
||||
_echo\
|
||||
_forktest\
|
||||
_grep\
|
||||
_init\
|
||||
_kill\
|
||||
_ln\
|
||||
_ls\
|
||||
_mkdir\
|
||||
_rm\
|
||||
_sh\
|
||||
_stressfs\
|
||||
_usertests\
|
||||
_wc\
|
||||
_zombie\
|
||||
_date\
|
||||
_alarmtest\
|
||||
_uthread\
|
||||
|
||||
fs.img: mkfs README $(UPROGS)
|
||||
./mkfs fs.img README $(UPROGS)
|
||||
|
||||
-include *.d
|
||||
|
||||
clean:
|
||||
rm -f *.tex *.dvi *.idx *.aux *.log *.ind *.ilg \
|
||||
*.o *.d *.asm *.sym vectors.S bootblock entryother \
|
||||
initcode initcode.out kernel xv6.img fs.img kernelmemfs \
|
||||
xv6memfs.img mkfs .gdbinit \
|
||||
$(UPROGS)
|
||||
|
||||
# make a printout
|
||||
FILES = $(shell grep -v '^\#' runoff.list)
|
||||
PRINT = runoff.list runoff.spec README toc.hdr toc.ftr $(FILES)
|
||||
|
||||
xv6.pdf: $(PRINT)
|
||||
./runoff
|
||||
ls -l xv6.pdf
|
||||
|
||||
print: xv6.pdf
|
||||
|
||||
# run in emulators
|
||||
|
||||
bochs : fs.img xv6.img
|
||||
if [ ! -e .bochsrc ]; then ln -s dot-bochsrc .bochsrc; fi
|
||||
bochs -q
|
||||
|
||||
# try to generate a unique GDB port
|
||||
GDBPORT = $(shell expr `id -u` % 5000 + 25000)
|
||||
# QEMU's gdb stub command line changed in 0.11
|
||||
QEMUGDB = $(shell if $(QEMU) -help | grep -q '^-gdb'; \
|
||||
then echo "-gdb tcp::$(GDBPORT)"; \
|
||||
else echo "-s -p $(GDBPORT)"; fi)
|
||||
ifndef CPUS
|
||||
CPUS := 1
|
||||
endif
|
||||
QEMUOPTS = -drive file=fs.img,index=1,media=disk,format=raw -drive file=xv6.img,index=0,media=disk,format=raw -smp $(CPUS) -m 512 $(QEMUEXTRA)
|
||||
QEMUEXTRA = -snapshot
|
||||
|
||||
gdb:
|
||||
gdb -x .gdbinit
|
||||
|
||||
qemu: fs.img xv6.img
|
||||
$(QEMU) -serial mon:stdio $(QEMUOPTS)
|
||||
|
||||
qemu-memfs: xv6memfs.img
|
||||
$(QEMU) -drive file=xv6memfs.img,index=0,media=disk,format=raw -smp $(CPUS) -m 256
|
||||
|
||||
qemu-nox: fs.img xv6.img
|
||||
$(QEMU) -nographic $(QEMUOPTS)
|
||||
|
||||
.gdbinit: .gdbinit.tmpl
|
||||
sed "s/localhost:1234/localhost:$(GDBPORT)/" < $^ > $@
|
||||
|
||||
qemu-gdb: fs.img xv6.img .gdbinit
|
||||
@echo "*** Now run 'gdb'." 1>&2
|
||||
$(QEMU) -serial mon:stdio $(QEMUOPTS) -S $(QEMUGDB)
|
||||
|
||||
qemu-nox-gdb: fs.img xv6.img .gdbinit
|
||||
@echo "*** Now run 'gdb'." 1>&2
|
||||
$(QEMU) -nographic $(QEMUOPTS) -S $(QEMUGDB)
|
||||
|
||||
# CUT HERE
|
||||
# prepare dist for students
|
||||
# after running make dist, probably want to
|
||||
# rename it to rev0 or rev1 or so on and then
|
||||
# check in that version.
|
||||
|
||||
EXTRA=\
|
||||
mkfs.c ulib.c user.h cat.c echo.c forktest.c grep.c kill.c\
|
||||
ln.c ls.c mkdir.c rm.c stressfs.c usertests.c wc.c zombie.c\
|
||||
printf.c umalloc.c\
|
||||
README dot-bochsrc *.pl toc.* runoff runoff1 runoff.list\
|
||||
.gdbinit.tmpl gdbutil\
|
||||
|
||||
dist:
|
||||
rm -rf dist
|
||||
mkdir dist
|
||||
for i in $(FILES); \
|
||||
do \
|
||||
grep -v PAGEBREAK $$i >dist/$$i; \
|
||||
done
|
||||
sed '/CUT HERE/,$$d' Makefile >dist/Makefile
|
||||
echo >dist/runoff.spec
|
||||
cp $(EXTRA) dist
|
||||
|
||||
dist-test:
|
||||
rm -rf dist
|
||||
make dist
|
||||
rm -rf dist-test
|
||||
mkdir dist-test
|
||||
cp dist/* dist-test
|
||||
cd dist-test; $(MAKE) print
|
||||
cd dist-test; $(MAKE) bochs || true
|
||||
cd dist-test; $(MAKE) qemu
|
||||
|
||||
# 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-rev10.tar.gz # the next one will be 10 (9/17)
|
||||
|
||||
.PHONY: dist-test dist
|
||||
296
xv6-public/xv6.si4project/Backup/Makefile(4513)
Normal file
296
xv6-public/xv6.si4project/Backup/Makefile(4513)
Normal file
@@ -0,0 +1,296 @@
|
||||
OBJS = \
|
||||
bio.o\
|
||||
console.o\
|
||||
exec.o\
|
||||
file.o\
|
||||
fs.o\
|
||||
ide.o\
|
||||
ioapic.o\
|
||||
kalloc.o\
|
||||
kbd.o\
|
||||
lapic.o\
|
||||
log.o\
|
||||
main.o\
|
||||
mp.o\
|
||||
picirq.o\
|
||||
pipe.o\
|
||||
proc.o\
|
||||
sleeplock.o\
|
||||
spinlock.o\
|
||||
string.o\
|
||||
swtch.o\
|
||||
syscall.o\
|
||||
sysfile.o\
|
||||
sysproc.o\
|
||||
trapasm.o\
|
||||
trap.o\
|
||||
uart.o\
|
||||
vectors.o\
|
||||
vm.o\
|
||||
|
||||
# Cross-compiling (e.g., on Mac OS X)
|
||||
# TOOLPREFIX = i386-jos-elf
|
||||
|
||||
# Using native tools (e.g., on X86 Linux)
|
||||
#TOOLPREFIX =
|
||||
|
||||
# Try to infer the correct TOOLPREFIX if not set
|
||||
ifndef TOOLPREFIX
|
||||
TOOLPREFIX := $(shell if i386-jos-elf-objdump -i 2>&1 | grep '^elf32-i386$$' >/dev/null 2>&1; \
|
||||
then echo 'i386-jos-elf-'; \
|
||||
elif objdump -i 2>&1 | grep 'elf32-i386' >/dev/null 2>&1; \
|
||||
then echo ''; \
|
||||
else echo "***" 1>&2; \
|
||||
echo "*** Error: Couldn't find an i386-*-elf version of GCC/binutils." 1>&2; \
|
||||
echo "*** Is the directory with i386-jos-elf-gcc in your PATH?" 1>&2; \
|
||||
echo "*** If your i386-*-elf toolchain is installed with a command" 1>&2; \
|
||||
echo "*** prefix other than 'i386-jos-elf-', set your TOOLPREFIX" 1>&2; \
|
||||
echo "*** environment variable to that prefix and run 'make' again." 1>&2; \
|
||||
echo "*** To turn off this error, run 'gmake TOOLPREFIX= ...'." 1>&2; \
|
||||
echo "***" 1>&2; exit 1; fi)
|
||||
endif
|
||||
|
||||
# If the makefile can't find QEMU, specify its path here
|
||||
# QEMU = qemu-system-i386
|
||||
|
||||
# Try to infer the correct QEMU
|
||||
ifndef QEMU
|
||||
QEMU = $(shell if which qemu > /dev/null; \
|
||||
then echo qemu; exit; \
|
||||
elif which qemu-system-i386 > /dev/null; \
|
||||
then echo qemu-system-i386; exit; \
|
||||
elif which qemu-system-x86_64 > /dev/null; \
|
||||
then echo qemu-system-x86_64; exit; \
|
||||
else \
|
||||
qemu=/Applications/Q.app/Contents/MacOS/i386-softmmu.app/Contents/MacOS/i386-softmmu; \
|
||||
if test -x $$qemu; then echo $$qemu; exit; fi; fi; \
|
||||
echo "***" 1>&2; \
|
||||
echo "*** Error: Couldn't find a working QEMU executable." 1>&2; \
|
||||
echo "*** Is the directory containing the qemu binary in your PATH" 1>&2; \
|
||||
echo "*** or have you tried setting the QEMU variable in Makefile?" 1>&2; \
|
||||
echo "***" 1>&2; exit 1)
|
||||
endif
|
||||
|
||||
CC = $(TOOLPREFIX)gcc
|
||||
AS = $(TOOLPREFIX)gas
|
||||
LD = $(TOOLPREFIX)ld
|
||||
OBJCOPY = $(TOOLPREFIX)objcopy
|
||||
OBJDUMP = $(TOOLPREFIX)objdump
|
||||
CFLAGS = -fno-pic -static -fno-builtin -fno-strict-aliasing -O2 -Wall -MD -ggdb -m32 -Werror -fno-omit-frame-pointer
|
||||
CFLAGS += $(shell $(CC) -fno-stack-protector -E -x c /dev/null >/dev/null 2>&1 && echo -fno-stack-protector)
|
||||
ASFLAGS = -m32 -gdwarf-2 -Wa,-divide
|
||||
# FreeBSD ld wants ``elf_i386_fbsd''
|
||||
LDFLAGS += -m $(shell $(LD) -V | grep elf_i386 2>/dev/null | head -n 1)
|
||||
|
||||
# Disable PIE when possible (for Ubuntu 16.10 toolchain)
|
||||
ifneq ($(shell $(CC) -dumpspecs 2>/dev/null | grep -e '[^f]no-pie'),)
|
||||
CFLAGS += -fno-pie -no-pie
|
||||
endif
|
||||
ifneq ($(shell $(CC) -dumpspecs 2>/dev/null | grep -e '[^f]nopie'),)
|
||||
CFLAGS += -fno-pie -nopie
|
||||
endif
|
||||
|
||||
xv6.img: bootblock kernel
|
||||
dd if=/dev/zero of=xv6.img count=10000
|
||||
dd if=bootblock of=xv6.img conv=notrunc
|
||||
dd if=kernel of=xv6.img seek=1 conv=notrunc
|
||||
|
||||
xv6memfs.img: bootblock kernelmemfs
|
||||
dd if=/dev/zero of=xv6memfs.img count=10000
|
||||
dd if=bootblock of=xv6memfs.img conv=notrunc
|
||||
dd if=kernelmemfs of=xv6memfs.img seek=1 conv=notrunc
|
||||
|
||||
bootblock: bootasm.S bootmain.c
|
||||
$(CC) $(CFLAGS) -fno-pic -O -nostdinc -I. -c bootmain.c
|
||||
$(CC) $(CFLAGS) -fno-pic -nostdinc -I. -c bootasm.S
|
||||
$(LD) $(LDFLAGS) -N -e start -Ttext 0x7C00 -o bootblock.o bootasm.o bootmain.o
|
||||
$(OBJDUMP) -S bootblock.o > bootblock.asm
|
||||
$(OBJCOPY) -S -O binary -j .text bootblock.o bootblock
|
||||
./sign.pl bootblock
|
||||
|
||||
entryother: entryother.S
|
||||
$(CC) $(CFLAGS) -fno-pic -nostdinc -I. -c entryother.S
|
||||
$(LD) $(LDFLAGS) -N -e start -Ttext 0x7000 -o bootblockother.o entryother.o
|
||||
$(OBJCOPY) -S -O binary -j .text bootblockother.o entryother
|
||||
$(OBJDUMP) -S bootblockother.o > entryother.asm
|
||||
|
||||
initcode: initcode.S
|
||||
$(CC) $(CFLAGS) -nostdinc -I. -c initcode.S
|
||||
$(LD) $(LDFLAGS) -N -e start -Ttext 0 -o initcode.out initcode.o
|
||||
$(OBJCOPY) -S -O binary initcode.out initcode
|
||||
$(OBJDUMP) -S initcode.o > initcode.asm
|
||||
|
||||
kernel: $(OBJS) entry.o entryother initcode kernel.ld
|
||||
$(LD) $(LDFLAGS) -T kernel.ld -o kernel entry.o $(OBJS) -b binary initcode entryother
|
||||
$(OBJDUMP) -S kernel > kernel.asm
|
||||
$(OBJDUMP) -t kernel | sed '1,/SYMBOL TABLE/d; s/ .* / /; /^$$/d' > kernel.sym
|
||||
|
||||
_uthread: uthread.o uthread_switch.o
|
||||
$(LD) $(LDFLAGS) -N -e main -Ttext 0 -o _uthread uthread.o uthread_switch.o $(ULIB)
|
||||
$(OBJDUMP) -S _uthread > uthread.asm
|
||||
|
||||
# kernelmemfs is a copy of kernel that maintains the
|
||||
# disk image in memory instead of writing to a disk.
|
||||
# This is not so useful for testing persistent storage or
|
||||
# exploring disk buffering implementations, but it is
|
||||
# great for testing the kernel on real hardware without
|
||||
# needing a scratch disk.
|
||||
MEMFSOBJS = $(filter-out ide.o,$(OBJS)) memide.o
|
||||
kernelmemfs: $(MEMFSOBJS) entry.o entryother initcode kernel.ld fs.img
|
||||
$(LD) $(LDFLAGS) -T kernel.ld -o kernelmemfs entry.o $(MEMFSOBJS) -b binary initcode entryother fs.img
|
||||
$(OBJDUMP) -S kernelmemfs > kernelmemfs.asm
|
||||
$(OBJDUMP) -t kernelmemfs | sed '1,/SYMBOL TABLE/d; s/ .* / /; /^$$/d' > kernelmemfs.sym
|
||||
|
||||
tags: $(OBJS) entryother.S _init
|
||||
etags *.S *.c
|
||||
|
||||
vectors.S: vectors.pl
|
||||
./vectors.pl > vectors.S
|
||||
|
||||
ULIB = ulib.o usys.o printf.o umalloc.o
|
||||
|
||||
_%: %.o $(ULIB)
|
||||
$(LD) $(LDFLAGS) -N -e main -Ttext 0 -o $@ $^
|
||||
$(OBJDUMP) -S $@ > $*.asm
|
||||
$(OBJDUMP) -t $@ | sed '1,/SYMBOL TABLE/d; s/ .* / /; /^$$/d' > $*.sym
|
||||
|
||||
_forktest: forktest.o $(ULIB)
|
||||
# forktest has less library code linked in - needs to be small
|
||||
# in order to be able to max out the proc table.
|
||||
$(LD) $(LDFLAGS) -N -e main -Ttext 0 -o _forktest forktest.o ulib.o usys.o
|
||||
$(OBJDUMP) -S _forktest > forktest.asm
|
||||
|
||||
mkfs: mkfs.c fs.h
|
||||
gcc -Werror -Wall -o mkfs mkfs.c
|
||||
|
||||
# Prevent deletion of intermediate files, e.g. cat.o, after first build, so
|
||||
# that disk image changes after first build are persistent until clean. More
|
||||
# details:
|
||||
# http://www.gnu.org/software/make/manual/html_node/Chained-Rules.html
|
||||
.PRECIOUS: %.o
|
||||
|
||||
UPROGS=\
|
||||
_cat\
|
||||
_echo\
|
||||
_forktest\
|
||||
_grep\
|
||||
_init\
|
||||
_kill\
|
||||
_ln\
|
||||
_ls\
|
||||
_mkdir\
|
||||
_rm\
|
||||
_sh\
|
||||
_stressfs\
|
||||
_usertests\
|
||||
_wc\
|
||||
_zombie\
|
||||
_date\
|
||||
_alarmtest\
|
||||
_uthread\
|
||||
|
||||
fs.img: mkfs README $(UPROGS)
|
||||
./mkfs fs.img README $(UPROGS)
|
||||
|
||||
-include *.d
|
||||
|
||||
clean:
|
||||
rm -f *.tex *.dvi *.idx *.aux *.log *.ind *.ilg \
|
||||
*.o *.d *.asm *.sym vectors.S bootblock entryother \
|
||||
initcode initcode.out kernel xv6.img fs.img kernelmemfs \
|
||||
xv6memfs.img mkfs .gdbinit \
|
||||
$(UPROGS)
|
||||
|
||||
# make a printout
|
||||
FILES = $(shell grep -v '^\#' runoff.list)
|
||||
PRINT = runoff.list runoff.spec README toc.hdr toc.ftr $(FILES)
|
||||
|
||||
xv6.pdf: $(PRINT)
|
||||
./runoff
|
||||
ls -l xv6.pdf
|
||||
|
||||
print: xv6.pdf
|
||||
|
||||
# run in emulators
|
||||
|
||||
bochs : fs.img xv6.img
|
||||
if [ ! -e .bochsrc ]; then ln -s dot-bochsrc .bochsrc; fi
|
||||
bochs -q
|
||||
|
||||
# try to generate a unique GDB port
|
||||
GDBPORT = $(shell expr `id -u` % 5000 + 25000)
|
||||
# QEMU's gdb stub command line changed in 0.11
|
||||
QEMUGDB = $(shell if $(QEMU) -help | grep -q '^-gdb'; \
|
||||
then echo "-gdb tcp::$(GDBPORT)"; \
|
||||
else echo "-s -p $(GDBPORT)"; fi)
|
||||
ifndef CPUS
|
||||
CPUS := 2
|
||||
endif
|
||||
QEMUOPTS = -drive file=fs.img,index=1,media=disk,format=raw -drive file=xv6.img,index=0,media=disk,format=raw -smp $(CPUS) -m 512 $(QEMUEXTRA)
|
||||
|
||||
gdb:
|
||||
gdb -x .gdbinit
|
||||
|
||||
qemu: fs.img xv6.img
|
||||
$(QEMU) -serial mon:stdio $(QEMUOPTS)
|
||||
|
||||
qemu-memfs: xv6memfs.img
|
||||
$(QEMU) -drive file=xv6memfs.img,index=0,media=disk,format=raw -smp $(CPUS) -m 256
|
||||
|
||||
qemu-nox: fs.img xv6.img
|
||||
$(QEMU) -nographic $(QEMUOPTS)
|
||||
|
||||
.gdbinit: .gdbinit.tmpl
|
||||
sed "s/localhost:1234/localhost:$(GDBPORT)/" < $^ > $@
|
||||
|
||||
qemu-gdb: fs.img xv6.img .gdbinit
|
||||
@echo "*** Now run 'gdb'." 1>&2
|
||||
$(QEMU) -serial mon:stdio $(QEMUOPTS) -S $(QEMUGDB)
|
||||
|
||||
qemu-nox-gdb: fs.img xv6.img .gdbinit
|
||||
@echo "*** Now run 'gdb'." 1>&2
|
||||
$(QEMU) -nographic $(QEMUOPTS) -S $(QEMUGDB)
|
||||
|
||||
# CUT HERE
|
||||
# prepare dist for students
|
||||
# after running make dist, probably want to
|
||||
# rename it to rev0 or rev1 or so on and then
|
||||
# check in that version.
|
||||
|
||||
EXTRA=\
|
||||
mkfs.c ulib.c user.h cat.c echo.c forktest.c grep.c kill.c\
|
||||
ln.c ls.c mkdir.c rm.c stressfs.c usertests.c wc.c zombie.c\
|
||||
printf.c umalloc.c\
|
||||
README dot-bochsrc *.pl toc.* runoff runoff1 runoff.list\
|
||||
.gdbinit.tmpl gdbutil\
|
||||
|
||||
dist:
|
||||
rm -rf dist
|
||||
mkdir dist
|
||||
for i in $(FILES); \
|
||||
do \
|
||||
grep -v PAGEBREAK $$i >dist/$$i; \
|
||||
done
|
||||
sed '/CUT HERE/,$$d' Makefile >dist/Makefile
|
||||
echo >dist/runoff.spec
|
||||
cp $(EXTRA) dist
|
||||
|
||||
dist-test:
|
||||
rm -rf dist
|
||||
make dist
|
||||
rm -rf dist-test
|
||||
mkdir dist-test
|
||||
cp dist/* dist-test
|
||||
cd dist-test; $(MAKE) print
|
||||
cd dist-test; $(MAKE) bochs || true
|
||||
cd dist-test; $(MAKE) qemu
|
||||
|
||||
# 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-rev10.tar.gz # the next one will be 10 (9/17)
|
||||
|
||||
.PHONY: dist-test dist
|
||||
299
xv6-public/xv6.si4project/Backup/Makefile(7520)
Normal file
299
xv6-public/xv6.si4project/Backup/Makefile(7520)
Normal file
@@ -0,0 +1,299 @@
|
||||
OBJS = \
|
||||
bio.o\
|
||||
console.o\
|
||||
exec.o\
|
||||
file.o\
|
||||
fs.o\
|
||||
ide.o\
|
||||
ioapic.o\
|
||||
kalloc.o\
|
||||
kbd.o\
|
||||
lapic.o\
|
||||
log.o\
|
||||
main.o\
|
||||
mp.o\
|
||||
picirq.o\
|
||||
pipe.o\
|
||||
proc.o\
|
||||
sleeplock.o\
|
||||
spinlock.o\
|
||||
string.o\
|
||||
swtch.o\
|
||||
syscall.o\
|
||||
sysfile.o\
|
||||
sysproc.o\
|
||||
trapasm.o\
|
||||
trap.o\
|
||||
uart.o\
|
||||
vectors.o\
|
||||
vm.o\
|
||||
|
||||
# Cross-compiling (e.g., on Mac OS X)
|
||||
# TOOLPREFIX = i386-jos-elf
|
||||
|
||||
# Using native tools (e.g., on X86 Linux)
|
||||
#TOOLPREFIX =
|
||||
|
||||
# Try to infer the correct TOOLPREFIX if not set
|
||||
ifndef TOOLPREFIX
|
||||
TOOLPREFIX := $(shell if i386-jos-elf-objdump -i 2>&1 | grep '^elf32-i386$$' >/dev/null 2>&1; \
|
||||
then echo 'i386-jos-elf-'; \
|
||||
elif objdump -i 2>&1 | grep 'elf32-i386' >/dev/null 2>&1; \
|
||||
then echo ''; \
|
||||
else echo "***" 1>&2; \
|
||||
echo "*** Error: Couldn't find an i386-*-elf version of GCC/binutils." 1>&2; \
|
||||
echo "*** Is the directory with i386-jos-elf-gcc in your PATH?" 1>&2; \
|
||||
echo "*** If your i386-*-elf toolchain is installed with a command" 1>&2; \
|
||||
echo "*** prefix other than 'i386-jos-elf-', set your TOOLPREFIX" 1>&2; \
|
||||
echo "*** environment variable to that prefix and run 'make' again." 1>&2; \
|
||||
echo "*** To turn off this error, run 'gmake TOOLPREFIX= ...'." 1>&2; \
|
||||
echo "***" 1>&2; exit 1; fi)
|
||||
endif
|
||||
|
||||
# If the makefile can't find QEMU, specify its path here
|
||||
# QEMU = qemu-system-i386
|
||||
|
||||
# Try to infer the correct QEMU
|
||||
ifndef QEMU
|
||||
QEMU = $(shell if which qemu > /dev/null; \
|
||||
then echo qemu; exit; \
|
||||
elif which qemu-system-i386 > /dev/null; \
|
||||
then echo qemu-system-i386; exit; \
|
||||
elif which qemu-system-x86_64 > /dev/null; \
|
||||
then echo qemu-system-x86_64; exit; \
|
||||
else \
|
||||
qemu=/Applications/Q.app/Contents/MacOS/i386-softmmu.app/Contents/MacOS/i386-softmmu; \
|
||||
if test -x $$qemu; then echo $$qemu; exit; fi; fi; \
|
||||
echo "***" 1>&2; \
|
||||
echo "*** Error: Couldn't find a working QEMU executable." 1>&2; \
|
||||
echo "*** Is the directory containing the qemu binary in your PATH" 1>&2; \
|
||||
echo "*** or have you tried setting the QEMU variable in Makefile?" 1>&2; \
|
||||
echo "***" 1>&2; exit 1)
|
||||
endif
|
||||
|
||||
CC = $(TOOLPREFIX)gcc
|
||||
AS = $(TOOLPREFIX)gas
|
||||
LD = $(TOOLPREFIX)ld
|
||||
OBJCOPY = $(TOOLPREFIX)objcopy
|
||||
OBJDUMP = $(TOOLPREFIX)objdump
|
||||
CFLAGS = -fno-pic -static -fno-builtin -fno-strict-aliasing -O2 -Wall -MD -ggdb -m32 -Werror -fno-omit-frame-pointer
|
||||
CFLAGS += $(shell $(CC) -fno-stack-protector -E -x c /dev/null >/dev/null 2>&1 && echo -fno-stack-protector)
|
||||
ASFLAGS = -m32 -gdwarf-2 -Wa,-divide
|
||||
# FreeBSD ld wants ``elf_i386_fbsd''
|
||||
LDFLAGS += -m $(shell $(LD) -V | grep elf_i386 2>/dev/null | head -n 1)
|
||||
|
||||
# Disable PIE when possible (for Ubuntu 16.10 toolchain)
|
||||
ifneq ($(shell $(CC) -dumpspecs 2>/dev/null | grep -e '[^f]no-pie'),)
|
||||
CFLAGS += -fno-pie -no-pie
|
||||
endif
|
||||
ifneq ($(shell $(CC) -dumpspecs 2>/dev/null | grep -e '[^f]nopie'),)
|
||||
CFLAGS += -fno-pie -nopie
|
||||
endif
|
||||
|
||||
xv6.img: bootblock kernel
|
||||
dd if=/dev/zero of=xv6.img count=10000
|
||||
dd if=bootblock of=xv6.img conv=notrunc
|
||||
dd if=kernel of=xv6.img seek=1 conv=notrunc
|
||||
|
||||
xv6memfs.img: bootblock kernelmemfs
|
||||
dd if=/dev/zero of=xv6memfs.img count=10000
|
||||
dd if=bootblock of=xv6memfs.img conv=notrunc
|
||||
dd if=kernelmemfs of=xv6memfs.img seek=1 conv=notrunc
|
||||
|
||||
bootblock: bootasm.S bootmain.c
|
||||
$(CC) $(CFLAGS) -fno-pic -O -nostdinc -I. -c bootmain.c
|
||||
$(CC) $(CFLAGS) -fno-pic -nostdinc -I. -c bootasm.S
|
||||
$(LD) $(LDFLAGS) -N -e start -Ttext 0x7C00 -o bootblock.o bootasm.o bootmain.o
|
||||
$(OBJDUMP) -S bootblock.o > bootblock.asm
|
||||
$(OBJCOPY) -S -O binary -j .text bootblock.o bootblock
|
||||
./sign.pl bootblock
|
||||
|
||||
entryother: entryother.S
|
||||
$(CC) $(CFLAGS) -fno-pic -nostdinc -I. -c entryother.S
|
||||
$(LD) $(LDFLAGS) -N -e start -Ttext 0x7000 -o bootblockother.o entryother.o
|
||||
$(OBJCOPY) -S -O binary -j .text bootblockother.o entryother
|
||||
$(OBJDUMP) -S bootblockother.o > entryother.asm
|
||||
|
||||
initcode: initcode.S
|
||||
$(CC) $(CFLAGS) -nostdinc -I. -c initcode.S
|
||||
$(LD) $(LDFLAGS) -N -e start -Ttext 0 -o initcode.out initcode.o
|
||||
$(OBJCOPY) -S -O binary initcode.out initcode
|
||||
$(OBJDUMP) -S initcode.o > initcode.asm
|
||||
|
||||
kernel: $(OBJS) entry.o entryother initcode kernel.ld
|
||||
$(LD) $(LDFLAGS) -T kernel.ld -o kernel entry.o $(OBJS) -b binary initcode entryother
|
||||
$(OBJDUMP) -S kernel > kernel.asm
|
||||
$(OBJDUMP) -t kernel | sed '1,/SYMBOL TABLE/d; s/ .* / /; /^$$/d' > kernel.sym
|
||||
|
||||
_uthread: uthread.o uthread_switch.o
|
||||
$(LD) $(LDFLAGS) -N -e main -Ttext 0 -o _uthread uthread.o uthread_switch.o $(ULIB)
|
||||
$(OBJDUMP) -S _uthread > uthread.asm
|
||||
|
||||
# kernelmemfs is a copy of kernel that maintains the
|
||||
# disk image in memory instead of writing to a disk.
|
||||
# This is not so useful for testing persistent storage or
|
||||
# exploring disk buffering implementations, but it is
|
||||
# great for testing the kernel on real hardware without
|
||||
# needing a scratch disk.
|
||||
MEMFSOBJS = $(filter-out ide.o,$(OBJS)) memide.o
|
||||
kernelmemfs: $(MEMFSOBJS) entry.o entryother initcode kernel.ld fs.img
|
||||
$(LD) $(LDFLAGS) -T kernel.ld -o kernelmemfs entry.o $(MEMFSOBJS) -b binary initcode entryother fs.img
|
||||
$(OBJDUMP) -S kernelmemfs > kernelmemfs.asm
|
||||
$(OBJDUMP) -t kernelmemfs | sed '1,/SYMBOL TABLE/d; s/ .* / /; /^$$/d' > kernelmemfs.sym
|
||||
|
||||
tags: $(OBJS) entryother.S _init
|
||||
etags *.S *.c
|
||||
|
||||
vectors.S: vectors.pl
|
||||
./vectors.pl > vectors.S
|
||||
|
||||
ULIB = ulib.o usys.o printf.o umalloc.o
|
||||
|
||||
_%: %.o $(ULIB)
|
||||
$(LD) $(LDFLAGS) -N -e main -Ttext 0 -o $@ $^
|
||||
$(OBJDUMP) -S $@ > $*.asm
|
||||
$(OBJDUMP) -t $@ | sed '1,/SYMBOL TABLE/d; s/ .* / /; /^$$/d' > $*.sym
|
||||
|
||||
_forktest: forktest.o $(ULIB)
|
||||
# forktest has less library code linked in - needs to be small
|
||||
# in order to be able to max out the proc table.
|
||||
$(LD) $(LDFLAGS) -N -e main -Ttext 0 -o _forktest forktest.o ulib.o usys.o
|
||||
$(OBJDUMP) -S _forktest > forktest.asm
|
||||
|
||||
mkfs: mkfs.c fs.h
|
||||
gcc -Werror -Wall -o mkfs mkfs.c
|
||||
|
||||
# Prevent deletion of intermediate files, e.g. cat.o, after first build, so
|
||||
# that disk image changes after first build are persistent until clean. More
|
||||
# details:
|
||||
# http://www.gnu.org/software/make/manual/html_node/Chained-Rules.html
|
||||
.PRECIOUS: %.o
|
||||
|
||||
UPROGS=\
|
||||
_cat\
|
||||
_echo\
|
||||
_forktest\
|
||||
_grep\
|
||||
_init\
|
||||
_kill\
|
||||
_ln\
|
||||
_ls\
|
||||
_mkdir\
|
||||
_rm\
|
||||
_sh\
|
||||
_stressfs\
|
||||
_usertests\
|
||||
_wc\
|
||||
_zombie\
|
||||
_date\
|
||||
_alarmtest\
|
||||
_uthread\
|
||||
_big\
|
||||
|
||||
fs.img: mkfs README $(UPROGS)
|
||||
./mkfs fs.img README $(UPROGS)
|
||||
|
||||
-include *.d
|
||||
|
||||
clean:
|
||||
rm -f *.tex *.dvi *.idx *.aux *.log *.ind *.ilg \
|
||||
*.o *.d *.asm *.sym vectors.S bootblock entryother \
|
||||
initcode initcode.out kernel xv6.img fs.img kernelmemfs \
|
||||
xv6memfs.img mkfs .gdbinit \
|
||||
$(UPROGS)
|
||||
|
||||
# make a printout
|
||||
FILES = $(shell grep -v '^\#' runoff.list)
|
||||
PRINT = runoff.list runoff.spec README toc.hdr toc.ftr $(FILES)
|
||||
|
||||
xv6.pdf: $(PRINT)
|
||||
./runoff
|
||||
ls -l xv6.pdf
|
||||
|
||||
print: xv6.pdf
|
||||
|
||||
# run in emulators
|
||||
|
||||
bochs : fs.img xv6.img
|
||||
if [ ! -e .bochsrc ]; then ln -s dot-bochsrc .bochsrc; fi
|
||||
bochs -q
|
||||
|
||||
# try to generate a unique GDB port
|
||||
GDBPORT = $(shell expr `id -u` % 5000 + 25000)
|
||||
# QEMU's gdb stub command line changed in 0.11
|
||||
QEMUGDB = $(shell if $(QEMU) -help | grep -q '^-gdb'; \
|
||||
then echo "-gdb tcp::$(GDBPORT)"; \
|
||||
else echo "-s -p $(GDBPORT)"; fi)
|
||||
ifndef CPUS
|
||||
CPUS := 1
|
||||
endif
|
||||
QEMUEXTRA = -snapshot
|
||||
QEMUOPTS = -drive file=fs.img,index=1,media=disk,format=raw -drive file=xv6.img,index=0,media=disk,format=raw -smp $(CPUS) -m 512 $(QEMUEXTRA)
|
||||
|
||||
|
||||
gdb:
|
||||
gdb -x .gdbinit
|
||||
|
||||
qemu: fs.img xv6.img
|
||||
$(QEMU) -serial mon:stdio $(QEMUOPTS)
|
||||
|
||||
qemu-memfs: xv6memfs.img
|
||||
$(QEMU) -drive file=xv6memfs.img,index=0,media=disk,format=raw -smp $(CPUS) -m 256
|
||||
|
||||
qemu-nox: fs.img xv6.img
|
||||
$(QEMU) -nographic $(QEMUOPTS)
|
||||
|
||||
.gdbinit: .gdbinit.tmpl
|
||||
sed "s/localhost:1234/localhost:$(GDBPORT)/" < $^ > $@
|
||||
|
||||
qemu-gdb: fs.img xv6.img .gdbinit
|
||||
@echo "*** Now run 'gdb'." 1>&2
|
||||
$(QEMU) -serial mon:stdio $(QEMUOPTS) -S $(QEMUGDB)
|
||||
|
||||
qemu-nox-gdb: fs.img xv6.img .gdbinit
|
||||
@echo "*** Now run 'gdb'." 1>&2
|
||||
$(QEMU) -nographic $(QEMUOPTS) -S $(QEMUGDB)
|
||||
|
||||
# CUT HERE
|
||||
# prepare dist for students
|
||||
# after running make dist, probably want to
|
||||
# rename it to rev0 or rev1 or so on and then
|
||||
# check in that version.
|
||||
|
||||
EXTRA=\
|
||||
mkfs.c ulib.c user.h cat.c echo.c forktest.c grep.c kill.c\
|
||||
ln.c ls.c mkdir.c rm.c stressfs.c usertests.c wc.c zombie.c\
|
||||
printf.c umalloc.c\
|
||||
README dot-bochsrc *.pl toc.* runoff runoff1 runoff.list\
|
||||
.gdbinit.tmpl gdbutil\
|
||||
|
||||
dist:
|
||||
rm -rf dist
|
||||
mkdir dist
|
||||
for i in $(FILES); \
|
||||
do \
|
||||
grep -v PAGEBREAK $$i >dist/$$i; \
|
||||
done
|
||||
sed '/CUT HERE/,$$d' Makefile >dist/Makefile
|
||||
echo >dist/runoff.spec
|
||||
cp $(EXTRA) dist
|
||||
|
||||
dist-test:
|
||||
rm -rf dist
|
||||
make dist
|
||||
rm -rf dist-test
|
||||
mkdir dist-test
|
||||
cp dist/* dist-test
|
||||
cd dist-test; $(MAKE) print
|
||||
cd dist-test; $(MAKE) bochs || true
|
||||
cd dist-test; $(MAKE) qemu
|
||||
|
||||
# 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-rev10.tar.gz # the next one will be 10 (9/17)
|
||||
|
||||
.PHONY: dist-test dist
|
||||
53
xv6-public/xv6.si4project/Backup/big(6818).c
Normal file
53
xv6-public/xv6.si4project/Backup/big(6818).c
Normal file
@@ -0,0 +1,53 @@
|
||||
#include "types.h"
|
||||
#include "stat.h"
|
||||
#include "user.h"
|
||||
#include "fcntl.h"
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
char buf[512];
|
||||
int fd, i, sectors;
|
||||
|
||||
fd = open("big.file", O_CREATE | O_WRONLY);
|
||||
if(fd < 0){
|
||||
printf(2, "big: cannot open big.file for writing\n");
|
||||
exit();
|
||||
}
|
||||
|
||||
sectors = 0;
|
||||
while(1){
|
||||
*(int*)buf = sectors;
|
||||
int cc = write(fd, buf, sizeof(buf));
|
||||
if(cc <= 0)
|
||||
break;
|
||||
sectors++;
|
||||
if (sectors % 100 == 0)
|
||||
printf(2, ".");
|
||||
}
|
||||
|
||||
printf(1, "\nwrote %d sectors\n", sectors);
|
||||
|
||||
close(fd);
|
||||
fd = open("big.file", O_RDONLY);
|
||||
if(fd < 0){
|
||||
printf(2, "big: cannot re-open big.file for reading\n");
|
||||
exit();
|
||||
}
|
||||
for(i = 0; i < sectors; i++){
|
||||
int cc = read(fd, buf, sizeof(buf));
|
||||
if(cc <= 0){
|
||||
printf(2, "big: read error at sector %d\n", i);
|
||||
exit();
|
||||
}
|
||||
if(*(int*)buf != i){
|
||||
printf(2, "big: read the wrong data (%d) for sector %d\n",
|
||||
*(int*)buf, i);
|
||||
exit();
|
||||
}
|
||||
}
|
||||
|
||||
printf(1, "done; ok\n");
|
||||
|
||||
exit();
|
||||
}
|
||||
37
xv6-public/xv6.si4project/Backup/file(5413).h
Normal file
37
xv6-public/xv6.si4project/Backup/file(5413).h
Normal file
@@ -0,0 +1,37 @@
|
||||
struct file {
|
||||
enum { FD_NONE, FD_PIPE, FD_INODE } type;
|
||||
int ref; // reference count
|
||||
char readable;
|
||||
char writable;
|
||||
struct pipe *pipe;
|
||||
struct inode *ip;
|
||||
uint off;
|
||||
};
|
||||
|
||||
|
||||
// in-memory copy of an inode
|
||||
struct inode {
|
||||
uint dev; // Device number
|
||||
uint inum; // Inode number
|
||||
int ref; // Reference count
|
||||
struct sleeplock lock; // protects everything below here
|
||||
int valid; // inode has been read from disk?
|
||||
|
||||
short type; // copy of disk inode
|
||||
short major;
|
||||
short minor;
|
||||
short nlink;
|
||||
uint size;
|
||||
uint addrs[NDIRECT+1];
|
||||
};
|
||||
|
||||
// table mapping major device number to
|
||||
// device functions
|
||||
struct devsw {
|
||||
int (*read)(struct inode*, char*, int);
|
||||
int (*write)(struct inode*, char*, int);
|
||||
};
|
||||
|
||||
extern struct devsw devsw[];
|
||||
|
||||
#define CONSOLE 1
|
||||
671
xv6-public/xv6.si4project/Backup/fs(4986).c
Normal file
671
xv6-public/xv6.si4project/Backup/fs(4986).c
Normal file
@@ -0,0 +1,671 @@
|
||||
// File system implementation. Five layers:
|
||||
// + Blocks: allocator for raw disk blocks.
|
||||
// + Log: crash recovery for multi-step updates.
|
||||
// + Files: inode allocator, reading, writing, metadata.
|
||||
// + Directories: inode with special contents (list of other inodes!)
|
||||
// + Names: paths like /usr/rtm/xv6/fs.c for convenient naming.
|
||||
//
|
||||
// This file contains the low-level file system manipulation
|
||||
// routines. The (higher-level) system call implementations
|
||||
// are in sysfile.c.
|
||||
|
||||
#include "types.h"
|
||||
#include "defs.h"
|
||||
#include "param.h"
|
||||
#include "stat.h"
|
||||
#include "mmu.h"
|
||||
#include "proc.h"
|
||||
#include "spinlock.h"
|
||||
#include "sleeplock.h"
|
||||
#include "fs.h"
|
||||
#include "buf.h"
|
||||
#include "file.h"
|
||||
|
||||
#define min(a, b) ((a) < (b) ? (a) : (b))
|
||||
static void itrunc(struct inode*);
|
||||
// there should be one superblock per disk device, but we run with
|
||||
// only one device
|
||||
struct superblock sb;
|
||||
|
||||
// Read the super block.
|
||||
void
|
||||
readsb(int dev, struct superblock *sb)
|
||||
{
|
||||
struct buf *bp;
|
||||
|
||||
bp = bread(dev, 1);
|
||||
memmove(sb, bp->data, sizeof(*sb));
|
||||
brelse(bp);
|
||||
}
|
||||
|
||||
// Zero a block.
|
||||
static void
|
||||
bzero(int dev, int bno)
|
||||
{
|
||||
struct buf *bp;
|
||||
|
||||
bp = bread(dev, bno);
|
||||
memset(bp->data, 0, BSIZE);
|
||||
log_write(bp);
|
||||
brelse(bp);
|
||||
}
|
||||
|
||||
// Blocks.
|
||||
|
||||
// Allocate a zeroed disk block.
|
||||
static uint
|
||||
balloc(uint dev)
|
||||
{
|
||||
int b, bi, m;
|
||||
struct buf *bp;
|
||||
|
||||
bp = 0;
|
||||
for(b = 0; b < sb.size; b += BPB){
|
||||
bp = bread(dev, BBLOCK(b, sb));
|
||||
for(bi = 0; bi < BPB && b + bi < sb.size; bi++){
|
||||
m = 1 << (bi % 8);
|
||||
if((bp->data[bi/8] & m) == 0){ // Is block free?
|
||||
bp->data[bi/8] |= m; // Mark block in use.
|
||||
log_write(bp);
|
||||
brelse(bp);
|
||||
bzero(dev, b + bi);
|
||||
return b + bi;
|
||||
}
|
||||
}
|
||||
brelse(bp);
|
||||
}
|
||||
panic("balloc: out of blocks");
|
||||
}
|
||||
|
||||
// Free a disk block.
|
||||
static void
|
||||
bfree(int dev, uint b)
|
||||
{
|
||||
struct buf *bp;
|
||||
int bi, m;
|
||||
|
||||
readsb(dev, &sb);
|
||||
bp = bread(dev, BBLOCK(b, sb));
|
||||
bi = b % BPB;
|
||||
m = 1 << (bi % 8);
|
||||
if((bp->data[bi/8] & m) == 0)
|
||||
panic("freeing free block");
|
||||
bp->data[bi/8] &= ~m;
|
||||
log_write(bp);
|
||||
brelse(bp);
|
||||
}
|
||||
|
||||
// Inodes.
|
||||
//
|
||||
// An inode describes a single unnamed file.
|
||||
// The inode disk structure holds metadata: the file's type,
|
||||
// its size, the number of links referring to it, and the
|
||||
// list of blocks holding the file's content.
|
||||
//
|
||||
// The inodes are laid out sequentially on disk at
|
||||
// sb.startinode. Each inode has a number, indicating its
|
||||
// position on the disk.
|
||||
//
|
||||
// The kernel keeps a cache of in-use inodes in memory
|
||||
// to provide a place for synchronizing access
|
||||
// to inodes used by multiple processes. The cached
|
||||
// inodes include book-keeping information that is
|
||||
// not stored on disk: ip->ref and ip->valid.
|
||||
//
|
||||
// An inode and its in-memory representation go through a
|
||||
// sequence of states before they can be used by the
|
||||
// rest of the file system code.
|
||||
//
|
||||
// * Allocation: an inode is allocated if its type (on disk)
|
||||
// is non-zero. ialloc() allocates, and iput() frees if
|
||||
// the reference and link counts have fallen to zero.
|
||||
//
|
||||
// * Referencing in cache: an entry in the inode cache
|
||||
// is free if ip->ref is zero. Otherwise ip->ref tracks
|
||||
// the number of in-memory pointers to the entry (open
|
||||
// files and current directories). iget() finds or
|
||||
// creates a cache entry and increments its ref; iput()
|
||||
// decrements ref.
|
||||
//
|
||||
// * Valid: the information (type, size, &c) in an inode
|
||||
// cache entry is only correct when ip->valid is 1.
|
||||
// ilock() reads the inode from
|
||||
// the disk and sets ip->valid, while iput() clears
|
||||
// ip->valid if ip->ref has fallen to zero.
|
||||
//
|
||||
// * Locked: file system code may only examine and modify
|
||||
// the information in an inode and its content if it
|
||||
// has first locked the inode.
|
||||
//
|
||||
// Thus a typical sequence is:
|
||||
// ip = iget(dev, inum)
|
||||
// ilock(ip)
|
||||
// ... examine and modify ip->xxx ...
|
||||
// iunlock(ip)
|
||||
// iput(ip)
|
||||
//
|
||||
// ilock() is separate from iget() so that system calls can
|
||||
// get a long-term reference to an inode (as for an open file)
|
||||
// and only lock it for short periods (e.g., in read()).
|
||||
// The separation also helps avoid deadlock and races during
|
||||
// pathname lookup. iget() increments ip->ref so that the inode
|
||||
// stays cached and pointers to it remain valid.
|
||||
//
|
||||
// Many internal file system functions expect the caller to
|
||||
// have locked the inodes involved; this lets callers create
|
||||
// multi-step atomic operations.
|
||||
//
|
||||
// The icache.lock spin-lock protects the allocation of icache
|
||||
// entries. Since ip->ref indicates whether an entry is free,
|
||||
// and ip->dev and ip->inum indicate which i-node an entry
|
||||
// holds, one must hold icache.lock while using any of those fields.
|
||||
//
|
||||
// An ip->lock sleep-lock protects all ip-> fields other than ref,
|
||||
// dev, and inum. One must hold ip->lock in order to
|
||||
// read or write that inode's ip->valid, ip->size, ip->type, &c.
|
||||
|
||||
struct {
|
||||
struct spinlock lock;
|
||||
struct inode inode[NINODE];
|
||||
} icache;
|
||||
|
||||
void
|
||||
iinit(int dev)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
initlock(&icache.lock, "icache");
|
||||
for(i = 0; i < NINODE; i++) {
|
||||
initsleeplock(&icache.inode[i].lock, "inode");
|
||||
}
|
||||
|
||||
readsb(dev, &sb);
|
||||
cprintf("sb: size %d nblocks %d ninodes %d nlog %d logstart %d\
|
||||
inodestart %d bmap start %d\n", sb.size, sb.nblocks,
|
||||
sb.ninodes, sb.nlog, sb.logstart, sb.inodestart,
|
||||
sb.bmapstart);
|
||||
}
|
||||
|
||||
static struct inode* iget(uint dev, uint inum);
|
||||
|
||||
//PAGEBREAK!
|
||||
// Allocate an inode on device dev.
|
||||
// Mark it as allocated by giving it type type.
|
||||
// Returns an unlocked but allocated and referenced inode.
|
||||
struct inode*
|
||||
ialloc(uint dev, short type)
|
||||
{
|
||||
int inum;
|
||||
struct buf *bp;
|
||||
struct dinode *dip;
|
||||
|
||||
for(inum = 1; inum < sb.ninodes; inum++){
|
||||
bp = bread(dev, IBLOCK(inum, sb));
|
||||
dip = (struct dinode*)bp->data + inum%IPB;
|
||||
if(dip->type == 0){ // a free inode
|
||||
memset(dip, 0, sizeof(*dip));
|
||||
dip->type = type;
|
||||
log_write(bp); // mark it allocated on the disk
|
||||
brelse(bp);
|
||||
return iget(dev, inum);
|
||||
}
|
||||
brelse(bp);
|
||||
}
|
||||
panic("ialloc: no inodes");
|
||||
}
|
||||
|
||||
// Copy a modified in-memory inode to disk.
|
||||
// Must be called after every change to an ip->xxx field
|
||||
// that lives on disk, since i-node cache is write-through.
|
||||
// Caller must hold ip->lock.
|
||||
void
|
||||
iupdate(struct inode *ip)
|
||||
{
|
||||
struct buf *bp;
|
||||
struct dinode *dip;
|
||||
|
||||
bp = bread(ip->dev, IBLOCK(ip->inum, sb));
|
||||
dip = (struct dinode*)bp->data + ip->inum%IPB;
|
||||
dip->type = ip->type;
|
||||
dip->major = ip->major;
|
||||
dip->minor = ip->minor;
|
||||
dip->nlink = ip->nlink;
|
||||
dip->size = ip->size;
|
||||
memmove(dip->addrs, ip->addrs, sizeof(ip->addrs));
|
||||
log_write(bp);
|
||||
brelse(bp);
|
||||
}
|
||||
|
||||
// Find the inode with number inum on device dev
|
||||
// and return the in-memory copy. Does not lock
|
||||
// the inode and does not read it from disk.
|
||||
static struct inode*
|
||||
iget(uint dev, uint inum)
|
||||
{
|
||||
struct inode *ip, *empty;
|
||||
|
||||
acquire(&icache.lock);
|
||||
|
||||
// Is the inode already cached?
|
||||
empty = 0;
|
||||
for(ip = &icache.inode[0]; ip < &icache.inode[NINODE]; ip++){
|
||||
if(ip->ref > 0 && ip->dev == dev && ip->inum == inum){
|
||||
ip->ref++;
|
||||
release(&icache.lock);
|
||||
return ip;
|
||||
}
|
||||
if(empty == 0 && ip->ref == 0) // Remember empty slot.
|
||||
empty = ip;
|
||||
}
|
||||
|
||||
// Recycle an inode cache entry.
|
||||
if(empty == 0)
|
||||
panic("iget: no inodes");
|
||||
|
||||
ip = empty;
|
||||
ip->dev = dev;
|
||||
ip->inum = inum;
|
||||
ip->ref = 1;
|
||||
ip->valid = 0;
|
||||
release(&icache.lock);
|
||||
|
||||
return ip;
|
||||
}
|
||||
|
||||
// Increment reference count for ip.
|
||||
// Returns ip to enable ip = idup(ip1) idiom.
|
||||
struct inode*
|
||||
idup(struct inode *ip)
|
||||
{
|
||||
acquire(&icache.lock);
|
||||
ip->ref++;
|
||||
release(&icache.lock);
|
||||
return ip;
|
||||
}
|
||||
|
||||
// Lock the given inode.
|
||||
// Reads the inode from disk if necessary.
|
||||
void
|
||||
ilock(struct inode *ip)
|
||||
{
|
||||
struct buf *bp;
|
||||
struct dinode *dip;
|
||||
|
||||
if(ip == 0 || ip->ref < 1)
|
||||
panic("ilock");
|
||||
|
||||
acquiresleep(&ip->lock);
|
||||
|
||||
if(ip->valid == 0){
|
||||
bp = bread(ip->dev, IBLOCK(ip->inum, sb));
|
||||
dip = (struct dinode*)bp->data + ip->inum%IPB;
|
||||
ip->type = dip->type;
|
||||
ip->major = dip->major;
|
||||
ip->minor = dip->minor;
|
||||
ip->nlink = dip->nlink;
|
||||
ip->size = dip->size;
|
||||
memmove(ip->addrs, dip->addrs, sizeof(ip->addrs));
|
||||
brelse(bp);
|
||||
ip->valid = 1;
|
||||
if(ip->type == 0)
|
||||
panic("ilock: no type");
|
||||
}
|
||||
}
|
||||
|
||||
// Unlock the given inode.
|
||||
void
|
||||
iunlock(struct inode *ip)
|
||||
{
|
||||
if(ip == 0 || !holdingsleep(&ip->lock) || ip->ref < 1)
|
||||
panic("iunlock");
|
||||
|
||||
releasesleep(&ip->lock);
|
||||
}
|
||||
|
||||
// Drop a reference to an in-memory inode.
|
||||
// If that was the last reference, the inode cache entry can
|
||||
// be recycled.
|
||||
// If that was the last reference and the inode has no links
|
||||
// to it, free the inode (and its content) on disk.
|
||||
// All calls to iput() must be inside a transaction in
|
||||
// case it has to free the inode.
|
||||
void
|
||||
iput(struct inode *ip)
|
||||
{
|
||||
acquiresleep(&ip->lock);
|
||||
if(ip->valid && ip->nlink == 0){
|
||||
acquire(&icache.lock);
|
||||
int r = ip->ref;
|
||||
release(&icache.lock);
|
||||
if(r == 1){
|
||||
// inode has no links and no other references: truncate and free.
|
||||
itrunc(ip);
|
||||
ip->type = 0;
|
||||
iupdate(ip);
|
||||
ip->valid = 0;
|
||||
}
|
||||
}
|
||||
releasesleep(&ip->lock);
|
||||
|
||||
acquire(&icache.lock);
|
||||
ip->ref--;
|
||||
release(&icache.lock);
|
||||
}
|
||||
|
||||
// Common idiom: unlock, then put.
|
||||
void
|
||||
iunlockput(struct inode *ip)
|
||||
{
|
||||
iunlock(ip);
|
||||
iput(ip);
|
||||
}
|
||||
|
||||
//PAGEBREAK!
|
||||
// Inode content
|
||||
//
|
||||
// The content (data) associated with each inode is stored
|
||||
// in blocks on the disk. The first NDIRECT block numbers
|
||||
// are listed in ip->addrs[]. The next NINDIRECT blocks are
|
||||
// listed in block ip->addrs[NDIRECT].
|
||||
|
||||
// Return the disk block address of the nth block in inode ip.
|
||||
// If there is no such block, bmap allocates one.
|
||||
static uint
|
||||
bmap(struct inode *ip, uint bn)
|
||||
{
|
||||
uint addr, *a;
|
||||
struct buf *bp;
|
||||
|
||||
if(bn < NDIRECT){
|
||||
if((addr = ip->addrs[bn]) == 0)
|
||||
ip->addrs[bn] = addr = balloc(ip->dev);
|
||||
return addr;
|
||||
}
|
||||
bn -= NDIRECT;
|
||||
|
||||
if(bn < NINDIRECT){
|
||||
// Load indirect block, allocating if necessary.
|
||||
if((addr = ip->addrs[NDIRECT]) == 0)
|
||||
ip->addrs[NDIRECT] = addr = balloc(ip->dev);
|
||||
bp = bread(ip->dev, addr);
|
||||
a = (uint*)bp->data;
|
||||
if((addr = a[bn]) == 0){
|
||||
a[bn] = addr = balloc(ip->dev);
|
||||
log_write(bp);
|
||||
}
|
||||
brelse(bp);
|
||||
return addr;
|
||||
}
|
||||
|
||||
panic("bmap: out of range");
|
||||
}
|
||||
|
||||
// Truncate inode (discard contents).
|
||||
// Only called when the inode has no links
|
||||
// to it (no directory entries referring to it)
|
||||
// and has no in-memory reference to it (is
|
||||
// not an open file or current directory).
|
||||
static void
|
||||
itrunc(struct inode *ip)
|
||||
{
|
||||
int i, j;
|
||||
struct buf *bp;
|
||||
uint *a;
|
||||
|
||||
for(i = 0; i < NDIRECT; i++){
|
||||
if(ip->addrs[i]){
|
||||
bfree(ip->dev, ip->addrs[i]);
|
||||
ip->addrs[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if(ip->addrs[NDIRECT]){
|
||||
bp = bread(ip->dev, ip->addrs[NDIRECT]);
|
||||
a = (uint*)bp->data;
|
||||
for(j = 0; j < NINDIRECT; j++){
|
||||
if(a[j])
|
||||
bfree(ip->dev, a[j]);
|
||||
}
|
||||
brelse(bp);
|
||||
bfree(ip->dev, ip->addrs[NDIRECT]);
|
||||
ip->addrs[NDIRECT] = 0;
|
||||
}
|
||||
|
||||
ip->size = 0;
|
||||
iupdate(ip);
|
||||
}
|
||||
|
||||
// Copy stat information from inode.
|
||||
// Caller must hold ip->lock.
|
||||
void
|
||||
stati(struct inode *ip, struct stat *st)
|
||||
{
|
||||
st->dev = ip->dev;
|
||||
st->ino = ip->inum;
|
||||
st->type = ip->type;
|
||||
st->nlink = ip->nlink;
|
||||
st->size = ip->size;
|
||||
}
|
||||
|
||||
//PAGEBREAK!
|
||||
// Read data from inode.
|
||||
// Caller must hold ip->lock.
|
||||
int
|
||||
readi(struct inode *ip, char *dst, uint off, uint n)
|
||||
{
|
||||
uint tot, m;
|
||||
struct buf *bp;
|
||||
|
||||
if(ip->type == T_DEV){
|
||||
if(ip->major < 0 || ip->major >= NDEV || !devsw[ip->major].read)
|
||||
return -1;
|
||||
return devsw[ip->major].read(ip, dst, n);
|
||||
}
|
||||
|
||||
if(off > ip->size || off + n < off)
|
||||
return -1;
|
||||
if(off + n > ip->size)
|
||||
n = ip->size - off;
|
||||
|
||||
for(tot=0; tot<n; tot+=m, off+=m, dst+=m){
|
||||
bp = bread(ip->dev, bmap(ip, off/BSIZE));
|
||||
m = min(n - tot, BSIZE - off%BSIZE);
|
||||
memmove(dst, bp->data + off%BSIZE, m);
|
||||
brelse(bp);
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
// PAGEBREAK!
|
||||
// Write data to inode.
|
||||
// Caller must hold ip->lock.
|
||||
int
|
||||
writei(struct inode *ip, char *src, uint off, uint n)
|
||||
{
|
||||
uint tot, m;
|
||||
struct buf *bp;
|
||||
|
||||
if(ip->type == T_DEV){
|
||||
if(ip->major < 0 || ip->major >= NDEV || !devsw[ip->major].write)
|
||||
return -1;
|
||||
return devsw[ip->major].write(ip, src, n);
|
||||
}
|
||||
|
||||
if(off > ip->size || off + n < off)
|
||||
return -1;
|
||||
if(off + n > MAXFILE*BSIZE)
|
||||
return -1;
|
||||
|
||||
for(tot=0; tot<n; tot+=m, off+=m, src+=m){
|
||||
bp = bread(ip->dev, bmap(ip, off/BSIZE));
|
||||
m = min(n - tot, BSIZE - off%BSIZE);
|
||||
memmove(bp->data + off%BSIZE, src, m);
|
||||
log_write(bp);
|
||||
brelse(bp);
|
||||
}
|
||||
|
||||
if(n > 0 && off > ip->size){
|
||||
ip->size = off;
|
||||
iupdate(ip);
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
//PAGEBREAK!
|
||||
// Directories
|
||||
|
||||
int
|
||||
namecmp(const char *s, const char *t)
|
||||
{
|
||||
return strncmp(s, t, DIRSIZ);
|
||||
}
|
||||
|
||||
// Look for a directory entry in a directory.
|
||||
// If found, set *poff to byte offset of entry.
|
||||
struct inode*
|
||||
dirlookup(struct inode *dp, char *name, uint *poff)
|
||||
{
|
||||
uint off, inum;
|
||||
struct dirent de;
|
||||
|
||||
if(dp->type != T_DIR)
|
||||
panic("dirlookup not DIR");
|
||||
|
||||
for(off = 0; off < dp->size; off += sizeof(de)){
|
||||
if(readi(dp, (char*)&de, off, sizeof(de)) != sizeof(de))
|
||||
panic("dirlookup read");
|
||||
if(de.inum == 0)
|
||||
continue;
|
||||
if(namecmp(name, de.name) == 0){
|
||||
// entry matches path element
|
||||
if(poff)
|
||||
*poff = off;
|
||||
inum = de.inum;
|
||||
return iget(dp->dev, inum);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Write a new directory entry (name, inum) into the directory dp.
|
||||
int
|
||||
dirlink(struct inode *dp, char *name, uint inum)
|
||||
{
|
||||
int off;
|
||||
struct dirent de;
|
||||
struct inode *ip;
|
||||
|
||||
// Check that name is not present.
|
||||
if((ip = dirlookup(dp, name, 0)) != 0){
|
||||
iput(ip);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Look for an empty dirent.
|
||||
for(off = 0; off < dp->size; off += sizeof(de)){
|
||||
if(readi(dp, (char*)&de, off, sizeof(de)) != sizeof(de))
|
||||
panic("dirlink read");
|
||||
if(de.inum == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
strncpy(de.name, name, DIRSIZ);
|
||||
de.inum = inum;
|
||||
if(writei(dp, (char*)&de, off, sizeof(de)) != sizeof(de))
|
||||
panic("dirlink");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//PAGEBREAK!
|
||||
// Paths
|
||||
|
||||
// Copy the next path element from path into name.
|
||||
// Return a pointer to the element following the copied one.
|
||||
// The returned path has no leading slashes,
|
||||
// so the caller can check *path=='\0' to see if the name is the last one.
|
||||
// If no name to remove, return 0.
|
||||
//
|
||||
// Examples:
|
||||
// skipelem("a/bb/c", name) = "bb/c", setting name = "a"
|
||||
// skipelem("///a//bb", name) = "bb", setting name = "a"
|
||||
// skipelem("a", name) = "", setting name = "a"
|
||||
// skipelem("", name) = skipelem("////", name) = 0
|
||||
//
|
||||
static char*
|
||||
skipelem(char *path, char *name)
|
||||
{
|
||||
char *s;
|
||||
int len;
|
||||
|
||||
while(*path == '/')
|
||||
path++;
|
||||
if(*path == 0)
|
||||
return 0;
|
||||
s = path;
|
||||
while(*path != '/' && *path != 0)
|
||||
path++;
|
||||
len = path - s;
|
||||
if(len >= DIRSIZ)
|
||||
memmove(name, s, DIRSIZ);
|
||||
else {
|
||||
memmove(name, s, len);
|
||||
name[len] = 0;
|
||||
}
|
||||
while(*path == '/')
|
||||
path++;
|
||||
return path;
|
||||
}
|
||||
|
||||
// Look up and return the inode for a path name.
|
||||
// If parent != 0, return the inode for the parent and copy the final
|
||||
// path element into name, which must have room for DIRSIZ bytes.
|
||||
// Must be called inside a transaction since it calls iput().
|
||||
static struct inode*
|
||||
namex(char *path, int nameiparent, char *name)
|
||||
{
|
||||
struct inode *ip, *next;
|
||||
|
||||
if(*path == '/')
|
||||
ip = iget(ROOTDEV, ROOTINO);
|
||||
else
|
||||
ip = idup(myproc()->cwd);
|
||||
|
||||
while((path = skipelem(path, name)) != 0){
|
||||
ilock(ip);
|
||||
if(ip->type != T_DIR){
|
||||
iunlockput(ip);
|
||||
return 0;
|
||||
}
|
||||
if(nameiparent && *path == '\0'){
|
||||
// Stop one level early.
|
||||
iunlock(ip);
|
||||
return ip;
|
||||
}
|
||||
if((next = dirlookup(ip, name, 0)) == 0){
|
||||
iunlockput(ip);
|
||||
return 0;
|
||||
}
|
||||
iunlockput(ip);
|
||||
ip = next;
|
||||
}
|
||||
if(nameiparent){
|
||||
iput(ip);
|
||||
return 0;
|
||||
}
|
||||
return ip;
|
||||
}
|
||||
|
||||
struct inode*
|
||||
namei(char *path)
|
||||
{
|
||||
char name[DIRSIZ];
|
||||
return namex(path, 0, name);
|
||||
}
|
||||
|
||||
struct inode*
|
||||
nameiparent(char *path, char *name)
|
||||
{
|
||||
return namex(path, 1, name);
|
||||
}
|
||||
57
xv6-public/xv6.si4project/Backup/fs(5757).h
Normal file
57
xv6-public/xv6.si4project/Backup/fs(5757).h
Normal file
@@ -0,0 +1,57 @@
|
||||
// On-disk file system format.
|
||||
// Both the kernel and user programs use this header file.
|
||||
|
||||
|
||||
#define ROOTINO 1 // root i-number
|
||||
#define BSIZE 512 // block size
|
||||
|
||||
// Disk layout:
|
||||
// [ boot block | super block | log | inode blocks |
|
||||
// free bit map | data blocks]
|
||||
//
|
||||
// mkfs computes the super block and builds an initial file system. The
|
||||
// super block describes the disk layout:
|
||||
struct superblock {
|
||||
uint size; // Size of file system image (blocks)
|
||||
uint nblocks; // Number of data blocks
|
||||
uint ninodes; // Number of inodes.
|
||||
uint nlog; // Number of log blocks
|
||||
uint logstart; // Block number of first log block
|
||||
uint inodestart; // Block number of first inode block
|
||||
uint bmapstart; // Block number of first free map block
|
||||
};
|
||||
|
||||
#define NDIRECT 12
|
||||
#define NINDIRECT (BSIZE / sizeof(uint))
|
||||
#define MAXFILE (NDIRECT + NINDIRECT)
|
||||
|
||||
// On-disk inode structure
|
||||
struct dinode {
|
||||
short type; // File type
|
||||
short major; // Major device number (T_DEV only)
|
||||
short minor; // Minor device number (T_DEV only)
|
||||
short nlink; // Number of links to inode in file system
|
||||
uint size; // Size of file (bytes)
|
||||
uint addrs[NDIRECT+1]; // Data block addresses
|
||||
};
|
||||
|
||||
// Inodes per block.
|
||||
#define IPB (BSIZE / sizeof(struct dinode))
|
||||
|
||||
// Block containing inode i
|
||||
#define IBLOCK(i, sb) ((i) / IPB + sb.inodestart)
|
||||
|
||||
// Bitmap bits per block
|
||||
#define BPB (BSIZE*8)
|
||||
|
||||
// Block of free map containing bit for block b
|
||||
#define BBLOCK(b, sb) (b/BPB + sb.bmapstart)
|
||||
|
||||
// Directory is a file containing a sequence of dirent structures.
|
||||
#define DIRSIZ 14
|
||||
|
||||
struct dirent {
|
||||
ushort inum;
|
||||
char name[DIRSIZ];
|
||||
};
|
||||
|
||||
234
xv6-public/xv6.si4project/Backup/log(5899).c
Normal file
234
xv6-public/xv6.si4project/Backup/log(5899).c
Normal file
@@ -0,0 +1,234 @@
|
||||
#include "types.h"
|
||||
#include "defs.h"
|
||||
#include "param.h"
|
||||
#include "spinlock.h"
|
||||
#include "sleeplock.h"
|
||||
#include "fs.h"
|
||||
#include "buf.h"
|
||||
|
||||
// Simple logging that allows concurrent FS system calls.
|
||||
//
|
||||
// A log transaction contains the updates of multiple FS system
|
||||
// calls. The logging system only commits when there are
|
||||
// no FS system calls active. Thus there is never
|
||||
// any reasoning required about whether a commit might
|
||||
// write an uncommitted system call's updates to disk.
|
||||
//
|
||||
// A system call should call begin_op()/end_op() to mark
|
||||
// its start and end. Usually begin_op() just increments
|
||||
// the count of in-progress FS system calls and returns.
|
||||
// But if it thinks the log is close to running out, it
|
||||
// sleeps until the last outstanding end_op() commits.
|
||||
//
|
||||
// The log is a physical re-do log containing disk blocks.
|
||||
// The on-disk log format:
|
||||
// header block, containing block #s for block A, B, C, ...
|
||||
// block A
|
||||
// block B
|
||||
// block C
|
||||
// ...
|
||||
// Log appends are synchronous.
|
||||
|
||||
// Contents of the header block, used for both the on-disk header block
|
||||
// and to keep track in memory of logged block# before commit.
|
||||
struct logheader {
|
||||
int n;
|
||||
int block[LOGSIZE];
|
||||
};
|
||||
|
||||
struct log {
|
||||
struct spinlock lock;
|
||||
int start;
|
||||
int size;
|
||||
int outstanding; // how many FS sys calls are executing.
|
||||
int committing; // in commit(), please wait.
|
||||
int dev;
|
||||
struct logheader lh;
|
||||
};
|
||||
struct log log;
|
||||
|
||||
static void recover_from_log(void);
|
||||
static void commit();
|
||||
|
||||
void
|
||||
initlog(int dev)
|
||||
{
|
||||
if (sizeof(struct logheader) >= BSIZE)
|
||||
panic("initlog: too big logheader");
|
||||
|
||||
struct superblock sb;
|
||||
initlock(&log.lock, "log");
|
||||
readsb(dev, &sb);
|
||||
log.start = sb.logstart;
|
||||
log.size = sb.nlog;
|
||||
log.dev = dev;
|
||||
recover_from_log();
|
||||
}
|
||||
|
||||
// Copy committed blocks from log to their home location
|
||||
static void
|
||||
install_trans(void)
|
||||
{
|
||||
int tail;
|
||||
|
||||
for (tail = 0; tail < log.lh.n; tail++) {
|
||||
struct buf *lbuf = bread(log.dev, log.start+tail+1); // read log block
|
||||
struct buf *dbuf = bread(log.dev, log.lh.block[tail]); // read dst
|
||||
memmove(dbuf->data, lbuf->data, BSIZE); // copy block to dst
|
||||
bwrite(dbuf); // write dst to disk
|
||||
brelse(lbuf);
|
||||
brelse(dbuf);
|
||||
}
|
||||
}
|
||||
|
||||
// Read the log header from disk into the in-memory log header
|
||||
static void
|
||||
read_head(void)
|
||||
{
|
||||
struct buf *buf = bread(log.dev, log.start);
|
||||
struct logheader *lh = (struct logheader *) (buf->data);
|
||||
int i;
|
||||
log.lh.n = lh->n;
|
||||
for (i = 0; i < log.lh.n; i++) {
|
||||
log.lh.block[i] = lh->block[i];
|
||||
}
|
||||
brelse(buf);
|
||||
}
|
||||
|
||||
// Write in-memory log header to disk.
|
||||
// This is the true point at which the
|
||||
// current transaction commits.
|
||||
static void
|
||||
write_head(void)
|
||||
{
|
||||
struct buf *buf = bread(log.dev, log.start);
|
||||
struct logheader *hb = (struct logheader *) (buf->data);
|
||||
int i;
|
||||
hb->n = log.lh.n;
|
||||
for (i = 0; i < log.lh.n; i++) {
|
||||
hb->block[i] = log.lh.block[i];
|
||||
}
|
||||
bwrite(buf);
|
||||
brelse(buf);
|
||||
}
|
||||
|
||||
static void
|
||||
recover_from_log(void)
|
||||
{
|
||||
read_head();
|
||||
install_trans(); // if committed, copy from log to disk
|
||||
log.lh.n = 0;
|
||||
write_head(); // clear the log
|
||||
}
|
||||
|
||||
// called at the start of each FS system call.
|
||||
void
|
||||
begin_op(void)
|
||||
{
|
||||
acquire(&log.lock);
|
||||
while(1){
|
||||
if(log.committing){
|
||||
sleep(&log, &log.lock);
|
||||
} else if(log.lh.n + (log.outstanding+1)*MAXOPBLOCKS > LOGSIZE){
|
||||
// this op might exhaust log space; wait for commit.
|
||||
sleep(&log, &log.lock);
|
||||
} else {
|
||||
log.outstanding += 1;
|
||||
release(&log.lock);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// called at the end of each FS system call.
|
||||
// commits if this was the last outstanding operation.
|
||||
void
|
||||
end_op(void)
|
||||
{
|
||||
int do_commit = 0;
|
||||
|
||||
acquire(&log.lock);
|
||||
log.outstanding -= 1;
|
||||
if(log.committing)
|
||||
panic("log.committing");
|
||||
if(log.outstanding == 0){
|
||||
do_commit = 1;
|
||||
log.committing = 1;
|
||||
} else {
|
||||
// begin_op() may be waiting for log space,
|
||||
// and decrementing log.outstanding has decreased
|
||||
// the amount of reserved space.
|
||||
wakeup(&log);
|
||||
}
|
||||
release(&log.lock);
|
||||
|
||||
if(do_commit){
|
||||
// call commit w/o holding locks, since not allowed
|
||||
// to sleep with locks.
|
||||
commit();
|
||||
acquire(&log.lock);
|
||||
log.committing = 0;
|
||||
wakeup(&log);
|
||||
release(&log.lock);
|
||||
}
|
||||
}
|
||||
|
||||
// Copy modified blocks from cache to log.
|
||||
static void
|
||||
write_log(void)
|
||||
{
|
||||
int tail;
|
||||
|
||||
for (tail = 0; tail < log.lh.n; tail++) {
|
||||
struct buf *to = bread(log.dev, log.start+tail+1); // log block
|
||||
struct buf *from = bread(log.dev, log.lh.block[tail]); // cache block
|
||||
memmove(to->data, from->data, BSIZE);
|
||||
bwrite(to); // write the log
|
||||
brelse(from);
|
||||
brelse(to);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
commit()
|
||||
{
|
||||
if (log.lh.n > 0) {
|
||||
write_log(); // Write modified blocks from cache to log
|
||||
write_head(); // Write header to disk -- the real commit
|
||||
install_trans(); // Now install writes to home locations
|
||||
log.lh.n = 0;
|
||||
write_head(); // Erase the transaction from the log
|
||||
}
|
||||
}
|
||||
|
||||
// Caller has modified b->data and is done with the buffer.
|
||||
// Record the block number and pin in the cache with B_DIRTY.
|
||||
// commit()/write_log() will do the disk write.
|
||||
//
|
||||
// log_write() replaces bwrite(); a typical use is:
|
||||
// bp = bread(...)
|
||||
// modify bp->data[]
|
||||
// log_write(bp)
|
||||
// brelse(bp)
|
||||
void
|
||||
log_write(struct buf *b)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (log.lh.n >= LOGSIZE || log.lh.n >= log.size - 1)
|
||||
panic("too big a transaction");
|
||||
if (log.outstanding < 1)
|
||||
panic("log_write outside of trans");
|
||||
|
||||
acquire(&log.lock);
|
||||
for (i = 0; i < log.lh.n; i++) {
|
||||
if (log.lh.block[i] == b->blockno) // log absorbtion
|
||||
break;
|
||||
}
|
||||
log.lh.block[i] = b->blockno;
|
||||
if (i == log.lh.n)
|
||||
log.lh.n++;
|
||||
b->flags |= B_DIRTY; // prevent eviction
|
||||
release(&log.lock);
|
||||
}
|
||||
|
||||
14
xv6-public/xv6.si4project/Backup/param(1678).h
Normal file
14
xv6-public/xv6.si4project/Backup/param(1678).h
Normal file
@@ -0,0 +1,14 @@
|
||||
#define NPROC 64 // maximum number of processes
|
||||
#define KSTACKSIZE 4096 // size of per-process kernel stack
|
||||
#define NCPU 8 // maximum number of CPUs
|
||||
#define NOFILE 16 // open files per process
|
||||
#define NFILE 100 // open files per system
|
||||
#define NINODE 50 // maximum number of active i-nodes
|
||||
#define NDEV 10 // maximum major device number
|
||||
#define ROOTDEV 1 // device number of file system root disk
|
||||
#define MAXARG 32 // max exec arguments
|
||||
#define MAXOPBLOCKS 10 // max # of blocks any FS op writes
|
||||
#define LOGSIZE (MAXOPBLOCKS*3) // max data blocks in on-disk log
|
||||
#define NBUF (MAXOPBLOCKS*3) // size of disk block cache
|
||||
#define FSSIZE 1000 // size of file system in blocks
|
||||
|
||||
14
xv6-public/xv6.si4project/Backup/param(8017).h
Normal file
14
xv6-public/xv6.si4project/Backup/param(8017).h
Normal file
@@ -0,0 +1,14 @@
|
||||
#define NPROC 64 // maximum number of processes
|
||||
#define KSTACKSIZE 4096 // size of per-process kernel stack
|
||||
#define NCPU 8 // maximum number of CPUs
|
||||
#define NOFILE 16 // open files per process
|
||||
#define NFILE 100 // open files per system
|
||||
#define NINODE 50 // maximum number of active i-nodes
|
||||
#define NDEV 10 // maximum major device number
|
||||
#define ROOTDEV 1 // device number of file system root disk
|
||||
#define MAXARG 32 // max exec arguments
|
||||
#define MAXOPBLOCKS 10 // max # of blocks any FS op writes
|
||||
#define LOGSIZE (MAXOPBLOCKS*3) // max data blocks in on-disk log
|
||||
#define NBUF (MAXOPBLOCKS*3) // size of disk block cache
|
||||
#define FSSIZE 20000 // size of file system in blocks
|
||||
|
||||
BIN
xv6-public/xv6.si4project/cache/parse/big.c.sisc
vendored
Normal file
BIN
xv6-public/xv6.si4project/cache/parse/big.c.sisc
vendored
Normal file
Binary file not shown.
BIN
xv6-public/xv6.si4project/cache/parse/file.h.sisc
vendored
BIN
xv6-public/xv6.si4project/cache/parse/file.h.sisc
vendored
Binary file not shown.
BIN
xv6-public/xv6.si4project/cache/parse/fs.c.sisc
vendored
BIN
xv6-public/xv6.si4project/cache/parse/fs.c.sisc
vendored
Binary file not shown.
BIN
xv6-public/xv6.si4project/cache/parse/fs.h.sisc
vendored
BIN
xv6-public/xv6.si4project/cache/parse/fs.h.sisc
vendored
Binary file not shown.
BIN
xv6-public/xv6.si4project/cache/parse/log.c.sisc
vendored
BIN
xv6-public/xv6.si4project/cache/parse/log.c.sisc
vendored
Binary file not shown.
BIN
xv6-public/xv6.si4project/cache/parse/param.h.sisc
vendored
BIN
xv6-public/xv6.si4project/cache/parse/param.h.sisc
vendored
Binary file not shown.
@@ -1,4 +1 @@
|
||||
---- sys_write Matches (3 in 2 files) ----
|
||||
syscall.c line 104 : extern int sys_write(void);
|
||||
syscall.c line 126 : [SYS_write] sys_write,
|
||||
sysfile.c line 83 : sys_write(void)
|
||||
---- commit(); Matches (0 in 0 files) ----
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user