Minimal implementation of sbrk that allocates from a static array
authorKevin Klues <klueska@cs.berkeley.edu>
Wed, 27 May 2009 11:03:47 +0000 (04:03 -0700)
committerKevin Klues <klueska@cs.berkeley.edu>
Fri, 5 Jun 2009 00:56:28 +0000 (17:56 -0700)
What we really need is to request memory from the OS and return pointers from there until we run
out and need to request more.  Barret and I talked a bit about this yesterday i.e. why not just
return chunks of pages through sbrk?  It could just as easily "malloc" pages of memory from the
OS and return pointers to those instead of relying on the presence of a HEAP that grows towards
the stack.

user/apps/parlib/Makefrag
user/parlib/inc/lib.h
user/parlib/inc/newlib_backend.h [new file with mode: 0644]
user/parlib/inc/parlib.h [deleted file]
user/parlib/src/Makefrag
user/parlib/src/newlib_backend.c [new file with mode: 0644]
user/parlib/src/parlib.c [deleted file]

index c19b4ed..aa7d182 100644 (file)
@@ -10,7 +10,7 @@ USER_APPS_PARLIB_LDFLAGS   := $(USER_LDFLAGS) -static \
 USER_APPS_PARLIB_LDDIRS    := -L$(OBJDIR)/$(USER_PARLIB_DIR) \
                               -L$(USER_PARLIB_NEWLIB_DIR)/lib
 
-USER_APPS_PARLIB_LDLIBS    := -lc -lm -lg -lparlib 
+USER_APPS_PARLIB_LDLIBS    := -lparlib -lc -lm -lg 
 
 USER_APPS_PARLIB_LDOBJS    := $(OBJDIR)/$(USER_PARLIB_DIR)/entry.o
 
index e0ea9a0..297e69d 100644 (file)
@@ -12,7 +12,7 @@
 #include <ros/syscall.h>
 #include <ros/env.h>
 #include <ros/error.h>
-#include <parlib.h>
+#include <newlib_backend.h>
 
 extern volatile env_t *env;
 // will need to change these types when we have real structs
diff --git a/user/parlib/inc/newlib_backend.h b/user/parlib/inc/newlib_backend.h
new file mode 100644 (file)
index 0000000..c1951b9
--- /dev/null
@@ -0,0 +1,212 @@
+/* See COPYRIGHT for copyright information. */
+/* Kevin Klues <klueska@cs.berkeley.edu>       */
+
+#ifndef _NEWLIB_LIBC_WRAPPERS_H
+#define _NEWLIB_LIBC_WRAPPERS_H_
+
+#include <errno.h>
+#include <sys/stat.h>
+#undef errno
+extern int errno;
+
+#define OPEN_ID                0
+#define CLOSE_ID       1
+#define READ_ID                2
+#define WRITE_ID       3
+#define LINK_ID                4
+#define UNLINK_ID      5
+#define LSEEK_ID       6
+#define FSTAT_ID       7
+#define ISATTY_ID      8
+#define STAT_ID                9
+#define NUM_CALLS      10
+
+
+// Fixed size of the client->server msgs for the various calls.
+#define OPEN_MESSAGE_FIXED_SIZE        sizeof(syscall_id) + 3*sizeof(int)
+#define CLOSE_MESSAGE_FIXED_SIZE       sizeof(syscall_id) + sizeof(int)
+#define READ_MESSAGE_FIXED_SIZE        sizeof(syscall_id) + 2*sizeof(int)
+#define WRITE_MESSAGE_FIXED_SIZE       sizeof(syscall_id) + 2*sizeof(int)
+#define LSEEK_MESSAGE_FIXED_SIZE       sizeof(syscall_id) + 3*sizeof(int)
+#define ISATTY_MESSAGE_FIXED_SIZE      sizeof(syscall_id) + sizeof(int)
+#define LINK_MESSAGE_FIXED_SIZE        sizeof(syscall_id) + 2*sizeof(int)
+#define UNLINK_MESSAGE_FIXED_SIZE      sizeof(syscall_id) + sizeof(int)
+#define FSTAT_MESSAGE_FIXED_SIZE       sizeof(syscall_id) + sizeof(int)
+#define STAT_MESSAGE_FIXED_SIZE        sizeof(syscall_id) + sizeof(int)
+
+// What is the max number of arguments (besides the syscall_id) we can have.
+// This should be the max of the above sizes.
+// This exists so we can  allocate a fixed amount of memory to process all incoming msgs
+// TODO: This makes the implicit assumption when referenced in server.c that each argument is of type int.
+//             If we change the above defs to no longer be sizeof(int) this will break in server.c
+#define MAX_FIXED_ARG_COUNT 3
+
+// Fixed server-> respponse msg sizes.
+#define OPEN_RETURN_MESSAGE_FIXED_SIZE                 sizeof(int)
+#define CLOSE_RETURN_MESSAGE_FIXED_SIZE        sizeof(int)
+#define READ_RETURN_MESSAGE_FIXED_SIZE                 sizeof(int)
+#define WRITE_RETURN_MESSAGE_FIXED_SIZE        sizeof(int)
+#define LSEEK_RETURN_MESSAGE_FIXED_SIZE        sizeof(int)
+#define ISATTY_RETURN_MESSAGE_FIXED_SIZE       sizeof(int)
+#define UNLINK_RETURN_MESSAGE_FIXED_SIZE       sizeof(int)
+#define LINK_RETURN_MESSAGE_FIXED_SIZE                 sizeof(int)
+#define STAT_RETURN_MESSAGE_FIXED_SIZE                 sizeof(int) + sizeof(struct stat)
+#define FSTAT_RETURN_MESSAGE_FIXED_SIZE        sizeof(int) + sizeof(struct stat)
+
+// New errno we want to define if a channel error occurs
+// Not yet fully implimented
+#define ECHANNEL -999
+
+// Value to send across the channel as a function return value in the event of server side termination
+// Note yet fully implimented
+#define CONNECTION_TERMINATED -2
+
+// Should refactor this next typedef. Just leave it as type int.
+typedef int syscall_id;
+
+// Replace with uint8?
+typedef char byte;
+
+/* _exit()
+ * Exit a program without cleaning up files. 
+ * If your system doesn't provide this, it is best to avoid linking 
+ * with subroutines that require it (exit, system).
+ */
+void _exit();
+    
+/* close()
+ * Close a file. 
+ * Minimal implementation.
+ */
+int close(int file);
+
+/* execve()
+ * Transfer control to a new process. 
+ * Minimal implementation (for a system without processes).
+ */
+
+int execve(char *name, char **argv, char **env);
+
+/* fork()
+ * Create a new process. 
+ * Minimal implementation (for a system without processes).
+ */
+int fork(void);
+
+/* fstat()
+ * Status of an open file. 
+ * For consistency with other minimal implementations in these stubs, 
+ * all files are regarded as character special devices. 
+ * The sys/stat.h header file required is distributed in the include 
+ * subdirectory for the newlib C library.
+ */
+int fstat(int file, struct stat *st);
+
+/* getpid()
+ * Process-ID; this is sometimes used to generate strings unlikely to 
+ * conflict with other processes. Minimal implementation, for a system 
+ * without processes.
+ */
+int getpid(void);
+
+/* isatty()
+ * Query whether output stream is a terminal. 
+ * For consistency with the other minimal implementations, 
+ * which only support output to stdout, this minimal 
+ * implementation is suggested.
+ */
+int isatty(int file);
+
+/* kill()
+ * Send a signal. 
+ * Minimal implementation.
+ */
+int kill(int pid, int sig);
+
+/* link()
+ * Establish a new name for an existing file. 
+ * Minimal implementation.
+ */
+int link(char *old, char *new);
+
+/* lseek()
+ * Set position in a file. 
+ * Minimal implementation.
+ */
+int lseek(int file, int ptr, int dir);
+
+/* __sseek64()
+ * Set position in a file. 
+ * Minimal implementation.
+ */
+int __sseek64(int file, int ptr, int dir);
+
+/* open()
+ * Open a file. 
+ * Minimal implementation.
+ */
+int open(const char *name, int flags, int mode);
+
+/* read()
+ * Read from a file. 
+ * Minimal implementation.
+ */
+int read(int file, char *ptr, int len);
+
+/* Read len bytes from the given channel to the buffer.
+ * If peek is 0, will wait indefinitely until that much data is read.
+ * If peek is 1, if no data is available, will return immediately.
+ *             However once some data is available, it will block until the entire amount is available.
+ */
+int read_from_channel(byte * buf, int len, int peek);
+
+/* sbrk()
+ * Increase program data space. 
+ * As malloc and related functions depend on this, it is 
+ * useful to have a working implementation. 
+ * The following suffices for a standalone system; it exploits the 
+ * symbol _end automatically defined by the GNU linker.
+ */
+caddr_t sbrk(int incr);
+
+/* send_message()
+ * Write the message defined in buffer out across the channel, and wait for a response.
+ * Caller is responsible for management of both the buffer passed in and the buffer ptr returned.
+ */
+byte *send_message(byte *message, int len);
+
+/* stat()
+ * Status of a file (by name). 
+ * Minimal implementation.
+ */
+int stat(char *file, struct stat *st);
+
+/* times()
+ * Timing information for current process. 
+ * Minimal implementation.
+ */
+int times(struct tms *buf);
+
+/* unlink()
+ * Remove a file's directory entry. 
+ * Minimal implementation.
+ */
+int unlink(char *name);
+
+/* wait()
+ * Wait for a child process. 
+ * Minimal implementation.
+ */
+int wait(int *status);
+
+/* write()
+ * Write to a file. 
+ */
+int write(int file, char *ptr, int len);
+
+/* write_to_channel()
+ * Send a message out over the channel, defined by msg, of length len
+ */
+int write_to_channel(byte * msg, int len);
+
+#endif //_NEWLIB_LIBC_WRAPPERS_H_
diff --git a/user/parlib/inc/parlib.h b/user/parlib/inc/parlib.h
deleted file mode 100644 (file)
index c1951b9..0000000
+++ /dev/null
@@ -1,212 +0,0 @@
-/* See COPYRIGHT for copyright information. */
-/* Kevin Klues <klueska@cs.berkeley.edu>       */
-
-#ifndef _NEWLIB_LIBC_WRAPPERS_H
-#define _NEWLIB_LIBC_WRAPPERS_H_
-
-#include <errno.h>
-#include <sys/stat.h>
-#undef errno
-extern int errno;
-
-#define OPEN_ID                0
-#define CLOSE_ID       1
-#define READ_ID                2
-#define WRITE_ID       3
-#define LINK_ID                4
-#define UNLINK_ID      5
-#define LSEEK_ID       6
-#define FSTAT_ID       7
-#define ISATTY_ID      8
-#define STAT_ID                9
-#define NUM_CALLS      10
-
-
-// Fixed size of the client->server msgs for the various calls.
-#define OPEN_MESSAGE_FIXED_SIZE        sizeof(syscall_id) + 3*sizeof(int)
-#define CLOSE_MESSAGE_FIXED_SIZE       sizeof(syscall_id) + sizeof(int)
-#define READ_MESSAGE_FIXED_SIZE        sizeof(syscall_id) + 2*sizeof(int)
-#define WRITE_MESSAGE_FIXED_SIZE       sizeof(syscall_id) + 2*sizeof(int)
-#define LSEEK_MESSAGE_FIXED_SIZE       sizeof(syscall_id) + 3*sizeof(int)
-#define ISATTY_MESSAGE_FIXED_SIZE      sizeof(syscall_id) + sizeof(int)
-#define LINK_MESSAGE_FIXED_SIZE        sizeof(syscall_id) + 2*sizeof(int)
-#define UNLINK_MESSAGE_FIXED_SIZE      sizeof(syscall_id) + sizeof(int)
-#define FSTAT_MESSAGE_FIXED_SIZE       sizeof(syscall_id) + sizeof(int)
-#define STAT_MESSAGE_FIXED_SIZE        sizeof(syscall_id) + sizeof(int)
-
-// What is the max number of arguments (besides the syscall_id) we can have.
-// This should be the max of the above sizes.
-// This exists so we can  allocate a fixed amount of memory to process all incoming msgs
-// TODO: This makes the implicit assumption when referenced in server.c that each argument is of type int.
-//             If we change the above defs to no longer be sizeof(int) this will break in server.c
-#define MAX_FIXED_ARG_COUNT 3
-
-// Fixed server-> respponse msg sizes.
-#define OPEN_RETURN_MESSAGE_FIXED_SIZE                 sizeof(int)
-#define CLOSE_RETURN_MESSAGE_FIXED_SIZE        sizeof(int)
-#define READ_RETURN_MESSAGE_FIXED_SIZE                 sizeof(int)
-#define WRITE_RETURN_MESSAGE_FIXED_SIZE        sizeof(int)
-#define LSEEK_RETURN_MESSAGE_FIXED_SIZE        sizeof(int)
-#define ISATTY_RETURN_MESSAGE_FIXED_SIZE       sizeof(int)
-#define UNLINK_RETURN_MESSAGE_FIXED_SIZE       sizeof(int)
-#define LINK_RETURN_MESSAGE_FIXED_SIZE                 sizeof(int)
-#define STAT_RETURN_MESSAGE_FIXED_SIZE                 sizeof(int) + sizeof(struct stat)
-#define FSTAT_RETURN_MESSAGE_FIXED_SIZE        sizeof(int) + sizeof(struct stat)
-
-// New errno we want to define if a channel error occurs
-// Not yet fully implimented
-#define ECHANNEL -999
-
-// Value to send across the channel as a function return value in the event of server side termination
-// Note yet fully implimented
-#define CONNECTION_TERMINATED -2
-
-// Should refactor this next typedef. Just leave it as type int.
-typedef int syscall_id;
-
-// Replace with uint8?
-typedef char byte;
-
-/* _exit()
- * Exit a program without cleaning up files. 
- * If your system doesn't provide this, it is best to avoid linking 
- * with subroutines that require it (exit, system).
- */
-void _exit();
-    
-/* close()
- * Close a file. 
- * Minimal implementation.
- */
-int close(int file);
-
-/* execve()
- * Transfer control to a new process. 
- * Minimal implementation (for a system without processes).
- */
-
-int execve(char *name, char **argv, char **env);
-
-/* fork()
- * Create a new process. 
- * Minimal implementation (for a system without processes).
- */
-int fork(void);
-
-/* fstat()
- * Status of an open file. 
- * For consistency with other minimal implementations in these stubs, 
- * all files are regarded as character special devices. 
- * The sys/stat.h header file required is distributed in the include 
- * subdirectory for the newlib C library.
- */
-int fstat(int file, struct stat *st);
-
-/* getpid()
- * Process-ID; this is sometimes used to generate strings unlikely to 
- * conflict with other processes. Minimal implementation, for a system 
- * without processes.
- */
-int getpid(void);
-
-/* isatty()
- * Query whether output stream is a terminal. 
- * For consistency with the other minimal implementations, 
- * which only support output to stdout, this minimal 
- * implementation is suggested.
- */
-int isatty(int file);
-
-/* kill()
- * Send a signal. 
- * Minimal implementation.
- */
-int kill(int pid, int sig);
-
-/* link()
- * Establish a new name for an existing file. 
- * Minimal implementation.
- */
-int link(char *old, char *new);
-
-/* lseek()
- * Set position in a file. 
- * Minimal implementation.
- */
-int lseek(int file, int ptr, int dir);
-
-/* __sseek64()
- * Set position in a file. 
- * Minimal implementation.
- */
-int __sseek64(int file, int ptr, int dir);
-
-/* open()
- * Open a file. 
- * Minimal implementation.
- */
-int open(const char *name, int flags, int mode);
-
-/* read()
- * Read from a file. 
- * Minimal implementation.
- */
-int read(int file, char *ptr, int len);
-
-/* Read len bytes from the given channel to the buffer.
- * If peek is 0, will wait indefinitely until that much data is read.
- * If peek is 1, if no data is available, will return immediately.
- *             However once some data is available, it will block until the entire amount is available.
- */
-int read_from_channel(byte * buf, int len, int peek);
-
-/* sbrk()
- * Increase program data space. 
- * As malloc and related functions depend on this, it is 
- * useful to have a working implementation. 
- * The following suffices for a standalone system; it exploits the 
- * symbol _end automatically defined by the GNU linker.
- */
-caddr_t sbrk(int incr);
-
-/* send_message()
- * Write the message defined in buffer out across the channel, and wait for a response.
- * Caller is responsible for management of both the buffer passed in and the buffer ptr returned.
- */
-byte *send_message(byte *message, int len);
-
-/* stat()
- * Status of a file (by name). 
- * Minimal implementation.
- */
-int stat(char *file, struct stat *st);
-
-/* times()
- * Timing information for current process. 
- * Minimal implementation.
- */
-int times(struct tms *buf);
-
-/* unlink()
- * Remove a file's directory entry. 
- * Minimal implementation.
- */
-int unlink(char *name);
-
-/* wait()
- * Wait for a child process. 
- * Minimal implementation.
- */
-int wait(int *status);
-
-/* write()
- * Write to a file. 
- */
-int write(int file, char *ptr, int len);
-
-/* write_to_channel()
- * Send a message out over the channel, defined by msg, of length len
- */
-int write_to_channel(byte * msg, int len);
-
-#endif //_NEWLIB_LIBC_WRAPPERS_H_
index fa0e33b..04a4594 100644 (file)
@@ -5,7 +5,7 @@ USER_PARLIB_SRC_CFLAGS   := $(USER_CFLAGS) --nopatch \
                             -I$(USER_PARLIB_DIR)/inc \
                             -I$(USER_PARLIB_NEWLIB_DIR)/include
 
-USER_PARLIB_SRC_SRCFILES := $(USER_PARLIB_SRC_DIR)/parlib.c \
+USER_PARLIB_SRC_SRCFILES := $(USER_PARLIB_SRC_DIR)/newlib_backend.c \
                             $(USER_PARLIB_SRC_DIR)/syscall.c \
                             $(USER_PARLIB_SRC_DIR)/libmain.c \
                             $(USER_PARLIB_SRC_DIR)/entry.S  
diff --git a/user/parlib/src/newlib_backend.c b/user/parlib/src/newlib_backend.c
new file mode 100644 (file)
index 0000000..0d91ae4
--- /dev/null
@@ -0,0 +1,513 @@
+/* See COPYRIGHT for copyright information. */
+/* Kevin Klues <klueska@cs.berkeley.edu>       */
+
+#ifdef __DEPUTY__
+#pragma nodeputy
+#endif
+
+#include <lib.h>
+#include <string.h>
+#include <malloc.h>
+#include <newlib_backend.h>
+
+/* environ
+ * A pointer to a list of environment variables and their values. 
+ * For a minimal environment, this empty list is adequate.
+ */
+char *__env[1] = { 0 };
+char **environ = __env;
+extern env_t* env;
+
+/* _exit()
+ * Exit a program without cleaning up files. 
+ * If your system doesn't provide this, it is best to avoid linking 
+ * with subroutines that require it (exit, system).
+ */
+void _exit() 
+{
+       sys_env_destroy(env->env_id);
+}
+    
+/* close()
+ * Close a file. 
+ */
+int close(int file) 
+{
+       // Allocate a new buffer of proper size
+       byte *out_msg = malloc(CLOSE_MESSAGE_FIXED_SIZE);
+       if(out_msg == NULL)
+               return -1;
+
+       byte *out_msg_pos = out_msg;
+
+       // Fill the buffer
+       *((syscall_id *)out_msg_pos) = CLOSE_ID;
+       out_msg_pos += sizeof(syscall_id);
+
+       *((int*)out_msg_pos) = file;
+       out_msg_pos += sizeof(int);
+
+
+       // Send message
+       byte *result = send_message(out_msg, CLOSE_MESSAGE_FIXED_SIZE);
+
+       free(out_msg);
+
+       if (result != NULL) {
+               // Read result
+               int return_val;
+               return_val = *((int *) result);
+               free(result);
+               return return_val;
+       } else {
+               return -1;
+       }
+}
+
+/* execve()
+ * Transfer control to a new process. 
+ * Minimal implementation (for a system without processes).
+ */
+
+int execve(char *name, char **argv, char **env) 
+{
+       errno = ENOMEM;
+       return -1;
+}
+
+/* fork()
+ * Create a new process. 
+ * Minimal implementation (for a system without processes).
+ */
+int fork(void) 
+{
+       errno = EAGAIN;
+    return -1;
+}
+
+/* fstat()
+ * Status of an open file. 
+ * For consistency with other minimal implementations in these stubs, 
+ * all files are regarded as character special devices. 
+ * The sys/stat.h header file required is distributed in the include 
+ * subdirectory for the newlib C library.
+ */
+int fstat(int file, struct stat *st) 
+{
+       st->st_mode = S_IFCHR;
+       return 0;
+}
+
+/* getpid()
+ * Process-ID; this is sometimes used to generate strings unlikely to 
+ * conflict with other processes. Minimal implementation, for a system 
+ * without processes.
+ */
+int getpid(void) 
+{
+       return env->env_id;
+}
+
+/* isatty()
+ * Query whether output stream is a terminal. 
+ * For consistency with the other minimal implementations, 
+ * which only support output to stdout, this minimal 
+ * implementation is suggested.
+ */
+int isatty(int file) 
+{
+       return 1;
+}
+
+/* kill()
+ * Send a signal. 
+ * Minimal implementation.
+ */
+int kill(int pid, int sig) 
+{
+       errno = EINVAL;
+    return -1;
+}
+
+/* link()
+ * Establish a new name for an existing file. 
+ * Minimal implementation.
+ */
+int link(char *old, char *new) 
+{
+       errno = EMLINK;
+       return -1;
+}
+
+/* lseek()
+ * Set position in a file. 
+ * Minimal implementation.
+ */
+int lseek(int file, int ptr, int dir) 
+{
+       return 0;
+}
+
+/* __sseek64()
+ * Set position in a file. 
+ * Minimal implementation.
+ */
+int __sseek64(int file, int ptr, int dir) 
+{
+       return 0;
+}
+
+/* open()
+ * Open a file. 
+ */
+int open(const char *name, int flags, int mode) 
+{
+       int s_len = strlen(name) + 1; // Null terminator
+       int out_msg_len = OPEN_MESSAGE_FIXED_SIZE + s_len;
+
+       // Allocate a new buffer of proper size
+       byte *out_msg = malloc(out_msg_len);
+       byte *out_msg_pos = out_msg;
+
+       if (out_msg == NULL)
+               return -1;
+
+       // Fill the buffer
+       *((syscall_id*)out_msg_pos) = OPEN_ID;
+       out_msg_pos += sizeof(syscall_id);
+
+       *((int*)out_msg_pos) = flags;
+       out_msg_pos += sizeof(int);
+
+       *((int*)out_msg_pos) = mode;
+       out_msg_pos += sizeof(int);
+
+       *((int*)out_msg_pos) = s_len;
+       out_msg_pos += sizeof(int);
+
+       memcpy(out_msg_pos, name, s_len);
+
+       // Send message
+       byte *result = send_message(out_msg, out_msg_len);
+
+       free(out_msg);
+
+       // Read result
+       int return_val;
+
+       if (result != NULL) {
+               return_val = *((int *)result);
+               free(result);
+       } else {
+               return_val = -1;
+       }
+
+       return return_val;
+}
+
+/* read()
+ * Read from a file. 
+ */
+int read(int file, char *ptr, int len) 
+{
+       // Allocate a new buffer of proper size
+       byte *out_msg = (byte*)malloc(READ_MESSAGE_FIXED_SIZE);
+       if (out_msg == NULL)
+               return -1;
+
+       byte *out_msg_pos = out_msg;
+
+       // Fill the buffer
+       *((syscall_id*)out_msg_pos) = READ_ID;
+       out_msg_pos += sizeof(syscall_id);
+
+       *((int *)out_msg_pos) = file;
+       out_msg_pos += sizeof(int);
+
+       *((int *)out_msg_pos) = len;
+       out_msg_pos += sizeof(int);
+
+       // Send message
+       byte *result = send_message(out_msg, READ_MESSAGE_FIXED_SIZE);
+
+       free(out_msg);
+
+       // Read result
+       int return_val;
+
+       if (result != NULL) {
+               return_val = *((int *)result);
+               memcpy(ptr, ((int *)result) + 1, return_val);
+               free(result);
+       } else {
+               return_val = -1;
+       }
+
+       return return_val;
+}
+
+/* Read len bytes from the given channel to the buffer.
+ * If peek is 0, will wait indefinitely until that much data is read.
+ * If peek is 1, if no data is available, will return immediately.
+ *             However once some data is available, it will block until the entire amount is available.
+ */
+int read_from_channel(byte * buf, int len, int peek)
+{
+       // TODO: NEED TO IMPLIMENT A TIMEOUT
+       //                      Also, watch out for CONNECTION TERMINATED
+       // TODO: Add a #define for peek / no peek. Don't know why I didnt do this from the start?
+       int total_read = 0;
+
+       int just_read = sys_serial_read(buf, len);
+
+
+       if (just_read < 0) return just_read;
+       if (just_read == 0 && peek) return just_read;
+
+       total_read += just_read;
+
+       while (total_read != len) {
+               just_read = sys_serial_read(buf + total_read, len - total_read);
+
+               if (just_read == -1) return -1;
+               total_read += just_read;
+       }
+
+       return total_read;
+}
+
+/* sbrk()
+ * Increase program data space. 
+ * As malloc and related functions depend on this, it is 
+ * useful to have a working implementation. 
+ * The following suffices for a standalone system; it exploits the 
+ * symbol _end automatically defined by the GNU linker.
+ */
+caddr_t sbrk(int incr) 
+{
+       #define HEAP_SIZE 5000
+       static uint8_t array[HEAP_SIZE];
+       static uint8_t* heap_end = array;
+       static uint8_t* stack_ptr = &(array[HEAP_SIZE-1]);
+
+       uint8_t* prev_heap_end; 
+
+       prev_heap_end = heap_end;
+       if (heap_end + incr > stack_ptr) {
+               errno = ENOMEM;
+               return (void*)-1;
+       }
+      
+       heap_end += incr;
+       return (caddr_t) prev_heap_end;
+}
+
+/* send_message()
+ * Write the message defined in buffer out across the channel, and wait for a response.
+ * Caller is responsible for management of both the buffer passed in and the buffer ptr returned.
+ */
+byte *send_message(byte *message, int len)
+{
+
+       syscall_id this_call_id = *((syscall_id*)message);
+
+       if (write_to_channel(message, len) != len)
+               return NULL;
+
+       int response_value;
+
+       // Pull the response from the server out of the channel.
+       if (read_from_channel((char*)&response_value, sizeof(int), 0) == -1) return NULL;
+
+       byte* return_msg = NULL;
+
+       // TODO: Make these sizes an array we index into, and only have this code once.
+       // TODO: Will have a flag that tells us we have a variable length response (right now only for read case)
+       // TODO: Default clause with error handling.
+       switch (this_call_id) {
+               case OPEN_ID:
+                       if ((return_msg = (byte*)malloc(OPEN_RETURN_MESSAGE_FIXED_SIZE)) == NULL)
+                               return NULL;
+
+                       break;
+
+               case CLOSE_ID:
+                       if ((return_msg = (byte*)malloc(CLOSE_RETURN_MESSAGE_FIXED_SIZE)) == NULL)
+                               return NULL;
+
+                       break;
+
+               case READ_ID:
+                       if ((return_msg = (byte*)malloc(READ_RETURN_MESSAGE_FIXED_SIZE + response_value)) == NULL)
+                               return NULL;
+
+
+                       if ((read_from_channel(return_msg + sizeof(int), response_value, 0)) == -1)
+                               return NULL;
+
+                       break;
+
+               case WRITE_ID:
+                       if ((return_msg = (byte*)malloc(WRITE_RETURN_MESSAGE_FIXED_SIZE)) == NULL)
+                               return NULL;
+
+                       break;
+
+
+               case LSEEK_ID:
+                       if ((return_msg = (byte*)malloc(LSEEK_RETURN_MESSAGE_FIXED_SIZE)) == NULL)
+                               return NULL;
+
+                       break;
+
+               case ISATTY_ID:
+                       if ((return_msg = (byte*)malloc(ISATTY_RETURN_MESSAGE_FIXED_SIZE)) == NULL)
+                               return NULL;
+
+                       break;
+
+               case UNLINK_ID:
+                       if ((return_msg = (byte*)malloc(UNLINK_RETURN_MESSAGE_FIXED_SIZE + ((response_value != -1) ? 0 : sizeof(int)))) == NULL)
+                               return NULL;
+
+
+                       if ((response_value == -1) && ((read_from_channel(return_msg + sizeof(int), sizeof(int), 0)) == -1))
+                               return NULL;
+
+                       break;
+
+               case LINK_ID:
+                       if ((return_msg = (byte*)malloc(LINK_RETURN_MESSAGE_FIXED_SIZE + ((response_value != -1) ? 0 : sizeof(int)))) == NULL)
+                               return NULL;
+
+
+                       if ((response_value == -1) && ((read_from_channel(return_msg + sizeof(int), sizeof(int), 0)) == -1))
+                               return NULL;
+
+                       break;
+
+               case FSTAT_ID:
+                       if ((return_msg = (byte*)malloc(FSTAT_RETURN_MESSAGE_FIXED_SIZE + ((response_value != -1) ? 0 : sizeof(int)))) == NULL)
+                               return NULL;
+
+                       if ((read_from_channel(return_msg + sizeof(int), sizeof(struct stat), 0)) == -1)
+                               return NULL;
+
+                       if ((response_value == -1) && ((read_from_channel(return_msg + sizeof(int) + sizeof(struct stat), sizeof(int), 0)) == -1))
+                               return NULL;
+
+                       break;
+
+               case STAT_ID:
+                       if ((return_msg = (byte*)malloc(STAT_RETURN_MESSAGE_FIXED_SIZE + ((response_value != -1) ? 0 : sizeof(int)))) == NULL)
+                               return NULL;
+
+                       if ((read_from_channel(return_msg + sizeof(int), sizeof(struct stat), 0)) == -1)
+                               return NULL;
+
+                       if ((response_value == -1) && ((read_from_channel(return_msg + sizeof(int) + sizeof(struct stat), sizeof(int), 0)) == -1))
+                               return NULL;
+
+                       break;
+       }
+
+       memcpy(return_msg, &response_value, sizeof(int));
+
+       return return_msg;
+}
+
+
+/* stat()
+ * Status of a file (by name). 
+ * Minimal implementation.
+ */
+int stat(char *file, struct stat *st) 
+{
+       st->st_mode = S_IFCHR;
+       return 0;
+}
+
+/* times()
+ * Timing information for current process. 
+ * Minimal implementation.
+ */
+int times(struct tms *buf) 
+{
+       return -1;
+}
+
+/* unlink()
+ * Remove a file's directory entry. 
+ * Minimal implementation.
+ */
+int unlink(char *name) 
+{
+       errno = ENOENT;
+       return -1;
+}
+
+/* wait()
+ * Wait for a child process. 
+ * Minimal implementation.
+ */
+int wait(int *status) 
+{
+       errno = ECHILD;
+       return -1;
+}
+
+/* write()
+ * Write to a file. 
+ */
+int write(int file, char *ptr, int len) {
+       int out_msg_len = WRITE_MESSAGE_FIXED_SIZE + len;
+
+       // Allocate a new buffer of proper size
+       byte *out_msg = malloc(out_msg_len);
+       byte *out_msg_pos = out_msg;
+
+       // Fill the buffer
+       *((syscall_id*)out_msg_pos) = WRITE_ID;
+       out_msg_pos += sizeof(syscall_id);
+
+       *((int*)out_msg_pos) = file;
+       out_msg_pos += sizeof(int);
+
+       *((int*)out_msg_pos) = len;
+       out_msg_pos += sizeof(int);
+
+       memcpy(out_msg_pos, ptr, len);
+
+       // Send message
+       byte *result = send_message(out_msg, out_msg_len);
+
+       free(out_msg);
+
+       // Read result
+       int return_val;
+
+       if (result != NULL) {
+               return_val = *((int *)result);
+               free(result);
+       } else {
+               return_val = -1;
+       }
+
+       return return_val;
+}
+
+
+/* write_to_channel()
+ * Send a message out over the channel, defined by msg, of length len
+ */
+int write_to_channel(byte * msg, int len)
+{
+       return sys_serial_write((char*)msg, len);
+}
+
+/* __swrite64()
+ * Write to a file. 
+ */
+int __swrite64(int file, char *ptr, int len) {
+       return 0;
+}
diff --git a/user/parlib/src/parlib.c b/user/parlib/src/parlib.c
deleted file mode 100644 (file)
index f2bd26c..0000000
+++ /dev/null
@@ -1,515 +0,0 @@
-/* See COPYRIGHT for copyright information. */
-/* Kevin Klues <klueska@cs.berkeley.edu>       */
-
-#ifdef __DEPUTY__
-#pragma nodeputy
-#endif
-
-#include <lib.h>
-#include <parlib.h>
-
-/* environ
- * A pointer to a list of environment variables and their values. 
- * For a minimal environment, this empty list is adequate.
- */
-char *__env[1] = { 0 };
-char **environ = __env;
-extern env_t* env;
-
-/* _exit()
- * Exit a program without cleaning up files. 
- * If your system doesn't provide this, it is best to avoid linking 
- * with subroutines that require it (exit, system).
- */
-void _exit() 
-{
-       sys_env_destroy(env->env_id);
-}
-    
-/* close()
- * Close a file. 
- */
-int close(int file) 
-{
-       // Allocate a new buffer of proper size
-       byte *out_msg = malloc(CLOSE_MESSAGE_FIXED_SIZE);
-       if(out_msg == NULL)
-               return -1;
-
-       byte *out_msg_pos = out_msg;
-
-       // Fill the buffer
-       *((syscall_id *)out_msg_pos) = CLOSE_ID;
-       out_msg_pos += sizeof(syscall_id);
-
-       *((int*)out_msg_pos) = file;
-       out_msg_pos += sizeof(int);
-
-
-       // Send message
-       byte *result = send_message(out_msg, CLOSE_MESSAGE_FIXED_SIZE);
-
-       free(out_msg);
-
-       if (result != NULL) {
-               // Read result
-               int return_val;
-               return_val = *((int *) result);
-               free(result);
-               return return_val;
-       } else {
-               return -1;
-       }
-}
-
-/* execve()
- * Transfer control to a new process. 
- * Minimal implementation (for a system without processes).
- */
-
-int execve(char *name, char **argv, char **env) 
-{
-       errno = ENOMEM;
-       return -1;
-}
-
-/* fork()
- * Create a new process. 
- * Minimal implementation (for a system without processes).
- */
-int fork(void) 
-{
-       errno = EAGAIN;
-    return -1;
-}
-
-/* fstat()
- * Status of an open file. 
- * For consistency with other minimal implementations in these stubs, 
- * all files are regarded as character special devices. 
- * The sys/stat.h header file required is distributed in the include 
- * subdirectory for the newlib C library.
- */
-int fstat(int file, struct stat *st) 
-{
-       st->st_mode = S_IFCHR;
-       return 0;
-}
-
-/* getpid()
- * Process-ID; this is sometimes used to generate strings unlikely to 
- * conflict with other processes. Minimal implementation, for a system 
- * without processes.
- */
-int getpid(void) 
-{
-       return env->env_id;
-}
-
-/* isatty()
- * Query whether output stream is a terminal. 
- * For consistency with the other minimal implementations, 
- * which only support output to stdout, this minimal 
- * implementation is suggested.
- */
-int isatty(int file) 
-{
-       return 1;
-}
-
-/* kill()
- * Send a signal. 
- * Minimal implementation.
- */
-int kill(int pid, int sig) 
-{
-       errno = EINVAL;
-    return -1;
-}
-
-/* link()
- * Establish a new name for an existing file. 
- * Minimal implementation.
- */
-int link(char *old, char *new) 
-{
-       errno = EMLINK;
-       return -1;
-}
-
-/* lseek()
- * Set position in a file. 
- * Minimal implementation.
- */
-int lseek(int file, int ptr, int dir) 
-{
-       return 0;
-}
-
-/* __sseek64()
- * Set position in a file. 
- * Minimal implementation.
- */
-int __sseek64(int file, int ptr, int dir) 
-{
-       return 0;
-}
-
-/* open()
- * Open a file. 
- */
-int open(const char *name, int flags, int mode) 
-{
-       int s_len = strlen(name) + 1; // Null terminator
-       int out_msg_len = OPEN_MESSAGE_FIXED_SIZE + s_len;
-
-       // Allocate a new buffer of proper size
-       byte *out_msg = malloc(out_msg_len);
-       byte *out_msg_pos = out_msg;
-
-       if (out_msg == NULL)
-               return -1;
-
-       // Fill the buffer
-       *((syscall_id*)out_msg_pos) = OPEN_ID;
-       out_msg_pos += sizeof(syscall_id);
-
-       *((int*)out_msg_pos) = flags;
-       out_msg_pos += sizeof(int);
-
-       *((int*)out_msg_pos) = mode;
-       out_msg_pos += sizeof(int);
-
-       *((int*)out_msg_pos) = s_len;
-       out_msg_pos += sizeof(int);
-
-       memcpy(out_msg_pos, name, s_len);
-
-       // Send message
-       byte *result = send_message(out_msg, out_msg_len);
-
-       free(out_msg);
-
-       // Read result
-       int return_val;
-
-       if (result != NULL) {
-               return_val = *((int *)result);
-               free(result);
-       } else {
-               return_val = -1;
-       }
-
-       return return_val;
-}
-
-/* read()
- * Read from a file. 
- */
-int read(int file, char *ptr, int len) 
-{
-       // Allocate a new buffer of proper size
-       byte *out_msg = (byte*)malloc(READ_MESSAGE_FIXED_SIZE);
-       if (out_msg == NULL)
-               return -1;
-
-       byte *out_msg_pos = out_msg;
-
-       // Fill the buffer
-       *((syscall_id*)out_msg_pos) = READ_ID;
-       out_msg_pos += sizeof(syscall_id);
-
-       *((int *)out_msg_pos) = file;
-       out_msg_pos += sizeof(int);
-
-       *((int *)out_msg_pos) = len;
-       out_msg_pos += sizeof(int);
-
-       // Send message
-       byte *result = send_message(out_msg, READ_MESSAGE_FIXED_SIZE);
-
-       free(out_msg);
-
-       // Read result
-       int return_val;
-
-       if (result != NULL) {
-               return_val = *((int *)result);
-               memcpy(ptr, ((int *)result) + 1, return_val);
-               free(result);
-       } else {
-               return_val = -1;
-       }
-
-       return return_val;
-}
-
-/* Read len bytes from the given channel to the buffer.
- * If peek is 0, will wait indefinitely until that much data is read.
- * If peek is 1, if no data is available, will return immediately.
- *             However once some data is available, it will block until the entire amount is available.
- */
-int read_from_channel(byte * buf, int len, int peek)
-{
-       // TODO: NEED TO IMPLIMENT A TIMEOUT
-       //                      Also, watch out for CONNECTION TERMINATED
-       // TODO: Add a #define for peek / no peek. Don't know why I didnt do this from the start?
-       int total_read = 0;
-
-       int just_read = sys_serial_read(buf, len);
-
-
-       if (just_read < 0) return just_read;
-       if (just_read == 0 && peek) return just_read;
-
-       total_read += just_read;
-
-       while (total_read != len) {
-               just_read = read(buf + total_read, len - total_read);
-
-               if (just_read == -1) return -1;
-               total_read += just_read;
-       }
-
-       return total_read;
-}
-
-/* sbrk()
- * Increase program data space. 
- * As malloc and related functions depend on this, it is 
- * useful to have a working implementation. 
- * The following suffices for a standalone system; it exploits the 
- * symbol _end automatically defined by the GNU linker.
- */
-caddr_t sbrk(int incr) 
-{
-/*
-       extern char _end;               // Defined by the linker
-       static char *heap_end;
-       char *prev_heap_end;
-
-       if (heap_end == 0) {
-               heap_end = &_end;
-       }
-       prev_heap_end = heap_end;
-       if (heap_end + incr > stack_ptr) {
-               write (1, "Heap and stack collision\n", 25);
-               abort ();
-       }
-      
-       heap_end += incr;
-       return (caddr_t) prev_heap_end;
-*/
-       errno = ENOMEM;
-       return (void*)-1;
-}
-
-/* send_message()
- * Write the message defined in buffer out across the channel, and wait for a response.
- * Caller is responsible for management of both the buffer passed in and the buffer ptr returned.
- */
-byte *send_message(byte *message, int len)
-{
-
-       syscall_id this_call_id = *((syscall_id*)message);
-
-       if (write_to_channel(message, len) != len)
-               return NULL;
-
-       int response_value;
-
-       // Pull the response from the server out of the channel.
-       if (read_from_channel((char*)&response_value, sizeof(int), 0) == -1) return NULL;
-
-       byte* return_msg;
-
-       // TODO: Make these sizes an array we index into, and only have this code once.
-       // TODO: Will have a flag that tells us we have a variable length response (right now only for read case)
-       // TODO: Default clause with error handling.
-       switch (this_call_id) {
-               case OPEN_ID:
-                       if ((return_msg = (byte*)malloc(OPEN_RETURN_MESSAGE_FIXED_SIZE)) == NULL)
-                               return NULL;
-
-                       break;
-
-               case CLOSE_ID:
-                       if ((return_msg = (byte*)malloc(CLOSE_RETURN_MESSAGE_FIXED_SIZE)) == NULL)
-                               return NULL;
-
-                       break;
-
-               case READ_ID:
-                       if ((return_msg = (byte*)malloc(READ_RETURN_MESSAGE_FIXED_SIZE + response_value)) == NULL)
-                               return NULL;
-
-
-                       if ((read_from_channel(return_msg + sizeof(int), response_value, 0)) == -1)
-                               return NULL;
-
-                       break;
-
-               case WRITE_ID:
-                       if ((return_msg = (byte*)malloc(WRITE_RETURN_MESSAGE_FIXED_SIZE)) == NULL)
-                               return NULL;
-
-                       break;
-
-
-               case LSEEK_ID:
-                       if ((return_msg = (byte*)malloc(LSEEK_RETURN_MESSAGE_FIXED_SIZE)) == NULL)
-                               return NULL;
-
-                       break;
-
-               case ISATTY_ID:
-                       if ((return_msg = (byte*)malloc(ISATTY_RETURN_MESSAGE_FIXED_SIZE)) == NULL)
-                               return NULL;
-
-                       break;
-
-               case UNLINK_ID:
-                       if ((return_msg = (byte*)malloc(UNLINK_RETURN_MESSAGE_FIXED_SIZE + ((response_value != -1) ? 0 : sizeof(int)))) == NULL)
-                               return NULL;
-
-
-                       if ((response_value == -1) && ((read_from_channel(return_msg + sizeof(int), sizeof(int), 0)) == -1))
-                               return NULL;
-
-                       break;
-
-               case LINK_ID:
-                       if ((return_msg = (byte*)malloc(LINK_RETURN_MESSAGE_FIXED_SIZE + ((response_value != -1) ? 0 : sizeof(int)))) == NULL)
-                               return NULL;
-
-
-                       if ((response_value == -1) && ((read_from_channel(return_msg + sizeof(int), sizeof(int), 0)) == -1))
-                               return NULL;
-
-                       break;
-
-               case FSTAT_ID:
-                       if ((return_msg = (byte*)malloc(FSTAT_RETURN_MESSAGE_FIXED_SIZE + ((response_value != -1) ? 0 : sizeof(int)))) == NULL)
-                               return NULL;
-
-                       if ((read_from_channel(return_msg + sizeof(int), sizeof(struct stat), 0)) == -1)
-                               return NULL;
-
-                       if ((response_value == -1) && ((read_from_channel(return_msg + sizeof(int) + sizeof(struct stat), sizeof(int), 0)) == -1))
-                               return NULL;
-
-                       break;
-
-               case STAT_ID:
-                       if ((return_msg = (byte*)malloc(STAT_RETURN_MESSAGE_FIXED_SIZE + ((response_value != -1) ? 0 : sizeof(int)))) == NULL)
-                               return NULL;
-
-                       if ((read_from_channel(return_msg + sizeof(int), sizeof(struct stat), 0)) == -1)
-                               return NULL;
-
-                       if ((response_value == -1) && ((read_from_channel(return_msg + sizeof(int) + sizeof(struct stat), sizeof(int), 0)) == -1))
-                               return NULL;
-
-                       break;
-       }
-
-       memcpy(return_msg, &response_value, sizeof(int));
-
-       return return_msg;
-}
-
-
-/* stat()
- * Status of a file (by name). 
- * Minimal implementation.
- */
-int stat(char *file, struct stat *st) 
-{
-       st->st_mode = S_IFCHR;
-       return 0;
-}
-
-/* times()
- * Timing information for current process. 
- * Minimal implementation.
- */
-int times(struct tms *buf) 
-{
-       return -1;
-}
-
-/* unlink()
- * Remove a file's directory entry. 
- * Minimal implementation.
- */
-int unlink(char *name) 
-{
-       errno = ENOENT;
-       return -1;
-}
-
-/* wait()
- * Wait for a child process. 
- * Minimal implementation.
- */
-int wait(int *status) 
-{
-       errno = ECHILD;
-       return -1;
-}
-
-/* write()
- * Write to a file. 
- */
-int write(int file, char *ptr, int len) {
-       int out_msg_len = WRITE_MESSAGE_FIXED_SIZE + len;
-
-       // Allocate a new buffer of proper size
-       byte *out_msg = malloc(out_msg_len);
-       byte *out_msg_pos = out_msg;
-
-       // Fill the buffer
-       *((syscall_id*)out_msg_pos) = WRITE_ID;
-       out_msg_pos += sizeof(syscall_id);
-
-       *((int*)out_msg_pos) = file;
-       out_msg_pos += sizeof(int);
-
-       *((int*)out_msg_pos) = len;
-       out_msg_pos += sizeof(int);
-
-       memcpy(out_msg_pos, ptr, len);
-
-       // Send message
-       byte *result = send_message(out_msg, out_msg_len);
-
-       free(out_msg);
-
-       // Read result
-       int return_val;
-
-       if (result != NULL) {
-               return_val = *((int *)result);
-               free(result);
-       } else {
-               return_val = -1;
-       }
-
-       return return_val;
-}
-
-
-/* write_to_channel()
- * Send a message out over the channel, defined by msg, of length len
- */
-int write_to_channel(byte * msg, int len)
-{
-       return sys_serial_write((char*)msg, len);
-}
-
-/* __swrite64()
- * Write to a file. 
- */
-int __swrite64(int file, char *ptr, int len) {
-       return 0;
-}