Added ability to load an arbitrary binary from an ethernet server and launch it
[akaros.git] / kern / src / syscall.c
index 7e6f69b..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,7 +116,23 @@ 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) 
 {
        extern int eth_up;
@@ -107,7 +141,7 @@ static ssize_t sys_eth_read(env_t* e, char *DANGEROUS buf, size_t len)
                extern int packet_waiting;
                extern int packet_buffer_size;
                extern char* packet_buffer;
-               extern page_t* packet_buffer_page;
+               extern char* packet_buffer_orig;
                extern int packet_buffer_pos;
                        
                if (packet_waiting == 0)
@@ -120,7 +154,7 @@ static ssize_t sys_eth_read(env_t* e, char *DANGEROUS buf, size_t len)
                packet_buffer_pos = packet_buffer_pos + read_len;
        
                if (packet_buffer_pos == packet_buffer_size) {
-                       page_free(packet_buffer_page);
+                       kfree(packet_buffer_orig);
                        packet_waiting = 0;
                }
        
@@ -297,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: