Fixed up some stuff to try and get printf from newlib to work since sbrk is now in...
authorKevin Klues <klueska@cs.berkeley.edu>
Wed, 27 May 2009 13:38:44 +0000 (06:38 -0700)
committerKevin Klues <klueska@cs.berkeley.edu>
Fri, 5 Jun 2009 00:57:04 +0000 (17:57 -0700)
Doesn't seem to work yet though.  I basically have a redirect in teh body of the write() function
that says if its a write to stdout to call the sys_cputs syscall instead.  Somehow there is
something weird going on in the manager though where I can't just create one environment, run it
and then panic immediately.  I get stuck in some weird infinite loop where it creates an
environment, destroys it, gives me a whole bunch of kernel warnings, and then repeats.  Looking
into this now...

12 files changed:
user/apps/parlib/Makefrag
user/apps/parlib/hello.c
user/apps/roslib/Makefrag
user/parlib/inc/lib.h [deleted file]
user/parlib/inc/newlib_backend.h
user/parlib/inc/parlib.h [new file with mode: 0644]
user/parlib/src/Makefrag
user/parlib/src/entry.S
user/parlib/src/libmain.c [deleted file]
user/parlib/src/newlib_backend.c
user/parlib/src/parlibmain.c [new file with mode: 0644]
user/parlib/src/syscall.c

index aa7d182..cdb76fc 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    := -lparlib -lc -lm -lg 
+USER_APPS_PARLIB_LDLIBS    := --start-group -lc -lm -lg -lparlib --end-group
 
 USER_APPS_PARLIB_LDOBJS    := $(OBJDIR)/$(USER_PARLIB_DIR)/entry.o
 
index db008b1..f5429d7 100644 (file)
@@ -3,6 +3,6 @@
 
 int main(int argc, char** argv)
 {
-       printf("Hello world from newlib!!\n");
+//     printf("Hello world from newlib!!\n");
        return 0;
 }
index 0faedab..91af1d7 100644 (file)
@@ -6,11 +6,11 @@ USER_APPS_ROSLIB_CFLAGS    := $(USER_CFLAGS) -nostdinc \
 USER_APPS_ROSLIB_LDFLAGS   := $(USER_LDFLAGS) -nostdlib -static \
                               -T $(USER_APPS_ROSLIB_DIR)/apps.ld
 USER_APPS_ROSLIB_LDDIRS    := -L$(OBJDIR)/$(USER_ROSLIB_DIR)
-USER_APPS_ROSLIB_LDLIBS    := -livyroslib -lroslib
-USER_APPS_ROSLIB_LDOBJS    := $(OBJDIR)/$(USER_ROSLIB_DIR)/entry.o \
-                              $(OBJDIR)/$(USER_ROSLIB_DIR)/libivyroslib.a \
-                              $(OBJDIR)/$(USER_ROSLIB_DIR)/libroslib.a 
+USER_APPS_ROSLIB_LDLIBS    := --start-group -livyroslib -lroslib --end-group
+USER_APPS_ROSLIB_LDOBJS    := $(OBJDIR)/$(USER_ROSLIB_DIR)/entry.o 
 USER_APPS_ROSLIB_LDDEPENDS := $(USER_APPS_ROSLIB_LDOBJS) \
+                              $(OBJDIR)/$(USER_ROSLIB_DIR)/libivyroslib.a \
+                              $(OBJDIR)/$(USER_ROSLIB_DIR)/libroslib.a \
                               $(OBJDIR)/$(USER_APPS_ROSLIB_DIR)/%.o       
 USER_APPS_ROSLIB_GCC_LIB   := $(GCC_LIB)
 
diff --git a/user/parlib/inc/lib.h b/user/parlib/inc/lib.h
deleted file mode 100644 (file)
index 297e69d..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-// Main public header file for our user-land support library,
-// whose code lives in the lib directory.
-// This library is roughly our OS's version of a standard C library,
-// and is intended to be linked into all user-mode applications
-// (NOT the kernel or boot loader).
-
-#ifndef ROS_INC_LIB_H
-#define ROS_INC_LIB_H 1
-
-#include <arch/types.h>
-#include <ros/memlayout.h>
-#include <ros/syscall.h>
-#include <ros/env.h>
-#include <ros/error.h>
-#include <newlib_backend.h>
-
-extern volatile env_t *env;
-// will need to change these types when we have real structs
-// seems like they need to be either arrays [] or functions () for it to work
-extern volatile uint8_t (COUNT(PGSIZE * UINFO_PAGES) procinfo)[];
-extern volatile uint8_t (COUNT(PGSIZE * UDATA_PAGES) procdata)[];
-
-error_t        sys_serial_write(void* buf, uint16_t len); 
-uint16_t       sys_serial_read(void* buf, uint16_t len);
-envid_t                sys_getenvid(void);
-uint32_t       sys_getcpuid(void);
-int                    sys_env_destroy(envid_t);
-
-#endif // !ROS_INC_LIB_H
index c1951b9..ce28961 100644 (file)
@@ -67,92 +67,6 @@ 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.
@@ -160,50 +74,12 @@ int read(int file, char *ptr, int len);
  */
 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
  */
diff --git a/user/parlib/inc/parlib.h b/user/parlib/inc/parlib.h
new file mode 100644 (file)
index 0000000..19bb1ab
--- /dev/null
@@ -0,0 +1,30 @@
+// Main public header file for our user-land support library,
+// whose code lives in the lib directory.
+// This library is roughly our OS's version of a standard C library,
+// and is intended to be linked into all user-mode applications
+// (NOT the kernel or boot loader).
+
+#ifndef ROS_INC_LIB_H
+#define ROS_INC_LIB_H 1
+
+#include <arch/types.h>
+#include <ros/memlayout.h>
+#include <ros/syscall.h>
+#include <ros/env.h>
+#include <ros/error.h>
+#include <newlib_backend.h>
+
+extern volatile env_t *env;
+// will need to change these types when we have real structs
+// seems like they need to be either arrays [] or functions () for it to work
+extern volatile uint8_t (COUNT(PGSIZE * UINFO_PAGES) procinfo)[];
+extern volatile uint8_t (COUNT(PGSIZE * UDATA_PAGES) procdata)[];
+
+error_t        sys_cputs(const char *s, size_t len);
+error_t        sys_serial_write(void* buf, uint16_t len); 
+uint16_t       sys_serial_read(void* buf, uint16_t len);
+envid_t                sys_getenvid(void);
+uint32_t       sys_getcpuid(void);
+void           sys_env_destroy(envid_t);
+
+#endif // !ROS_INC_LIB_H
index 04a4594..63a203b 100644 (file)
@@ -7,7 +7,7 @@ USER_PARLIB_SRC_CFLAGS   := $(USER_CFLAGS) --nopatch \
 
 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)/parlibmain.c \
                             $(USER_PARLIB_SRC_DIR)/entry.S  
 
 USER_PARLIB_SRC_OBJFILES := $(patsubst $(USER_PARLIB_SRC_DIR)/%.c, \
index cc33ea3..4734b02 100644 (file)
@@ -34,6 +34,6 @@ _start:
        pushl $0
 
 args_exist:
-       call libmain
+       call parlibmain
 1:      jmp 1b
 
diff --git a/user/parlib/src/libmain.c b/user/parlib/src/libmain.c
deleted file mode 100644 (file)
index f6167fb..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-// Called from entry.S to get us going.
-// entry.S already took care of defining envs, pages, vpd, and vpt.
-#ifdef __DEPUTY__
-#pragma nodeputy
-#endif
-
-#include <ros/syscall.h>
-#include <lib.h>
-
-volatile env_t *env;
-extern int main(int argc, char **argv);
-
-void libmain(int argc, char **argv)
-{
-       // set env to point at our env structure in envs[].
-       // TODO: for now, the kernel just copies our env struct to the beginning of
-       // procinfo.  When we figure out what we want there, change this.
-       env = (env_t*)procinfo; 
-
-       // call user main routine
-       int e = main(argc, argv);
-
-       // exit gracefully
-       _exit(e);
-}
index 0d91ae4..f8c43c2 100644 (file)
@@ -5,10 +5,12 @@
 #pragma nodeputy
 #endif
 
-#include <lib.h>
+#include <parlib.h>
+#include <newlib_backend.h>
 #include <string.h>
 #include <malloc.h>
-#include <newlib_backend.h>
+#include <stdlib.h>
+#include <stdio.h>
 
 /* environ
  * A pointer to a list of environment variables and their values. 
@@ -23,9 +25,10 @@ extern env_t* env;
  * If your system doesn't provide this, it is best to avoid linking 
  * with subroutines that require it (exit, system).
  */
-void _exit(
+void _exit(int __status) _ATTRIBUTE ((noreturn))
 {
        sys_env_destroy(env->env_id);
+       while(1); //Should never get here...
 }
     
 /* close()
@@ -285,7 +288,7 @@ int read_from_channel(byte * buf, int len, int peek)
  */
 caddr_t sbrk(int incr) 
 {
-       #define HEAP_SIZE 5000
+       #define HEAP_SIZE 1000
        static uint8_t array[HEAP_SIZE];
        static uint8_t* heap_end = array;
        static uint8_t* stack_ptr = &(array[HEAP_SIZE-1]);
@@ -460,6 +463,9 @@ int wait(int *status)
  * Write to a file. 
  */
 int write(int file, char *ptr, int len) {
+       if(file == 1) //STDOUT_FILENO
+               return sys_cputs(ptr, len);
+       
        int out_msg_len = WRITE_MESSAGE_FIXED_SIZE + len;
 
        // Allocate a new buffer of proper size
diff --git a/user/parlib/src/parlibmain.c b/user/parlib/src/parlibmain.c
new file mode 100644 (file)
index 0000000..be49a5f
--- /dev/null
@@ -0,0 +1,25 @@
+// Called from entry.S to get us going.
+// entry.S already took care of defining envs, pages, vpd, and vpt.
+#ifdef __DEPUTY__
+#pragma nodeputy
+#endif
+
+#include <parlib.h>
+#include <stdlib.h>
+
+volatile env_t *env;
+extern int main(int argc, char **argv);
+
+void parlibmain(int argc, char **argv)
+{
+       // set env to point at our env structure in envs[].
+       // TODO: for now, the kernel just copies our env struct to the beginning of
+       // procinfo.  When we figure out what we want there, change this.
+       env = (env_t*)procinfo; 
+
+       // call user main routine
+       int r = main(argc, argv);
+
+       // exit gracefully
+       exit(r);
+}
index ddf479a..7d9ee41 100644 (file)
@@ -4,8 +4,7 @@
 #endif
 
 #include <arch/x86.h>
-#include <ros/syscall.h>
-#include <lib.h>
+#include <parlib.h>
 
 // TODO: modify to take only four parameters
 static uint32_t
@@ -76,9 +75,10 @@ static inline uint32_t syscall(int num, uint32_t a1, uint32_t a2, uint32_t a3,
        #endif
 }
 
-int sys_env_destroy(envid_t envid)
+void sys_env_destroy(envid_t envid)
 {
-       return syscall(SYS_env_destroy, envid, 0, 0, 0, 0);
+       syscall(SYS_env_destroy, envid, 0, 0, 0, 0);
+       while(1); //Should never get here...
 }
 
 envid_t sys_getenvid(void)
@@ -91,6 +91,11 @@ uint32_t sys_getcpuid(void)
         return syscall(SYS_getcpuid, 0, 0, 0, 0, 0);
 }
 
+error_t sys_cputs(const char *s, size_t len)
+{
+    return syscall(SYS_cputs, (uint32_t) s,  len, 0, 0, 0);
+}
+
 //Write a buffer over the serial port
 error_t sys_serial_write(void* buf, uint16_t len) 
 {