Got the kernel's nose out of cmdline args
authorAndrew Waterman <waterman@ubuntu.(none)>
Mon, 21 Dec 2009 05:40:51 +0000 (21:40 -0800)
committerAndrew Waterman <waterman@ubuntu.(none)>
Mon, 21 Dec 2009 05:40:51 +0000 (21:40 -0800)
kern/include/process.h
kern/include/ros/procdata.h
kern/src/env.c
kern/src/syscall.c
user/apps/parlib/matrix.c
user/apps/parlib/run_binary.c
user/apps/parlib/run_binary_colored.c
user/parlib/inc/parlib.h
user/parlib/src/parlibmain.c
user/parlib/src/syscall.c
usrbin/sparc/tlstest

index 6c1ddee..bb54b51 100644 (file)
@@ -73,9 +73,6 @@ void proc_startcore(struct proc *SAFE p, trapframe_t *SAFE tf)
 void proc_destroy(struct proc *SAFE p);
 void proc_yield(struct proc *SAFE p);
 
-/* argc/argv.  TODO: figure out how to move this out of the kernel. */
-size_t proc_init_argc_argv(struct proc* p, size_t nargs, const char** args);
-
 /* Process core management.  Only call these if you are RUNNING_M or RUNNABLE_M.
  * These all adjust the vcoremap and take appropriate actions (like __startcore
  * if you were already RUNNING_M.  You could be RUNNABLE_M with no vcores when
index 6b9bc3e..75e71b3 100644 (file)
@@ -9,17 +9,11 @@
 #include <ros/error.h>
 #include <ros/common.h>
 
-#define PROCINFO_MAX_ARGC 32
-#define PROCINFO_MAX_ARGV_SIZE 1024
+#define PROCINFO_MAX_ARGV_SIZE 2048
 
 typedef struct procinfo {
        pid_t pid;
        size_t max_harts;
-
-       // Temp way to pass arguments to a new process
-       size_t argc;
-       char* argv[PROCINFO_MAX_ARGC];
-
        uint64_t tsc_freq;
 
        char argv_buf[PROCINFO_MAX_ARGV_SIZE];
index a263892..e837f6a 100644 (file)
@@ -145,40 +145,6 @@ env_setup_vm_error:
        return -ENOMEM;
 }
 
-// Sets up argc/argv in procinfo.  Returns number of
-// args successfully imported (because of size restrictions).
-// The procinfo pages must have been mapped into the user's
-// address space before this function can be called.
-size_t
-proc_init_argc_argv(struct proc* p, size_t nargs, const char** args)
-{
-       // TODO: right now we assume procinfo can be directly addressed
-       // by the kernel (i.e. it's continguous.
-       static_assert(sizeof(struct procinfo) <= PGSIZE);
-
-       if(nargs > PROCINFO_MAX_ARGC)
-               nargs = PROCINFO_MAX_ARGC;
-
-       char* argv[PROCINFO_MAX_ARGC] = {0};
-       static_assert(sizeof(argv) == sizeof(p->env_procinfo->argv));
-
-       size_t size = 0, argc;
-       for(argc = 0; argc < nargs; argc++)
-       {
-               size_t len = strnlen(args[argc],PROCINFO_MAX_ARGV_SIZE);
-               if(size+len+1 > PROCINFO_MAX_ARGV_SIZE)
-                       break;
-               memcpy(&p->env_procinfo->argv_buf[size],args[argc],len+1);
-               argv[argc] = (char*)(UINFO+offsetof(struct procinfo,argv_buf)+size);
-               size += len+1;
-       }
-
-       p->env_procinfo->argc = argc;
-       memcpy(p->env_procinfo->argv,argv,sizeof(argv));
-
-       return argc;
-}
-
 // Allocate len bytes of physical memory for environment env,
 // and map it at virtual address va in the environment's address space.
 // Pages are zeroed by upage_alloc.
index 163efe7..948d1de 100644 (file)
@@ -82,11 +82,16 @@ static ssize_t sys_serial_read(env_t* e, char *DANGEROUS _buf, size_t len)
 /* START OF REMOTE SYSTEMCALL SUPPORT SYSCALLS. THESE WILL GO AWAY AS THINGS MATURE */
 //
 
-static ssize_t sys_run_binary(env_t* e, void *DANGEROUS binary_buf,
-                  void*DANGEROUS arg, size_t len, size_t num_colors)
+static ssize_t sys_run_binary(env_t* e, void *DANGEROUS binary_buf, size_t len,
+                              void*DANGEROUS arg, size_t arglen,
+                              size_t num_colors)
 {
        env_t* env = proc_create(NULL,0);
        assert(env != NULL);
+
+       static_assert(PROCINFO_NUM_PAGES == 1);
+       assert(memcpy_from_user(e,env->env_procinfo->argv_buf,arg,arglen) == ESUCCESS);
+
        env_load_icode(env,e,binary_buf,len);
        __proc_set_state(env, PROC_RUNNABLE_S);
        schedule_proc(env);
@@ -552,8 +557,7 @@ intreg_t syscall(struct proc *p, uintreg_t syscallno, uintreg_t a1,
                        return sys_serial_read(p, (char *DANGEROUS)a1, (size_t)a2);
        #endif
                case SYS_run_binary:
-                       return sys_run_binary(p, (char *DANGEROUS)a1, (char* DANGEROUS)a2, 
-                                                                  (size_t)a3, (size_t)a4);
+                       return sys_run_binary(p, (char *DANGEROUS)a1, (size_t)a2, (void* DANGEROUS)a3, (size_t)a4, (size_t)a5);
        #ifdef __NETWORK__
                case SYS_eth_write:
                        return sys_eth_write(p, (char *DANGEROUS)a1, (size_t)a2);
index 145e82b..c86470e 100644 (file)
@@ -13,8 +13,8 @@ extern void change_user();
 extern void set_default_user();
 extern void file_io();
 extern void file_error();
-extern void run_binary();
-extern int  run_binary_filename(const char* fn);
+extern void run_binary(size_t colors);
+extern int  run_binary_filename(const char* fn, size_t colors);
 extern void run_binary_colored();
 extern char prompt[256];
 
@@ -56,10 +56,10 @@ int main(int argc, char** argv)
                else if (strcmp(s, "file_error") == 0)
                        file_error();
                else if (strcmp(s, "run_binary") == 0)
-                       run_binary();
+                       run_binary(0);
                else if (strcmp(s, "run_binary_colored") == 0)
                        run_binary_colored();
-               else if (run_binary_filename(s) == 0)
+               else if (run_binary_filename(s,0) == 0)
                        ;
                else
                        help(); 
index 4357681..2d882bc 100644 (file)
@@ -13,30 +13,43 @@ extern char * readline(const char *prompt);
 #define MALLOC_SIZE     1048576
 #define READ_SIZE       1024
 
-static void fd_error() {
-       fprintf(stderr, "Error: Unable to run remote binary (fd error): %s\n", strerror(errno));
-}
+int run_binary_filename(const char* cmdline, size_t colors)
+{
+       int ret = 0;
 
-static void malloc_error() {
-       fprintf(stderr, "Error: Unable to run remote binary: No more memory avaialable!\n");
-}
+       char argv_buf[PROCINFO_MAX_ARGV_SIZE] = {0};
+       char* argv_buf_ptr = argv_buf;
+       for(int argc = 0; ; argc++)
+       {
+               while(*cmdline == ' ')
+                       cmdline++;
+               if(*cmdline == 0)
+                       break;
 
-static void read_error(void* buf, int fd) {
-       free(buf);
-       close(fd);
-       fprintf(stderr, "Error: Unable to run remote binary (read error): %s\n", strerror(errno));
-}
+               char* p = strchr(cmdline,' ');
+               int len = p == NULL ? strlen(cmdline) : p-cmdline;
 
-static void realloc_error(void* buf, int fd) {
-       free(buf);
-       close(fd);
-       fprintf(stderr, "Error: Unable to run remote binary: No more memory available!\n");
-}
+               memcpy(argv_buf_ptr,cmdline,len);
+               argv_buf_ptr[len] = 0;
+               argv_buf_ptr += len+1;
+
+               if(p == NULL)
+               {
+                       argc++;
+                       break;
+               }
 
-int run_binary_filename(const char* file_name)
-{      
-       int fd = open(file_name, O_RDONLY, 0);
-       if(fd < 0) return fd;
+               cmdline = p;
+       }
+       
+
+       int fd = open(argv_buf, O_RDONLY, 0);
+       if(fd < 0)
+       {
+               printf("open failed\n");
+               ret = -1;
+               goto open_error;
+       }
        
        int total_bytes_read = 0;
        int bytes_read = 0;
@@ -47,35 +60,49 @@ int run_binary_filename(const char* file_name)
                if(total_bytes_read+READ_SIZE > bufsz)
                {
                        void* temp_buf = realloc(binary_buf,bufsz+MALLOC_SIZE);
-                       if(temp_buf == NULL) { realloc_error(binary_buf, fd); return 0; }
+                       if(temp_buf == NULL)
+                       {
+                               printf("realloc failed\n");
+                               ret = -1;
+                               goto realloc_error;
+                       }
+
                        binary_buf = temp_buf;
                        bufsz += MALLOC_SIZE;
                }
 
                bytes_read = read(fd, binary_buf+total_bytes_read, READ_SIZE);
                total_bytes_read += bytes_read;
-               if(bytes_read < 0) { read_error(binary_buf, fd); return 0; }
+               if(bytes_read < 0)
+               {
+                       printf("read error\n");
+                       ret = -1;
+                       goto read_error;
+               }
                if(bytes_read == 0) break;
        }
-       printf("Loading Binary: %s, ROMSIZE: %d\n",file_name,total_bytes_read);
-       ssize_t error = sys_run_binary(binary_buf, NULL, total_bytes_read, 0);
-       if(error < 0) {
+       printf("Loading Binary: %s, ROMSIZE: %d\n",argv_buf,total_bytes_read);
+       ret = sys_run_binary(binary_buf, total_bytes_read, argv_buf, PROCINFO_MAX_ARGV_SIZE, colors);
+       if(ret < 0)
                fprintf(stderr, "Error: Unable to run remote binary\n");
-       }
+       else
+               syscall(SYS_yield,0,0,0,0,0);
+
+read_error:
+realloc_error:
        free(binary_buf);
        close(fd);
-       syscall(SYS_yield,0,0,0,0,0);
-       return 0;
+open_error:
+       return ret;
 }
 
-void run_binary()
+void run_binary(size_t colors)
 {
        char* readline_result = readline("\nEnter name of binary to execute: ");
        if (readline_result == NULL) {
                printf("Error reading from console.\n");
                return;
        }
-       if(run_binary_filename(readline_result) < 0)
-               fd_error();
+       run_binary_filename(readline_result, colors);
 }
 
index 9e60ba0..be73517 100644 (file)
@@ -1,87 +1,17 @@
-#include <string.h>
 #include <stdlib.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <stdint.h>
 #include <stdio.h>
-#include <unistd.h>
-#include <parlib.h>
 
 extern char * readline(const char *prompt);
 
-#define READ_SIZE       1024
-uint8_t* binary_buf;
-
-static void fd_error() {
-       fprintf(stderr, "Error: Unable to run remote binary (fd error): %s\n", 
-                                                             strerror(errno));
-}
-
-static void malloc_error() {
-       fprintf(stderr, 
-               "Error: Unable to run remote binary: No more memory avaialable!\n");
-}
-
-static void read_error(void* buf, int fd) {
-       free(binary_buf);
-       close(fd);
-       fprintf(stderr, "Error: Unable to run remote binary (read error): %s\n", 
-                                                               strerror(errno));
-}
-
-static void realloc_error(void* buf, int fd) {
-       free(binary_buf);
-       close(fd);
-       fprintf(stderr, 
-               "Error: Unable to run remote binary: No more memory available!\n");
-}
-
 void run_binary_colored()
 {      
-       char* name = readline("\nEnter name of binary to execute: ");
-       if (name == NULL) {
-               printf("Error reading from console.\n");
-               return;
-       }
-       char* file_name = name;
-       //char * file_name = malloc(strlen(name) + 8);
-       //sprintf(file_name, "./apps/%s", name);
-       int fd = open(file_name, O_RDONLY, 0);
-       //free(file_name);
-       if(fd < 0) { fd_error(); return; };
-
-       char* colors = readline("\nEnter number of colors: ");
+       char* colors = readline("Enter number of colors: ");
        if (colors == NULL) {
                printf("Error reading from console.\n");
                return;
        }
-       size_t num_colors = atoi(colors);
-       
-       int iters = 1;
-       binary_buf = malloc(READ_SIZE);
-       if(binary_buf == NULL) { malloc_error(); return; }
-       
-       int total_bytes_read = 0;
-       int bytes_read = read(fd, binary_buf, READ_SIZE);
-       if(bytes_read < 0) { read_error(binary_buf, fd); return; }
-       
-       while(bytes_read > 0) {
-               total_bytes_read += bytes_read; 
-               void* temp_buf = realloc(binary_buf, READ_SIZE*(++iters));
-               if(temp_buf == NULL) { realloc_error(binary_buf, fd); return; } 
-               binary_buf = temp_buf;
-               bytes_read = read(fd, binary_buf+total_bytes_read, READ_SIZE);
-               if(bytes_read < 0) { read_error(binary_buf, fd); return; }
-       }
-       printf("Loading Binary: %s, ROMSIZE: %d\n", name, total_bytes_read);
-       ssize_t error = sys_run_binary(binary_buf, NULL, 
-                           total_bytes_read, num_colors);
-       if(error < 0) {
-               fprintf(stderr, "Error: Unable to run remote binary\n");
-       }
-       free(binary_buf);
-       close(fd);
-       syscall(SYS_yield,0,0,0,0,0);
+
+       extern void run_binary(size_t);
+       run_binary((size_t)atoi(colors));
 }
 
index dc3db8e..38104a4 100644 (file)
@@ -33,8 +33,9 @@ ssize_t     sys_serial_write(void* buf, size_t len);
 ssize_t     sys_serial_read(void* buf, size_t len);
 ssize_t     sys_eth_write(void *COUNT(len) buf, size_t len); 
 ssize_t     sys_eth_read(void *COUNT(len) buf, size_t len);
-ssize_t     sys_run_binary(void* binary_buf, void* arg, size_t len, 
-                                                 size_t num_colors);
+ssize_t     sys_run_binary(void* binary_buf, size_t len,
+                           void* arg, size_t arglen, 
+                           size_t num_colors);
 int         sys_getpid(void);
 size_t      sys_getcpuid(void);
 error_t     sys_brk(void* addr);
index 43c26b3..3a65d6b 100644 (file)
@@ -34,6 +34,26 @@ void parlib_ctors()
                ((ctor*)__CTOR_LIST__)[nctor-i-1]();
 }
 
+// build argv from procinfo.argv_buf, which is a packed array
+// of null-terminated strings, terminated by a final null character
+char** parlib_build_argc_argv(int* argc)
+{
+       char* buf = procinfo.argv_buf;
+       for(*argc = 0; *buf; (*argc)++)
+               buf += strlen(buf)+1;
+
+       buf = procinfo.argv_buf;
+       char** argv = (char**)malloc(sizeof(char*)*(*argc+1));
+       for(int i = 0; i < *argc; i++)
+       {
+               argv[i] = buf;
+               buf += strlen(buf)+1;
+       }
+       argv[*argc] = 0;
+
+       return argv;
+}
+
 struct timeval timeval_start;
 
 void parlibmain()
@@ -58,9 +78,15 @@ void parlibmain()
        // call static destructors on exit
        atexit(&parlib_dtors);
 
+       // set up argc/argv
+       int argc;
+       char** argv = parlib_build_argc_argv(&argc);
+
        // call user main routine
        extern int main(int argc, char * NTS * COUNT(argc) NT argv);
-       int r = main(procinfo.argc, procinfo.argv);
+       int r = main(argc,argv);
+
+       // here I'd free(argv), but since we're exiting, it doesn't matter...
 
        // exit gracefully
        exit(r);
index 5e70d2d..d4d6b05 100644 (file)
@@ -58,11 +58,12 @@ ssize_t sys_serial_read(void* buf, size_t len)
 }
 
 //Run a binary loaded at the specificed address with the specified arguments
-ssize_t sys_run_binary(void* binary_buf, void* arg, size_t len, 
+ssize_t sys_run_binary(void* binary_buf, size_t len, void* arg, size_t arglen,
                                               size_t num_colors) 
 {
-       return syscall(SYS_run_binary, (intreg_t)binary_buf, (intreg_t)arg, len, 
-                                                                 num_colors, 0);
+       return syscall(SYS_run_binary, (intreg_t)binary_buf, (intreg_t)len,
+                                       (intreg_t)arg, (intreg_t)arglen,
+                                      (intreg_t)num_colors);
 }
 
 //Write a buffer over ethernet
index 19a6a5c..c6642a8 100755 (executable)
Binary files a/usrbin/sparc/tlstest and b/usrbin/sparc/tlstest differ