Compare commits

...

11 Commits

Author SHA1 Message Date
hheik 4cd2466900 First successful rust library call 2024-04-30 00:23:04 +03:00
hheik f33ef06498 Added basic rust library for testing 2024-04-29 22:56:23 +03:00
hheik 61a7340ea8 Updated .editorconfig 2024-04-29 22:37:09 +03:00
hheik 8102452c7f Formatted *.c files 2024-04-29 22:17:39 +03:00
Frans Kaashoek f5b93ef12f Update acks
61810
2022-08-25 14:20:52 -04:00
Frans Kaashoek 3d6ce9b308 Separate tests in slow and quick. The slow tests run xv6 out of
memory, out of disk space, or test big directories.

Support -q option to run only the quick tests, which saves about
7mins.

Clean up driver by removing duplicated code.
2022-08-25 09:45:35 -04:00
Robert Morris ed101befee comment the sfences 2022-08-24 13:47:47 -04:00
Robert Morris 581bc4cbd1 sfence before enabling paging 2022-08-24 13:42:59 -04:00
Robert Morris 29ce3161f8 Merge branch 'riscv' of g.csail.mit.edu:xv6-dev into riscv 2022-08-24 13:24:37 -04:00
Robert Morris 9c1b8a4eb0 sfence before writing satp, as well as after 2022-08-24 13:24:24 -04:00
Frans Kaashoek cc486ddee0 Help students read this C syntax 2022-08-24 08:57:56 -04:00
55 changed files with 7050 additions and 7683 deletions

5
.cargo/config.toml Normal file
View File

@ -0,0 +1,5 @@
[build]
target = "riscv64gc-unknown-none-elf"
[target.riscv64-unknown-elf]
linker = "/opt/riscv/bin/riscv64-unknown-elf-gcc"

4
.clang-format Normal file
View File

@ -0,0 +1,4 @@
SortIncludes: Never
UseTab: Always
IndentWidth: 4
TabWidth: 4

View File

@ -4,19 +4,4 @@ root = true
[*]
end_of_line = lf
insert_final_newline = true
indent_style = space
indent_size = 4
[*.{c,h}]
indent_size = 2
[*.S]
indent_size = 8
[*.ld]
indent_size = 2
[Makefile]
indent_style = tab
indent_size = 8

1
.rustfmt.toml Normal file
View File

@ -0,0 +1 @@
hard_tabs = true

View File

@ -1,5 +1,8 @@
K=kernel
U=user
R=rust
RTARGET = riscv64gc-unknown-none-elf
OBJS = \
$K/entry.o \
@ -30,6 +33,9 @@ OBJS = \
$K/plic.o \
$K/virtio_disk.o
RLIBS = \
$R/foo/target/$(RTARGET)/release/libfoo.a
# riscv64-unknown-elf- or riscv64-linux-gnu-
# perhaps in /opt/riscv/bin
#TOOLPREFIX =
@ -73,8 +79,8 @@ endif
LDFLAGS = -z max-page-size=4096
$K/kernel: $(OBJS) $K/kernel.ld $U/initcode
$(LD) $(LDFLAGS) -T $K/kernel.ld -o $K/kernel $(OBJS)
$K/kernel: $(OBJS) $K/kernel.ld $U/initcode rustlibs
$(LD) $(LDFLAGS) -T $K/kernel.ld -o $K/kernel $(OBJS) $(RLIBS)
$(OBJDUMP) -S $K/kernel > $K/kernel.asm
$(OBJDUMP) -t $K/kernel | sed '1,/SYMBOL TABLE/d; s/ .* / /; /^$$/d' > $K/kernel.sym
@ -138,6 +144,9 @@ fs.img: mkfs/mkfs README $(UPROGS)
-include kernel/*.d user/*.d
rustlibs:
cargo build -r --manifest-path $R/foo/Cargo.toml
clean:
rm -f *.tex *.dvi *.idx *.aux *.log *.ind *.ilg \
*/*.o */*.d */*.asm */*.sym \
@ -145,6 +154,7 @@ clean:
mkfs/mkfs .gdbinit \
$U/usys.S \
$(UPROGS)
cargo clean --manifest-path $R/foo/Cargo.toml
# try to generate a unique GDB port
GDBPORT = $(shell expr `id -u` % 5000 + 25000)

36
README
View File

@ -6,7 +6,7 @@ ACKNOWLEDGMENTS
xv6 is inspired by John Lions's Commentary on UNIX 6th Edition (Peer
to Peer Communications; ISBN: 1-57398-013-7; 1st edition (June 14,
2000)). See also https://pdos.csail.mit.edu/6.828/, which provides
2000)). See also https://pdos.csail.mit.edu/6.1810/, which provides
pointers to on-line resources for v6.
The following people have made contributions: Russ Cox (context switching,
@ -14,29 +14,31 @@ locking), Cliff Frey (MP), Xiao Yu (MP), Nickolai Zeldovich, and Austin
Clements.
We are also grateful for the bug reports and patches contributed by
Takahiro Aoyagi, Silas Boyd-Wickizer, Anton Burtsev, Ian Chen, Dan
Cross, Cody Cutler, Mike CAT, Tej Chajed, Asami Doi, eyalz800, Nelson
Elhage, Saar Ettinger, Alice Ferrazzi, Nathaniel Filardo, flespark,
Peter Froehlich, Yakir Goaron, Shivam Handa, Matt Harvey, Bryan Henry,
jaichenhengjie, Jim Huang, Matúš Jókay, Alexander Kapshuk, Anders
Kaseorg, kehao95, Wolfgang Keller, Jungwoo Kim, Jonathan Kimmitt,
Eddie Kohler, Vadim Kolontsov, Austin Liew, l0stman, Pavan
Maddamsetti, Imbar Marinescu, Yandong Mao, Matan Shabtay, Hitoshi
Mitake, Carmi Merimovich, Mark Morrissey, mtasm, Joel Nider,
OptimisticSide, Greg Price, Jude Rich, Ayan Shafqat, Eldar Sehayek,
Yongming Shen, Fumiya Shigemitsu, Cam Tenny, tyfkda, Warren Toomey,
Stephen Tu, Rafael Ubal, Amane Uehara, Pablo Ventura, Xi Wang, Keiichi
Watanabe, Nicolas Wolovick, wxdao, Grant Wu, Jindong Zhang, Icenowy
Zheng, ZhUyU1997, and Zou Chang Wei.
Takahiro Aoyagi, Silas Boyd-Wickizer, Anton Burtsev, carlclone, Ian
Chen, Dan Cross, Cody Cutler, Mike CAT, Tej Chajed, Asami Doi,
eyalz800, Nelson Elhage, Saar Ettinger, Alice Ferrazzi, Nathaniel
Filardo, flespark, Peter Froehlich, Yakir Goaron, Shivam Handa, Matt
Harvey, Bryan Henry, jaichenhengjie, Jim Huang, Matúš Jókay, John
Jolly, Alexander Kapshuk, Anders Kaseorg, kehao95, Wolfgang Keller,
Jungwoo Kim, Jonathan Kimmitt, Eddie Kohler, Vadim Kolontsov, Austin
Liew, l0stman, Pavan Maddamsetti, Imbar Marinescu, Yandong Mao, Matan
Shabtay, Hitoshi Mitake, Carmi Merimovich, Mark Morrissey, mtasm, Joel
Nider, Hayato Ohhashi, OptimisticSide, Harry Porter, Greg Price, Jude
Rich, segfault, Ayan Shafqat, Eldar Sehayek, Yongming Shen, Fumiya
Shigemitsu, Cam Tenny, tyfkda, Warren Toomey, Stephen Tu, Rafael Ubal,
Amane Uehara, Pablo Ventura, Xi Wang, WaheedHafez, Keiichi Watanabe,
Nicolas Wolovick, wxdao, Grant Wu, Jindong Zhang, Icenowy Zheng,
ZhUyU1997, and Zou Chang Wei.
The code in the files that constitute xv6 is
Copyright 2006-2020 Frans Kaashoek, Robert Morris, and Russ Cox.
Copyright 2006-2022 Frans Kaashoek, Robert Morris, and Russ Cox.
ERROR REPORTS
Please send errors and suggestions to Frans Kaashoek and Robert Morris
(kaashoek,rtm@mit.edu). The main purpose of xv6 is as a teaching
operating system for MIT's 6.S081, so we are more interested in
operating system for MIT's 6.1810, so we are more interested in
simplifications and clarifications than new features.
BUILDING AND RUNNING XV6

View File

@ -13,7 +13,6 @@
// * Only one process at a time can use a buffer,
// so do not keep them longer than necessary.
#include "types.h"
#include "param.h"
#include "spinlock.h"
@ -33,9 +32,7 @@ struct {
struct buf head;
} bcache;
void
binit(void)
{
void binit(void) {
struct buf *b;
initlock(&bcache.lock, "bcache");
@ -55,9 +52,7 @@ binit(void)
// Look through buffer cache for block on device dev.
// If not found, allocate a buffer.
// In either case, return locked buffer.
static struct buf*
bget(uint dev, uint blockno)
{
static struct buf *bget(uint dev, uint blockno) {
struct buf *b;
acquire(&bcache.lock);
@ -89,9 +84,7 @@ bget(uint dev, uint blockno)
}
// Return a locked buf with the contents of the indicated block.
struct buf*
bread(uint dev, uint blockno)
{
struct buf *bread(uint dev, uint blockno) {
struct buf *b;
b = bget(dev, blockno);
@ -103,9 +96,7 @@ bread(uint dev, uint blockno)
}
// Write b's contents to disk. Must be locked.
void
bwrite(struct buf *b)
{
void bwrite(struct buf *b) {
if (!holdingsleep(&b->lock))
panic("bwrite");
virtio_disk_rw(b, 1);
@ -113,9 +104,7 @@ bwrite(struct buf *b)
// Release a locked buffer.
// Move to the head of the most-recently-used list.
void
brelse(struct buf *b)
{
void brelse(struct buf *b) {
if (!holdingsleep(&b->lock))
panic("brelse");
@ -136,18 +125,14 @@ brelse(struct buf *b)
release(&bcache.lock);
}
void
bpin(struct buf *b) {
void bpin(struct buf *b) {
acquire(&bcache.lock);
b->refcnt++;
release(&bcache.lock);
}
void
bunpin(struct buf *b) {
void bunpin(struct buf *b) {
acquire(&bcache.lock);
b->refcnt--;
release(&bcache.lock);
}

View File

@ -30,12 +30,12 @@
// called by printf(), and to echo input characters,
// but not from write().
//
void
consputc(int c)
{
void consputc(int c) {
if (c == BACKSPACE) {
// if the user typed backspace, overwrite with a space.
uartputc_sync('\b'); uartputc_sync(' '); uartputc_sync('\b');
uartputc_sync('\b');
uartputc_sync(' ');
uartputc_sync('\b');
} else {
uartputc_sync(c);
}
@ -55,9 +55,7 @@ struct {
//
// user write()s to the console go here.
//
int
consolewrite(int user_src, uint64 src, int n)
{
int consolewrite(int user_src, uint64 src, int n) {
int i;
for (i = 0; i < n; i++) {
@ -76,9 +74,7 @@ consolewrite(int user_src, uint64 src, int n)
// user_dist indicates whether dst is a user
// or kernel address.
//
int
consoleread(int user_dst, uint64 dst, int n)
{
int consoleread(int user_dst, uint64 dst, int n) {
uint target;
int c;
char cbuf;
@ -132,9 +128,7 @@ consoleread(int user_dst, uint64 dst, int n)
// do erase/kill processing, append to cons.buf,
// wake up consoleread() if a whole line has arrived.
//
void
consoleintr(int c)
{
void consoleintr(int c) {
acquire(&cons.lock);
switch (c) {
@ -178,9 +172,7 @@ consoleintr(int c)
release(&cons.lock);
}
void
consoleinit(void)
{
void consoleinit(void) {
initlock(&cons.lock, "cons");
uartinit();

View File

@ -9,8 +9,7 @@
static int loadseg(pde_t *, uint64, struct inode *, uint, uint);
int flags2perm(int flags)
{
int flags2perm(int flags) {
int perm = 0;
if (flags & 0x1)
perm = PTE_X;
@ -19,9 +18,7 @@ int flags2perm(int flags)
return perm;
}
int
exec(char *path, char **argv)
{
int exec(char *path, char **argv) {
char *s, *last;
int i, off;
uint64 argc, sz = 0, sp, ustack[MAXARG], stackbase;
@ -62,7 +59,8 @@ exec(char *path, char **argv)
if (ph.vaddr % PGSIZE != 0)
goto bad;
uint64 sz1;
if((sz1 = uvmalloc(pagetable, sz, ph.vaddr + ph.memsz, flags2perm(ph.flags))) == 0)
if ((sz1 = uvmalloc(pagetable, sz, ph.vaddr + ph.memsz,
flags2perm(ph.flags))) == 0)
goto bad;
sz = sz1;
if (loadseg(pagetable, ph.vaddr, ip, ph.off, ph.filesz) < 0)
@ -144,9 +142,8 @@ exec(char *path, char **argv)
// va must be page-aligned
// and the pages from va to va+sz must already be mapped.
// Returns 0 on success, -1 on failure.
static int
loadseg(pagetable_t pagetable, uint64 va, struct inode *ip, uint offset, uint sz)
{
static int loadseg(pagetable_t pagetable, uint64 va, struct inode *ip,
uint offset, uint sz) {
uint i, n;
uint64 pa;

View File

@ -19,16 +19,10 @@ struct {
struct file file[NFILE];
} ftable;
void
fileinit(void)
{
initlock(&ftable.lock, "ftable");
}
void fileinit(void) { initlock(&ftable.lock, "ftable"); }
// Allocate a file structure.
struct file*
filealloc(void)
{
struct file *filealloc(void) {
struct file *f;
acquire(&ftable.lock);
@ -44,9 +38,7 @@ filealloc(void)
}
// Increment ref count for file f.
struct file*
filedup(struct file *f)
{
struct file *filedup(struct file *f) {
acquire(&ftable.lock);
if (f->ref < 1)
panic("filedup");
@ -56,9 +48,7 @@ filedup(struct file *f)
}
// Close file f. (Decrement ref count, close when reaches 0.)
void
fileclose(struct file *f)
{
void fileclose(struct file *f) {
struct file ff;
acquire(&ftable.lock);
@ -84,9 +74,7 @@ fileclose(struct file *f)
// Get metadata about file f.
// addr is a user virtual address, pointing to a struct stat.
int
filestat(struct file *f, uint64 addr)
{
int filestat(struct file *f, uint64 addr) {
struct proc *p = myproc();
struct stat st;
@ -103,9 +91,7 @@ filestat(struct file *f, uint64 addr)
// Read from file f.
// addr is a user virtual address.
int
fileread(struct file *f, uint64 addr, int n)
{
int fileread(struct file *f, uint64 addr, int n) {
int r = 0;
if (f->readable == 0)
@ -131,9 +117,7 @@ fileread(struct file *f, uint64 addr, int n)
// Write to file f.
// addr is a user virtual address.
int
filewrite(struct file *f, uint64 addr, int n)
{
int filewrite(struct file *f, uint64 addr, int n) {
int r, ret = 0;
if (f->writable == 0)
@ -179,4 +163,3 @@ filewrite(struct file *f, uint64 addr, int n)
return ret;
}

View File

@ -27,9 +27,7 @@
struct superblock sb;
// Read the super block.
static void
readsb(int dev, struct superblock *sb)
{
static void readsb(int dev, struct superblock *sb) {
struct buf *bp;
bp = bread(dev, 1);
@ -38,8 +36,7 @@ readsb(int dev, struct superblock *sb)
}
// Init fs
void
fsinit(int dev) {
void fsinit(int dev) {
readsb(dev, &sb);
if (sb.magic != FSMAGIC)
panic("invalid file system");
@ -47,9 +44,7 @@ fsinit(int dev) {
}
// Zero a block.
static void
bzero(int dev, int bno)
{
static void bzero(int dev, int bno) {
struct buf *bp;
bp = bread(dev, bno);
@ -62,9 +57,7 @@ bzero(int dev, int bno)
// Allocate a zeroed disk block.
// returns 0 if out of disk space.
static uint
balloc(uint dev)
{
static uint balloc(uint dev) {
int b, bi, m;
struct buf *bp;
@ -88,9 +81,7 @@ balloc(uint dev)
}
// Free a disk block.
static void
bfree(int dev, uint b)
{
static void bfree(int dev, uint b) {
struct buf *bp;
int bi, m;
@ -178,9 +169,7 @@ struct {
struct inode inode[NINODE];
} itable;
void
iinit()
{
void iinit() {
int i = 0;
initlock(&itable.lock, "itable");
@ -194,10 +183,8 @@ static struct inode* iget(uint dev, uint inum);
// Allocate an inode on device dev.
// Mark it as allocated by giving it type type.
// Returns an unlocked but allocated and referenced inode,
// or NULL if there is no free inode..
struct inode*
ialloc(uint dev, short type)
{
// or NULL if there is no free inode.
struct inode *ialloc(uint dev, short type) {
int inum;
struct buf *bp;
struct dinode *dip;
@ -222,9 +209,7 @@ ialloc(uint dev, short type)
// Must be called after every change to an ip->xxx field
// that lives on disk.
// Caller must hold ip->lock.
void
iupdate(struct inode *ip)
{
void iupdate(struct inode *ip) {
struct buf *bp;
struct dinode *dip;
@ -243,9 +228,7 @@ iupdate(struct inode *ip)
// 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)
{
static struct inode *iget(uint dev, uint inum) {
struct inode *ip, *empty;
acquire(&itable.lock);
@ -278,9 +261,7 @@ iget(uint dev, uint inum)
// Increment reference count for ip.
// Returns ip to enable ip = idup(ip1) idiom.
struct inode*
idup(struct inode *ip)
{
struct inode *idup(struct inode *ip) {
acquire(&itable.lock);
ip->ref++;
release(&itable.lock);
@ -289,9 +270,7 @@ idup(struct inode *ip)
// Lock the given inode.
// Reads the inode from disk if necessary.
void
ilock(struct inode *ip)
{
void ilock(struct inode *ip) {
struct buf *bp;
struct dinode *dip;
@ -317,9 +296,7 @@ ilock(struct inode *ip)
}
// Unlock the given inode.
void
iunlock(struct inode *ip)
{
void iunlock(struct inode *ip) {
if (ip == 0 || !holdingsleep(&ip->lock) || ip->ref < 1)
panic("iunlock");
@ -333,9 +310,7 @@ iunlock(struct inode *ip)
// 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)
{
void iput(struct inode *ip) {
acquire(&itable.lock);
if (ip->ref == 1 && ip->valid && ip->nlink == 0) {
@ -362,9 +337,7 @@ iput(struct inode *ip)
}
// Common idiom: unlock, then put.
void
iunlockput(struct inode *ip)
{
void iunlockput(struct inode *ip) {
iunlock(ip);
iput(ip);
}
@ -379,9 +352,7 @@ iunlockput(struct inode *ip)
// Return the disk block address of the nth block in inode ip.
// If there is no such block, bmap allocates one.
// returns 0 if out of disk space.
static uint
bmap(struct inode *ip, uint bn)
{
static uint bmap(struct inode *ip, uint bn) {
uint addr, *a;
struct buf *bp;
@ -422,9 +393,7 @@ bmap(struct inode *ip, uint bn)
// Truncate inode (discard contents).
// Caller must hold ip->lock.
void
itrunc(struct inode *ip)
{
void itrunc(struct inode *ip) {
int i, j;
struct buf *bp;
uint *a;
@ -454,9 +423,7 @@ itrunc(struct inode *ip)
// Copy stat information from inode.
// Caller must hold ip->lock.
void
stati(struct inode *ip, struct stat *st)
{
void stati(struct inode *ip, struct stat *st) {
st->dev = ip->dev;
st->ino = ip->inum;
st->type = ip->type;
@ -468,9 +435,7 @@ stati(struct inode *ip, struct stat *st)
// Caller must hold ip->lock.
// If user_dst==1, then dst is a user virtual address;
// otherwise, dst is a kernel address.
int
readi(struct inode *ip, int user_dst, uint64 dst, uint off, uint n)
{
int readi(struct inode *ip, int user_dst, uint64 dst, uint off, uint n) {
uint tot, m;
struct buf *bp;
@ -502,9 +467,7 @@ readi(struct inode *ip, int user_dst, uint64 dst, uint off, uint n)
// Returns the number of bytes successfully written.
// If the return value is less than the requested n,
// there was an error of some kind.
int
writei(struct inode *ip, int user_src, uint64 src, uint off, uint n)
{
int writei(struct inode *ip, int user_src, uint64 src, uint off, uint n) {
uint tot, m;
struct buf *bp;
@ -540,17 +503,11 @@ writei(struct inode *ip, int user_src, uint64 src, uint off, uint n)
// Directories
int
namecmp(const char *s, const char *t)
{
return strncmp(s, t, DIRSIZ);
}
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)
{
struct inode *dirlookup(struct inode *dp, char *name, uint *poff) {
uint off, inum;
struct dirent de;
@ -576,9 +533,7 @@ dirlookup(struct inode *dp, char *name, uint *poff)
// Write a new directory entry (name, inum) into the directory dp.
// Returns 0 on success, -1 on failure (e.g. out of disk blocks).
int
dirlink(struct inode *dp, char *name, uint inum)
{
int dirlink(struct inode *dp, char *name, uint inum) {
int off;
struct dirent de;
struct inode *ip;
@ -619,9 +574,7 @@ dirlink(struct inode *dp, char *name, uint inum)
// skipelem("a", name) = "", setting name = "a"
// skipelem("", name) = skipelem("////", name) = 0
//
static char*
skipelem(char *path, char *name)
{
static char *skipelem(char *path, char *name) {
char *s;
int len;
@ -648,9 +601,7 @@ skipelem(char *path, char *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)
{
static struct inode *namex(char *path, int nameiparent, char *name) {
struct inode *ip, *next;
if (*path == '/')
@ -683,15 +634,11 @@ namex(char *path, int nameiparent, char *name)
return ip;
}
struct inode*
namei(char *path)
{
struct inode *namei(char *path) {
char name[DIRSIZ];
return namex(path, 0, name);
}
struct inode*
nameiparent(char *path, char *name)
{
struct inode *nameiparent(char *path, char *name) {
return namex(path, 1, name);
}

View File

@ -23,16 +23,12 @@ struct {
struct run *freelist;
} kmem;
void
kinit()
{
void kinit() {
initlock(&kmem.lock, "kmem");
freerange(end, (void *)PHYSTOP);
}
void
freerange(void *pa_start, void *pa_end)
{
void freerange(void *pa_start, void *pa_end) {
char *p;
p = (char *)PGROUNDUP((uint64)pa_start);
for (; p + PGSIZE <= (char *)pa_end; p += PGSIZE)
@ -43,9 +39,7 @@ freerange(void *pa_start, void *pa_end)
// which normally should have been returned by a
// call to kalloc(). (The exception is when
// initializing the allocator; see kinit above.)
void
kfree(void *pa)
{
void kfree(void *pa) {
struct run *r;
if (((uint64)pa % PGSIZE) != 0 || (char *)pa < end || (uint64)pa >= PHYSTOP)
@ -65,9 +59,7 @@ kfree(void *pa)
// Allocate one 4096-byte page of physical memory.
// Returns a pointer that the kernel can use.
// Returns 0 if the memory cannot be allocated.
void *
kalloc(void)
{
void *kalloc(void) {
struct run *r;
acquire(&kmem.lock);

View File

@ -51,9 +51,7 @@ struct log log;
static void recover_from_log(void);
static void commit();
void
initlog(int dev, struct superblock *sb)
{
void initlog(int dev, struct superblock *sb) {
if (sizeof(struct logheader) >= BSIZE)
panic("initlog: too big logheader");
@ -65,13 +63,12 @@ initlog(int dev, struct superblock *sb)
}
// Copy committed blocks from log to their home location
static void
install_trans(int recovering)
{
static void install_trans(int recovering) {
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
bwrite(dbuf); // write dst to disk
@ -83,9 +80,7 @@ install_trans(int recovering)
}
// Read the log header from disk into the in-memory log header
static void
read_head(void)
{
static void read_head(void) {
struct buf *buf = bread(log.dev, log.start);
struct logheader *lh = (struct logheader *)(buf->data);
int i;
@ -99,9 +94,7 @@ read_head(void)
// Write in-memory log header to disk.
// This is the true point at which the
// current transaction commits.
static void
write_head(void)
{
static void write_head(void) {
struct buf *buf = bread(log.dev, log.start);
struct logheader *hb = (struct logheader *)(buf->data);
int i;
@ -113,9 +106,7 @@ write_head(void)
brelse(buf);
}
static void
recover_from_log(void)
{
static void recover_from_log(void) {
read_head();
install_trans(1); // if committed, copy from log to disk
log.lh.n = 0;
@ -123,9 +114,7 @@ recover_from_log(void)
}
// called at the start of each FS system call.
void
begin_op(void)
{
void begin_op(void) {
acquire(&log.lock);
while (1) {
if (log.committing) {
@ -143,9 +132,7 @@ begin_op(void)
// called at the end of each FS system call.
// commits if this was the last outstanding operation.
void
end_op(void)
{
void end_op(void) {
int do_commit = 0;
acquire(&log.lock);
@ -175,9 +162,7 @@ end_op(void)
}
// Copy modified blocks from cache to log.
static void
write_log(void)
{
static void write_log(void) {
int tail;
for (tail = 0; tail < log.lh.n; tail++) {
@ -190,9 +175,7 @@ write_log(void)
}
}
static void
commit()
{
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
@ -211,9 +194,7 @@ commit()
// modify bp->data[]
// log_write(bp)
// brelse(bp)
void
log_write(struct buf *b)
{
void log_write(struct buf *b) {
int i;
acquire(&log.lock);
@ -233,4 +214,3 @@ log_write(struct buf *b)
}
release(&log.lock);
}

View File

@ -3,19 +3,22 @@
#include "memlayout.h"
#include "riscv.h"
#include "defs.h"
#include <stdint.h>
extern int32_t add(int32_t right, int32_t left);
volatile static int started = 0;
// start() jumps here in supervisor mode on all CPUs.
void
main()
{
void main() {
if (cpuid() == 0) {
consoleinit();
printfinit();
printf("\n");
printf("xv6 kernel is booting\n");
printf("\n");
printf("rust library call: add(1, 2) = %d\n", add(1, 2));
printf("\n");
kinit(); // physical page allocator
kvminit(); // create kernel page table
kvminithart(); // turn on paging

View File

@ -19,9 +19,7 @@ struct pipe {
int writeopen; // write fd is still open
};
int
pipealloc(struct file **f0, struct file **f1)
{
int pipealloc(struct file **f0, struct file **f1) {
struct pipe *pi;
pi = 0;
@ -55,9 +53,7 @@ pipealloc(struct file **f0, struct file **f1)
return -1;
}
void
pipeclose(struct pipe *pi, int writable)
{
void pipeclose(struct pipe *pi, int writable) {
acquire(&pi->lock);
if (writable) {
pi->writeopen = 0;
@ -73,9 +69,7 @@ pipeclose(struct pipe *pi, int writable)
release(&pi->lock);
}
int
pipewrite(struct pipe *pi, uint64 addr, int n)
{
int pipewrite(struct pipe *pi, uint64 addr, int n) {
int i = 0;
struct proc *pr = myproc();
@ -102,9 +96,7 @@ pipewrite(struct pipe *pi, uint64 addr, int n)
return i;
}
int
piperead(struct pipe *pi, uint64 addr, int n)
{
int piperead(struct pipe *pi, uint64 addr, int n) {
int i;
struct proc *pr = myproc();
char ch;

View File

@ -8,17 +8,13 @@
// the riscv Platform Level Interrupt Controller (PLIC).
//
void
plicinit(void)
{
void plicinit(void) {
// set desired IRQ priorities non-zero (otherwise disabled).
*(uint32 *)(PLIC + UART0_IRQ * 4) = 1;
*(uint32 *)(PLIC + VIRTIO0_IRQ * 4) = 1;
}
void
plicinithart(void)
{
void plicinithart(void) {
int hart = cpuid();
// set enable bits for this hart's S-mode
@ -30,18 +26,14 @@ plicinithart(void)
}
// ask the PLIC what interrupt we should serve.
int
plic_claim(void)
{
int plic_claim(void) {
int hart = cpuid();
int irq = *(uint32 *)PLIC_SCLAIM(hart);
return irq;
}
// tell the PLIC we've served this IRQ.
void
plic_complete(int irq)
{
void plic_complete(int irq) {
int hart = cpuid();
*(uint32 *)PLIC_SCLAIM(hart) = irq;
}

View File

@ -25,9 +25,7 @@ static struct {
static char digits[] = "0123456789abcdef";
static void
printint(int xx, int base, int sign)
{
static void printint(int xx, int base, int sign) {
char buf[16];
int i;
uint x;
@ -49,9 +47,7 @@ printint(int xx, int base, int sign)
consputc(buf[i]);
}
static void
printptr(uint64 x)
{
static void printptr(uint64 x) {
int i;
consputc('0');
consputc('x');
@ -60,9 +56,7 @@ printptr(uint64 x)
}
// Print to the console. only understands %d, %x, %p, %s.
void
printf(char *fmt, ...)
{
void printf(char *fmt, ...) {
va_list ap;
int i, c, locking;
char *s;
@ -115,9 +109,7 @@ printf(char *fmt, ...)
release(&pr.lock);
}
void
panic(char *s)
{
void panic(char *s) {
pr.locking = 0;
printf("panic: ");
printf(s);
@ -127,9 +119,7 @@ panic(char *s)
;
}
void
printfinit(void)
{
void printfinit(void) {
initlock(&pr.lock, "pr");
pr.locking = 1;
}

View File

@ -29,9 +29,7 @@ struct spinlock wait_lock;
// Allocate a page for each process's kernel stack.
// Map it high in memory, followed by an invalid
// guard page.
void
proc_mapstacks(pagetable_t kpgtbl)
{
void proc_mapstacks(pagetable_t kpgtbl) {
struct proc *p;
for (p = proc; p < &proc[NPROC]; p++) {
@ -44,9 +42,7 @@ proc_mapstacks(pagetable_t kpgtbl)
}
// initialize the proc table.
void
procinit(void)
{
void procinit(void) {
struct proc *p;
initlock(&pid_lock, "nextpid");
@ -61,27 +57,21 @@ procinit(void)
// Must be called with interrupts disabled,
// to prevent race with process being moved
// to a different CPU.
int
cpuid()
{
int cpuid() {
int id = r_tp();
return id;
}
// Return this CPU's cpu struct.
// Interrupts must be disabled.
struct cpu*
mycpu(void)
{
struct cpu *mycpu(void) {
int id = cpuid();
struct cpu *c = &cpus[id];
return c;
}
// Return the current struct proc *, or zero if none.
struct proc*
myproc(void)
{
struct proc *myproc(void) {
push_off();
struct cpu *c = mycpu();
struct proc *p = c->proc;
@ -89,9 +79,7 @@ myproc(void)
return p;
}
int
allocpid()
{
int allocpid() {
int pid;
acquire(&pid_lock);
@ -106,9 +94,7 @@ allocpid()
// If found, initialize state required to run in the kernel,
// and return with p->lock held.
// If there are no free procs, or a memory allocation fails, return 0.
static struct proc*
allocproc(void)
{
static struct proc *allocproc(void) {
struct proc *p;
for (p = proc; p < &proc[NPROC]; p++) {
@ -152,9 +138,7 @@ found:
// free a proc structure and the data hanging from it,
// including user pages.
// p->lock must be held.
static void
freeproc(struct proc *p)
{
static void freeproc(struct proc *p) {
if (p->trapframe)
kfree((void *)p->trapframe);
p->trapframe = 0;
@ -173,9 +157,7 @@ freeproc(struct proc *p)
// Create a user page table for a given process, with no user memory,
// but with trampoline and trapframe pages.
pagetable_t
proc_pagetable(struct proc *p)
{
pagetable_t proc_pagetable(struct proc *p) {
pagetable_t pagetable;
// An empty page table.
@ -187,16 +169,16 @@ proc_pagetable(struct proc *p)
// at the highest user virtual address.
// only the supervisor uses it, on the way
// to/from user space, so not PTE_U.
if(mappages(pagetable, TRAMPOLINE, PGSIZE,
(uint64)trampoline, PTE_R | PTE_X) < 0){
if (mappages(pagetable, TRAMPOLINE, PGSIZE, (uint64)trampoline,
PTE_R | PTE_X) < 0) {
uvmfree(pagetable, 0);
return 0;
}
// map the trapframe page just below the trampoline page, for
// trampoline.S.
if(mappages(pagetable, TRAPFRAME, PGSIZE,
(uint64)(p->trapframe), PTE_R | PTE_W) < 0){
if (mappages(pagetable, TRAPFRAME, PGSIZE, (uint64)(p->trapframe),
PTE_R | PTE_W) < 0) {
uvmunmap(pagetable, TRAMPOLINE, 1, 0);
uvmfree(pagetable, 0);
return 0;
@ -207,9 +189,7 @@ proc_pagetable(struct proc *p)
// Free a process's page table, and free the
// physical memory it refers to.
void
proc_freepagetable(pagetable_t pagetable, uint64 sz)
{
void proc_freepagetable(pagetable_t pagetable, uint64 sz) {
uvmunmap(pagetable, TRAMPOLINE, 1, 0);
uvmunmap(pagetable, TRAPFRAME, 1, 0);
uvmfree(pagetable, sz);
@ -218,20 +198,15 @@ proc_freepagetable(pagetable_t pagetable, uint64 sz)
// a user program that calls exec("/init")
// assembled from ../user/initcode.S
// od -t xC ../user/initcode
uchar initcode[] = {
0x17, 0x05, 0x00, 0x00, 0x13, 0x05, 0x45, 0x02,
0x97, 0x05, 0x00, 0x00, 0x93, 0x85, 0x35, 0x02,
0x93, 0x08, 0x70, 0x00, 0x73, 0x00, 0x00, 0x00,
0x93, 0x08, 0x20, 0x00, 0x73, 0x00, 0x00, 0x00,
0xef, 0xf0, 0x9f, 0xff, 0x2f, 0x69, 0x6e, 0x69,
0x74, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00
};
uchar initcode[] = {0x17, 0x05, 0x00, 0x00, 0x13, 0x05, 0x45, 0x02, 0x97,
0x05, 0x00, 0x00, 0x93, 0x85, 0x35, 0x02, 0x93, 0x08,
0x70, 0x00, 0x73, 0x00, 0x00, 0x00, 0x93, 0x08, 0x20,
0x00, 0x73, 0x00, 0x00, 0x00, 0xef, 0xf0, 0x9f, 0xff,
0x2f, 0x69, 0x6e, 0x69, 0x74, 0x00, 0x00, 0x24, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
// Set up first user process.
void
userinit(void)
{
void userinit(void) {
struct proc *p;
p = allocproc();
@ -256,9 +231,7 @@ userinit(void)
// Grow or shrink user memory by n bytes.
// Return 0 on success, -1 on failure.
int
growproc(int n)
{
int growproc(int n) {
uint64 sz;
struct proc *p = myproc();
@ -276,9 +249,7 @@ growproc(int n)
// Create a new process, copying the parent.
// Sets up child kernel stack to return as if from fork() system call.
int
fork(void)
{
int fork(void) {
int i, pid;
struct proc *np;
struct proc *p = myproc();
@ -327,9 +298,7 @@ fork(void)
// Pass p's abandoned children to init.
// Caller must hold wait_lock.
void
reparent(struct proc *p)
{
void reparent(struct proc *p) {
struct proc *pp;
for (pp = proc; pp < &proc[NPROC]; pp++) {
@ -343,9 +312,7 @@ reparent(struct proc *p)
// Exit the current process. Does not return.
// An exited process remains in the zombie state
// until its parent calls wait().
void
exit(int status)
{
void exit(int status) {
struct proc *p = myproc();
if (p == initproc)
@ -387,9 +354,7 @@ exit(int status)
// Wait for a child process to exit and return its pid.
// Return -1 if this process has no children.
int
wait(uint64 addr)
{
int wait(uint64 addr) {
struct proc *pp;
int havekids, pid;
struct proc *p = myproc();
@ -408,7 +373,8 @@ wait(uint64 addr)
if (pp->state == ZOMBIE) {
// Found one.
pid = pp->pid;
if(addr != 0 && copyout(p->pagetable, addr, (char *)&pp->xstate,
if (addr != 0 &&
copyout(p->pagetable, addr, (char *)&pp->xstate,
sizeof(pp->xstate)) < 0) {
release(&pp->lock);
release(&wait_lock);
@ -441,9 +407,7 @@ wait(uint64 addr)
// - swtch to start running that process.
// - eventually that process transfers control
// via swtch back to the scheduler.
void
scheduler(void)
{
void scheduler(void) {
struct proc *p;
struct cpu *c = mycpu();
@ -478,9 +442,7 @@ scheduler(void)
// be proc->intena and proc->noff, but that would
// break in the few places where a lock is held but
// there's no process.
void
sched(void)
{
void sched(void) {
int intena;
struct proc *p = myproc();
@ -499,9 +461,7 @@ sched(void)
}
// Give up the CPU for one scheduling round.
void
yield(void)
{
void yield(void) {
struct proc *p = myproc();
acquire(&p->lock);
p->state = RUNNABLE;
@ -511,9 +471,7 @@ yield(void)
// A fork child's very first scheduling by scheduler()
// will swtch to forkret.
void
forkret(void)
{
void forkret(void) {
static int first = 1;
// Still holding p->lock from scheduler.
@ -532,9 +490,7 @@ forkret(void)
// Atomically release lock and sleep on chan.
// Reacquires lock when awakened.
void
sleep(void *chan, struct spinlock *lk)
{
void sleep(void *chan, struct spinlock *lk) {
struct proc *p = myproc();
// Must acquire p->lock in order to
@ -563,9 +519,7 @@ sleep(void *chan, struct spinlock *lk)
// Wake up all processes sleeping on chan.
// Must be called without any p->lock.
void
wakeup(void *chan)
{
void wakeup(void *chan) {
struct proc *p;
for (p = proc; p < &proc[NPROC]; p++) {
@ -582,9 +536,7 @@ wakeup(void *chan)
// Kill the process with the given pid.
// The victim won't exit until it tries to return
// to user space (see usertrap() in trap.c).
int
kill(int pid)
{
int kill(int pid) {
struct proc *p;
for (p = proc; p < &proc[NPROC]; p++) {
@ -603,17 +555,13 @@ kill(int pid)
return -1;
}
void
setkilled(struct proc *p)
{
void setkilled(struct proc *p) {
acquire(&p->lock);
p->killed = 1;
release(&p->lock);
}
int
killed(struct proc *p)
{
int killed(struct proc *p) {
int k;
acquire(&p->lock);
@ -625,9 +573,7 @@ killed(struct proc *p)
// Copy to either a user address, or kernel address,
// depending on usr_dst.
// Returns 0 on success, -1 on error.
int
either_copyout(int user_dst, uint64 dst, void *src, uint64 len)
{
int either_copyout(int user_dst, uint64 dst, void *src, uint64 len) {
struct proc *p = myproc();
if (user_dst) {
return copyout(p->pagetable, dst, src, len);
@ -640,9 +586,7 @@ either_copyout(int user_dst, uint64 dst, void *src, uint64 len)
// Copy from either a user address, or kernel address,
// depending on usr_src.
// Returns 0 on success, -1 on error.
int
either_copyin(void *dst, int user_src, uint64 src, uint64 len)
{
int either_copyin(void *dst, int user_src, uint64 src, uint64 len) {
struct proc *p = myproc();
if (user_src) {
return copyin(p->pagetable, dst, src, len);
@ -655,17 +599,10 @@ either_copyin(void *dst, int user_src, uint64 src, uint64 len)
// 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)
{
void procdump(void) {
static char *states[] = {
[UNUSED] "unused",
[USED] "used",
[SLEEPING] "sleep ",
[RUNNABLE] "runble",
[RUNNING] "run ",
[ZOMBIE] "zombie"
};
[UNUSED] "unused", [USED] "used", [SLEEPING] "sleep ",
[RUNNABLE] "runble", [RUNNING] "run ", [ZOMBIE] "zombie"};
struct proc *p;
char *state;

View File

@ -12,16 +12,11 @@
#include "fs.h"
#include "buf.h"
void
ramdiskinit(void)
{
}
void ramdiskinit(void) {}
// If B_DIRTY is set, write buf to disk, clear B_DIRTY, set B_VALID.
// Else if B_VALID is not set, read buf from disk, set B_VALID.
void
ramdiskrw(struct buf *b)
{
void ramdiskrw(struct buf *b) {
if (!holdingsleep(&b->lock))
panic("ramdiskrw: buf not locked");
if ((b->flags & (B_VALID | B_DIRTY)) == B_VALID)

View File

@ -9,18 +9,14 @@
#include "proc.h"
#include "sleeplock.h"
void
initsleeplock(struct sleeplock *lk, char *name)
{
void initsleeplock(struct sleeplock *lk, char *name) {
initlock(&lk->lk, "sleep lock");
lk->name = name;
lk->locked = 0;
lk->pid = 0;
}
void
acquiresleep(struct sleeplock *lk)
{
void acquiresleep(struct sleeplock *lk) {
acquire(&lk->lk);
while (lk->locked) {
sleep(lk, &lk->lk);
@ -30,9 +26,7 @@ acquiresleep(struct sleeplock *lk)
release(&lk->lk);
}
void
releasesleep(struct sleeplock *lk)
{
void releasesleep(struct sleeplock *lk) {
acquire(&lk->lk);
lk->locked = 0;
lk->pid = 0;
@ -40,9 +34,7 @@ releasesleep(struct sleeplock *lk)
release(&lk->lk);
}
int
holdingsleep(struct sleeplock *lk)
{
int holdingsleep(struct sleeplock *lk) {
int r;
acquire(&lk->lk);
@ -50,6 +42,3 @@ holdingsleep(struct sleeplock *lk)
release(&lk->lk);
return r;
}

View File

@ -8,9 +8,7 @@
#include "proc.h"
#include "defs.h"
void
initlock(struct spinlock *lk, char *name)
{
void initlock(struct spinlock *lk, char *name) {
lk->name = name;
lk->locked = 0;
lk->cpu = 0;
@ -18,9 +16,7 @@ initlock(struct spinlock *lk, char *name)
// Acquire the lock.
// Loops (spins) until the lock is acquired.
void
acquire(struct spinlock *lk)
{
void acquire(struct spinlock *lk) {
push_off(); // disable interrupts to avoid deadlock.
if (holding(lk))
panic("acquire");
@ -43,9 +39,7 @@ acquire(struct spinlock *lk)
}
// Release the lock.
void
release(struct spinlock *lk)
{
void release(struct spinlock *lk) {
if (!holding(lk))
panic("release");
@ -73,9 +67,7 @@ release(struct spinlock *lk)
// Check whether this cpu is holding the lock.
// Interrupts must be off.
int
holding(struct spinlock *lk)
{
int holding(struct spinlock *lk) {
int r;
r = (lk->locked && lk->cpu == mycpu());
return r;
@ -85,9 +77,7 @@ holding(struct spinlock *lk)
// it takes two pop_off()s to undo two push_off()s. Also, if interrupts
// are initially off, then push_off, pop_off leaves them off.
void
push_off(void)
{
void push_off(void) {
int old = intr_get();
intr_off();
@ -96,9 +86,7 @@ push_off(void)
mycpu()->noff += 1;
}
void
pop_off(void)
{
void pop_off(void) {
struct cpu *c = mycpu();
if (intr_get())
panic("pop_off - interruptible");

View File

@ -17,9 +17,7 @@ uint64 timer_scratch[NCPU][5];
extern void timervec();
// entry.S jumps here in machine mode on stack0.
void
start()
{
void start() {
// set M Previous Privilege mode to Supervisor, for mret.
unsigned long x = r_mstatus();
x &= ~MSTATUS_MPP_MASK;
@ -59,9 +57,7 @@ start()
// at timervec in kernelvec.S,
// which turns them into software interrupts for
// devintr() in trap.c.
void
timerinit()
{
void timerinit() {
// each CPU has a separate source of timer interrupts.
int id = r_mhartid();

View File

@ -1,8 +1,6 @@
#include "types.h"
void*
memset(void *dst, int c, uint n)
{
void *memset(void *dst, int c, uint n) {
char *cdst = (char *)dst;
int i;
for (i = 0; i < n; i++) {
@ -11,9 +9,7 @@ memset(void *dst, int c, uint n)
return dst;
}
int
memcmp(const void *v1, const void *v2, uint n)
{
int memcmp(const void *v1, const void *v2, uint n) {
const uchar *s1, *s2;
s1 = v1;
@ -27,9 +23,7 @@ memcmp(const void *v1, const void *v2, uint n)
return 0;
}
void*
memmove(void *dst, const void *src, uint n)
{
void *memmove(void *dst, const void *src, uint n) {
const char *s;
char *d;
@ -51,15 +45,11 @@ memmove(void *dst, const void *src, uint n)
}
// memcpy exists to placate GCC. Use memmove.
void*
memcpy(void *dst, const void *src, uint n)
{
void *memcpy(void *dst, const void *src, uint n) {
return memmove(dst, src, n);
}
int
strncmp(const char *p, const char *q, uint n)
{
int strncmp(const char *p, const char *q, uint n) {
while (n > 0 && *p && *p == *q)
n--, p++, q++;
if (n == 0)
@ -67,9 +57,7 @@ strncmp(const char *p, const char *q, uint n)
return (uchar)*p - (uchar)*q;
}
char*
strncpy(char *s, const char *t, int n)
{
char *strncpy(char *s, const char *t, int n) {
char *os;
os = s;
@ -81,9 +69,7 @@ strncpy(char *s, const char *t, int n)
}
// Like strncpy but guaranteed to NUL-terminate.
char*
safestrcpy(char *s, const char *t, int n)
{
char *safestrcpy(char *s, const char *t, int n) {
char *os;
os = s;
@ -95,13 +81,10 @@ safestrcpy(char *s, const char *t, int n)
return os;
}
int
strlen(const char *s)
{
int strlen(const char *s) {
int n;
for (n = 0; s[n]; n++)
;
return n;
}

View File

@ -8,11 +8,10 @@
#include "defs.h"
// Fetch the uint64 at addr from the current process.
int
fetchaddr(uint64 addr, uint64 *ip)
{
int fetchaddr(uint64 addr, uint64 *ip) {
struct proc *p = myproc();
if(addr >= p->sz || addr+sizeof(uint64) > p->sz) // both tests needed, in case of overflow
if (addr >= p->sz ||
addr + sizeof(uint64) > p->sz) // both tests needed, in case of overflow
return -1;
if (copyin(p->pagetable, (char *)ip, addr, sizeof(*ip)) != 0)
return -1;
@ -21,18 +20,14 @@ fetchaddr(uint64 addr, uint64 *ip)
// Fetch the nul-terminated string at addr from the current process.
// Returns length of string, not including nul, or -1 for error.
int
fetchstr(uint64 addr, char *buf, int max)
{
int fetchstr(uint64 addr, char *buf, int max) {
struct proc *p = myproc();
if (copyinstr(p->pagetable, buf, addr, max) < 0)
return -1;
return strlen(buf);
}
static uint64
argraw(int n)
{
static uint64 argraw(int n) {
struct proc *p = myproc();
switch (n) {
case 0:
@ -53,32 +48,23 @@ argraw(int n)
}
// Fetch the nth 32-bit system call argument.
void
argint(int n, int *ip)
{
*ip = argraw(n);
}
void argint(int n, int *ip) { *ip = argraw(n); }
// Retrieve an argument as a pointer.
// Doesn't check for legality, since
// copyin/copyout will do that.
void
argaddr(int n, uint64 *ip)
{
*ip = argraw(n);
}
void argaddr(int n, uint64 *ip) { *ip = argraw(n); }
// Fetch the nth word-sized system call argument as a null-terminated string.
// Copies into buf, at most max.
// Returns string length if OK (including nul), -1 if error.
int
argstr(int n, char *buf, int max)
{
int argstr(int n, char *buf, int max) {
uint64 addr;
argaddr(n, &addr);
return fetchstr(addr, buf, max);
}
// Prototypes for the functions that handle system calls.
extern uint64 sys_fork(void);
extern uint64 sys_exit(void);
extern uint64 sys_wait(void);
@ -101,42 +87,29 @@ extern uint64 sys_link(void);
extern uint64 sys_mkdir(void);
extern uint64 sys_close(void);
// An array mapping syscall numbers from syscall.h
// to the function that handles the system call.
static uint64 (*syscalls[])(void) = {
[SYS_fork] sys_fork,
[SYS_exit] sys_exit,
[SYS_wait] sys_wait,
[SYS_pipe] sys_pipe,
[SYS_read] sys_read,
[SYS_kill] sys_kill,
[SYS_exec] sys_exec,
[SYS_fstat] sys_fstat,
[SYS_chdir] sys_chdir,
[SYS_dup] sys_dup,
[SYS_getpid] sys_getpid,
[SYS_sbrk] sys_sbrk,
[SYS_sleep] sys_sleep,
[SYS_uptime] sys_uptime,
[SYS_open] sys_open,
[SYS_write] sys_write,
[SYS_mknod] sys_mknod,
[SYS_unlink] sys_unlink,
[SYS_link] sys_link,
[SYS_mkdir] sys_mkdir,
[SYS_close] sys_close,
[SYS_fork] sys_fork, [SYS_exit] sys_exit, [SYS_wait] sys_wait,
[SYS_pipe] sys_pipe, [SYS_read] sys_read, [SYS_kill] sys_kill,
[SYS_exec] sys_exec, [SYS_fstat] sys_fstat, [SYS_chdir] sys_chdir,
[SYS_dup] sys_dup, [SYS_getpid] sys_getpid, [SYS_sbrk] sys_sbrk,
[SYS_sleep] sys_sleep, [SYS_uptime] sys_uptime, [SYS_open] sys_open,
[SYS_write] sys_write, [SYS_mknod] sys_mknod, [SYS_unlink] sys_unlink,
[SYS_link] sys_link, [SYS_mkdir] sys_mkdir, [SYS_close] sys_close,
};
void
syscall(void)
{
void syscall(void) {
int num;
struct proc *p = myproc();
num = p->trapframe->a7;
if (num > 0 && num < NELEM(syscalls) && syscalls[num]) {
// Use num to lookup the system call function for num, call it,
// and store its return value in p->trapframe->a0
p->trapframe->a0 = syscalls[num]();
} else {
printf("%d %s: unknown sys call %d\n",
p->pid, p->name, num);
printf("%d %s: unknown sys call %d\n", p->pid, p->name, num);
p->trapframe->a0 = -1;
}
}

View File

@ -18,9 +18,7 @@
// Fetch the nth word-sized system call argument as a file descriptor
// and return both the descriptor and the corresponding struct file.
static int
argfd(int n, int *pfd, struct file **pf)
{
static int argfd(int n, int *pfd, struct file **pf) {
int fd;
struct file *f;
@ -36,9 +34,7 @@ argfd(int n, int *pfd, struct file **pf)
// Allocate a file descriptor for the given file.
// Takes over file reference from caller on success.
static int
fdalloc(struct file *f)
{
static int fdalloc(struct file *f) {
int fd;
struct proc *p = myproc();
@ -51,9 +47,7 @@ fdalloc(struct file *f)
return -1;
}
uint64
sys_dup(void)
{
uint64 sys_dup(void) {
struct file *f;
int fd;
@ -65,9 +59,7 @@ sys_dup(void)
return fd;
}
uint64
sys_read(void)
{
uint64 sys_read(void) {
struct file *f;
int n;
uint64 p;
@ -79,9 +71,7 @@ sys_read(void)
return fileread(f, p, n);
}
uint64
sys_write(void)
{
uint64 sys_write(void) {
struct file *f;
int n;
uint64 p;
@ -94,9 +84,7 @@ sys_write(void)
return filewrite(f, p, n);
}
uint64
sys_close(void)
{
uint64 sys_close(void) {
int fd;
struct file *f;
@ -107,9 +95,7 @@ sys_close(void)
return 0;
}
uint64
sys_fstat(void)
{
uint64 sys_fstat(void) {
struct file *f;
uint64 st; // user pointer to struct stat
@ -120,9 +106,7 @@ sys_fstat(void)
}
// Create the path new as a link to the same inode as old.
uint64
sys_link(void)
{
uint64 sys_link(void) {
char name[DIRSIZ], new[MAXPATH], old[MAXPATH];
struct inode *dp, *ip;
@ -170,9 +154,7 @@ bad:
}
// Is the directory dp empty except for "." and ".." ?
static int
isdirempty(struct inode *dp)
{
static int isdirempty(struct inode *dp) {
int off;
struct dirent de;
@ -185,9 +167,7 @@ isdirempty(struct inode *dp)
return 1;
}
uint64
sys_unlink(void)
{
uint64 sys_unlink(void) {
struct inode *ip, *dp;
struct dirent de;
char name[DIRSIZ], path[MAXPATH];
@ -242,9 +222,7 @@ bad:
return -1;
}
static struct inode*
create(char *path, short type, short major, short minor)
{
static struct inode *create(char *path, short type, short major, short minor) {
struct inode *ip, *dp;
char name[DIRSIZ];
@ -301,9 +279,7 @@ create(char *path, short type, short major, short minor)
return 0;
}
uint64
sys_open(void)
{
uint64 sys_open(void) {
char path[MAXPATH];
int fd, omode;
struct file *f;
@ -370,9 +346,7 @@ sys_open(void)
return fd;
}
uint64
sys_mkdir(void)
{
uint64 sys_mkdir(void) {
char path[MAXPATH];
struct inode *ip;
@ -386,9 +360,7 @@ sys_mkdir(void)
return 0;
}
uint64
sys_mknod(void)
{
uint64 sys_mknod(void) {
struct inode *ip;
char path[MAXPATH];
int major, minor;
@ -406,9 +378,7 @@ sys_mknod(void)
return 0;
}
uint64
sys_chdir(void)
{
uint64 sys_chdir(void) {
char path[MAXPATH];
struct inode *ip;
struct proc *p = myproc();
@ -431,9 +401,7 @@ sys_chdir(void)
return 0;
}
uint64
sys_exec(void)
{
uint64 sys_exec(void) {
char path[MAXPATH], *argv[MAXARG];
int i;
uint64 uargv, uarg;
@ -474,9 +442,7 @@ sys_exec(void)
return -1;
}
uint64
sys_pipe(void)
{
uint64 sys_pipe(void) {
uint64 fdarray; // user pointer to array of two integers
struct file *rf, *wf;
int fd0, fd1;
@ -494,7 +460,8 @@ sys_pipe(void)
return -1;
}
if (copyout(p->pagetable, fdarray, (char *)&fd0, sizeof(fd0)) < 0 ||
copyout(p->pagetable, fdarray+sizeof(fd0), (char *)&fd1, sizeof(fd1)) < 0){
copyout(p->pagetable, fdarray + sizeof(fd0), (char *)&fd1,
sizeof(fd1)) < 0) {
p->ofile[fd0] = 0;
p->ofile[fd1] = 0;
fileclose(rf);

View File

@ -6,38 +6,24 @@
#include "spinlock.h"
#include "proc.h"
uint64
sys_exit(void)
{
uint64 sys_exit(void) {
int n;
argint(0, &n);
exit(n);
return 0; // not reached
}
uint64
sys_getpid(void)
{
return myproc()->pid;
}
uint64 sys_getpid(void) { return myproc()->pid; }
uint64
sys_fork(void)
{
return fork();
}
uint64 sys_fork(void) { return fork(); }
uint64
sys_wait(void)
{
uint64 sys_wait(void) {
uint64 p;
argaddr(0, &p);
return wait(p);
}
uint64
sys_sbrk(void)
{
uint64 sys_sbrk(void) {
uint64 addr;
int n;
@ -48,9 +34,7 @@ sys_sbrk(void)
return addr;
}
uint64
sys_sleep(void)
{
uint64 sys_sleep(void) {
int n;
uint ticks0;
@ -68,9 +52,7 @@ sys_sleep(void)
return 0;
}
uint64
sys_kill(void)
{
uint64 sys_kill(void) {
int pid;
argint(0, &pid);
@ -79,9 +61,7 @@ sys_kill(void)
// return how many clock tick interrupts have occurred
// since start.
uint64
sys_uptime(void)
{
uint64 sys_uptime(void) {
uint xticks;
acquire(&tickslock);

View File

@ -80,9 +80,18 @@ uservec:
# load the address of usertrap(), from p->trapframe->kernel_trap
ld t0, 16(a0)
# load the kernel page table, from p->trapframe->kernel_satp
# fetch the kernel page table address, from p->trapframe->kernel_satp.
ld t1, 0(a0)
# wait for any previous memory operations to complete, so that
# they use the user page table.
sfence.vma zero, zero
# install the kernel page table.
csrw satp, t1
# flush now-stale user entries from the TLB.
sfence.vma zero, zero
# jump to usertrap(), which does not return
@ -96,6 +105,7 @@ userret:
# a0: user page table, for satp.
# switch to the user page table.
sfence.vma zero, zero
csrw satp, a0
sfence.vma zero, zero

View File

@ -16,26 +16,16 @@ void kernelvec();
extern int devintr();
void
trapinit(void)
{
initlock(&tickslock, "time");
}
void trapinit(void) { initlock(&tickslock, "time"); }
// set up to take exceptions and traps while in the kernel.
void
trapinithart(void)
{
w_stvec((uint64)kernelvec);
}
void trapinithart(void) { w_stvec((uint64)kernelvec); }
//
// handle an interrupt, exception, or system call from user space.
// called from trampoline.S
//
void
usertrap(void)
{
void usertrap(void) {
int which_dev = 0;
if ((r_sstatus() & SSTATUS_SPP) != 0)
@ -86,9 +76,7 @@ usertrap(void)
//
// return to user space
//
void
usertrapret(void)
{
void usertrapret(void) {
struct proc *p = myproc();
// we're about to switch the destination of traps from
@ -131,9 +119,7 @@ usertrapret(void)
// interrupts and exceptions from kernel code go here via kernelvec,
// on whatever the current kernel stack is.
void
kerneltrap()
{
void kerneltrap() {
int which_dev = 0;
uint64 sepc = r_sepc();
uint64 sstatus = r_sstatus();
@ -160,9 +146,7 @@ kerneltrap()
w_sstatus(sstatus);
}
void
clockintr()
{
void clockintr() {
acquire(&tickslock);
ticks++;
wakeup(&ticks);
@ -174,13 +158,10 @@ clockintr()
// returns 2 if timer interrupt,
// 1 if other device,
// 0 if not recognized.
int
devintr()
{
int devintr() {
uint64 scause = r_scause();
if((scause & 0x8000000000000000L) &&
(scause & 0xff) == 9){
if ((scause & 0x8000000000000000L) && (scause & 0xff) == 9) {
// this is a supervisor external interrupt, via PLIC.
// irq indicates which device interrupted.
@ -218,4 +199,3 @@ devintr()
return 0;
}
}

View File

@ -49,9 +49,7 @@ extern volatile int panicked; // from printf.c
void uartstart();
void
uartinit(void)
{
void uartinit(void) {
// disable interrupts.
WriteReg(IER, 0x00);
@ -83,9 +81,7 @@ uartinit(void)
// because it may block, it can't be called
// from interrupts; it's only suitable for use
// by write().
void
uartputc(int c)
{
void uartputc(int c) {
acquire(&uart_tx_lock);
if (panicked) {
@ -103,14 +99,11 @@ uartputc(int c)
release(&uart_tx_lock);
}
// alternate version of uartputc() that doesn't
// use interrupts, for use by kernel printf() and
// to echo characters. it spins waiting for the uart's
// output register to be empty.
void
uartputc_sync(int c)
{
void uartputc_sync(int c) {
push_off();
if (panicked) {
@ -130,9 +123,7 @@ uartputc_sync(int c)
// in the transmit buffer, send it.
// caller must hold uart_tx_lock.
// called from both the top- and bottom-half.
void
uartstart()
{
void uartstart() {
while (1) {
if (uart_tx_w == uart_tx_r) {
// transmit buffer is empty.
@ -158,9 +149,7 @@ uartstart()
// read one input character from the UART.
// return -1 if none is waiting.
int
uartgetc(void)
{
int uartgetc(void) {
if (ReadReg(LSR) & 0x01) {
// input data is ready.
return ReadReg(RHR);
@ -172,9 +161,7 @@ uartgetc(void)
// handle a uart interrupt, raised because input has
// arrived, or the uart is ready for more output, or
// both. called from devintr().
void
uartintr(void)
{
void uartintr(void) {
// read and process incoming characters.
while (1) {
int c = uartgetc();

View File

@ -2,7 +2,8 @@
// driver for qemu's virtio disk device.
// uses qemu's mmio interface to virtio.
//
// qemu ... -drive file=fs.img,if=none,format=raw,id=x0 -device virtio-blk-device,drive=x0,bus=virtio-mmio-bus.0
// qemu ... -drive file=fs.img,if=none,format=raw,id=x0 -device
// virtio-blk-device,drive=x0,bus=virtio-mmio-bus.0
//
#include "types.h"
@ -58,16 +59,13 @@ static struct disk {
} disk;
void
virtio_disk_init(void)
{
void virtio_disk_init(void) {
uint32 status = 0;
initlock(&disk.vdisk_lock, "virtio_disk");
if (*R(VIRTIO_MMIO_MAGIC_VALUE) != 0x74726976 ||
*R(VIRTIO_MMIO_VERSION) != 2 ||
*R(VIRTIO_MMIO_DEVICE_ID) != 2 ||
*R(VIRTIO_MMIO_VERSION) != 2 || *R(VIRTIO_MMIO_DEVICE_ID) != 2 ||
*R(VIRTIO_MMIO_VENDOR_ID) != 0x554d4551) {
panic("could not find virtio disk");
}
@ -153,9 +151,7 @@ virtio_disk_init(void)
}
// find a free descriptor, mark it non-free, return its index.
static int
alloc_desc()
{
static int alloc_desc() {
for (int i = 0; i < NUM; i++) {
if (disk.free[i]) {
disk.free[i] = 0;
@ -166,9 +162,7 @@ alloc_desc()
}
// mark a descriptor as free.
static void
free_desc(int i)
{
static void free_desc(int i) {
if (i >= NUM)
panic("free_desc 1");
if (disk.free[i])
@ -182,9 +176,7 @@ free_desc(int i)
}
// free a chain of descriptors.
static void
free_chain(int i)
{
static void free_chain(int i) {
while (1) {
int flag = disk.desc[i].flags;
int nxt = disk.desc[i].next;
@ -198,9 +190,7 @@ free_chain(int i)
// allocate three descriptors (they need not be contiguous).
// disk transfers always use three descriptors.
static int
alloc3_desc(int *idx)
{
static int alloc3_desc(int *idx) {
for (int i = 0; i < 3; i++) {
idx[i] = alloc_desc();
if (idx[i] < 0) {
@ -212,9 +202,7 @@ alloc3_desc(int *idx)
return 0;
}
void
virtio_disk_rw(struct buf *b, int write)
{
void virtio_disk_rw(struct buf *b, int write) {
uint64 sector = b->blockno * (BSIZE / 512);
acquire(&disk.vdisk_lock);
@ -291,9 +279,7 @@ virtio_disk_rw(struct buf *b, int write)
release(&disk.vdisk_lock);
}
void
virtio_disk_intr()
{
void virtio_disk_intr() {
acquire(&disk.vdisk_lock);
// the device won't raise another interrupt until we tell it

View File

@ -16,9 +16,7 @@ extern char etext[]; // kernel.ld sets this to end of kernel code.
extern char trampoline[]; // trampoline.S
// Make a direct-map page table for the kernel.
pagetable_t
kvmmake(void)
{
pagetable_t kvmmake(void) {
pagetable_t kpgtbl;
kpgtbl = (pagetable_t)kalloc();
@ -37,7 +35,8 @@ kvmmake(void)
kvmmap(kpgtbl, KERNBASE, KERNBASE, (uint64)etext - KERNBASE, PTE_R | PTE_X);
// map kernel data and the physical RAM we'll make use of.
kvmmap(kpgtbl, (uint64)etext, (uint64)etext, PHYSTOP-(uint64)etext, PTE_R | PTE_W);
kvmmap(kpgtbl, (uint64)etext, (uint64)etext, PHYSTOP - (uint64)etext,
PTE_R | PTE_W);
// map the trampoline for trap entry/exit to
// the highest virtual address in the kernel.
@ -50,18 +49,17 @@ kvmmake(void)
}
// Initialize the one kernel_pagetable
void
kvminit(void)
{
kernel_pagetable = kvmmake();
}
void kvminit(void) { kernel_pagetable = kvmmake(); }
// Switch h/w page table register to the kernel's page table,
// and enable paging.
void
kvminithart()
{
void kvminithart() {
// wait for any previous writes to the page table memory to finish.
sfence_vma();
w_satp(MAKE_SATP(kernel_pagetable));
// flush stale entries from the TLB.
sfence_vma();
}
@ -77,9 +75,7 @@ kvminithart()
// 21..29 -- 9 bits of level-1 index.
// 12..20 -- 9 bits of level-0 index.
// 0..11 -- 12 bits of byte offset within the page.
pte_t *
walk(pagetable_t pagetable, uint64 va, int alloc)
{
pte_t *walk(pagetable_t pagetable, uint64 va, int alloc) {
if (va >= MAXVA)
panic("walk");
@ -100,9 +96,7 @@ walk(pagetable_t pagetable, uint64 va, int alloc)
// Look up a virtual address, return the physical address,
// or 0 if not mapped.
// Can only be used to look up user pages.
uint64
walkaddr(pagetable_t pagetable, uint64 va)
{
uint64 walkaddr(pagetable_t pagetable, uint64 va) {
pte_t *pte;
uint64 pa;
@ -123,9 +117,7 @@ walkaddr(pagetable_t pagetable, uint64 va)
// add a mapping to the kernel page table.
// only used when booting.
// does not flush TLB or enable paging.
void
kvmmap(pagetable_t kpgtbl, uint64 va, uint64 pa, uint64 sz, int perm)
{
void kvmmap(pagetable_t kpgtbl, uint64 va, uint64 pa, uint64 sz, int perm) {
if (mappages(kpgtbl, va, sz, pa, perm) != 0)
panic("kvmmap");
}
@ -134,9 +126,8 @@ kvmmap(pagetable_t kpgtbl, uint64 va, uint64 pa, uint64 sz, int perm)
// physical addresses starting at pa. va and size might not
// be page-aligned. Returns 0 on success, -1 if walk() couldn't
// allocate a needed page-table page.
int
mappages(pagetable_t pagetable, uint64 va, uint64 size, uint64 pa, int perm)
{
int mappages(pagetable_t pagetable, uint64 va, uint64 size, uint64 pa,
int perm) {
uint64 a, last;
pte_t *pte;
@ -162,9 +153,7 @@ mappages(pagetable_t pagetable, uint64 va, uint64 size, uint64 pa, int perm)
// Remove npages of mappings starting from va. va must be
// page-aligned. The mappings must exist.
// Optionally free the physical memory.
void
uvmunmap(pagetable_t pagetable, uint64 va, uint64 npages, int do_free)
{
void uvmunmap(pagetable_t pagetable, uint64 va, uint64 npages, int do_free) {
uint64 a;
pte_t *pte;
@ -188,9 +177,7 @@ uvmunmap(pagetable_t pagetable, uint64 va, uint64 npages, int do_free)
// create an empty user page table.
// returns 0 if out of memory.
pagetable_t
uvmcreate()
{
pagetable_t uvmcreate() {
pagetable_t pagetable;
pagetable = (pagetable_t)kalloc();
if (pagetable == 0)
@ -202,9 +189,7 @@ uvmcreate()
// Load the user initcode into address 0 of pagetable,
// for the very first process.
// sz must be less than a page.
void
uvmfirst(pagetable_t pagetable, uchar *src, uint sz)
{
void uvmfirst(pagetable_t pagetable, uchar *src, uint sz) {
char *mem;
if (sz >= PGSIZE)
@ -217,9 +202,7 @@ uvmfirst(pagetable_t pagetable, uchar *src, uint sz)
// Allocate PTEs and physical memory to grow process from oldsz to
// newsz, which need not be page aligned. Returns new size or 0 on error.
uint64
uvmalloc(pagetable_t pagetable, uint64 oldsz, uint64 newsz, int xperm)
{
uint64 uvmalloc(pagetable_t pagetable, uint64 oldsz, uint64 newsz, int xperm) {
char *mem;
uint64 a;
@ -234,7 +217,8 @@ uvmalloc(pagetable_t pagetable, uint64 oldsz, uint64 newsz, int xperm)
return 0;
}
memset(mem, 0, PGSIZE);
if(mappages(pagetable, a, PGSIZE, (uint64)mem, PTE_R|PTE_U|xperm) != 0){
if (mappages(pagetable, a, PGSIZE, (uint64)mem,
PTE_R | PTE_U | xperm) != 0) {
kfree(mem);
uvmdealloc(pagetable, a, oldsz);
return 0;
@ -247,9 +231,7 @@ uvmalloc(pagetable_t pagetable, uint64 oldsz, uint64 newsz, int xperm)
// newsz. oldsz and newsz need not be page-aligned, nor does newsz
// need to be less than oldsz. oldsz can be larger than the actual
// process size. Returns the new process size.
uint64
uvmdealloc(pagetable_t pagetable, uint64 oldsz, uint64 newsz)
{
uint64 uvmdealloc(pagetable_t pagetable, uint64 oldsz, uint64 newsz) {
if (newsz >= oldsz)
return oldsz;
@ -263,9 +245,7 @@ uvmdealloc(pagetable_t pagetable, uint64 oldsz, uint64 newsz)
// Recursively free page-table pages.
// All leaf mappings must already have been removed.
void
freewalk(pagetable_t pagetable)
{
void freewalk(pagetable_t pagetable) {
// there are 2^9 = 512 PTEs in a page table.
for (int i = 0; i < 512; i++) {
pte_t pte = pagetable[i];
@ -283,9 +263,7 @@ freewalk(pagetable_t pagetable)
// Free user memory pages,
// then free page-table pages.
void
uvmfree(pagetable_t pagetable, uint64 sz)
{
void uvmfree(pagetable_t pagetable, uint64 sz) {
if (sz > 0)
uvmunmap(pagetable, 0, PGROUNDUP(sz) / PGSIZE, 1);
freewalk(pagetable);
@ -297,9 +275,7 @@ uvmfree(pagetable_t pagetable, uint64 sz)
// physical memory.
// returns 0 on success, -1 on failure.
// frees any allocated pages on failure.
int
uvmcopy(pagetable_t old, pagetable_t new, uint64 sz)
{
int uvmcopy(pagetable_t old, pagetable_t new, uint64 sz) {
pte_t *pte;
uint64 pa, i;
uint flags;
@ -329,9 +305,7 @@ uvmcopy(pagetable_t old, pagetable_t new, uint64 sz)
// mark a PTE invalid for user access.
// used by exec for the user stack guard page.
void
uvmclear(pagetable_t pagetable, uint64 va)
{
void uvmclear(pagetable_t pagetable, uint64 va) {
pte_t *pte;
pte = walk(pagetable, va, 0);
@ -343,9 +317,7 @@ uvmclear(pagetable_t pagetable, uint64 va)
// Copy from kernel to user.
// Copy len bytes from src to virtual address dstva in a given page table.
// Return 0 on success, -1 on error.
int
copyout(pagetable_t pagetable, uint64 dstva, char *src, uint64 len)
{
int copyout(pagetable_t pagetable, uint64 dstva, char *src, uint64 len) {
uint64 n, va0, pa0;
while (len > 0) {
@ -368,9 +340,7 @@ copyout(pagetable_t pagetable, uint64 dstva, char *src, uint64 len)
// Copy from user to kernel.
// Copy len bytes to dst from virtual address srcva in a given page table.
// Return 0 on success, -1 on error.
int
copyin(pagetable_t pagetable, char *dst, uint64 srcva, uint64 len)
{
int copyin(pagetable_t pagetable, char *dst, uint64 srcva, uint64 len) {
uint64 n, va0, pa0;
while (len > 0) {
@ -394,9 +364,7 @@ copyin(pagetable_t pagetable, char *dst, uint64 srcva, uint64 len)
// Copy bytes to dst from virtual address srcva in a given page table,
// until a '\0', or max.
// Return 0 on success, -1 on error.
int
copyinstr(pagetable_t pagetable, char *dst, uint64 srcva, uint64 max)
{
int copyinstr(pagetable_t pagetable, char *dst, uint64 srcva, uint64 max) {
uint64 n, va0, pa0;
int got_null = 0;

View File

@ -12,7 +12,12 @@
#include "kernel/param.h"
#ifndef static_assert
#define static_assert(a, b) do { switch (0) case 0: case (a): ; } while (0)
#define static_assert(a, b) \
do { \
switch (0) \
case 0: \
case (a):; \
} while (0)
#endif
#define NINODES 200
@ -32,7 +37,6 @@ char zeroes[BSIZE];
uint freeinode = 1;
uint freeblock;
void balloc(int);
void wsect(uint, void *);
void winode(uint, struct dinode *);
@ -43,9 +47,7 @@ void iappend(uint inum, void *p, int n);
void die(const char *);
// convert to riscv byte order
ushort
xshort(ushort x)
{
ushort xshort(ushort x) {
ushort y;
uchar *a = (uchar *)&y;
a[0] = x;
@ -53,9 +55,7 @@ xshort(ushort x)
return y;
}
uint
xint(uint x)
{
uint xint(uint x) {
uint y;
uchar *a = (uchar *)&y;
a[0] = x;
@ -65,16 +65,13 @@ xint(uint x)
return y;
}
int
main(int argc, char *argv[])
{
int main(int argc, char *argv[]) {
int i, cc, fd;
uint rootino, inum, off;
struct dirent de;
char buf[BSIZE];
struct dinode din;
static_assert(sizeof(int) == 4, "Integers must be 4 bytes!");
if (argc < 2) {
@ -102,7 +99,8 @@ main(int argc, char *argv[])
sb.inodestart = xint(2 + nlog);
sb.bmapstart = xint(2 + nlog + ninodeblocks);
printf("nmeta %d (boot, super, log blocks %u inode blocks %u, bitmap blocks %u) blocks %d total %d\n",
printf("nmeta %d (boot, super, log blocks %u inode blocks %u, bitmap "
"blocks %u) blocks %d total %d\n",
nmeta, nlog, ninodeblocks, nbitmap, nblocks, FSSIZE);
freeblock = nmeta; // the first free block that we can allocate
@ -172,18 +170,14 @@ main(int argc, char *argv[])
exit(0);
}
void
wsect(uint sec, void *buf)
{
void wsect(uint sec, void *buf) {
if (lseek(fsfd, sec * BSIZE, 0) != sec * BSIZE)
die("lseek");
if (write(fsfd, buf, BSIZE) != BSIZE)
die("write");
}
void
winode(uint inum, struct dinode *ip)
{
void winode(uint inum, struct dinode *ip) {
char buf[BSIZE];
uint bn;
struct dinode *dip;
@ -195,9 +189,7 @@ winode(uint inum, struct dinode *ip)
wsect(bn, buf);
}
void
rinode(uint inum, struct dinode *ip)
{
void rinode(uint inum, struct dinode *ip) {
char buf[BSIZE];
uint bn;
struct dinode *dip;
@ -208,18 +200,14 @@ rinode(uint inum, struct dinode *ip)
*ip = *dip;
}
void
rsect(uint sec, void *buf)
{
void rsect(uint sec, void *buf) {
if (lseek(fsfd, sec * BSIZE, 0) != sec * BSIZE)
die("lseek");
if (read(fsfd, buf, BSIZE) != BSIZE)
die("read");
}
uint
ialloc(ushort type)
{
uint ialloc(ushort type) {
uint inum = freeinode++;
struct dinode din;
@ -231,9 +219,7 @@ ialloc(ushort type)
return inum;
}
void
balloc(int used)
{
void balloc(int used) {
uchar buf[BSIZE];
int i;
@ -249,9 +235,7 @@ balloc(int used)
#define min(a, b) ((a) < (b) ? (a) : (b))
void
iappend(uint inum, void *xp, int n)
{
void iappend(uint inum, void *xp, int n) {
char *p = (char *)xp;
uint fbn, off, n1;
struct dinode din;
@ -293,9 +277,7 @@ iappend(uint inum, void *xp, int n)
winode(inum, &din);
}
void
die(const char *s)
{
void die(const char *s) {
perror(s);
exit(1);
}

1
rust/foo/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/target

7
rust/foo/Cargo.lock generated Normal file
View File

@ -0,0 +1,7 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "foo"
version = "0.1.0"

14
rust/foo/Cargo.toml Normal file
View File

@ -0,0 +1,14 @@
[package]
name = "foo"
version = "0.1.0"
edition = "2021"
[lib]
crate-type = [ "staticlib" ]
[profile.release]
panic = "abort"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]

13
rust/foo/src/lib.rs Normal file
View File

@ -0,0 +1,13 @@
#![no_std]
#![crate_type = "staticlib"]
#[no_mangle]
pub extern "C" fn add(left: i32, right: i32) -> i32 {
left + right
}
#[panic_handler]
#[no_mangle]
fn panic(_info: &core::panic::PanicInfo) -> ! {
loop {}
}

View File

@ -4,9 +4,7 @@
char buf[512];
void
cat(int fd)
{
void cat(int fd) {
int n;
while ((n = read(fd, buf, sizeof(buf))) > 0) {
@ -21,9 +19,7 @@ cat(int fd)
}
}
int
main(int argc, char *argv[])
{
int main(int argc, char *argv[]) {
int fd, i;
if (argc <= 1) {

View File

@ -2,9 +2,7 @@
#include "kernel/stat.h"
#include "user/user.h"
int
main(int argc, char *argv[])
{
int main(int argc, char *argv[]) {
int i;
for (i = 1; i < argc; i++) {

View File

@ -7,15 +7,9 @@
#define N 1000
void
print(const char *s)
{
write(1, s, strlen(s));
}
void print(const char *s) { write(1, s, strlen(s)); }
void
forktest(void)
{
void forktest(void) {
int n, pid;
print("fork test\n");
@ -48,9 +42,7 @@ forktest(void)
print("fork test OK\n");
}
int
main(void)
{
int main(void) {
forktest();
exit(0);
}

View File

@ -7,9 +7,7 @@
char buf[1024];
int match(char *, char *);
void
grep(char *pattern, int fd)
{
void grep(char *pattern, int fd) {
int n, m;
char *p, *q;
@ -33,9 +31,7 @@ grep(char *pattern, int fd)
}
}
int
main(int argc, char *argv[])
{
int main(int argc, char *argv[]) {
int fd, i;
char *pattern;
@ -68,9 +64,7 @@ main(int argc, char *argv[])
int matchhere(char *, char *);
int matchstar(int, char *, char *);
int
match(char *re, char *text)
{
int match(char *re, char *text) {
if (re[0] == '^')
return matchhere(re + 1, text);
do { // must look at empty string
@ -81,8 +75,7 @@ match(char *re, char *text)
}
// matchhere: search for re at beginning of text
int matchhere(char *re, char *text)
{
int matchhere(char *re, char *text) {
if (re[0] == '\0')
return 1;
if (re[1] == '*')
@ -95,12 +88,10 @@ int matchhere(char *re, char *text)
}
// matchstar: search for c*re at beginning of text
int matchstar(int c, char *re, char *text)
{
int matchstar(int c, char *re, char *text) {
do { // a * matches zero or more instances
if (matchhere(re, text))
return 1;
} while (*text != '\0' && (*text++ == c || c == '.'));
return 0;
}

View File

@ -13,9 +13,7 @@
#include "kernel/riscv.h"
// from FreeBSD.
int
do_rand(unsigned long *ctx)
{
int do_rand(unsigned long *ctx) {
/*
* Compute x = (7^5 * x) mod (2^31 - 1)
* without overflowing 31 bits:
@ -41,15 +39,9 @@ do_rand(unsigned long *ctx)
unsigned long rand_next = 1;
int
rand(void)
{
return (do_rand(&rand_next));
}
int rand(void) { return (do_rand(&rand_next)); }
void
go(int which_child)
{
void go(int which_child) {
int fd = -1;
static char buf[999];
char *break0 = sbrk(0);
@ -286,16 +278,15 @@ go(int which_child)
wait(&st1);
wait(&st2);
if (st1 != 0 || st2 != 0 || strcmp(buf, "hi\n") != 0) {
printf("grind: exec pipeline failed %d %d \"%s\"\n", st1, st2, buf);
printf("grind: exec pipeline failed %d %d \"%s\"\n", st1, st2,
buf);
exit(1);
}
}
}
}
void
iter()
{
void iter() {
unlink("a");
unlink("b");
@ -305,7 +296,7 @@ iter()
exit(1);
}
if (pid1 == 0) {
rand_next = 31;
rand_next ^= 31;
go(0);
exit(0);
}
@ -316,7 +307,7 @@ iter()
exit(1);
}
if (pid2 == 0) {
rand_next = 7177;
rand_next ^= 7177;
go(1);
exit(0);
}
@ -333,9 +324,7 @@ iter()
exit(0);
}
int
main()
{
int main() {
while (1) {
int pid = fork();
if (pid == 0) {
@ -346,5 +335,6 @@ main()
wait(0);
}
sleep(20);
rand_next += 1;
}
}

View File

@ -11,9 +11,7 @@
char *argv[] = {"sh", 0};
int
main(void)
{
int main(void) {
int pid, wpid;
if (open("console", O_RDWR) < 0) {

View File

@ -2,9 +2,7 @@
#include "kernel/stat.h"
#include "user/user.h"
int
main(int argc, char **argv)
{
int main(int argc, char **argv) {
int i;
if (argc < 2) {

View File

@ -2,9 +2,7 @@
#include "kernel/stat.h"
#include "user/user.h"
int
main(int argc, char *argv[])
{
int main(int argc, char *argv[]) {
if (argc != 3) {
fprintf(2, "Usage: ln old new\n");
exit(1);

View File

@ -3,9 +3,7 @@
#include "user/user.h"
#include "kernel/fs.h"
char*
fmtname(char *path)
{
char *fmtname(char *path) {
static char buf[DIRSIZ + 1];
char *p;
@ -22,9 +20,7 @@ fmtname(char *path)
return buf;
}
void
ls(char *path)
{
void ls(char *path) {
char buf[512], *p;
int fd;
struct dirent de;
@ -71,9 +67,7 @@ ls(char *path)
close(fd);
}
int
main(int argc, char *argv[])
{
int main(int argc, char *argv[]) {
int i;
if (argc < 2) {

View File

@ -2,9 +2,7 @@
#include "kernel/stat.h"
#include "user/user.h"
int
main(int argc, char *argv[])
{
int main(int argc, char *argv[]) {
int i;
if (argc < 2) {

View File

@ -6,15 +6,9 @@
static char digits[] = "0123456789ABCDEF";
static void
putc(int fd, char c)
{
write(fd, &c, 1);
}
static void putc(int fd, char c) { write(fd, &c, 1); }
static void
printint(int fd, int xx, int base, int sgn)
{
static void printint(int fd, int xx, int base, int sgn) {
char buf[16];
int i, neg;
uint x;
@ -38,8 +32,7 @@ printint(int fd, int xx, int base, int sgn)
putc(fd, buf[i]);
}
static void
printptr(int fd, uint64 x) {
static void printptr(int fd, uint64 x) {
int i;
putc(fd, '0');
putc(fd, 'x');
@ -48,9 +41,7 @@ printptr(int fd, uint64 x) {
}
// Print to the given fd. Only understands %d, %x, %p, %s.
void
vprintf(int fd, const char *fmt, va_list ap)
{
void vprintf(int fd, const char *fmt, va_list ap) {
char *s;
int c, i, state;
@ -94,18 +85,14 @@ vprintf(int fd, const char *fmt, va_list ap)
}
}
void
fprintf(int fd, const char *fmt, ...)
{
void fprintf(int fd, const char *fmt, ...) {
va_list ap;
va_start(ap, fmt);
vprintf(fd, fmt, ap);
}
void
printf(const char *fmt, ...)
{
void printf(const char *fmt, ...) {
va_list ap;
va_start(ap, fmt);

View File

@ -2,9 +2,7 @@
#include "kernel/stat.h"
#include "user/user.h"
int
main(int argc, char *argv[])
{
int main(int argc, char *argv[]) {
int i;
if (argc < 2) {

View File

@ -55,9 +55,7 @@ struct cmd *parsecmd(char*);
void runcmd(struct cmd *) __attribute__((noreturn));
// Execute cmd. Never returns.
void
runcmd(struct cmd *cmd)
{
void runcmd(struct cmd *cmd) {
int p[2];
struct backcmd *bcmd;
struct execcmd *ecmd;
@ -131,9 +129,7 @@ runcmd(struct cmd *cmd)
exit(0);
}
int
getcmd(char *buf, int nbuf)
{
int getcmd(char *buf, int nbuf) {
write(2, "$ ", 2);
memset(buf, 0, nbuf);
gets(buf, nbuf);
@ -142,9 +138,7 @@ getcmd(char *buf, int nbuf)
return 0;
}
int
main(void)
{
int main(void) {
static char buf[100];
int fd;
@ -172,16 +166,12 @@ main(void)
exit(0);
}
void
panic(char *s)
{
void panic(char *s) {
fprintf(2, "%s\n", s);
exit(1);
}
int
fork1(void)
{
int fork1(void) {
int pid;
pid = fork();
@ -193,9 +183,7 @@ fork1(void)
// PAGEBREAK!
// Constructors
struct cmd*
execcmd(void)
{
struct cmd *execcmd(void) {
struct execcmd *cmd;
cmd = malloc(sizeof(*cmd));
@ -204,9 +192,8 @@ execcmd(void)
return (struct cmd *)cmd;
}
struct cmd*
redircmd(struct cmd *subcmd, char *file, char *efile, int mode, int fd)
{
struct cmd *redircmd(struct cmd *subcmd, char *file, char *efile, int mode,
int fd) {
struct redircmd *cmd;
cmd = malloc(sizeof(*cmd));
@ -220,9 +207,7 @@ redircmd(struct cmd *subcmd, char *file, char *efile, int mode, int fd)
return (struct cmd *)cmd;
}
struct cmd*
pipecmd(struct cmd *left, struct cmd *right)
{
struct cmd *pipecmd(struct cmd *left, struct cmd *right) {
struct pipecmd *cmd;
cmd = malloc(sizeof(*cmd));
@ -233,9 +218,7 @@ pipecmd(struct cmd *left, struct cmd *right)
return (struct cmd *)cmd;
}
struct cmd*
listcmd(struct cmd *left, struct cmd *right)
{
struct cmd *listcmd(struct cmd *left, struct cmd *right) {
struct listcmd *cmd;
cmd = malloc(sizeof(*cmd));
@ -246,9 +229,7 @@ listcmd(struct cmd *left, struct cmd *right)
return (struct cmd *)cmd;
}
struct cmd*
backcmd(struct cmd *subcmd)
{
struct cmd *backcmd(struct cmd *subcmd) {
struct backcmd *cmd;
cmd = malloc(sizeof(*cmd));
@ -263,9 +244,7 @@ backcmd(struct cmd *subcmd)
char whitespace[] = " \t\r\n\v";
char symbols[] = "<|>&;()";
int
gettoken(char **ps, char *es, char **q, char **eq)
{
int gettoken(char **ps, char *es, char **q, char **eq) {
char *s;
int ret;
@ -308,9 +287,7 @@ gettoken(char **ps, char *es, char **q, char **eq)
return ret;
}
int
peek(char **ps, char *es, char *toks)
{
int peek(char **ps, char *es, char *toks) {
char *s;
s = *ps;
@ -325,9 +302,7 @@ struct cmd *parsepipe(char**, char*);
struct cmd *parseexec(char **, char *);
struct cmd *nulterminate(struct cmd *);
struct cmd*
parsecmd(char *s)
{
struct cmd *parsecmd(char *s) {
char *es;
struct cmd *cmd;
@ -342,9 +317,7 @@ parsecmd(char *s)
return cmd;
}
struct cmd*
parseline(char **ps, char *es)
{
struct cmd *parseline(char **ps, char *es) {
struct cmd *cmd;
cmd = parsepipe(ps, es);
@ -359,9 +332,7 @@ parseline(char **ps, char *es)
return cmd;
}
struct cmd*
parsepipe(char **ps, char *es)
{
struct cmd *parsepipe(char **ps, char *es) {
struct cmd *cmd;
cmd = parseexec(ps, es);
@ -372,9 +343,7 @@ parsepipe(char **ps, char *es)
return cmd;
}
struct cmd*
parseredirs(struct cmd *cmd, char **ps, char *es)
{
struct cmd *parseredirs(struct cmd *cmd, char **ps, char *es) {
int tok;
char *q, *eq;
@ -397,9 +366,7 @@ parseredirs(struct cmd *cmd, char **ps, char *es)
return cmd;
}
struct cmd*
parseblock(char **ps, char *es)
{
struct cmd *parseblock(char **ps, char *es) {
struct cmd *cmd;
if (!peek(ps, es, "("))
@ -413,9 +380,7 @@ parseblock(char **ps, char *es)
return cmd;
}
struct cmd*
parseexec(char **ps, char *es)
{
struct cmd *parseexec(char **ps, char *es) {
char *q, *eq;
int tok, argc;
struct execcmd *cmd;
@ -447,9 +412,7 @@ parseexec(char **ps, char *es)
}
// NUL-terminate all the counted strings.
struct cmd*
nulterminate(struct cmd *cmd)
{
struct cmd *nulterminate(struct cmd *cmd) {
int i;
struct backcmd *bcmd;
struct execcmd *ecmd;

View File

@ -13,9 +13,7 @@
#include "kernel/fs.h"
#include "kernel/fcntl.h"
int
main(int argc, char *argv[])
{
int main(int argc, char *argv[]) {
int fd, i;
char path[] = "stressfs0";
char data[512];

View File

@ -6,17 +6,13 @@
//
// wrapper so that it's OK if main() does not call exit().
//
void
_main()
{
void _main() {
extern int main();
main();
exit(0);
}
char*
strcpy(char *s, const char *t)
{
char *strcpy(char *s, const char *t) {
char *os;
os = s;
@ -25,17 +21,13 @@ strcpy(char *s, const char *t)
return os;
}
int
strcmp(const char *p, const char *q)
{
int strcmp(const char *p, const char *q) {
while (*p && *p == *q)
p++, q++;
return (uchar)*p - (uchar)*q;
}
uint
strlen(const char *s)
{
uint strlen(const char *s) {
int n;
for (n = 0; s[n]; n++)
@ -43,9 +35,7 @@ strlen(const char *s)
return n;
}
void*
memset(void *dst, int c, uint n)
{
void *memset(void *dst, int c, uint n) {
char *cdst = (char *)dst;
int i;
for (i = 0; i < n; i++) {
@ -54,18 +44,14 @@ memset(void *dst, int c, uint n)
return dst;
}
char*
strchr(const char *s, char c)
{
char *strchr(const char *s, char c) {
for (; *s; s++)
if (*s == c)
return (char *)s;
return 0;
}
char*
gets(char *buf, int max)
{
char *gets(char *buf, int max) {
int i, cc;
char c;
@ -81,9 +67,7 @@ gets(char *buf, int max)
return buf;
}
int
stat(const char *n, struct stat *st)
{
int stat(const char *n, struct stat *st) {
int fd;
int r;
@ -95,9 +79,7 @@ stat(const char *n, struct stat *st)
return r;
}
int
atoi(const char *s)
{
int atoi(const char *s) {
int n;
n = 0;
@ -106,9 +88,7 @@ atoi(const char *s)
return n;
}
void*
memmove(void *vdst, const void *vsrc, int n)
{
void *memmove(void *vdst, const void *vsrc, int n) {
char *dst;
const char *src;
@ -126,9 +106,7 @@ memmove(void *vdst, const void *vsrc, int n)
return vdst;
}
int
memcmp(const void *s1, const void *s2, uint n)
{
int memcmp(const void *s1, const void *s2, uint n) {
const char *p1 = s1, *p2 = s2;
while (n-- > 0) {
if (*p1 != *p2) {
@ -140,8 +118,6 @@ memcmp(const void *s1, const void *s2, uint n)
return 0;
}
void *
memcpy(void *dst, const void *src, uint n)
{
void *memcpy(void *dst, const void *src, uint n) {
return memmove(dst, src, n);
}

View File

@ -21,9 +21,7 @@ typedef union header Header;
static Header base;
static Header *freep;
void
free(void *ap)
{
void free(void *ap) {
Header *bp, *p;
bp = (Header *)ap - 1;
@ -43,9 +41,7 @@ free(void *ap)
freep = p;
}
static Header*
morecore(uint nu)
{
static Header *morecore(uint nu) {
char *p;
Header *hp;
@ -60,9 +56,7 @@ morecore(uint nu)
return freep;
}
void*
malloc(uint nbytes)
{
void *malloc(uint nbytes) {
Header *p, *prevp;
uint nunits;

File diff suppressed because it is too large Load Diff

View File

@ -4,9 +4,7 @@
char buf[512];
void
wc(int fd, char *name)
{
void wc(int fd, char *name) {
int i, n;
int l, w, c, inword;
@ -32,9 +30,7 @@ wc(int fd, char *name)
printf("%d %d %d %s\n", l, w, c, name);
}
int
main(int argc, char *argv[])
{
int main(int argc, char *argv[]) {
int fd, i;
if (argc <= 1) {

View File

@ -5,9 +5,7 @@
#include "kernel/stat.h"
#include "user/user.h"
int
main(void)
{
int main(void) {
if (fork() > 0)
sleep(5); // Let child exit before parent.
exit(0);