This commit is contained in:
Anish Athalye
2018-10-24 20:44:45 -04:00
parent da1f8392b1
commit c67463e23c
71 changed files with 4734 additions and 18 deletions

82
inc/args.h Normal file
View File

@@ -0,0 +1,82 @@
#ifndef JOS_INC_ARGS_H
#define JOS_INC_ARGS_H
struct Argstate;
// JOS command-line parsing functions.
// Initializes the Argstate buffer from argc and argv.
// (Note: it is safe to use a 'const char **' for argv.)
void argstart(int *argc, char **argv, struct Argstate *args);
// Returns the next flag in the argument list,
// or -1 if there are no more flags.
//
// Flags stop at a non-flag (anything that doesn't start with '-'),
// at the end of the argument list, before "-", or after "--",
// whichever comes first. Any "--" argument is not returned.
//
// Consumes arguments from the argc/argv array passed in to argstart.
// If you argstart with an argc/argv array of ["sh", "-i", "foo"],
// the first call to argnext will return 'i' and change the array to
// ["sh", "foo"]. Thus, when argnext returns -1, the argc/argv array
// contains just the non-flag arguments.
int argnext(struct Argstate *);
// Returns the next value for the current flag, or 0 if it has no value.
// For example, given an argument list ["-fval1", "val2", "val3"],
// a call to argnext() will return 'f', after which repeated calls to
// argnextvalue will return "val1", "val2", and "val3".
// Consumes arguments from the argc/argv array.
char *argnextvalue(struct Argstate *);
// Returns the current flag's value, or 0 if it has no value.
// Behaves like argnextvalue, except that repeated calls to argvalue will
// return the same value.
char *argvalue(struct Argstate *);
// Example:
//
// #include <inc/lib.h>
//
// void
// umain(int argc, char **argv)
// {
// int i;
// struct Argstate args;
//
// argstart(&argc, argv, &args);
// while ((i = argnext(&args)) >= 0)
// switch (i) {
// case 'r':
// case 'x':
// cprintf("'-%c' flag\n", i);
// break;
// case 'f':
// cprintf("'-f %s' flag\n", argvalue(&args));
// break;
// default:
// cprintf("unknown flag\n");
// }
//
// for (i = 1; i < argc; i++)
// cprintf("argument '%s'\n", argv[i]);
// }
//
// If this program is run with the arguments
// ["-rx", "-f", "foo", "--", "-r", "duh"]
// it will print out
// '-r' flag
// '-x' flag
// '-f foo' flag
// argument '-r'
// argument 'duh'
struct Argstate {
int *argc;
const char **argv;
const char *curarg;
const char *argvalue;
};
#endif

View File

@@ -41,6 +41,7 @@ enum {
// Special environment types
enum EnvType {
ENV_TYPE_USER = 0,
ENV_TYPE_FS, // File system server
};
struct Env {

View File

@@ -17,6 +17,15 @@ enum {
E_IPC_NOT_RECV , // Attempt to send to env that is not recving
E_EOF , // Unexpected end of file
// File system error codes -- only seen in user-level
E_NO_DISK , // No free space left on disk
E_MAX_OPEN , // Too many files are open
E_NOT_FOUND , // File or block not found
E_BAD_PATH , // Bad path
E_FILE_EXISTS , // File already exists
E_NOT_EXEC , // File not a valid executable
E_NOT_SUPP , // Operation not supported
MAXERROR
};

58
inc/fd.h Normal file
View File

@@ -0,0 +1,58 @@
// Public definitions for the POSIX-like file descriptor emulation layer
// that our user-land support library implements for the use of applications.
// See the code in the lib directory for the implementation details.
#ifndef JOS_INC_FD_H
#define JOS_INC_FD_H
#include <inc/types.h>
#include <inc/fs.h>
struct Fd;
struct Stat;
struct Dev;
// Per-device-class file descriptor operations
struct Dev {
int dev_id;
const char *dev_name;
ssize_t (*dev_read)(struct Fd *fd, void *buf, size_t len);
ssize_t (*dev_write)(struct Fd *fd, const void *buf, size_t len);
int (*dev_close)(struct Fd *fd);
int (*dev_stat)(struct Fd *fd, struct Stat *stat);
int (*dev_trunc)(struct Fd *fd, off_t length);
};
struct FdFile {
int id;
};
struct Fd {
int fd_dev_id;
off_t fd_offset;
int fd_omode;
union {
// File server files
struct FdFile fd_file;
};
};
struct Stat {
char st_name[MAXNAMELEN];
off_t st_size;
int st_isdir;
struct Dev *st_dev;
};
char* fd2data(struct Fd *fd);
int fd2num(struct Fd *fd);
int fd_alloc(struct Fd **fd_store);
int fd_close(struct Fd *fd, bool must_exist);
int fd_lookup(int fdnum, struct Fd **fd_store);
int dev_lookup(int devid, struct Dev **dev_store);
extern struct Dev devfile;
extern struct Dev devcons;
extern struct Dev devpipe;
#endif // not JOS_INC_FD_H

116
inc/fs.h Normal file
View File

@@ -0,0 +1,116 @@
// See COPYRIGHT for copyright information.
#ifndef JOS_INC_FS_H
#define JOS_INC_FS_H
#include <inc/types.h>
#include <inc/mmu.h>
// File nodes (both in-memory and on-disk)
// Bytes per file system block - same as page size
#define BLKSIZE PGSIZE
#define BLKBITSIZE (BLKSIZE * 8)
// Maximum size of a filename (a single path component), including null
// Must be a multiple of 4
#define MAXNAMELEN 128
// Maximum size of a complete pathname, including null
#define MAXPATHLEN 1024
// Number of block pointers in a File descriptor
#define NDIRECT 10
// Number of direct block pointers in an indirect block
#define NINDIRECT (BLKSIZE / 4)
#define MAXFILESIZE ((NDIRECT + NINDIRECT) * BLKSIZE)
struct File {
char f_name[MAXNAMELEN]; // filename
off_t f_size; // file size in bytes
uint32_t f_type; // file type
// Block pointers.
// A block is allocated iff its value is != 0.
uint32_t f_direct[NDIRECT]; // direct blocks
uint32_t f_indirect; // indirect block
// Pad out to 256 bytes; must do arithmetic in case we're compiling
// fsformat on a 64-bit machine.
uint8_t f_pad[256 - MAXNAMELEN - 8 - 4*NDIRECT - 4];
} __attribute__((packed)); // required only on some 64-bit machines
// An inode block contains exactly BLKFILES 'struct File's
#define BLKFILES (BLKSIZE / sizeof(struct File))
// File types
#define FTYPE_REG 0 // Regular file
#define FTYPE_DIR 1 // Directory
// File system super-block (both in-memory and on-disk)
#define FS_MAGIC 0x4A0530AE // related vaguely to 'J\0S!'
struct Super {
uint32_t s_magic; // Magic number: FS_MAGIC
uint32_t s_nblocks; // Total number of blocks on disk
struct File s_root; // Root directory node
};
// Definitions for requests from clients to file system
enum {
FSREQ_OPEN = 1,
FSREQ_SET_SIZE,
// Read returns a Fsret_read on the request page
FSREQ_READ,
FSREQ_WRITE,
// Stat returns a Fsret_stat on the request page
FSREQ_STAT,
FSREQ_FLUSH,
FSREQ_REMOVE,
FSREQ_SYNC
};
union Fsipc {
struct Fsreq_open {
char req_path[MAXPATHLEN];
int req_omode;
} open;
struct Fsreq_set_size {
int req_fileid;
off_t req_size;
} set_size;
struct Fsreq_read {
int req_fileid;
size_t req_n;
} read;
struct Fsret_read {
char ret_buf[PGSIZE];
} readRet;
struct Fsreq_write {
int req_fileid;
size_t req_n;
char req_buf[PGSIZE - (sizeof(int) + sizeof(size_t))];
} write;
struct Fsreq_stat {
int req_fileid;
} stat;
struct Fsret_stat {
char ret_name[MAXNAMELEN];
off_t ret_size;
int ret_isdir;
} statRet;
struct Fsreq_flush {
int req_fileid;
} flush;
struct Fsreq_remove {
char req_path[MAXPATHLEN];
} remove;
// Ensure Fsipc is one page
char _pad[PGSIZE];
};
#endif /* !JOS_INC_FS_H */

View File

@@ -17,6 +17,9 @@
#include <inc/memlayout.h>
#include <inc/syscall.h>
#include <inc/trap.h>
#include <inc/fs.h>
#include <inc/fd.h>
#include <inc/args.h>
#define USED(x) (void)(x)
@@ -46,6 +49,7 @@ int sys_env_destroy(envid_t);
void sys_yield(void);
static envid_t sys_exofork(void);
int sys_env_set_status(envid_t env, int status);
int sys_env_set_trapframe(envid_t env, struct Trapframe *tf);
int sys_env_set_pgfault_upcall(envid_t env, void *upcall);
int sys_page_alloc(envid_t env, void *pg, int perm);
int sys_page_map(envid_t src_env, void *src_pg,
@@ -75,7 +79,43 @@ envid_t ipc_find_env(enum EnvType type);
envid_t fork(void);
envid_t sfork(void); // Challenge!
// fd.c
int close(int fd);
ssize_t read(int fd, void *buf, size_t nbytes);
ssize_t write(int fd, const void *buf, size_t nbytes);
int seek(int fd, off_t offset);
void close_all(void);
ssize_t readn(int fd, void *buf, size_t nbytes);
int dup(int oldfd, int newfd);
int fstat(int fd, struct Stat *statbuf);
int stat(const char *path, struct Stat *statbuf);
// file.c
int open(const char *path, int mode);
int ftruncate(int fd, off_t size);
int remove(const char *path);
int sync(void);
// pageref.c
int pageref(void *addr);
// spawn.c
envid_t spawn(const char *program, const char **argv);
envid_t spawnl(const char *program, const char *arg0, ...);
// console.c
void cputchar(int c);
int getchar(void);
int iscons(int fd);
int opencons(void);
// pipe.c
int pipe(int pipefds[2]);
int pipeisclosed(int pipefd);
// wait.c
void wait(envid_t env);
/* File open modes */
#define O_RDONLY 0x0000 /* open for reading only */

33
inc/partition.h Normal file
View File

@@ -0,0 +1,33 @@
#ifndef JOS_INC_PARTITION_H
#define JOS_INC_PARTITION_H
#include <inc/types.h>
/*
* This file contains definitions for x86 partition tables, and comes from
* Mike Mammarella.
*/
// Offset of 1st partition descriptor in a partition sector
#define PTABLE_OFFSET 446
// 2-byte partition table magic number location and value
#define PTABLE_MAGIC_OFFSET 510
#define PTABLE_MAGIC "\x55\xAA"
// Partition type constants
#define PTYPE_JOS_KERN 0x27 // JOS kernel
#define PTYPE_JOSFS 0x28 // JOS file system
// Extended partition identifiers
#define PTYPE_DOS_EXTENDED 0x05
#define PTYPE_W95_EXTENDED 0x0F
#define PTYPE_LINUX_EXTENDED 0x85
struct Partitiondesc {
uint8_t boot;
uint8_t chs_begin[3];
uint8_t type;
uint8_t chs_end[3];
uint32_t lba_start;
uint32_t lba_length;
};
#endif

View File

@@ -12,6 +12,7 @@ enum {
SYS_page_unmap,
SYS_exofork,
SYS_env_set_status,
SYS_env_set_trapframe,
SYS_env_set_pgfault_upcall,
SYS_yield,
SYS_ipc_try_send,