Added ability to load an arbitrary binary from an ethernet server and launch it
[akaros.git] / kern / src / syscall.c
index 4e51b99..0be42f8 100644 (file)
@@ -17,6 +17,7 @@
 #include <pmap.h>
 #include <trap.h>
 #include <syscall.h>
+#include <kmalloc.h>
 
 void syscall_wrapper(struct Trapframe *tf)
 {
@@ -72,6 +73,19 @@ static ssize_t sys_serial_read(env_t* e, char *DANGEROUS buf, size_t len)
        #endif
 }
 
+static ssize_t sys_run_binary(env_t* e, void* binary_buf, void* arg, size_t len) {
+       uint8_t* new_binary = kmalloc(len, 0);
+       memcpy(new_binary, binary_buf, len);
+
+       env_t* env = env_create((uint8_t*)new_binary, len);
+       kfree(new_binary);
+       
+       e->env_status = ENV_RUNNABLE;
+       env_run(env);
+       return 0;
+}
+
+// This is probably not a syscall we want. Its hacky. Here just for syscall stuff until get a stack.
 static ssize_t sys_eth_write(env_t* e, const char *DANGEROUS buf, size_t len) 
 { 
        extern int eth_up;
@@ -84,11 +98,15 @@ static ssize_t sys_eth_write(env_t* e, const char *DANGEROUS buf, size_t len)
                int cur_packet_len = 0;
                while (total_sent != len) {
                        cur_packet_len = ((len - total_sent) > MAX_PACKET_DATA) ? MAX_PACKET_DATA : (len - total_sent);
-                       
-                       just_sent = send_packet(packet_wrap(buf + total_sent, cur_packet_len), cur_packet_len + PACKET_HEADER_SIZE);
+                       char* wrap_buffer = packet_wrap(buf + total_sent, cur_packet_len);
+                       just_sent = send_frame(wrap_buffer, cur_packet_len + PACKET_HEADER_SIZE);
                        
                        if (just_sent < 0)
-                               return -1; // This should be an error code of its own
+                               return 0; // This should be an error code of its own
+                               
+                       if (wrap_buffer)
+                               kfree(wrap_buffer);
+                               
                        total_sent += cur_packet_len;
                }
                
@@ -98,22 +116,52 @@ static ssize_t sys_eth_write(env_t* e, const char *DANGEROUS buf, size_t len)
        else
                return -E_INVAL;
 }
+/*
+static ssize_t sys_eth_write(env_t* e, const char *DANGEROUS buf, size_t len) 
+{ 
+       extern int eth_up;
+       
+       if (eth_up) {
+               
+               char *COUNT(len) _buf = user_mem_assert(e, buf, len, PTE_U);
+               
+               return(send_frame(buf, len));
+       }
+       return -E_INVAL;
+}
+*/
+
 
+// This is probably not a syscall we want. Its hacky. Here just for syscall stuff until get a stack.
 static ssize_t sys_eth_read(env_t* e, char *DANGEROUS buf, size_t len) 
-{/*
-       #ifdef SERIAL_IO
-           char *COUNT(len) _buf = user_mem_assert(e, buf, len, PTE_U);
-               size_t bytes_read = 0;
-               int c;
-               while((c = serial_read_byte()) != -1) {
-                       buf[bytes_read++] = (uint8_t)c;
-                       if(bytes_read == len) break;
+{
+       extern int eth_up;
+       
+       if (eth_up) {
+               extern int packet_waiting;
+               extern int packet_buffer_size;
+               extern char* packet_buffer;
+               extern char* packet_buffer_orig;
+               extern int packet_buffer_pos;
+                       
+               if (packet_waiting == 0)
+                       return 0;
+                       
+               int read_len = ((packet_buffer_pos + len) > packet_buffer_size) ? packet_buffer_size - packet_buffer_pos : len;
+
+               memcpy(buf, packet_buffer + packet_buffer_pos, read_len);
+       
+               packet_buffer_pos = packet_buffer_pos + read_len;
+       
+               if (packet_buffer_pos == packet_buffer_size) {
+                       kfree(packet_buffer_orig);
+                       packet_waiting = 0;
                }
-               return (ssize_t)bytes_read;
-       #else
+       
+               return read_len;
+       }
+       else
                return -E_INVAL;
-       #endif*/
-               return 0;
 }
 
 // Invalidate the cache of this core
@@ -283,6 +331,9 @@ intreg_t syscall(env_t* e, uint32_t syscallno, uint32_t a1, uint32_t a2,
                        return sys_serial_write(e, (char *DANGEROUS)a1, (size_t)a2);
                case SYS_serial_read:
                        return sys_serial_read(e, (char *DANGEROUS)a1, (size_t)a2);
+               case SYS_run_binary:
+                       return sys_run_binary(e, (char *DANGEROUS)a1, 
+                                             (char* DANGEROUS)a2, (size_t)a3);
                case SYS_eth_write:
                        return sys_eth_write(e, (char *DANGEROUS)a1, (size_t)a2);
                case SYS_eth_read: