Compare commits

..

No commits in common. "362d5adeb23752dfa6ed5456b72a700bc5752ebe" and "948cfbdb1ff8af3924fe149960824d601df13163" have entirely different histories.

41 changed files with 769 additions and 854 deletions

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.1810/, which provides
2000)). See also https://pdos.csail.mit.edu/6.828/, which provides
pointers to on-line resources for v6.
The following people have made contributions: Russ Cox (context switching,
@ -14,31 +14,29 @@ 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, 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.
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.
The code in the files that constitute xv6 is
Copyright 2006-2022 Frans Kaashoek, Robert Morris, and Russ Cox.
Copyright 2006-2020 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.1810, so we are more interested in
operating system for MIT's 6.S081, so we are more interested in
simplifications and clarifications than new features.
BUILDING AND RUNNING XV6

View file

@ -56,7 +56,7 @@ binit(void)
// If not found, allocate a buffer.
// In either case, return locked buffer.
static struct buf*
bget(u32 dev, u32 blockno)
bget(uint dev, uint blockno)
{
struct buf *b;
@ -90,7 +90,7 @@ bget(u32 dev, u32 blockno)
// Return a locked buf with the contents of the indicated block.
struct buf*
bread(u32 dev, u32 blockno)
bread(uint dev, uint blockno)
{
struct buf *b;

View file

@ -1,12 +1,12 @@
struct buf {
int valid; // has data been read from disk?
int disk; // does disk "own" buf?
u32 dev;
u32 blockno;
uint dev;
uint blockno;
struct sleeplock lock;
u32 refcnt;
uint refcnt;
struct buf *prev; // LRU cache list
struct buf *next;
u8 data[BSIZE];
uchar data[BSIZE];
};

View file

@ -47,16 +47,16 @@ struct {
// input
#define INPUT_BUF_SIZE 128
char buf[INPUT_BUF_SIZE];
u32 r; // Read index
u32 w; // Write index
u32 e; // Edit index
uint r; // Read index
uint w; // Write index
uint e; // Edit index
} cons;
//
// user write()s to the console go here.
//
int
consolewrite(int user_src, u64 src, int n)
consolewrite(int user_src, uint64 src, int n)
{
int i;
@ -77,9 +77,9 @@ consolewrite(int user_src, u64 src, int n)
// or kernel address.
//
int
consoleread(int user_dst, u64 dst, int n)
consoleread(int user_dst, uint64 dst, int n)
{
u32 target;
uint target;
int c;
char cbuf;

View file

@ -11,7 +11,7 @@ struct superblock;
// bio.c
void binit(void);
struct buf* bread(u32, u32);
struct buf* bread(uint, uint);
void brelse(struct buf*);
void bwrite(struct buf*);
void bpin(struct buf*);
@ -30,15 +30,15 @@ struct file* filealloc(void);
void fileclose(struct file*);
struct file* filedup(struct file*);
void fileinit(void);
int fileread(struct file*, u64, int n);
int filestat(struct file*, u64 addr);
int filewrite(struct file*, u64, int n);
int fileread(struct file*, uint64, int n);
int filestat(struct file*, uint64 addr);
int filewrite(struct file*, uint64, int n);
// fs.c
void fsinit(int);
int dirlink(struct inode*, char*, u32);
struct inode* dirlookup(struct inode*, char*, u32*);
struct inode* ialloc(u32, short);
int dirlink(struct inode*, char*, uint);
struct inode* dirlookup(struct inode*, char*, uint*);
struct inode* ialloc(uint, short);
struct inode* idup(struct inode*);
void iinit();
void ilock(struct inode*);
@ -49,9 +49,9 @@ void iupdate(struct inode*);
int namecmp(const char*, const char*);
struct inode* namei(char*);
struct inode* nameiparent(char*, char*);
int readi(struct inode*, int, u64, u32, u32);
int readi(struct inode*, int, uint64, uint, uint);
void stati(struct inode*, struct stat*);
int writei(struct inode*, int, u64, u32, u32);
int writei(struct inode*, int, uint64, uint, uint);
void itrunc(struct inode*);
// ramdisk.c
@ -73,8 +73,8 @@ void end_op(void);
// pipe.c
int pipealloc(struct file**, struct file**);
void pipeclose(struct pipe*, int);
int piperead(struct pipe*, u64, int);
int pipewrite(struct pipe*, u64, int);
int piperead(struct pipe*, uint64, int);
int pipewrite(struct pipe*, uint64, int);
// printf.c
void printf(char*, ...);
@ -88,7 +88,7 @@ int fork(void);
int growproc(int);
void proc_mapstacks(pagetable_t);
pagetable_t proc_pagetable(struct proc *);
void proc_freepagetable(pagetable_t, u64);
void proc_freepagetable(pagetable_t, uint64);
int kill(int);
int killed(struct proc*);
void setkilled(struct proc*);
@ -100,11 +100,11 @@ void scheduler(void) __attribute__((noreturn));
void sched(void);
void sleep(void*, struct spinlock*);
void userinit(void);
int wait(u64);
int wait(uint64);
void wakeup(void*);
void yield(void);
int either_copyout(int user_dst, u64 dst, void *src, u64 len);
int either_copyin(void *dst, int user_src, u64 src, u64 len);
int either_copyout(int user_dst, uint64 dst, void *src, uint64 len);
int either_copyin(void *dst, int user_src, uint64 src, uint64 len);
void procdump(void);
// swtch.S
@ -125,24 +125,24 @@ int holdingsleep(struct sleeplock*);
void initsleeplock(struct sleeplock*, char*);
// string.c
int memcmp(const void*, const void*, u32);
void* memmove(void*, const void*, u32);
void* memset(void*, int, u32);
int memcmp(const void*, const void*, uint);
void* memmove(void*, const void*, uint);
void* memset(void*, int, uint);
char* safestrcpy(char*, const char*, int);
int strlen(const char*);
int strncmp(const char*, const char*, u32);
int strncmp(const char*, const char*, uint);
char* strncpy(char*, const char*, int);
// syscall.c
void argint(int, int*);
int argstr(int, char*, int);
void argaddr(int, u64 *);
int fetchstr(u64, char*, int);
int fetchaddr(u64, u64*);
void argaddr(int, uint64 *);
int fetchstr(uint64, char*, int);
int fetchaddr(uint64, uint64*);
void syscall();
// trap.c
extern u32 ticks;
extern uint ticks;
void trapinit(void);
void trapinithart(void);
extern struct spinlock tickslock;
@ -158,21 +158,21 @@ int uartgetc(void);
// vm.c
void kvminit(void);
void kvminithart(void);
void kvmmap(pagetable_t, u64, u64, u64, int);
int mappages(pagetable_t, u64, u64, u64, int);
void kvmmap(pagetable_t, uint64, uint64, uint64, int);
int mappages(pagetable_t, uint64, uint64, uint64, int);
pagetable_t uvmcreate(void);
void uvmfirst(pagetable_t, u8 *, u32);
u64 uvmalloc(pagetable_t, u64, u64, int);
u64 uvmdealloc(pagetable_t, u64, u64);
int uvmcopy(pagetable_t, pagetable_t, u64);
void uvmfree(pagetable_t, u64);
void uvmunmap(pagetable_t, u64, u64, int);
void uvmclear(pagetable_t, u64);
pte_t * walk(pagetable_t, u64, int);
u64 walkaddr(pagetable_t, u64);
int copyout(pagetable_t, u64, char *, u64);
int copyin(pagetable_t, char *, u64, u64);
int copyinstr(pagetable_t, char *, u64, u64);
void uvmfirst(pagetable_t, uchar *, uint);
uint64 uvmalloc(pagetable_t, uint64, uint64, int);
uint64 uvmdealloc(pagetable_t, uint64, uint64);
int uvmcopy(pagetable_t, pagetable_t, uint64);
void uvmfree(pagetable_t, uint64);
void uvmunmap(pagetable_t, uint64, uint64, int);
void uvmclear(pagetable_t, uint64);
pte_t * walk(pagetable_t, uint64, int);
uint64 walkaddr(pagetable_t, uint64);
int copyout(pagetable_t, uint64, char *, uint64);
int copyin(pagetable_t, char *, uint64, uint64);
int copyinstr(pagetable_t, char *, uint64, uint64);
// plic.c
void plicinit(void);

View file

@ -4,33 +4,33 @@
// File header
struct elfhdr {
u32 magic; // must equal ELF_MAGIC
u8 elf[12];
u16 type;
u16 machine;
u32 version;
u64 entry;
u64 phoff;
u64 shoff;
u32 flags;
u16 ehsize;
u16 phentsize;
u16 phnum;
u16 shentsize;
u16 shnum;
u16 shstrndx;
uint magic; // must equal ELF_MAGIC
uchar elf[12];
ushort type;
ushort machine;
uint version;
uint64 entry;
uint64 phoff;
uint64 shoff;
uint flags;
ushort ehsize;
ushort phentsize;
ushort phnum;
ushort shentsize;
ushort shnum;
ushort shstrndx;
};
// Program section header
struct proghdr {
u32 type;
u32 flags;
u64 off;
u64 vaddr;
u64 paddr;
u64 filesz;
u64 memsz;
u64 align;
uint32 type;
uint32 flags;
uint64 off;
uint64 vaddr;
uint64 paddr;
uint64 filesz;
uint64 memsz;
uint64 align;
};
// Values for Proghdr type

View file

@ -7,7 +7,7 @@
#include "defs.h"
#include "elf.h"
static int loadseg(pde_t *, u64, struct inode *, u32, u32);
static int loadseg(pde_t *, uint64, struct inode *, uint, uint);
int flags2perm(int flags)
{
@ -24,7 +24,7 @@ exec(char *path, char **argv)
{
char *s, *last;
int i, off;
u64 argc, sz = 0, sp, ustack[MAXARG], stackbase;
uint64 argc, sz = 0, sp, ustack[MAXARG], stackbase;
struct elfhdr elf;
struct inode *ip;
struct proghdr ph;
@ -40,7 +40,7 @@ exec(char *path, char **argv)
ilock(ip);
// Check ELF header
if(readi(ip, 0, (u64)&elf, 0, sizeof(elf)) != sizeof(elf))
if(readi(ip, 0, (uint64)&elf, 0, sizeof(elf)) != sizeof(elf))
goto bad;
if(elf.magic != ELF_MAGIC)
@ -51,7 +51,7 @@ exec(char *path, char **argv)
// Load program into memory.
for(i=0, off=elf.phoff; i<elf.phnum; i++, off+=sizeof(ph)){
if(readi(ip, 0, (u64)&ph, off, sizeof(ph)) != sizeof(ph))
if(readi(ip, 0, (uint64)&ph, off, sizeof(ph)) != sizeof(ph))
goto bad;
if(ph.type != ELF_PROG_LOAD)
continue;
@ -61,7 +61,7 @@ exec(char *path, char **argv)
goto bad;
if(ph.vaddr % PGSIZE != 0)
goto bad;
u64 sz1;
uint64 sz1;
if((sz1 = uvmalloc(pagetable, sz, ph.vaddr + ph.memsz, flags2perm(ph.flags))) == 0)
goto bad;
sz = sz1;
@ -73,13 +73,13 @@ exec(char *path, char **argv)
ip = 0;
p = myproc();
u64 oldsz = p->sz;
uint64 oldsz = p->sz;
// Allocate two pages at the next page boundary.
// Make the first inaccessible as a stack guard.
// Use the second as the user stack.
sz = PGROUNDUP(sz);
u64 sz1;
uint64 sz1;
if((sz1 = uvmalloc(pagetable, sz, sz + 2*PGSIZE, PTE_W)) == 0)
goto bad;
sz = sz1;
@ -102,11 +102,11 @@ exec(char *path, char **argv)
ustack[argc] = 0;
// push the array of argv[] pointers.
sp -= (argc+1) * sizeof(u64);
sp -= (argc+1) * sizeof(uint64);
sp -= sp % 16;
if(sp < stackbase)
goto bad;
if(copyout(pagetable, sp, (char *)ustack, (argc+1)*sizeof(u64)) < 0)
if(copyout(pagetable, sp, (char *)ustack, (argc+1)*sizeof(uint64)) < 0)
goto bad;
// arguments to user main(argc, argv)
@ -145,10 +145,10 @@ exec(char *path, char **argv)
// 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, u64 va, struct inode *ip, u32 offset, u32 sz)
loadseg(pagetable_t pagetable, uint64 va, struct inode *ip, uint offset, uint sz)
{
u32 i, n;
u64 pa;
uint i, n;
uint64 pa;
for(i = 0; i < sz; i += PGSIZE){
pa = walkaddr(pagetable, va + i);
@ -158,7 +158,7 @@ loadseg(pagetable_t pagetable, u64 va, struct inode *ip, u32 offset, u32 sz)
n = sz - i;
else
n = PGSIZE;
if(readi(ip, 0, (u64)pa, offset+i, n) != n)
if(readi(ip, 0, (uint64)pa, offset+i, n) != n)
return -1;
}

View file

@ -85,7 +85,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, u64 addr)
filestat(struct file *f, uint64 addr)
{
struct proc *p = myproc();
struct stat st;
@ -104,7 +104,7 @@ filestat(struct file *f, u64 addr)
// Read from file f.
// addr is a user virtual address.
int
fileread(struct file *f, u64 addr, int n)
fileread(struct file *f, uint64 addr, int n)
{
int r = 0;
@ -132,7 +132,7 @@ fileread(struct file *f, u64 addr, int n)
// Write to file f.
// addr is a user virtual address.
int
filewrite(struct file *f, u64 addr, int n)
filewrite(struct file *f, uint64 addr, int n)
{
int r, ret = 0;

View file

@ -5,18 +5,18 @@ struct file {
char writable;
struct pipe *pipe; // FD_PIPE
struct inode *ip; // FD_INODE and FD_DEVICE
u32 off; // FD_INODE
uint off; // FD_INODE
short major; // FD_DEVICE
};
#define major(dev) ((dev) >> 16 & 0xFFFF)
#define minor(dev) ((dev) & 0xFFFF)
#define mkdev(m,n) ((u32)((m)<<16| (n)))
#define mkdev(m,n) ((uint)((m)<<16| (n)))
// in-memory copy of an inode
struct inode {
u32 dev; // Device number
u32 inum; // Inode number
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?
@ -25,14 +25,14 @@ struct inode {
short major;
short minor;
short nlink;
u32 size;
u32 addrs[NDIRECT+1];
uint size;
uint addrs[NDIRECT+1];
};
// map major device number to device functions.
struct devsw {
int (*read)(int, u64, int);
int (*write)(int, u64, int);
int (*read)(int, uint64, int);
int (*write)(int, uint64, int);
};
extern struct devsw devsw[];

View file

@ -62,8 +62,8 @@ bzero(int dev, int bno)
// Allocate a zeroed disk block.
// returns 0 if out of disk space.
static u32
balloc(u32 dev)
static uint
balloc(uint dev)
{
int b, bi, m;
struct buf *bp;
@ -89,7 +89,7 @@ balloc(u32 dev)
// Free a disk block.
static void
bfree(int dev, u32 b)
bfree(int dev, uint b)
{
struct buf *bp;
int bi, m;
@ -189,14 +189,13 @@ iinit()
}
}
static struct inode* iget(u32 dev, u32 inum);
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.
// Returns an unlocked but allocated and referenced inode.
struct inode*
ialloc(u32 dev, short type)
ialloc(uint dev, short type)
{
int inum;
struct buf *bp;
@ -214,8 +213,7 @@ ialloc(u32 dev, short type)
}
brelse(bp);
}
printf("ialloc: no inodes\n");
return 0;
panic("ialloc: no inodes");
}
// Copy a modified in-memory inode to disk.
@ -244,7 +242,7 @@ iupdate(struct inode *ip)
// and return the in-memory copy. Does not lock
// the inode and does not read it from disk.
static struct inode*
iget(u32 dev, u32 inum)
iget(uint dev, uint inum)
{
struct inode *ip, *empty;
@ -379,10 +377,10 @@ 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 u32
bmap(struct inode *ip, u32 bn)
static uint
bmap(struct inode *ip, uint bn)
{
u32 addr, *a;
uint addr, *a;
struct buf *bp;
if(bn < NDIRECT){
@ -405,7 +403,7 @@ bmap(struct inode *ip, u32 bn)
ip->addrs[NDIRECT] = addr;
}
bp = bread(ip->dev, addr);
a = (u32*)bp->data;
a = (uint*)bp->data;
if((addr = a[bn]) == 0){
addr = balloc(ip->dev);
if(addr){
@ -427,7 +425,7 @@ itrunc(struct inode *ip)
{
int i, j;
struct buf *bp;
u32 *a;
uint *a;
for(i = 0; i < NDIRECT; i++){
if(ip->addrs[i]){
@ -438,7 +436,7 @@ itrunc(struct inode *ip)
if(ip->addrs[NDIRECT]){
bp = bread(ip->dev, ip->addrs[NDIRECT]);
a = (u32*)bp->data;
a = (uint*)bp->data;
for(j = 0; j < NINDIRECT; j++){
if(a[j])
bfree(ip->dev, a[j]);
@ -469,9 +467,9 @@ stati(struct inode *ip, struct stat *st)
// 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, u64 dst, u32 off, u32 n)
readi(struct inode *ip, int user_dst, uint64 dst, uint off, uint n)
{
u32 tot, m;
uint tot, m;
struct buf *bp;
if(off > ip->size || off + n < off)
@ -480,7 +478,7 @@ readi(struct inode *ip, int user_dst, u64 dst, u32 off, u32 n)
n = ip->size - off;
for(tot=0; tot<n; tot+=m, off+=m, dst+=m){
u32 addr = bmap(ip, off/BSIZE);
uint addr = bmap(ip, off/BSIZE);
if(addr == 0)
break;
bp = bread(ip->dev, addr);
@ -503,9 +501,9 @@ readi(struct inode *ip, int user_dst, u64 dst, u32 off, u32 n)
// 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, u64 src, u32 off, u32 n)
writei(struct inode *ip, int user_src, uint64 src, uint off, uint n)
{
u32 tot, m;
uint tot, m;
struct buf *bp;
if(off > ip->size || off + n < off)
@ -514,7 +512,7 @@ writei(struct inode *ip, int user_src, u64 src, u32 off, u32 n)
return -1;
for(tot=0; tot<n; tot+=m, off+=m, src+=m){
u32 addr = bmap(ip, off/BSIZE);
uint addr = bmap(ip, off/BSIZE);
if(addr == 0)
break;
bp = bread(ip->dev, addr);
@ -549,16 +547,16 @@ namecmp(const char *s, const char *t)
// 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, u32 *poff)
dirlookup(struct inode *dp, char *name, uint *poff)
{
u32 off, inum;
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, 0, (u64)&de, off, sizeof(de)) != sizeof(de))
if(readi(dp, 0, (uint64)&de, off, sizeof(de)) != sizeof(de))
panic("dirlookup read");
if(de.inum == 0)
continue;
@ -577,7 +575,7 @@ dirlookup(struct inode *dp, char *name, u32 *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, u32 inum)
dirlink(struct inode *dp, char *name, uint inum)
{
int off;
struct dirent de;
@ -591,7 +589,7 @@ dirlink(struct inode *dp, char *name, u32 inum)
// Look for an empty dirent.
for(off = 0; off < dp->size; off += sizeof(de)){
if(readi(dp, 0, (u64)&de, off, sizeof(de)) != sizeof(de))
if(readi(dp, 0, (uint64)&de, off, sizeof(de)) != sizeof(de))
panic("dirlink read");
if(de.inum == 0)
break;
@ -599,7 +597,7 @@ dirlink(struct inode *dp, char *name, u32 inum)
strncpy(de.name, name, DIRSIZ);
de.inum = inum;
if(writei(dp, 0, (u64)&de, off, sizeof(de)) != sizeof(de))
if(writei(dp, 0, (uint64)&de, off, sizeof(de)) != sizeof(de))
return -1;
return 0;

View file

@ -12,20 +12,20 @@
// mkfs computes the super block and builds an initial file system. The
// super block describes the disk layout:
struct superblock {
u32 magic; // Must be FSMAGIC
u32 size; // Size of file system image (blocks)
u32 nblocks; // Number of data blocks
u32 ninodes; // Number of inodes.
u32 nlog; // Number of log blocks
u32 logstart; // Block number of first log block
u32 inodestart; // Block number of first inode block
u32 bmapstart; // Block number of first free map block
uint magic; // Must be FSMAGIC
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 FSMAGIC 0x10203040
#define NDIRECT 12
#define NINDIRECT (BSIZE / sizeof(u32))
#define NINDIRECT (BSIZE / sizeof(uint))
#define MAXFILE (NDIRECT + NINDIRECT)
// On-disk inode structure
@ -34,8 +34,8 @@ struct dinode {
short major; // Major device number (T_DEVICE only)
short minor; // Minor device number (T_DEVICE only)
short nlink; // Number of links to inode in file system
u32 size; // Size of file (bytes)
u32 addrs[NDIRECT+1]; // Data block addresses
uint size; // Size of file (bytes)
uint addrs[NDIRECT+1]; // Data block addresses
};
// Inodes per block.
@ -54,7 +54,7 @@ struct dinode {
#define DIRSIZ 14
struct dirent {
u16 inum;
ushort inum;
char name[DIRSIZ];
};

View file

@ -34,7 +34,7 @@ void
freerange(void *pa_start, void *pa_end)
{
char *p;
p = (char*)PGROUNDUP((u64)pa_start);
p = (char*)PGROUNDUP((uint64)pa_start);
for(; p + PGSIZE <= (char*)pa_end; p += PGSIZE)
kfree(p);
}
@ -48,7 +48,7 @@ kfree(void *pa)
{
struct run *r;
if(((u64)pa % PGSIZE) != 0 || (char*)pa < end || (u64)pa >= PHYSTOP)
if(((uint64)pa % PGSIZE) != 0 || (char*)pa < end || (uint64)pa >= PHYSTOP)
panic("kfree");
// Fill with junk to catch dangling refs.

View file

@ -13,8 +13,8 @@
struct pipe {
struct spinlock lock;
char data[PIPESIZE];
u32 nread; // number of bytes read
u32 nwrite; // number of bytes written
uint nread; // number of bytes read
uint nwrite; // number of bytes written
int readopen; // read fd is still open
int writeopen; // write fd is still open
};
@ -74,7 +74,7 @@ pipeclose(struct pipe *pi, int writable)
}
int
pipewrite(struct pipe *pi, u64 addr, int n)
pipewrite(struct pipe *pi, uint64 addr, int n)
{
int i = 0;
struct proc *pr = myproc();
@ -103,7 +103,7 @@ pipewrite(struct pipe *pi, u64 addr, int n)
}
int
piperead(struct pipe *pi, u64 addr, int n)
piperead(struct pipe *pi, uint64 addr, int n)
{
int i;
struct proc *pr = myproc();

View file

@ -12,8 +12,8 @@ void
plicinit(void)
{
// set desired IRQ priorities non-zero (otherwise disabled).
*(u32*)(PLIC + UART0_IRQ*4) = 1;
*(u32*)(PLIC + VIRTIO0_IRQ*4) = 1;
*(uint32*)(PLIC + UART0_IRQ*4) = 1;
*(uint32*)(PLIC + VIRTIO0_IRQ*4) = 1;
}
void
@ -23,10 +23,10 @@ plicinithart(void)
// set enable bits for this hart's S-mode
// for the uart and virtio disk.
*(u32*)PLIC_SENABLE(hart) = (1 << UART0_IRQ) | (1 << VIRTIO0_IRQ);
*(uint32*)PLIC_SENABLE(hart) = (1 << UART0_IRQ) | (1 << VIRTIO0_IRQ);
// set this hart's S-mode priority threshold to 0.
*(u32*)PLIC_SPRIORITY(hart) = 0;
*(uint32*)PLIC_SPRIORITY(hart) = 0;
}
// ask the PLIC what interrupt we should serve.
@ -34,7 +34,7 @@ int
plic_claim(void)
{
int hart = cpuid();
int irq = *(u32*)PLIC_SCLAIM(hart);
int irq = *(uint32*)PLIC_SCLAIM(hart);
return irq;
}
@ -43,5 +43,5 @@ void
plic_complete(int irq)
{
int hart = cpuid();
*(u32*)PLIC_SCLAIM(hart) = irq;
*(uint32*)PLIC_SCLAIM(hart) = irq;
}

View file

@ -30,7 +30,7 @@ printint(int xx, int base, int sign)
{
char buf[16];
int i;
u32 x;
uint x;
if(sign && (sign = xx < 0))
x = -xx;
@ -50,13 +50,13 @@ printint(int xx, int base, int sign)
}
static void
printptr(u64 x)
printptr(uint64 x)
{
int i;
consputc('0');
consputc('x');
for (i = 0; i < (sizeof(u64) * 2); i++, x <<= 4)
consputc(digits[x >> (sizeof(u64) * 8 - 4)]);
for (i = 0; i < (sizeof(uint64) * 2); i++, x <<= 4)
consputc(digits[x >> (sizeof(uint64) * 8 - 4)]);
}
// Print to the console. only understands %d, %x, %p, %s.
@ -91,7 +91,7 @@ printf(char *fmt, ...)
printint(va_arg(ap, int), 16, 1);
break;
case 'p':
printptr(va_arg(ap, u64));
printptr(va_arg(ap, uint64));
break;
case 's':
if((s = va_arg(ap, char*)) == 0)

View file

@ -38,8 +38,8 @@ proc_mapstacks(pagetable_t kpgtbl)
char *pa = kalloc();
if(pa == 0)
panic("kalloc");
u64 va = KSTACK((int) (p - proc));
kvmmap(kpgtbl, va, (u64)pa, PGSIZE, PTE_R | PTE_W);
uint64 va = KSTACK((int) (p - proc));
kvmmap(kpgtbl, va, (uint64)pa, PGSIZE, PTE_R | PTE_W);
}
}
@ -143,7 +143,7 @@ found:
// Set up new context to start executing at forkret,
// which returns to user space.
memset(&p->context, 0, sizeof(p->context));
p->context.ra = (u64)forkret;
p->context.ra = (uint64)forkret;
p->context.sp = p->kstack + PGSIZE;
return p;
@ -188,7 +188,7 @@ proc_pagetable(struct proc *p)
// only the supervisor uses it, on the way
// to/from user space, so not PTE_U.
if(mappages(pagetable, TRAMPOLINE, PGSIZE,
(u64)trampoline, PTE_R | PTE_X) < 0){
(uint64)trampoline, PTE_R | PTE_X) < 0){
uvmfree(pagetable, 0);
return 0;
}
@ -196,7 +196,7 @@ proc_pagetable(struct proc *p)
// map the trapframe page just below the trampoline page, for
// trampoline.S.
if(mappages(pagetable, TRAPFRAME, PGSIZE,
(u64)(p->trapframe), PTE_R | PTE_W) < 0){
(uint64)(p->trapframe), PTE_R | PTE_W) < 0){
uvmunmap(pagetable, TRAMPOLINE, 1, 0);
uvmfree(pagetable, 0);
return 0;
@ -208,7 +208,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, u64 sz)
proc_freepagetable(pagetable_t pagetable, uint64 sz)
{
uvmunmap(pagetable, TRAMPOLINE, 1, 0);
uvmunmap(pagetable, TRAPFRAME, 1, 0);
@ -218,7 +218,7 @@ proc_freepagetable(pagetable_t pagetable, u64 sz)
// a user program that calls exec("/init")
// assembled from ../user/initcode.S
// od -t xC ../user/initcode
u8 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,
@ -259,7 +259,7 @@ userinit(void)
int
growproc(int n)
{
u64 sz;
uint64 sz;
struct proc *p = myproc();
sz = p->sz;
@ -388,7 +388,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(u64 addr)
wait(uint64 addr)
{
struct proc *pp;
int havekids, pid;
@ -626,7 +626,7 @@ killed(struct proc *p)
// depending on usr_dst.
// Returns 0 on success, -1 on error.
int
either_copyout(int user_dst, u64 dst, void *src, u64 len)
either_copyout(int user_dst, uint64 dst, void *src, uint64 len)
{
struct proc *p = myproc();
if(user_dst){
@ -641,7 +641,7 @@ either_copyout(int user_dst, u64 dst, void *src, u64 len)
// depending on usr_src.
// Returns 0 on success, -1 on error.
int
either_copyin(void *dst, int user_src, u64 src, u64 len)
either_copyin(void *dst, int user_src, uint64 src, uint64 len)
{
struct proc *p = myproc();
if(user_src){

View file

@ -1,21 +1,21 @@
// Saved registers for kernel context switches.
struct context {
u64 ra;
u64 sp;
uint64 ra;
uint64 sp;
// callee-saved
u64 s0;
u64 s1;
u64 s2;
u64 s3;
u64 s4;
u64 s5;
u64 s6;
u64 s7;
u64 s8;
u64 s9;
u64 s10;
u64 s11;
uint64 s0;
uint64 s1;
uint64 s2;
uint64 s3;
uint64 s4;
uint64 s5;
uint64 s6;
uint64 s7;
uint64 s8;
uint64 s9;
uint64 s10;
uint64 s11;
};
// Per-CPU state.
@ -41,42 +41,42 @@ extern struct cpu cpus[NCPU];
// return-to-user path via usertrapret() doesn't return through
// the entire kernel call stack.
struct trapframe {
/* 0 */ u64 kernel_satp; // kernel page table
/* 8 */ u64 kernel_sp; // top of process's kernel stack
/* 16 */ u64 kernel_trap; // usertrap()
/* 24 */ u64 epc; // saved user program counter
/* 32 */ u64 kernel_hartid; // saved kernel tp
/* 40 */ u64 ra;
/* 48 */ u64 sp;
/* 56 */ u64 gp;
/* 64 */ u64 tp;
/* 72 */ u64 t0;
/* 80 */ u64 t1;
/* 88 */ u64 t2;
/* 96 */ u64 s0;
/* 104 */ u64 s1;
/* 112 */ u64 a0;
/* 120 */ u64 a1;
/* 128 */ u64 a2;
/* 136 */ u64 a3;
/* 144 */ u64 a4;
/* 152 */ u64 a5;
/* 160 */ u64 a6;
/* 168 */ u64 a7;
/* 176 */ u64 s2;
/* 184 */ u64 s3;
/* 192 */ u64 s4;
/* 200 */ u64 s5;
/* 208 */ u64 s6;
/* 216 */ u64 s7;
/* 224 */ u64 s8;
/* 232 */ u64 s9;
/* 240 */ u64 s10;
/* 248 */ u64 s11;
/* 256 */ u64 t3;
/* 264 */ u64 t4;
/* 272 */ u64 t5;
/* 280 */ u64 t6;
/* 0 */ uint64 kernel_satp; // kernel page table
/* 8 */ uint64 kernel_sp; // top of process's kernel stack
/* 16 */ uint64 kernel_trap; // usertrap()
/* 24 */ uint64 epc; // saved user program counter
/* 32 */ uint64 kernel_hartid; // saved kernel tp
/* 40 */ uint64 ra;
/* 48 */ uint64 sp;
/* 56 */ uint64 gp;
/* 64 */ uint64 tp;
/* 72 */ uint64 t0;
/* 80 */ uint64 t1;
/* 88 */ uint64 t2;
/* 96 */ uint64 s0;
/* 104 */ uint64 s1;
/* 112 */ uint64 a0;
/* 120 */ uint64 a1;
/* 128 */ uint64 a2;
/* 136 */ uint64 a3;
/* 144 */ uint64 a4;
/* 152 */ uint64 a5;
/* 160 */ uint64 a6;
/* 168 */ uint64 a7;
/* 176 */ uint64 s2;
/* 184 */ uint64 s3;
/* 192 */ uint64 s4;
/* 200 */ uint64 s5;
/* 208 */ uint64 s6;
/* 216 */ uint64 s7;
/* 224 */ uint64 s8;
/* 232 */ uint64 s9;
/* 240 */ uint64 s10;
/* 248 */ uint64 s11;
/* 256 */ uint64 t3;
/* 264 */ uint64 t4;
/* 272 */ uint64 t5;
/* 280 */ uint64 t6;
};
enum procstate { UNUSED, USED, SLEEPING, RUNNABLE, RUNNING, ZOMBIE };
@ -96,8 +96,8 @@ struct proc {
struct proc *parent; // Parent process
// these are private to the process, so p->lock need not be held.
u64 kstack; // Virtual address of kernel stack
u64 sz; // Size of process memory (bytes)
uint64 kstack; // Virtual address of kernel stack
uint64 sz; // Size of process memory (bytes)
pagetable_t pagetable; // User page table
struct trapframe *trapframe; // data page for trampoline.S
struct context context; // swtch() here to run process

View file

@ -30,7 +30,7 @@ ramdiskrw(struct buf *b)
if(b->blockno >= FSSIZE)
panic("ramdiskrw: blockno too big");
u64 diskaddr = b->blockno * BSIZE;
uint64 diskaddr = b->blockno * BSIZE;
char *addr = (char *)RAMDISK + diskaddr;
if(b->flags & B_DIRTY){

View file

@ -1,10 +1,10 @@
#ifndef __ASSEMBLER__
// which hart (core) is this?
static inline u64
static inline uint64
r_mhartid()
{
u64 x;
uint64 x;
asm volatile("csrr %0, mhartid" : "=r" (x) );
return x;
}
@ -17,16 +17,16 @@ r_mhartid()
#define MSTATUS_MPP_U (0L << 11)
#define MSTATUS_MIE (1L << 3) // machine-mode interrupt enable.
static inline u64
static inline uint64
r_mstatus()
{
u64 x;
uint64 x;
asm volatile("csrr %0, mstatus" : "=r" (x) );
return x;
}
static inline void
w_mstatus(u64 x)
w_mstatus(uint64 x)
{
asm volatile("csrw mstatus, %0" : : "r" (x));
}
@ -35,7 +35,7 @@ w_mstatus(u64 x)
// instruction address to which a return from
// exception will go.
static inline void
w_mepc(u64 x)
w_mepc(uint64 x)
{
asm volatile("csrw mepc, %0" : : "r" (x));
}
@ -48,31 +48,31 @@ w_mepc(u64 x)
#define SSTATUS_SIE (1L << 1) // Supervisor Interrupt Enable
#define SSTATUS_UIE (1L << 0) // User Interrupt Enable
static inline u64
static inline uint64
r_sstatus()
{
u64 x;
uint64 x;
asm volatile("csrr %0, sstatus" : "=r" (x) );
return x;
}
static inline void
w_sstatus(u64 x)
w_sstatus(uint64 x)
{
asm volatile("csrw sstatus, %0" : : "r" (x));
}
// Supervisor Interrupt Pending
static inline u64
static inline uint64
r_sip()
{
u64 x;
uint64 x;
asm volatile("csrr %0, sip" : "=r" (x) );
return x;
}
static inline void
w_sip(u64 x)
w_sip(uint64 x)
{
asm volatile("csrw sip, %0" : : "r" (x));
}
@ -81,16 +81,16 @@ w_sip(u64 x)
#define SIE_SEIE (1L << 9) // external
#define SIE_STIE (1L << 5) // timer
#define SIE_SSIE (1L << 1) // software
static inline u64
static inline uint64
r_sie()
{
u64 x;
uint64 x;
asm volatile("csrr %0, sie" : "=r" (x) );
return x;
}
static inline void
w_sie(u64 x)
w_sie(uint64 x)
{
asm volatile("csrw sie, %0" : : "r" (x));
}
@ -99,16 +99,16 @@ w_sie(u64 x)
#define MIE_MEIE (1L << 11) // external
#define MIE_MTIE (1L << 7) // timer
#define MIE_MSIE (1L << 3) // software
static inline u64
static inline uint64
r_mie()
{
u64 x;
uint64 x;
asm volatile("csrr %0, mie" : "=r" (x) );
return x;
}
static inline void
w_mie(u64 x)
w_mie(uint64 x)
{
asm volatile("csrw mie, %0" : : "r" (x));
}
@ -117,45 +117,45 @@ w_mie(u64 x)
// instruction address to which a return from
// exception will go.
static inline void
w_sepc(u64 x)
w_sepc(uint64 x)
{
asm volatile("csrw sepc, %0" : : "r" (x));
}
static inline u64
static inline uint64
r_sepc()
{
u64 x;
uint64 x;
asm volatile("csrr %0, sepc" : "=r" (x) );
return x;
}
// Machine Exception Delegation
static inline u64
static inline uint64
r_medeleg()
{
u64 x;
uint64 x;
asm volatile("csrr %0, medeleg" : "=r" (x) );
return x;
}
static inline void
w_medeleg(u64 x)
w_medeleg(uint64 x)
{
asm volatile("csrw medeleg, %0" : : "r" (x));
}
// Machine Interrupt Delegation
static inline u64
static inline uint64
r_mideleg()
{
u64 x;
uint64 x;
asm volatile("csrr %0, mideleg" : "=r" (x) );
return x;
}
static inline void
w_mideleg(u64 x)
w_mideleg(uint64 x)
{
asm volatile("csrw mideleg, %0" : : "r" (x));
}
@ -163,35 +163,35 @@ w_mideleg(u64 x)
// Supervisor Trap-Vector Base Address
// low two bits are mode.
static inline void
w_stvec(u64 x)
w_stvec(uint64 x)
{
asm volatile("csrw stvec, %0" : : "r" (x));
}
static inline u64
static inline uint64
r_stvec()
{
u64 x;
uint64 x;
asm volatile("csrr %0, stvec" : "=r" (x) );
return x;
}
// Machine-mode interrupt vector
static inline void
w_mtvec(u64 x)
w_mtvec(uint64 x)
{
asm volatile("csrw mtvec, %0" : : "r" (x));
}
// Physical Memory Protection
static inline void
w_pmpcfg0(u64 x)
w_pmpcfg0(uint64 x)
{
asm volatile("csrw pmpcfg0, %0" : : "r" (x));
}
static inline void
w_pmpaddr0(u64 x)
w_pmpaddr0(uint64 x)
{
asm volatile("csrw pmpaddr0, %0" : : "r" (x));
}
@ -199,68 +199,68 @@ w_pmpaddr0(u64 x)
// use riscv's sv39 page table scheme.
#define SATP_SV39 (8L << 60)
#define MAKE_SATP(pagetable) (SATP_SV39 | (((u64)pagetable) >> 12))
#define MAKE_SATP(pagetable) (SATP_SV39 | (((uint64)pagetable) >> 12))
// supervisor address translation and protection;
// holds the address of the page table.
static inline void
w_satp(u64 x)
w_satp(uint64 x)
{
asm volatile("csrw satp, %0" : : "r" (x));
}
static inline u64
static inline uint64
r_satp()
{
u64 x;
uint64 x;
asm volatile("csrr %0, satp" : "=r" (x) );
return x;
}
static inline void
w_mscratch(u64 x)
w_mscratch(uint64 x)
{
asm volatile("csrw mscratch, %0" : : "r" (x));
}
// Supervisor Trap Cause
static inline u64
static inline uint64
r_scause()
{
u64 x;
uint64 x;
asm volatile("csrr %0, scause" : "=r" (x) );
return x;
}
// Supervisor Trap Value
static inline u64
static inline uint64
r_stval()
{
u64 x;
uint64 x;
asm volatile("csrr %0, stval" : "=r" (x) );
return x;
}
// Machine-mode Counter-Enable
static inline void
w_mcounteren(u64 x)
w_mcounteren(uint64 x)
{
asm volatile("csrw mcounteren, %0" : : "r" (x));
}
static inline u64
static inline uint64
r_mcounteren()
{
u64 x;
uint64 x;
asm volatile("csrr %0, mcounteren" : "=r" (x) );
return x;
}
// machine-mode cycle counter
static inline u64
static inline uint64
r_time()
{
u64 x;
uint64 x;
asm volatile("csrr %0, time" : "=r" (x) );
return x;
}
@ -283,38 +283,38 @@ intr_off()
static inline int
intr_get()
{
u64 x = r_sstatus();
uint64 x = r_sstatus();
return (x & SSTATUS_SIE) != 0;
}
static inline u64
static inline uint64
r_sp()
{
u64 x;
uint64 x;
asm volatile("mv %0, sp" : "=r" (x) );
return x;
}
// read and write tp, the thread pointer, which xv6 uses to hold
// this core's hartid (core number), the index into cpus[].
static inline u64
static inline uint64
r_tp()
{
u64 x;
uint64 x;
asm volatile("mv %0, tp" : "=r" (x) );
return x;
}
static inline void
w_tp(u64 x)
w_tp(uint64 x)
{
asm volatile("mv tp, %0" : : "r" (x));
}
static inline u64
static inline uint64
r_ra()
{
u64 x;
uint64 x;
asm volatile("mv %0, ra" : "=r" (x) );
return x;
}
@ -327,8 +327,8 @@ sfence_vma()
asm volatile("sfence.vma zero, zero");
}
typedef u64 pte_t;
typedef u64 *pagetable_t; // 512 PTEs
typedef uint64 pte_t;
typedef uint64 *pagetable_t; // 512 PTEs
#endif // __ASSEMBLER__
@ -345,7 +345,7 @@ typedef u64 *pagetable_t; // 512 PTEs
#define PTE_U (1L << 4) // user can access
// shift a physical address to the right place for a PTE.
#define PA2PTE(pa) ((((u64)pa) >> 12) << 10)
#define PA2PTE(pa) ((((uint64)pa) >> 12) << 10)
#define PTE2PA(pte) (((pte) >> 10) << 12)
@ -354,7 +354,7 @@ typedef u64 *pagetable_t; // 512 PTEs
// extract the three 9-bit page table indices from a virtual address.
#define PXMASK 0x1FF // 9 bits
#define PXSHIFT(level) (PGSHIFT+(9*(level)))
#define PX(level, va) ((((u64) (va)) >> PXSHIFT(level)) & PXMASK)
#define PX(level, va) ((((uint64) (va)) >> PXSHIFT(level)) & PXMASK)
// one beyond the highest possible virtual address.
// MAXVA is actually one bit less than the max allowed by

View file

@ -1,6 +1,6 @@
// Long-term locks for processes
struct sleeplock {
u32 locked; // Is the lock held?
uint locked; // Is the lock held?
struct spinlock lk; // spinlock protecting this sleep lock
// For debugging:

View file

@ -1,6 +1,6 @@
// Mutual exclusion lock.
struct spinlock {
u32 locked; // Is the lock held?
uint locked; // Is the lock held?
// For debugging:
char *name; // Name of lock.

View file

@ -11,7 +11,7 @@ void timerinit();
__attribute__ ((aligned (16))) char stack0[4096 * NCPU];
// a scratch area per CPU for machine-mode timer interrupts.
u64 timer_scratch[NCPU][5];
uint64 timer_scratch[NCPU][5];
// assembly code in kernelvec.S for machine-mode timer interrupt.
extern void timervec();
@ -28,7 +28,7 @@ start()
// set M Exception Program Counter to main, for mret.
// requires gcc -mcmodel=medany
w_mepc((u64)main);
w_mepc((uint64)main);
// disable paging for now.
w_satp(0);
@ -67,19 +67,19 @@ timerinit()
// ask the CLINT for a timer interrupt.
int interval = 1000000; // cycles; about 1/10th second in qemu.
*(u64*)CLINT_MTIMECMP(id) = *(u64*)CLINT_MTIME + interval;
*(uint64*)CLINT_MTIMECMP(id) = *(uint64*)CLINT_MTIME + interval;
// prepare information in scratch[] for timervec.
// scratch[0..2] : space for timervec to save registers.
// scratch[3] : address of CLINT MTIMECMP register.
// scratch[4] : desired interval (in cycles) between timer interrupts.
u64 *scratch = &timer_scratch[id][0];
uint64 *scratch = &timer_scratch[id][0];
scratch[3] = CLINT_MTIMECMP(id);
scratch[4] = interval;
w_mscratch((u64)scratch);
w_mscratch((uint64)scratch);
// set the machine-mode trap handler.
w_mtvec((u64)timervec);
w_mtvec((uint64)timervec);
// enable machine-mode interrupts.
w_mstatus(r_mstatus() | MSTATUS_MIE);

View file

@ -4,8 +4,8 @@
struct stat {
int dev; // File system's disk device
u32 ino; // Inode number
uint ino; // Inode number
short type; // Type of file
short nlink; // Number of links to file
u64 size; // Size of file in bytes
uint64 size; // Size of file in bytes
};

View file

@ -1,7 +1,7 @@
#include "types.h"
void*
memset(void *dst, int c, u32 n)
memset(void *dst, int c, uint n)
{
char *cdst = (char *) dst;
int i;
@ -12,9 +12,9 @@ memset(void *dst, int c, u32 n)
}
int
memcmp(const void *v1, const void *v2, u32 n)
memcmp(const void *v1, const void *v2, uint n)
{
const u8 *s1, *s2;
const uchar *s1, *s2;
s1 = v1;
s2 = v2;
@ -28,7 +28,7 @@ memcmp(const void *v1, const void *v2, u32 n)
}
void*
memmove(void *dst, const void *src, u32 n)
memmove(void *dst, const void *src, uint n)
{
const char *s;
char *d;
@ -52,19 +52,19 @@ memmove(void *dst, const void *src, u32 n)
// memcpy exists to placate GCC. Use memmove.
void*
memcpy(void *dst, const void *src, u32 n)
memcpy(void *dst, const void *src, uint n)
{
return memmove(dst, src, n);
}
int
strncmp(const char *p, const char *q, u32 n)
strncmp(const char *p, const char *q, uint n)
{
while(n > 0 && *p && *p == *q)
n--, p++, q++;
if(n == 0)
return 0;
return (u8)*p - (u8)*q;
return (uchar)*p - (uchar)*q;
}
char*

View file

@ -7,12 +7,12 @@
#include "syscall.h"
#include "defs.h"
// Fetch the u64 at addr from the current process.
// Fetch the uint64 at addr from the current process.
int
fetchaddr(u64 addr, u64 *ip)
fetchaddr(uint64 addr, uint64 *ip)
{
struct proc *p = myproc();
if(addr >= p->sz || addr+sizeof(u64) > 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;
@ -22,7 +22,7 @@ fetchaddr(u64 addr, u64 *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(u64 addr, char *buf, int max)
fetchstr(uint64 addr, char *buf, int max)
{
struct proc *p = myproc();
if(copyinstr(p->pagetable, buf, addr, max) < 0)
@ -30,7 +30,7 @@ fetchstr(u64 addr, char *buf, int max)
return strlen(buf);
}
static u64
static uint64
argraw(int n)
{
struct proc *p = myproc();
@ -63,7 +63,7 @@ argint(int n, int *ip)
// Doesn't check for legality, since
// copyin/copyout will do that.
void
argaddr(int n, u64 *ip)
argaddr(int n, uint64 *ip)
{
*ip = argraw(n);
}
@ -74,37 +74,34 @@ argaddr(int n, u64 *ip)
int
argstr(int n, char *buf, int max)
{
u64 addr;
uint64 addr;
argaddr(n, &addr);
return fetchstr(addr, buf, max);
}
// Prototypes for the functions that handle system calls.
extern u64 sys_fork(void);
extern u64 sys_exit(void);
extern u64 sys_wait(void);
extern u64 sys_pipe(void);
extern u64 sys_read(void);
extern u64 sys_kill(void);
extern u64 sys_exec(void);
extern u64 sys_fstat(void);
extern u64 sys_chdir(void);
extern u64 sys_dup(void);
extern u64 sys_getpid(void);
extern u64 sys_sbrk(void);
extern u64 sys_sleep(void);
extern u64 sys_uptime(void);
extern u64 sys_open(void);
extern u64 sys_write(void);
extern u64 sys_mknod(void);
extern u64 sys_unlink(void);
extern u64 sys_link(void);
extern u64 sys_mkdir(void);
extern u64 sys_close(void);
extern uint64 sys_fork(void);
extern uint64 sys_exit(void);
extern uint64 sys_wait(void);
extern uint64 sys_pipe(void);
extern uint64 sys_read(void);
extern uint64 sys_kill(void);
extern uint64 sys_exec(void);
extern uint64 sys_fstat(void);
extern uint64 sys_chdir(void);
extern uint64 sys_dup(void);
extern uint64 sys_getpid(void);
extern uint64 sys_sbrk(void);
extern uint64 sys_sleep(void);
extern uint64 sys_uptime(void);
extern uint64 sys_open(void);
extern uint64 sys_write(void);
extern uint64 sys_mknod(void);
extern uint64 sys_unlink(void);
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 u64 (*syscalls[])(void) = {
static uint64 (*syscalls[])(void) = {
[SYS_fork] sys_fork,
[SYS_exit] sys_exit,
[SYS_wait] sys_wait,
@ -136,8 +133,6 @@ syscall(void)
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",

View file

@ -51,7 +51,7 @@ fdalloc(struct file *f)
return -1;
}
u64
uint64
sys_dup(void)
{
struct file *f;
@ -65,12 +65,12 @@ sys_dup(void)
return fd;
}
u64
uint64
sys_read(void)
{
struct file *f;
int n;
u64 p;
uint64 p;
argaddr(1, &p);
argint(2, &n);
@ -79,12 +79,12 @@ sys_read(void)
return fileread(f, p, n);
}
u64
uint64
sys_write(void)
{
struct file *f;
int n;
u64 p;
uint64 p;
argaddr(1, &p);
argint(2, &n);
@ -94,7 +94,7 @@ sys_write(void)
return filewrite(f, p, n);
}
u64
uint64
sys_close(void)
{
int fd;
@ -107,11 +107,11 @@ sys_close(void)
return 0;
}
u64
uint64
sys_fstat(void)
{
struct file *f;
u64 st; // user pointer to struct stat
uint64 st; // user pointer to struct stat
argaddr(1, &st);
if(argfd(0, 0, &f) < 0)
@ -120,7 +120,7 @@ sys_fstat(void)
}
// Create the path new as a link to the same inode as old.
u64
uint64
sys_link(void)
{
char name[DIRSIZ], new[MAXPATH], old[MAXPATH];
@ -177,7 +177,7 @@ isdirempty(struct inode *dp)
struct dirent de;
for(off=2*sizeof(de); off<dp->size; off+=sizeof(de)){
if(readi(dp, 0, (u64)&de, off, sizeof(de)) != sizeof(de))
if(readi(dp, 0, (uint64)&de, off, sizeof(de)) != sizeof(de))
panic("isdirempty: readi");
if(de.inum != 0)
return 0;
@ -185,13 +185,13 @@ isdirempty(struct inode *dp)
return 1;
}
u64
uint64
sys_unlink(void)
{
struct inode *ip, *dp;
struct dirent de;
char name[DIRSIZ], path[MAXPATH];
u32 off;
uint off;
if(argstr(0, path, MAXPATH) < 0)
return -1;
@ -220,7 +220,7 @@ sys_unlink(void)
}
memset(&de, 0, sizeof(de));
if(writei(dp, 0, (u64)&de, off, sizeof(de)) != sizeof(de))
if(writei(dp, 0, (uint64)&de, off, sizeof(de)) != sizeof(de))
panic("unlink: writei");
if(ip->type == T_DIR){
dp->nlink--;
@ -262,10 +262,8 @@ create(char *path, short type, short major, short minor)
return 0;
}
if((ip = ialloc(dp->dev, type)) == 0){
iunlockput(dp);
return 0;
}
if((ip = ialloc(dp->dev, type)) == 0)
panic("create: ialloc");
ilock(ip);
ip->major = major;
@ -301,7 +299,7 @@ create(char *path, short type, short major, short minor)
return 0;
}
u64
uint64
sys_open(void)
{
char path[MAXPATH];
@ -370,7 +368,7 @@ sys_open(void)
return fd;
}
u64
uint64
sys_mkdir(void)
{
char path[MAXPATH];
@ -386,7 +384,7 @@ sys_mkdir(void)
return 0;
}
u64
uint64
sys_mknod(void)
{
struct inode *ip;
@ -406,7 +404,7 @@ sys_mknod(void)
return 0;
}
u64
uint64
sys_chdir(void)
{
char path[MAXPATH];
@ -431,12 +429,12 @@ sys_chdir(void)
return 0;
}
u64
uint64
sys_exec(void)
{
char path[MAXPATH], *argv[MAXARG];
int i;
u64 uargv, uarg;
uint64 uargv, uarg;
argaddr(1, &uargv);
if(argstr(0, path, MAXPATH) < 0) {
@ -447,7 +445,7 @@ sys_exec(void)
if(i >= NELEM(argv)){
goto bad;
}
if(fetchaddr(uargv+sizeof(u64)*i, (u64*)&uarg) < 0){
if(fetchaddr(uargv+sizeof(uint64)*i, (uint64*)&uarg) < 0){
goto bad;
}
if(uarg == 0){
@ -474,10 +472,10 @@ sys_exec(void)
return -1;
}
u64
uint64
sys_pipe(void)
{
u64 fdarray; // user pointer to array of two integers
uint64 fdarray; // user pointer to array of two integers
struct file *rf, *wf;
int fd0, fd1;
struct proc *p = myproc();

View file

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

View file

@ -80,18 +80,9 @@ uservec:
# load the address of usertrap(), from p->trapframe->kernel_trap
ld t0, 16(a0)
# fetch the kernel page table address, from p->trapframe->kernel_satp.
# load the kernel page table, 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
@ -105,7 +96,6 @@ 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

@ -7,7 +7,7 @@
#include "defs.h"
struct spinlock tickslock;
u32 ticks;
uint ticks;
extern char trampoline[], uservec[], userret[];
@ -26,7 +26,7 @@ trapinit(void)
void
trapinithart(void)
{
w_stvec((u64)kernelvec);
w_stvec((uint64)kernelvec);
}
//
@ -43,7 +43,7 @@ usertrap(void)
// send interrupts and exceptions to kerneltrap(),
// since we're now in the kernel.
w_stvec((u64)kernelvec);
w_stvec((uint64)kernelvec);
struct proc *p = myproc();
@ -97,14 +97,14 @@ usertrapret(void)
intr_off();
// send syscalls, interrupts, and exceptions to uservec in trampoline.S
u64 trampoline_uservec = TRAMPOLINE + (uservec - trampoline);
uint64 trampoline_uservec = TRAMPOLINE + (uservec - trampoline);
w_stvec(trampoline_uservec);
// set up trapframe values that uservec will need when
// the process next traps into the kernel.
p->trapframe->kernel_satp = r_satp(); // kernel page table
p->trapframe->kernel_sp = p->kstack + PGSIZE; // process's kernel stack
p->trapframe->kernel_trap = (u64)usertrap;
p->trapframe->kernel_trap = (uint64)usertrap;
p->trapframe->kernel_hartid = r_tp(); // hartid for cpuid()
// set up the registers that trampoline.S's sret will use
@ -120,13 +120,13 @@ usertrapret(void)
w_sepc(p->trapframe->epc);
// tell trampoline.S the user page table to switch to.
u64 satp = MAKE_SATP(p->pagetable);
uint64 satp = MAKE_SATP(p->pagetable);
// jump to userret in trampoline.S at the top of memory, which
// switches to the user page table, restores user registers,
// and switches to user mode with sret.
u64 trampoline_userret = TRAMPOLINE + (userret - trampoline);
((void (*)(u64))trampoline_userret)(satp);
uint64 trampoline_userret = TRAMPOLINE + (userret - trampoline);
((void (*)(uint64))trampoline_userret)(satp);
}
// interrupts and exceptions from kernel code go here via kernelvec,
@ -135,9 +135,9 @@ void
kerneltrap()
{
int which_dev = 0;
u64 sepc = r_sepc();
u64 sstatus = r_sstatus();
u64 scause = r_scause();
uint64 sepc = r_sepc();
uint64 sstatus = r_sstatus();
uint64 scause = r_scause();
if((sstatus & SSTATUS_SPP) == 0)
panic("kerneltrap: not from supervisor mode");
@ -177,7 +177,7 @@ clockintr()
int
devintr()
{
u64 scause = r_scause();
uint64 scause = r_scause();
if((scause & 0x8000000000000000L) &&
(scause & 0xff) == 9){

View file

@ -1,6 +1,10 @@
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;
typedef unsigned long u64;
typedef unsigned int uint;
typedef unsigned short ushort;
typedef unsigned char uchar;
typedef u64 pde_t;
typedef unsigned char uint8;
typedef unsigned short uint16;
typedef unsigned int uint32;
typedef unsigned long uint64;
typedef uint64 pde_t;

View file

@ -42,8 +42,8 @@
struct spinlock uart_tx_lock;
#define UART_TX_BUF_SIZE 32
char uart_tx_buf[UART_TX_BUF_SIZE];
u64 uart_tx_w; // write next to uart_tx_buf[uart_tx_w % UART_TX_BUF_SIZE]
u64 uart_tx_r; // read next from uart_tx_buf[uart_tx_r % UART_TX_BUF_SIZE]
uint64 uart_tx_w; // write next to uart_tx_buf[uart_tx_w % UART_TX_BUF_SIZE]
uint64 uart_tx_r; // read next from uart_tx_buf[uart_tx_r % UART_TX_BUF_SIZE]
extern volatile int panicked; // from printf.c

View file

@ -51,32 +51,32 @@
// a single descriptor, from the spec.
struct virtq_desc {
u64 addr;
u32 len;
u16 flags;
u16 next;
uint64 addr;
uint32 len;
uint16 flags;
uint16 next;
};
#define VRING_DESC_F_NEXT 1 // chained with another descriptor
#define VRING_DESC_F_WRITE 2 // device writes (vs read)
// the (entire) avail ring, from the spec.
struct virtq_avail {
u16 flags; // always zero
u16 idx; // driver will write ring[idx] next
u16 ring[NUM]; // descriptor numbers of chain heads
u16 unused;
uint16 flags; // always zero
uint16 idx; // driver will write ring[idx] next
uint16 ring[NUM]; // descriptor numbers of chain heads
uint16 unused;
};
// one entry in the "used" ring, with which the
// device tells the driver about completed requests.
struct virtq_used_elem {
u32 id; // index of start of completed descriptor chain
u32 len;
uint32 id; // index of start of completed descriptor chain
uint32 len;
};
struct virtq_used {
u16 flags; // always zero
u16 idx; // device increments when it adds a ring[] entry
uint16 flags; // always zero
uint16 idx; // device increments when it adds a ring[] entry
struct virtq_used_elem ring[NUM];
};
@ -90,7 +90,7 @@ struct virtq_used {
// to be followed by two more descriptors containing
// the block, and a one-byte status.
struct virtio_blk_req {
u32 type; // VIRTIO_BLK_T_IN or ..._OUT
u32 reserved;
u64 sector;
uint32 type; // VIRTIO_BLK_T_IN or ..._OUT
uint32 reserved;
uint64 sector;
};

View file

@ -17,7 +17,7 @@
#include "virtio.h"
// the address of virtio mmio register r.
#define R(r) ((volatile u32 *)(VIRTIO0 + (r)))
#define R(r) ((volatile uint32 *)(VIRTIO0 + (r)))
static struct disk {
// a set (not a ring) of DMA descriptors, with which the
@ -40,7 +40,7 @@ static struct disk {
// our own book-keeping.
char free[NUM]; // is a descriptor free?
u16 used_idx; // we've looked this far in used[2..NUM].
uint16 used_idx; // we've looked this far in used[2..NUM].
// track info about in-flight operations,
// for use when completion interrupt arrives.
@ -61,7 +61,7 @@ static struct disk {
void
virtio_disk_init(void)
{
u32 status = 0;
uint32 status = 0;
initlock(&disk.vdisk_lock, "virtio_disk");
@ -84,7 +84,7 @@ virtio_disk_init(void)
*R(VIRTIO_MMIO_STATUS) = status;
// negotiate features
u64 features = *R(VIRTIO_MMIO_DEVICE_FEATURES);
uint64 features = *R(VIRTIO_MMIO_DEVICE_FEATURES);
features &= ~(1 << VIRTIO_BLK_F_RO);
features &= ~(1 << VIRTIO_BLK_F_SCSI);
features &= ~(1 << VIRTIO_BLK_F_CONFIG_WCE);
@ -111,7 +111,7 @@ virtio_disk_init(void)
panic("virtio disk should not be ready");
// check maximum queue size.
u32 max = *R(VIRTIO_MMIO_QUEUE_NUM_MAX);
uint32 max = *R(VIRTIO_MMIO_QUEUE_NUM_MAX);
if(max == 0)
panic("virtio disk has no queue 0");
if(max < NUM)
@ -131,12 +131,12 @@ virtio_disk_init(void)
*R(VIRTIO_MMIO_QUEUE_NUM) = NUM;
// write physical addresses.
*R(VIRTIO_MMIO_QUEUE_DESC_LOW) = (u64)disk.desc;
*R(VIRTIO_MMIO_QUEUE_DESC_HIGH) = (u64)disk.desc >> 32;
*R(VIRTIO_MMIO_DRIVER_DESC_LOW) = (u64)disk.avail;
*R(VIRTIO_MMIO_DRIVER_DESC_HIGH) = (u64)disk.avail >> 32;
*R(VIRTIO_MMIO_DEVICE_DESC_LOW) = (u64)disk.used;
*R(VIRTIO_MMIO_DEVICE_DESC_HIGH) = (u64)disk.used >> 32;
*R(VIRTIO_MMIO_QUEUE_DESC_LOW) = (uint64)disk.desc;
*R(VIRTIO_MMIO_QUEUE_DESC_HIGH) = (uint64)disk.desc >> 32;
*R(VIRTIO_MMIO_DRIVER_DESC_LOW) = (uint64)disk.avail;
*R(VIRTIO_MMIO_DRIVER_DESC_HIGH) = (uint64)disk.avail >> 32;
*R(VIRTIO_MMIO_DEVICE_DESC_LOW) = (uint64)disk.used;
*R(VIRTIO_MMIO_DEVICE_DESC_HIGH) = (uint64)disk.used >> 32;
// queue is ready.
*R(VIRTIO_MMIO_QUEUE_READY) = 0x1;
@ -215,7 +215,7 @@ alloc3_desc(int *idx)
void
virtio_disk_rw(struct buf *b, int write)
{
u64 sector = b->blockno * (BSIZE / 512);
uint64 sector = b->blockno * (BSIZE / 512);
acquire(&disk.vdisk_lock);
@ -244,12 +244,12 @@ virtio_disk_rw(struct buf *b, int write)
buf0->reserved = 0;
buf0->sector = sector;
disk.desc[idx[0]].addr = (u64) buf0;
disk.desc[idx[0]].addr = (uint64) buf0;
disk.desc[idx[0]].len = sizeof(struct virtio_blk_req);
disk.desc[idx[0]].flags = VRING_DESC_F_NEXT;
disk.desc[idx[0]].next = idx[1];
disk.desc[idx[1]].addr = (u64) b->data;
disk.desc[idx[1]].addr = (uint64) b->data;
disk.desc[idx[1]].len = BSIZE;
if(write)
disk.desc[idx[1]].flags = 0; // device reads b->data
@ -259,7 +259,7 @@ virtio_disk_rw(struct buf *b, int write)
disk.desc[idx[1]].next = idx[2];
disk.info[idx[0]].status = 0xff; // device writes 0 on success
disk.desc[idx[2]].addr = (u64) &disk.info[idx[0]].status;
disk.desc[idx[2]].addr = (uint64) &disk.info[idx[0]].status;
disk.desc[idx[2]].len = 1;
disk.desc[idx[2]].flags = VRING_DESC_F_WRITE; // device writes the status
disk.desc[idx[2]].next = 0;

View file

@ -34,14 +34,14 @@ kvmmake(void)
kvmmap(kpgtbl, PLIC, PLIC, 0x400000, PTE_R | PTE_W);
// map kernel text executable and read-only.
kvmmap(kpgtbl, KERNBASE, KERNBASE, (u64)etext-KERNBASE, PTE_R | PTE_X);
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, (u64)etext, (u64)etext, PHYSTOP-(u64)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.
kvmmap(kpgtbl, TRAMPOLINE, (u64)trampoline, PGSIZE, PTE_R | PTE_X);
kvmmap(kpgtbl, TRAMPOLINE, (uint64)trampoline, PGSIZE, PTE_R | PTE_X);
// allocate and map a kernel stack for each process.
proc_mapstacks(kpgtbl);
@ -61,12 +61,7 @@ kvminit(void)
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();
}
@ -83,7 +78,7 @@ kvminithart()
// 12..20 -- 9 bits of level-0 index.
// 0..11 -- 12 bits of byte offset within the page.
pte_t *
walk(pagetable_t pagetable, u64 va, int alloc)
walk(pagetable_t pagetable, uint64 va, int alloc)
{
if(va >= MAXVA)
panic("walk");
@ -105,11 +100,11 @@ walk(pagetable_t pagetable, u64 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.
u64
walkaddr(pagetable_t pagetable, u64 va)
uint64
walkaddr(pagetable_t pagetable, uint64 va)
{
pte_t *pte;
u64 pa;
uint64 pa;
if(va >= MAXVA)
return 0;
@ -129,7 +124,7 @@ walkaddr(pagetable_t pagetable, u64 va)
// only used when booting.
// does not flush TLB or enable paging.
void
kvmmap(pagetable_t kpgtbl, u64 va, u64 pa, u64 sz, int perm)
kvmmap(pagetable_t kpgtbl, uint64 va, uint64 pa, uint64 sz, int perm)
{
if(mappages(kpgtbl, va, sz, pa, perm) != 0)
panic("kvmmap");
@ -140,9 +135,9 @@ kvmmap(pagetable_t kpgtbl, u64 va, u64 pa, u64 sz, int perm)
// be page-aligned. Returns 0 on success, -1 if walk() couldn't
// allocate a needed page-table page.
int
mappages(pagetable_t pagetable, u64 va, u64 size, u64 pa, int perm)
mappages(pagetable_t pagetable, uint64 va, uint64 size, uint64 pa, int perm)
{
u64 a, last;
uint64 a, last;
pte_t *pte;
if(size == 0)
@ -168,9 +163,9 @@ mappages(pagetable_t pagetable, u64 va, u64 size, u64 pa, int perm)
// page-aligned. The mappings must exist.
// Optionally free the physical memory.
void
uvmunmap(pagetable_t pagetable, u64 va, u64 npages, int do_free)
uvmunmap(pagetable_t pagetable, uint64 va, uint64 npages, int do_free)
{
u64 a;
uint64 a;
pte_t *pte;
if((va % PGSIZE) != 0)
@ -184,7 +179,7 @@ uvmunmap(pagetable_t pagetable, u64 va, u64 npages, int do_free)
if(PTE_FLAGS(*pte) == PTE_V)
panic("uvmunmap: not a leaf");
if(do_free){
u64 pa = PTE2PA(*pte);
uint64 pa = PTE2PA(*pte);
kfree((void*)pa);
}
*pte = 0;
@ -208,7 +203,7 @@ uvmcreate()
// for the very first process.
// sz must be less than a page.
void
uvmfirst(pagetable_t pagetable, u8 *src, u32 sz)
uvmfirst(pagetable_t pagetable, uchar *src, uint sz)
{
char *mem;
@ -216,17 +211,17 @@ uvmfirst(pagetable_t pagetable, u8 *src, u32 sz)
panic("uvmfirst: more than a page");
mem = kalloc();
memset(mem, 0, PGSIZE);
mappages(pagetable, 0, PGSIZE, (u64)mem, PTE_W|PTE_R|PTE_X|PTE_U);
mappages(pagetable, 0, PGSIZE, (uint64)mem, PTE_W|PTE_R|PTE_X|PTE_U);
memmove(mem, src, 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.
u64
uvmalloc(pagetable_t pagetable, u64 oldsz, u64 newsz, int xperm)
uint64
uvmalloc(pagetable_t pagetable, uint64 oldsz, uint64 newsz, int xperm)
{
char *mem;
u64 a;
uint64 a;
if(newsz < oldsz)
return oldsz;
@ -239,7 +234,7 @@ uvmalloc(pagetable_t pagetable, u64 oldsz, u64 newsz, int xperm)
return 0;
}
memset(mem, 0, PGSIZE);
if(mappages(pagetable, a, PGSIZE, (u64)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;
@ -252,8 +247,8 @@ uvmalloc(pagetable_t pagetable, u64 oldsz, u64 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.
u64
uvmdealloc(pagetable_t pagetable, u64 oldsz, u64 newsz)
uint64
uvmdealloc(pagetable_t pagetable, uint64 oldsz, uint64 newsz)
{
if(newsz >= oldsz)
return oldsz;
@ -276,7 +271,7 @@ freewalk(pagetable_t pagetable)
pte_t pte = pagetable[i];
if((pte & PTE_V) && (pte & (PTE_R|PTE_W|PTE_X)) == 0){
// this PTE points to a lower-level page table.
u64 child = PTE2PA(pte);
uint64 child = PTE2PA(pte);
freewalk((pagetable_t)child);
pagetable[i] = 0;
} else if(pte & PTE_V){
@ -289,7 +284,7 @@ freewalk(pagetable_t pagetable)
// Free user memory pages,
// then free page-table pages.
void
uvmfree(pagetable_t pagetable, u64 sz)
uvmfree(pagetable_t pagetable, uint64 sz)
{
if(sz > 0)
uvmunmap(pagetable, 0, PGROUNDUP(sz)/PGSIZE, 1);
@ -303,11 +298,11 @@ uvmfree(pagetable_t pagetable, u64 sz)
// returns 0 on success, -1 on failure.
// frees any allocated pages on failure.
int
uvmcopy(pagetable_t old, pagetable_t new, u64 sz)
uvmcopy(pagetable_t old, pagetable_t new, uint64 sz)
{
pte_t *pte;
u64 pa, i;
u32 flags;
uint64 pa, i;
uint flags;
char *mem;
for(i = 0; i < sz; i += PGSIZE){
@ -320,7 +315,7 @@ uvmcopy(pagetable_t old, pagetable_t new, u64 sz)
if((mem = kalloc()) == 0)
goto err;
memmove(mem, (char*)pa, PGSIZE);
if(mappages(new, i, PGSIZE, (u64)mem, flags) != 0){
if(mappages(new, i, PGSIZE, (uint64)mem, flags) != 0){
kfree(mem);
goto err;
}
@ -335,7 +330,7 @@ uvmcopy(pagetable_t old, pagetable_t new, u64 sz)
// mark a PTE invalid for user access.
// used by exec for the user stack guard page.
void
uvmclear(pagetable_t pagetable, u64 va)
uvmclear(pagetable_t pagetable, uint64 va)
{
pte_t *pte;
@ -349,9 +344,9 @@ uvmclear(pagetable_t pagetable, u64 va)
// 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, u64 dstva, char *src, u64 len)
copyout(pagetable_t pagetable, uint64 dstva, char *src, uint64 len)
{
u64 n, va0, pa0;
uint64 n, va0, pa0;
while(len > 0){
va0 = PGROUNDDOWN(dstva);
@ -374,9 +369,9 @@ copyout(pagetable_t pagetable, u64 dstva, char *src, u64 len)
// 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, u64 srcva, u64 len)
copyin(pagetable_t pagetable, char *dst, uint64 srcva, uint64 len)
{
u64 n, va0, pa0;
uint64 n, va0, pa0;
while(len > 0){
va0 = PGROUNDDOWN(srcva);
@ -400,9 +395,9 @@ copyin(pagetable_t pagetable, char *dst, u64 srcva, u64 len)
// until a '\0', or max.
// Return 0 on success, -1 on error.
int
copyinstr(pagetable_t pagetable, char *dst, u64 srcva, u64 max)
copyinstr(pagetable_t pagetable, char *dst, uint64 srcva, uint64 max)
{
u64 n, va0, pa0;
uint64 n, va0, pa0;
int got_null = 0;
while(got_null == 0 && max > 0){

View file

@ -47,7 +47,7 @@ ushort
xshort(ushort x)
{
ushort y;
u8 *a = (u8*)&y;
uchar *a = (uchar*)&y;
a[0] = x;
a[1] = x >> 8;
return y;
@ -57,7 +57,7 @@ uint
xint(uint x)
{
uint y;
u8 *a = (u8*)&y;
uchar *a = (uchar*)&y;
a[0] = x;
a[1] = x >> 8;
a[2] = x >> 16;
@ -234,7 +234,7 @@ ialloc(ushort type)
void
balloc(int used)
{
u8 buf[BSIZE];
uchar buf[BSIZE];
int i;
printf("balloc: first %d blocks have been allocated\n", used);

View file

@ -53,7 +53,7 @@ go(int which_child)
int fd = -1;
static char buf[999];
char *break0 = sbrk(0);
u64 iters = 0;
uint64 iters = 0;
mkdir("grindir");
if(chdir("grindir") != 0){
@ -305,7 +305,7 @@ iter()
exit(1);
}
if(pid1 == 0){
rand_next ^= 31;
rand_next = 31;
go(0);
exit(0);
}
@ -316,7 +316,7 @@ iter()
exit(1);
}
if(pid2 == 0){
rand_next ^= 7177;
rand_next = 7177;
go(1);
exit(0);
}
@ -346,6 +346,5 @@ main()
wait(0);
}
sleep(20);
rand_next += 1;
}
}

View file

@ -17,7 +17,7 @@ printint(int fd, int xx, int base, int sgn)
{
char buf[16];
int i, neg;
u32 x;
uint x;
neg = 0;
if(sgn && xx < 0){
@ -39,12 +39,12 @@ printint(int fd, int xx, int base, int sgn)
}
static void
printptr(int fd, u64 x) {
printptr(int fd, uint64 x) {
int i;
putc(fd, '0');
putc(fd, 'x');
for (i = 0; i < (sizeof(u64) * 2); i++, x <<= 4)
putc(fd, digits[x >> (sizeof(u64) * 8 - 4)]);
for (i = 0; i < (sizeof(uint64) * 2); i++, x <<= 4)
putc(fd, digits[x >> (sizeof(uint64) * 8 - 4)]);
}
// Print to the given fd. Only understands %d, %x, %p, %s.
@ -67,11 +67,11 @@ vprintf(int fd, const char *fmt, va_list ap)
if(c == 'd'){
printint(fd, va_arg(ap, int), 10, 1);
} else if(c == 'l') {
printint(fd, va_arg(ap, u64), 10, 0);
printint(fd, va_arg(ap, uint64), 10, 0);
} else if(c == 'x') {
printint(fd, va_arg(ap, int), 16, 0);
} else if(c == 'p') {
printptr(fd, va_arg(ap, u64));
printptr(fd, va_arg(ap, uint64));
} else if(c == 's'){
s = va_arg(ap, char*);
if(s == 0)
@ -81,7 +81,7 @@ vprintf(int fd, const char *fmt, va_list ap)
s++;
}
} else if(c == 'c'){
putc(fd, va_arg(ap, u32));
putc(fd, va_arg(ap, uint));
} else if(c == '%'){
putc(fd, c);
} else {

View file

@ -30,10 +30,10 @@ strcmp(const char *p, const char *q)
{
while(*p && *p == *q)
p++, q++;
return (u8)*p - (u8)*q;
return (uchar)*p - (uchar)*q;
}
u32
uint
strlen(const char *s)
{
int n;
@ -44,7 +44,7 @@ strlen(const char *s)
}
void*
memset(void *dst, int c, u32 n)
memset(void *dst, int c, uint n)
{
char *cdst = (char *) dst;
int i;
@ -127,7 +127,7 @@ memmove(void *vdst, const void *vsrc, int n)
}
int
memcmp(const void *s1, const void *s2, u32 n)
memcmp(const void *s1, const void *s2, uint n)
{
const char *p1 = s1, *p2 = s2;
while (n-- > 0) {
@ -141,7 +141,7 @@ memcmp(const void *s1, const void *s2, u32 n)
}
void *
memcpy(void *dst, const void *src, u32 n)
memcpy(void *dst, const void *src, uint n)
{
return memmove(dst, src, n);
}

View file

@ -11,7 +11,7 @@ typedef long Align;
union header {
struct {
union header *ptr;
u32 size;
uint size;
} s;
Align x;
};
@ -44,7 +44,7 @@ free(void *ap)
}
static Header*
morecore(u32 nu)
morecore(uint nu)
{
char *p;
Header *hp;
@ -61,10 +61,10 @@ morecore(u32 nu)
}
void*
malloc(u32 nbytes)
malloc(uint nbytes)
{
Header *p, *prevp;
u32 nunits;
uint nunits;
nunits = (nbytes + sizeof(Header) - 1)/sizeof(Header) + 1;
if((prevp = freep) == 0){

View file

@ -32,10 +32,10 @@ int strcmp(const char*, const char*);
void fprintf(int, const char*, ...);
void printf(const char*, ...);
char* gets(char*, int max);
u32 strlen(const char*);
void* memset(void*, int, u32);
void* malloc(u32);
uint strlen(const char*);
void* memset(void*, int, uint);
void* malloc(uint);
void free(void*);
int atoi(const char*);
int memcmp(const void *, const void *, u32);
void *memcpy(void *, const void *, u32);
int memcmp(const void *, const void *, uint);
void *memcpy(void *, const void *, uint);

View file

@ -21,21 +21,15 @@
char buf[BUFSZ];
//
// Section with tests that run fairly quickly. Use -q if you want to
// run just those. With -q usertests also runs the ones that take a
// fair of time.
//
// what if you pass ridiculous pointers to system calls
// that read user memory with copyin?
void
copyin(char *s)
{
u64 addrs[] = { 0x80000000LL, 0xffffffffffffffff };
uint64 addrs[] = { 0x80000000LL, 0xffffffffffffffff };
for(int ai = 0; ai < 2; ai++){
u64 addr = addrs[ai];
uint64 addr = addrs[ai];
int fd = open("copyin1", O_CREATE|O_WRONLY);
if(fd < 0){
@ -76,10 +70,10 @@ copyin(char *s)
void
copyout(char *s)
{
u64 addrs[] = { 0x80000000LL, 0xffffffffffffffff };
uint64 addrs[] = { 0x80000000LL, 0xffffffffffffffff };
for(int ai = 0; ai < 2; ai++){
u64 addr = addrs[ai];
uint64 addr = addrs[ai];
int fd = open("README", 0);
if(fd < 0){
@ -117,10 +111,10 @@ copyout(char *s)
void
copyinstr1(char *s)
{
u64 addrs[] = { 0x80000000LL, 0xffffffffffffffff };
uint64 addrs[] = { 0x80000000LL, 0xffffffffffffffff };
for(int ai = 0; ai < 2; ai++){
u64 addr = addrs[ai];
uint64 addr = addrs[ai];
int fd = open((char *)addr, O_CREATE|O_WRONLY);
if(fd >= 0){
@ -199,11 +193,11 @@ void
copyinstr3(char *s)
{
sbrk(8192);
u64 top = (u64) sbrk(0);
uint64 top = (uint64) sbrk(0);
if((top % PGSIZE) != 0){
sbrk(PGSIZE - (top % PGSIZE));
}
top = (u64) sbrk(0);
top = (uint64) sbrk(0);
if(top % PGSIZE){
printf("oops\n");
exit(1);
@ -245,14 +239,14 @@ rwsbrk()
{
int fd, n;
u64 a = (u64) sbrk(8192);
uint64 a = (uint64) sbrk(8192);
if(a == 0xffffffffffffffffLL) {
printf("sbrk(rwsbrk) failed\n");
exit(1);
}
if ((u64) sbrk(-8192) == 0xffffffffffffffffLL) {
if ((uint64) sbrk(-8192) == 0xffffffffffffffffLL) {
printf("sbrk(rwsbrk) shrink failed\n");
exit(1);
}
@ -1397,7 +1391,7 @@ concreate(char *s)
int i, pid, n, fd;
char fa[N];
struct {
u16 inum;
ushort inum;
char name[DIRSIZ];
} de;
@ -1518,6 +1512,46 @@ linkunlink(char *s)
exit(0);
}
// directory that uses indirect blocks
void
bigdir(char *s)
{
enum { N = 500 };
int i, fd;
char name[10];
unlink("bd");
fd = open("bd", O_CREATE);
if(fd < 0){
printf("%s: bigdir create failed\n", s);
exit(1);
}
close(fd);
for(i = 0; i < N; i++){
name[0] = 'x';
name[1] = '0' + (i / 64);
name[2] = '0' + (i % 64);
name[3] = '\0';
if(link("bd", name) != 0){
printf("%s: bigdir link(bd, %s) failed\n", s, name);
exit(1);
}
}
unlink("bd");
for(i = 0; i < N; i++){
name[0] = 'x';
name[1] = '0' + (i / 64);
name[2] = '0' + (i % 64);
name[3] = '\0';
if(unlink(name) != 0){
printf("%s: bigdir unlink failed", s);
exit(1);
}
}
}
void
subdir(char *s)
@ -1724,6 +1758,59 @@ bigwrite(char *s)
}
}
// concurrent writes to try to provoke deadlock in the virtio disk
// driver.
void
manywrites(char *s)
{
int nchildren = 4;
int howmany = 30; // increase to look for deadlock
for(int ci = 0; ci < nchildren; ci++){
int pid = fork();
if(pid < 0){
printf("fork failed\n");
exit(1);
}
if(pid == 0){
char name[3];
name[0] = 'b';
name[1] = 'a' + ci;
name[2] = '\0';
unlink(name);
for(int iters = 0; iters < howmany; iters++){
for(int i = 0; i < ci+1; i++){
int fd = open(name, O_CREATE | O_RDWR);
if(fd < 0){
printf("%s: cannot create %s\n", s, name);
exit(1);
}
int sz = sizeof(buf);
int cc = write(fd, buf, sz);
if(cc != sz){
printf("%s: write(%d) ret %d\n", s, sz, cc);
exit(1);
}
close(fd);
}
unlink(name);
}
unlink(name);
exit(0);
}
}
for(int ci = 0; ci < nchildren; ci++){
int st = 0;
wait(&st);
if(st != 0)
exit(st);
}
exit(0);
}
void
bigfile(char *s)
@ -2062,13 +2149,13 @@ sbrkmuch(char *s)
{
enum { BIG=100*1024*1024 };
char *c, *oldbrk, *a, *lastaddr, *p;
u64 amt;
uint64 amt;
oldbrk = sbrk(0);
// can one grow address space to something big?
a = sbrk(0);
amt = BIG - (u64)a;
amt = BIG - (uint64)a;
p = sbrk(amt);
if (p != a) {
printf("%s: sbrk test failed to grow big address space; enough phys mem?\n", s);
@ -2145,7 +2232,7 @@ kernmem(char *s)
void
MAXVAplus(char *s)
{
volatile u64 a = MAXVA;
volatile uint64 a = MAXVA;
for( ; a != 0; a <<= 1){
int pid;
pid = fork();
@ -2185,7 +2272,7 @@ sbrkfail(char *s)
for(i = 0; i < sizeof(pids)/sizeof(pids[0]); i++){
if((pids[i] = fork()) == 0){
// allocate a lot of memory
sbrk(BIG - (u64)sbrk(0));
sbrk(BIG - (uint64)sbrk(0));
write(fds[1], "x", 1);
// sit around until killed
for(;;) sleep(1000);
@ -2267,10 +2354,10 @@ void
validatetest(char *s)
{
int hi;
u64 p;
uint64 p;
hi = 1100*1024;
for(p = 0; p <= (u32)hi; p += PGSIZE){
for(p = 0; p <= (uint)hi; p += PGSIZE){
// try to crash the kernel by passing in a bad string pointer
if(link("nosuchfile", (char*)p) != -1){
printf("%s: link should not succeed\n", s);
@ -2445,7 +2532,7 @@ textwrite(char *s)
}
// regression test. copyin(), copyout(), and copyinstr() used to cast
// the virtual page address to u32, which (with certain wild system
// the virtual page address to uint, which (with certain wild system
// call arguments) resulted in a kernel page faults.
void *big = (void*) 0xeaeb0b5b00002f5e;
void
@ -2471,7 +2558,7 @@ sbrkbugs(char *s)
exit(1);
}
if(pid == 0){
int sz = (u64) sbrk(0);
int sz = (uint64) sbrk(0);
// free all user memory; there used to be a bug that
// would not adjust p->sz correctly in this case,
// causing exit() to panic.
@ -2487,7 +2574,7 @@ sbrkbugs(char *s)
exit(1);
}
if(pid == 0){
int sz = (u64) sbrk(0);
int sz = (uint64) sbrk(0);
// set the break to somewhere in the very first
// page; there used to be a bug that would incorrectly
// free the first page.
@ -2503,7 +2590,7 @@ sbrkbugs(char *s)
}
if(pid == 0){
// set the break in the middle of a page.
sbrk((10*4096 + 2048) - (u64)sbrk(0));
sbrk((10*4096 + 2048) - (uint64)sbrk(0));
// reduce the break a bit, but not enough to
// cause a page to be freed. this used to cause
@ -2523,13 +2610,13 @@ sbrkbugs(char *s)
void
sbrklast(char *s)
{
u64 top = (u64) sbrk(0);
uint64 top = (uint64) sbrk(0);
if((top % 4096) != 0)
sbrk(4096 - (top % 4096));
sbrk(4096);
sbrk(10);
sbrk(-20);
top = (u64) sbrk(0);
top = (uint64) sbrk(0);
char *p = (char *) (top - 64);
p[0] = 'x';
p[1] = '\0';
@ -2555,189 +2642,6 @@ sbrk8000(char *s)
}
// regression test. test whether exec() leaks memory if one of the
// arguments is invalid. the test passes if the kernel doesn't panic.
void
badarg(char *s)
{
for(int i = 0; i < 50000; i++){
char *argv[2];
argv[0] = (char*)0xffffffff;
argv[1] = 0;
exec("echo", argv);
}
exit(0);
}
struct test {
void (*f)(char *);
char *s;
} quicktests[] = {
{copyin, "copyin"},
{copyout, "copyout"},
{copyinstr1, "copyinstr1"},
{copyinstr2, "copyinstr2"},
{copyinstr3, "copyinstr3"},
{rwsbrk, "rwsbrk" },
{truncate1, "truncate1"},
{truncate2, "truncate2"},
{truncate3, "truncate3"},
{openiputtest, "openiput"},
{exitiputtest, "exitiput"},
{iputtest, "iput"},
{opentest, "opentest"},
{writetest, "writetest"},
{writebig, "writebig"},
{createtest, "createtest"},
{dirtest, "dirtest"},
{exectest, "exectest"},
{pipe1, "pipe1"},
{killstatus, "killstatus"},
{preempt, "preempt"},
{exitwait, "exitwait"},
{reparent, "reparent" },
{twochildren, "twochildren"},
{forkfork, "forkfork"},
{forkforkfork, "forkforkfork"},
{reparent2, "reparent2"},
{mem, "mem"},
{sharedfd, "sharedfd"},
{fourfiles, "fourfiles"},
{createdelete, "createdelete"},
{unlinkread, "unlinkread"},
{linktest, "linktest"},
{concreate, "concreate"},
{linkunlink, "linkunlink"},
{subdir, "subdir"},
{bigwrite, "bigwrite"},
{bigfile, "bigfile"},
{fourteen, "fourteen"},
{rmdot, "rmdot"},
{dirfile, "dirfile"},
{iref, "iref"},
{forktest, "forktest"},
{sbrkbasic, "sbrkbasic"},
{sbrkmuch, "sbrkmuch"},
{kernmem, "kernmem"},
{MAXVAplus, "MAXVAplus"},
{sbrkfail, "sbrkfail"},
{sbrkarg, "sbrkarg"},
{validatetest, "validatetest"},
{bsstest, "bsstest"},
{bigargtest, "bigargtest"},
{argptest, "argptest"},
{stacktest, "stacktest"},
{textwrite, "textwrite"},
{pgbug, "pgbug" },
{sbrkbugs, "sbrkbugs" },
{sbrklast, "sbrklast"},
{sbrk8000, "sbrk8000"},
{badarg, "badarg" },
{ 0, 0},
};
//
// Section with tests that take a fair bit of time
//
// directory that uses indirect blocks
void
bigdir(char *s)
{
enum { N = 500 };
int i, fd;
char name[10];
unlink("bd");
fd = open("bd", O_CREATE);
if(fd < 0){
printf("%s: bigdir create failed\n", s);
exit(1);
}
close(fd);
for(i = 0; i < N; i++){
name[0] = 'x';
name[1] = '0' + (i / 64);
name[2] = '0' + (i % 64);
name[3] = '\0';
if(link("bd", name) != 0){
printf("%s: bigdir link(bd, %s) failed\n", s, name);
exit(1);
}
}
unlink("bd");
for(i = 0; i < N; i++){
name[0] = 'x';
name[1] = '0' + (i / 64);
name[2] = '0' + (i % 64);
name[3] = '\0';
if(unlink(name) != 0){
printf("%s: bigdir unlink failed", s);
exit(1);
}
}
}
// concurrent writes to try to provoke deadlock in the virtio disk
// driver.
void
manywrites(char *s)
{
int nchildren = 4;
int howmany = 30; // increase to look for deadlock
for(int ci = 0; ci < nchildren; ci++){
int pid = fork();
if(pid < 0){
printf("fork failed\n");
exit(1);
}
if(pid == 0){
char name[3];
name[0] = 'b';
name[1] = 'a' + ci;
name[2] = '\0';
unlink(name);
for(int iters = 0; iters < howmany; iters++){
for(int i = 0; i < ci+1; i++){
int fd = open(name, O_CREATE | O_RDWR);
if(fd < 0){
printf("%s: cannot create %s\n", s, name);
exit(1);
}
int sz = sizeof(buf);
int cc = write(fd, buf, sz);
if(cc != sz){
printf("%s: write(%d) ret %d\n", s, sz, cc);
exit(1);
}
close(fd);
}
unlink(name);
}
unlink(name);
exit(0);
}
}
for(int ci = 0; ci < nchildren; ci++){
int st = 0;
wait(&st);
if(st != 0)
exit(st);
}
exit(0);
}
// regression test. does write() with an invalid buffer pointer cause
// a block to be allocated for a file that is then not freed when the
// file is deleted? if the kernel has this bug, it will panic: balloc:
@ -2775,6 +2679,21 @@ badwrite(char *s)
exit(0);
}
// regression test. test whether exec() leaks memory if one of the
// arguments is invalid. the test passes if the kernel doesn't panic.
void
badarg(char *s)
{
for(int i = 0; i < 50000; i++){
char *argv[2];
argv[0] = (char*)0xffffffff;
argv[1] = 0;
exec("echo", argv);
}
exit(0);
}
// test the exec() code that cleans up if it runs out
// of memory. it's really a test that such a condition
// doesn't cause a panic.
@ -2789,7 +2708,7 @@ execout(char *s)
} else if(pid == 0){
// allocate all of memory.
while(1){
u64 a = (u64) sbrk(4096);
uint64 a = (uint64) sbrk(4096);
if(a == 0xffffffffffffffffLL)
break;
*(char*)(a + 4096 - 1) = 1;
@ -2831,7 +2750,6 @@ diskfull(char *s)
unlink(name);
int fd = open(name, O_CREATE|O_RDWR|O_TRUNC);
if(fd < 0){
// oops, ran out of inodes before running out of blocks.
printf("%s: could not create file %s\n", s, name);
done = 1;
break;
@ -2849,8 +2767,7 @@ diskfull(char *s)
// now that there are no free blocks, test that dirlink()
// merely fails (doesn't panic) if it can't extend
// directory content. one of these file creations
// is expected to fail.
// directory content.
int nzz = 128;
for(int i = 0; i < nzz; i++){
char name[32];
@ -2861,15 +2778,14 @@ diskfull(char *s)
name[4] = '\0';
unlink(name);
int fd = open(name, O_CREATE|O_RDWR|O_TRUNC);
if(fd < 0)
if(fd < 0){
printf("%s: could not create file %s\n", s, name);
break;
}
close(fd);
}
// this mkdir() is expected to fail.
if(mkdir("diskfulldir") == 0)
printf("%s: mkdir(diskfulldir) unexpectedly succeeded!\n");
mkdir("diskfulldir");
unlink("diskfulldir");
for(int i = 0; i < nzz; i++){
@ -2893,91 +2809,6 @@ diskfull(char *s)
}
}
void
outofinodes(char *s)
{
int nzz = 32*32;
for(int i = 0; i < nzz; i++){
char name[32];
name[0] = 'z';
name[1] = 'z';
name[2] = '0' + (i / 32);
name[3] = '0' + (i % 32);
name[4] = '\0';
unlink(name);
int fd = open(name, O_CREATE|O_RDWR|O_TRUNC);
if(fd < 0){
// failure is eventually expected.
break;
}
close(fd);
}
for(int i = 0; i < nzz; i++){
char name[32];
name[0] = 'z';
name[1] = 'z';
name[2] = '0' + (i / 32);
name[3] = '0' + (i % 32);
name[4] = '\0';
unlink(name);
}
}
struct test slowtests[] = {
{bigdir, "bigdir"},
{manywrites, "manywrites"},
{badwrite, "badwrite" },
{execout, "execout"},
{diskfull, "diskfull"},
{outofinodes, "outofinodes"},
{ 0, 0},
};
//
// drive tests
//
// run each test in its own process. run returns 1 if child's exit()
// indicates success.
int
run(void f(char *), char *s) {
int pid;
int xstatus;
printf("test %s: ", s);
if((pid = fork()) < 0) {
printf("runtest: fork error\n");
exit(1);
}
if(pid == 0) {
f(s);
exit(0);
} else {
wait(&xstatus);
if(xstatus != 0)
printf("FAILED\n");
else
printf("OK\n");
return xstatus == 0;
}
}
int
runtests(struct test *tests, char *justone) {
for (struct test *t = tests; t->s != 0; t++) {
if((justone == 0) || strcmp(t->s, justone) == 0) {
if(!run(t->f, t->s)){
printf("SOME TESTS FAILED\n");
return 1;
}
}
}
return 0;
}
//
// use sbrk() to count how many free physical memory pages there are.
// touches the pages to force allocation.
@ -3005,7 +2836,7 @@ countfree()
close(fds[0]);
while(1){
u64 a = (u64) sbrk(4096);
uint64 a = (uint64) sbrk(4096);
if(a == 0xffffffffffffffff){
break;
}
@ -3044,58 +2875,165 @@ countfree()
return n;
}
// run each test in its own process. run returns 1 if child's exit()
// indicates success.
int
drivetests(int quick, int continuous, char *justone) {
do {
printf("usertests starting\n");
int free0 = countfree();
int free1 = 0;
if (runtests(quicktests, justone)) {
if(continuous != 2) {
return 1;
}
}
if(!quick) {
if (justone == 0)
printf("usertests slow tests starting\n");
if (runtests(slowtests, justone)) {
if(continuous != 2) {
return 1;
}
}
}
if((free1 = countfree()) < free0) {
printf("FAILED -- lost some free pages %d (out of %d)\n", free1, free0);
if(continuous != 2) {
return 1;
}
}
} while(continuous);
return 0;
run(void f(char *), char *s) {
int pid;
int xstatus;
printf("test %s: ", s);
if((pid = fork()) < 0) {
printf("runtest: fork error\n");
exit(1);
}
if(pid == 0) {
f(s);
exit(0);
} else {
wait(&xstatus);
if(xstatus != 0)
printf("FAILED\n");
else
printf("OK\n");
return xstatus == 0;
}
}
int
main(int argc, char *argv[])
{
int continuous = 0;
int quick = 0;
char *justone = 0;
if(argc == 2 && strcmp(argv[1], "-q") == 0){
quick = 1;
} else if(argc == 2 && strcmp(argv[1], "-c") == 0){
if(argc == 2 && strcmp(argv[1], "-c") == 0){
continuous = 1;
} else if(argc == 2 && strcmp(argv[1], "-C") == 0){
continuous = 2;
} else if(argc == 2 && argv[1][0] != '-'){
justone = argv[1];
} else if(argc > 1){
printf("Usage: usertests [-c] [-C] [-q] [testname]\n");
printf("Usage: usertests [-c] [testname]\n");
exit(1);
}
if (drivetests(quick, continuous, justone)) {
exit(1);
struct test {
void (*f)(char *);
char *s;
} tests[] = {
{copyin, "copyin"},
{copyout, "copyout"},
{copyinstr1, "copyinstr1"},
{copyinstr2, "copyinstr2"},
{copyinstr3, "copyinstr3"},
{rwsbrk, "rwsbrk" },
{truncate1, "truncate1"},
{truncate2, "truncate2"},
{truncate3, "truncate3"},
{openiputtest, "openiput"},
{exitiputtest, "exitiput"},
{iputtest, "iput"},
{opentest, "opentest"},
{writetest, "writetest"},
{writebig, "writebig"},
{createtest, "createtest"},
{dirtest, "dirtest"},
{exectest, "exectest"},
{pipe1, "pipe1"},
{killstatus, "killstatus"},
{preempt, "preempt"},
{exitwait, "exitwait"},
{reparent, "reparent" },
{twochildren, "twochildren"},
{forkfork, "forkfork"},
{forkforkfork, "forkforkfork"},
{reparent2, "reparent2"},
{mem, "mem"},
{sharedfd, "sharedfd"},
{fourfiles, "fourfiles"},
{createdelete, "createdelete"},
{unlinkread, "unlinkread"},
{linktest, "linktest"},
{concreate, "concreate"},
{linkunlink, "linkunlink"},
{bigdir, "bigdir"}, // slow
{subdir, "subdir"},
{bigwrite, "bigwrite"},
{manywrites, "manywrites"},
{bigfile, "bigfile"},
{fourteen, "fourteen"},
{rmdot, "rmdot"},
{dirfile, "dirfile"},
{iref, "iref"},
{forktest, "forktest"},
{sbrkbasic, "sbrkbasic"},
{sbrkmuch, "sbrkmuch"},
{kernmem, "kernmem"},
{MAXVAplus, "MAXVAplus"},
{sbrkfail, "sbrkfail"},
{sbrkarg, "sbrkarg"},
{validatetest, "validatetest"},
{bsstest, "bsstest"},
{bigargtest, "bigargtest"},
{argptest, "argptest"},
{stacktest, "stacktest"},
{textwrite, "textwrite"},
{pgbug, "pgbug" },
{sbrkbugs, "sbrkbugs" },
{sbrklast, "sbrklast"},
{sbrk8000, "sbrk8000"},
{badwrite, "badwrite" },
{badarg, "badarg" },
{execout, "execout"},
{diskfull, "diskfull"},
{ 0, 0},
};
if(continuous){
printf("continuous usertests starting\n");
while(1){
int fail = 0;
int free0 = countfree();
for (struct test *t = tests; t->s != 0; t++) {
if(!run(t->f, t->s)){
fail = 1;
break;
}
}
if(fail){
printf("SOME TESTS FAILED\n");
if(continuous != 2)
exit(1);
}
int free1 = countfree();
if(free1 < free0){
printf("FAILED -- lost %d free pages\n", free0 - free1);
if(continuous != 2)
exit(1);
}
}
}
printf("usertests starting\n");
int free0 = countfree();
int free1 = 0;
int fail = 0;
for (struct test *t = tests; t->s != 0; t++) {
if((justone == 0) || strcmp(t->s, justone) == 0) {
if(!run(t->f, t->s))
fail = 1;
}
}
if(fail){
printf("SOME TESTS FAILED\n");
exit(1);
} else if((free1 = countfree()) < free0){
printf("FAILED -- lost some free pages %d (out of %d)\n", free1, free0);
exit(1);
} else {
printf("ALL TESTS PASSED\n");
exit(0);
}
printf("ALL TESTS PASSED\n");
exit(0);
}