Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


updated module cleanup and added user space tools
Jack Lange [Fri, 18 Mar 2011 19:57:06 +0000 (14:57 -0500)]
linux_module/palacios-dev.c
linux_module/palacios-vm.c
linux_module/palacios.h
linux_usr/Makefile [new file with mode: 0644]
linux_usr/v3_cons.c [new file with mode: 0644]
linux_usr/v3_ctrl.c [new file with mode: 0644]
linux_usr/v3_mem.c [new file with mode: 0644]
linux_usr/v3_monitor.c [new file with mode: 0644]
linux_usr/v3_net.c [new file with mode: 0644]
linux_usr/v3_serial.c [new file with mode: 0644]
linux_usr/v3_stop.c [new file with mode: 0644]

index 585e807..8b30352 100644 (file)
@@ -125,11 +125,12 @@ static long v3_dev_ioctl(struct file * filp,
            INIT_LIST_HEAD(&(guest->streams));
            INIT_LIST_HEAD(&(guest->files));
            INIT_LIST_HEAD(&(guest->sockets));
+           init_completion(&(guest->start_done));
            init_completion(&(guest->thread_done));
 
            kthread_run(start_palacios_vm, guest, guest->name);
 
-           wait_for_completion(&(guest->thread_done));
+           wait_for_completion(&(guest->start_done));
 
            return guest->vm_dev;
            break;
@@ -232,8 +233,6 @@ static int __init v3_init(void) {
     palacios_init_stream();
     palacios_file_init();
     palacios_init_console();
-    
-
 
     return 0;
 
@@ -245,22 +244,29 @@ static int __init v3_init(void) {
     return ret;
 }
 
+
 static void __exit v3_exit(void) {
     extern u32 pg_allocs;
     extern u32 pg_frees;
     extern u32 mallocs;
     extern u32 frees;
 
+    dev_t dev = MKDEV(v3_major_num, MAX_VMS + 1);
+
     printk("Removing V3 Control device\n");
 
-    palacios_vmm_exit();
 
+    palacios_vmm_exit();
 
     printk("Palacios Mallocs = %d, Frees = %d\n", mallocs, frees);
     printk("Palacios Page Allocs = %d, Page Frees = %d\n", pg_allocs, pg_frees);
 
-
     unregister_chrdev_region(MKDEV(v3_major_num, 0), MAX_VMS + 1);
+
+    cdev_del(&ctrl_dev);
+
+    device_destroy(v3_class, dev);
+    class_destroy(v3_class);
 }
 
 
index cd3ba2c..1d8bfe0 100644 (file)
@@ -113,8 +113,6 @@ int start_palacios_vm(void * arg)  {
     unlock_kernel();
     
 
-
-
     guest->v3_ctx = v3_create_vm(guest->img, (void *)guest, guest->name);
 
     if (guest->v3_ctx == NULL) { 
@@ -143,19 +141,17 @@ int start_palacios_vm(void * arg)  {
        return -1;
     }
 
-    complete(&(guest->thread_done));
-
+    complete(&(guest->start_done));
 
     printk("palacios: launching vm\n");   
 
     if (v3_start_vm(guest->v3_ctx, 0xffffffff) < 0) { 
        printk("palacios: launch of vm failed\n");
        return -1;
-    } 
+    }
     
     complete(&(guest->thread_done));
 
-
     printk("palacios: vm completed.  returning.\n");
 
     return 0;
@@ -165,13 +161,16 @@ int start_palacios_vm(void * arg)  {
 
 
 int stop_palacios_vm(struct v3_guest * guest) {
-    
+
     v3_stop_vm(guest->v3_ctx);
 
     wait_for_completion(&(guest->thread_done));
 
     v3_free_vm(guest->v3_ctx);
     
+    device_destroy(v3_class, guest->vm_dev);
+
+    cdev_del(&(guest->cdev));
 
     return 0;
 }
index 1498b73..806e1e7 100644 (file)
@@ -44,6 +44,7 @@ struct v3_guest {
 
     struct palacios_console console;
 
+    struct completion start_done;
     struct completion thread_done;
 
     dev_t vm_dev; 
diff --git a/linux_usr/Makefile b/linux_usr/Makefile
new file mode 100644 (file)
index 0000000..2fc1ad8
--- /dev/null
@@ -0,0 +1,27 @@
+all: v3_ctrl v3_stop v3_cons v3_mem v3_monitor v3_serial v3_net
+
+
+v3_ctrl : v3_ctrl.c v3_ctrl.h
+       gcc -static v3_ctrl.c -o v3_ctrl 
+
+v3_stop : v3_stop.c v3_ctrl.h
+       gcc -static v3_stop.c -o v3_stop 
+
+v3_mem : v3_mem.c v3_ctrl.h
+       gcc -static v3_mem.c -o v3_mem 
+
+
+v3_cons : v3_cons.c v3_ctrl.h
+       gcc -static v3_cons.c -o v3_cons -lcurses
+
+v3_serial : v3_serial.c v3_ctrl.h
+       gcc -static v3_serial.c -pthread -o v3_serial 
+
+v3_monitor : v3_cons.c v3_ctrl.h
+       gcc -static v3_monitor.c -o v3_monitor
+
+v3_net : v3_net.c v3_ctrl.h
+       gcc -static v3_net.c -o v3_net
+
+clean:
+       rm -f v3_ctrl v3_cons v3_mem v3_monitor v3_serial v3_net
diff --git a/linux_usr/v3_cons.c b/linux_usr/v3_cons.c
new file mode 100644 (file)
index 0000000..0c991a5
--- /dev/null
@@ -0,0 +1,396 @@
+/* 
+ * V3 Console utility
+ * Taken from Palacios console display in MINIX ( by Erik Van der Kouwe )
+ * (c) Jack lange, 2010
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/ioctl.h> 
+#include <errno.h>
+#include <assert.h>
+#include <string.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <curses.h>
+#include <termios.h>
+#include <linux/kd.h>
+#include <linux/keyboard.h>
+
+#include "v3_ctrl.h"
+
+static int use_curses = 0;
+static int debug_enable = 0;
+
+
+typedef enum { CONSOLE_CURS_SET = 1,
+              CONSOLE_CHAR_SET = 2,
+              CONSOLE_SCROLL = 3,
+              CONSOLE_UPDATE = 4,
+               CONSOLE_RESOLUTION = 5 } console_op_t;
+
+
+
+static struct {
+    WINDOW * win;
+    int x;
+    int y;
+    int rows;
+    int cols;
+    struct termios termios_old;
+    unsigned char old_kbd_mode;
+} console;
+
+
+struct cursor_msg {
+    int x;
+    int y;
+} __attribute__((packed));
+
+struct character_msg {
+    int x;
+    int y;
+    char c;
+    unsigned char style;
+} __attribute__((packed));
+
+struct scroll_msg {
+    int lines;
+} __attribute__((packed));
+
+struct resolution_msg {
+    int cols;
+    int rows;
+} __attribute__((packed));
+
+
+struct cons_msg {
+    unsigned char op;
+    union {
+       struct cursor_msg cursor;
+       struct character_msg  character;
+       struct scroll_msg scroll;
+       struct resolution_msg resolution;
+    };
+} __attribute__((packed)); 
+
+
+
+
+static int handle_char_set(struct character_msg * msg) {
+    char c = msg->c;
+
+    if (debug_enable) {
+       fprintf(stderr, "setting char (%c), at (x=%d, y=%d)\n", c, msg->x, msg->y);
+    }
+
+    if (c == 0) {
+       c = ' ';
+    }
+
+
+    if ((c < ' ') || (c >= 127)) {
+       fprintf(stderr, "unexpected control character %d\n", c);
+       c = '?';
+    }
+
+    if (use_curses) {
+       /* clip whatever falls outside the visible area to avoid errors */
+       if ((msg->x < 0) || (msg->y < 0) ||
+           (msg->x > console.win->_maxx) || 
+           (msg->y > console.win->_maxy)) {
+
+           fprintf(stderr, "Char out of range (x=%d,y=%d) MAX:(x=%d,y=%d)\n",
+                   msg->x, msg->y, console.win->_maxx, console.win->_maxy);
+           return -1;
+       }
+
+       if ((msg->x == console.win->_maxx) &&
+           (msg->y == console.win->_maxy)) {
+           return -1;
+       }
+
+       mvwaddch(console.win, msg->y, msg->x, c);
+
+    } else {
+       //stdout text display
+       while (console.y < msg->y) {
+           printf("\n");
+           console.x = 0;
+           console.y++;
+       }
+
+       while (console.x < msg->x) {
+           printf(" ");
+           console.x++;
+       }
+
+       printf("%c", c);
+       console.x++;
+
+       assert(console.x <= console.cols); 
+
+       if (console.x == console.cols) {
+           printf("\n");
+           console.x = 0;
+           console.y++;
+       }
+    }
+
+    return 0;
+}
+
+int handle_curs_set(struct cursor_msg * msg) {
+    if (debug_enable) {
+       fprintf(stderr, "cursor set: (x=%d, y=%d)\n", msg->x, msg->y);
+    }
+
+    if (use_curses) {
+       /* nothing to do now, cursor is set before update to make sure it isn't 
+        * affected by character_set
+        */
+
+       console.x = msg->x;
+       console.y = msg->y;
+    }
+    
+    return 0;
+}
+
+
+int handle_scroll(struct scroll_msg * msg) {
+    int lines = msg->lines;
+
+    if (debug_enable) {
+       fprintf(stderr, "scroll: %d lines\n", lines);
+    }
+
+
+    assert(lines >= 0);
+
+    if (use_curses) {
+       while (lines > 0) {
+           scroll(console.win);
+           lines--;
+       }
+    } else {
+       console.y -= lines;     
+    }
+}
+
+int handle_text_resolution(struct resolution_msg * msg) {
+    if (debug_enable) {
+       fprintf(stderr, "text resolution: rows=%d, cols=%d\n", msg->rows, msg->cols);
+    }
+
+
+    console.rows = msg->rows;
+    console.cols = msg->cols;
+
+    return 0;
+}
+
+int handle_update( void ) {
+    if (debug_enable) {
+       fprintf(stderr, "update\n");
+    }    
+
+    if (use_curses) {
+
+       if ( (console.x >= 0) && (console.y >= 0) &&
+            (console.x <= console.win->_maxx) &&
+            (console.y <= console.win->_maxy) ) {
+
+           wmove(console.win, console.y, console.x);
+
+       }
+
+       wrefresh(console.win);
+    } else {
+       fflush(stdout);
+    }
+}
+
+
+int handle_console_msg(int cons_fd) {
+    int ret = 0;
+    struct cons_msg msg;
+
+    ret = read(cons_fd, &msg, sizeof(struct cons_msg));
+
+    switch (msg.op) {
+       case CONSOLE_CURS_SET:
+           //      printf("Console cursor set (x=%d, y=%d)\n", msg.cursor.x, msg.cursor.y);
+           handle_curs_set(&(msg.cursor));
+           break;
+       case CONSOLE_CHAR_SET:
+           handle_char_set(&(msg.character));
+           /*      printf("Console character set (x=%d, y=%d, c=%c, style=%c)\n", 
+             msg.character.x, msg.character.y, msg.character.c, msg.character.style);*/
+           break;
+       case CONSOLE_SCROLL:
+           //  printf("Console scroll (lines=%d)\n", msg.scroll.lines);
+           handle_scroll(&(msg.scroll));
+           break;
+       case CONSOLE_UPDATE:
+           // printf("Console update\n");
+           handle_update();
+           break;
+       case CONSOLE_RESOLUTION:
+           handle_text_resolution(&(msg.resolution));
+           break;
+       default:
+           printf("Invalid console message operation (%d)\n", msg.op);
+           break;
+    }
+
+    return 0;
+}
+
+
+int send_key(int cons_fd, char scan_code) {
+
+    return 0;
+}
+
+
+
+void handle_exit(void) {
+    fprintf(stderr, "Exiting from console terminal\n");
+
+    if (use_curses) {
+       endwin();
+    }
+
+    tcsetattr(STDIN_FILENO, TCSANOW, &console.termios_old);
+
+    ioctl(STDIN_FILENO, KDSKBMODE, K_XLATE);
+}
+
+int main(int argc, char* argv[]) {
+    int vm_fd;
+    int cons_fd;
+    char * vm_dev = NULL;
+    struct termios termios;
+
+    use_curses = 1;
+
+    if (argc < 2) {
+       printf("Usage: ./v3_cons <vm_device>\n");
+       return -1;
+    }
+
+    vm_dev = argv[1];
+
+
+
+    vm_fd = open(vm_dev, O_RDONLY);
+
+    if (vm_fd == -1) {
+       printf("Error opening VM device: %s\n", vm_dev);
+       return -1;
+    }
+
+    cons_fd = ioctl(vm_fd, V3_VM_CONSOLE_CONNECT, NULL); 
+
+    /* Close the file descriptor.  */ 
+    close(vm_fd); 
+
+    if (cons_fd < 0) {
+       printf("Error opening stream Console\n");
+       return -1;
+    }
+
+    tcgetattr(STDIN_FILENO, &console.termios_old);
+    atexit(handle_exit);
+
+    console.x = 0;
+    console.y = 0;
+
+
+    if (use_curses) {
+       gettmode();
+       console.win = initscr();
+       
+       if (console.win == NULL) {
+           fprintf(stderr, "Error initialization curses screen\n");
+           exit(-1);
+       }
+
+       scrollok(console.win, 1);
+    }
+
+    /*
+    termios = console.termios_old;
+    termios.c_iflag &= ~(BRKINT | ICRNL | IGNBRK | IGNCR | IGNPAR);
+    termios.c_iflag &= ~(INLCR | INPCK | ISTRIP | IXOFF | IXON | PARMRK); 
+    //termios.c_iflag &= ~(ICRNL | INLCR );    
+
+    //  termios.c_iflag |= SCANCODES; 
+    //    termios.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL); 
+    //termios.c_lflag &= ~(ICANON | IEXTEN | ISIG | NOFLSH);
+    termios.c_lflag &= ~(ICANON | ECHO);
+
+    termios.c_cc[VMIN] = 1;
+    termios.c_cc[VTIME] = 0;
+
+    tcflush(STDIN_FILENO, TCIFLUSH);
+    tcsetattr(STDIN_FILENO, TCSANOW, &termios);
+    */    
+
+    raw();
+       //cbreak();
+    noecho();
+    keypad(console.win, TRUE);
+
+    ioctl(STDIN_FILENO, KDSKBMODE, K_RAW);
+
+    while (1) {
+       int ret; 
+       int bytes_read = 0;
+       fd_set rset;
+
+       FD_ZERO(&rset);
+       FD_SET(cons_fd, &rset);
+       FD_SET(STDIN_FILENO, &rset);
+
+       ret = select(cons_fd + 1, &rset, NULL, NULL, NULL);
+       
+       //      printf("Returned from select...\n");
+
+       if (ret == 0) {
+           continue;
+       } else if (ret == -1) {
+           perror("Select returned error...\n");
+           return -1;
+       }
+
+       if (FD_ISSET(cons_fd, &rset)) {
+           if (handle_console_msg(cons_fd) == -1) {
+               printf("Console Error\n");
+               return -1;
+           }
+       }
+
+       if (FD_ISSET(STDIN_FILENO, &rset)) {
+           unsigned char key = getch();
+
+           if (key == 0x01) { // ESC
+               break;
+           }
+
+           if (write(cons_fd, &key, 1) != 1) {
+               fprintf(stderr, "ERrror sendign key to console\n");
+               return -1;
+           }
+           
+       }
+    } 
+
+    close(cons_fd);
+
+    return 0; 
+}
+
+
diff --git a/linux_usr/v3_ctrl.c b/linux_usr/v3_ctrl.c
new file mode 100644 (file)
index 0000000..c8bf216
--- /dev/null
@@ -0,0 +1,106 @@
+/* 
+ * V3 Control utility
+ * (c) Jack lange, 2010
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h> 
+#include <sys/ioctl.h> 
+#include <sys/stat.h> 
+#include <sys/types.h> 
+#include <unistd.h> 
+#include <string.h>
+#include "v3_ctrl.h"
+
+int read_file(int fd, int size, unsigned char * buf);
+
+int main(int argc, char* argv[]) {
+    char * filename = argv[1];
+    char * name = argv[2];
+    int guest_fd = 0;
+    int v3_fd = 0;
+    struct v3_guest_img guest_img;
+    struct stat guest_stats;
+    memset(&guest_img, 0, sizeof(struct v3_guest_img));
+
+    if (argc <= 2) {
+       printf("Usage: ./v3_ctrl <guest_img> <vm name>\n");
+       return -1;
+    }
+
+    printf("Launching guest: %s\n", filename);
+
+    guest_fd = open(filename, O_RDONLY); 
+
+    if (guest_fd == -1) {
+       printf("Error Opening guest image: %s\n", filename);
+       return -1;
+    }
+
+    if (fstat(guest_fd, &guest_stats) == -1) {
+       printf("ERROR: Could not stat guest image file -- %s\n", filename);
+       return -1;
+    }
+
+    
+    guest_img.size = guest_stats.st_size;
+    
+    // load guest image into user memory
+    guest_img.guest_data = malloc(guest_img.size);
+
+    read_file(guest_fd, guest_img.size, guest_img.guest_data);
+    
+    close(guest_fd);
+
+    printf("Loaded guest image. Launching to V3Vee\n");
+    
+    strncpy(guest_img.name, name, 127);
+
+
+    v3_fd = open(v3_dev, O_RDONLY);
+
+    if (v3_fd == -1) {
+       printf("Error opening V3Vee control device\n");
+       return -1;
+    }
+
+    ioctl(v3_fd, V3_START_GUEST, &guest_img); 
+
+
+
+    /* Close the file descriptor.  */ 
+    close(v3_fd); 
+
+
+    return 0; 
+} 
+
+
+
+int read_file(int fd, int size, unsigned char * buf) {
+    int left_to_read = size;
+    int have_read = 0;
+
+    while (left_to_read != 0) {
+       int bytes_read = read(fd, buf + have_read, left_to_read);
+
+       if (bytes_read <= 0) {
+           break;
+       }
+
+       have_read += bytes_read;
+       left_to_read -= bytes_read;
+    }
+
+    if (left_to_read != 0) {
+       printf("Error could not finish reading file\n");
+       return -1;
+    }
+    
+    return 0;
+}
diff --git a/linux_usr/v3_mem.c b/linux_usr/v3_mem.c
new file mode 100644 (file)
index 0000000..bb9758c
--- /dev/null
@@ -0,0 +1,77 @@
+/* 
+ * V3 Control utility
+ * (c) Jack lange, 2010
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h> 
+#include <sys/ioctl.h> 
+#include <sys/stat.h> 
+#include <sys/types.h> 
+#include <unistd.h> 
+#include <string.h>
+#include "v3_ctrl.h"
+
+
+int main(int argc, char* argv[]) {
+    unsigned long long base_addr = atoll(argv[1]);
+    unsigned long long num_bytes = atoll(argv[2]);
+    int v3_fd = 0;
+    struct v3_mem_region mem;
+
+    if (argc <= 2) {
+       printf("Usage: ./v3_mem <base_addr> <num_bytes>\n");
+       return -1;
+    }
+
+    printf("Giving Palacios %dMB of memory: \n", num_bytes / (1024 * 1024));
+
+    mem.base_addr = base_addr;
+    mem.num_pages = num_bytes / 4096;
+
+    v3_fd = open(v3_dev, O_RDONLY);
+
+    if (v3_fd == -1) {
+       printf("Error opening V3Vee control device\n");
+       return -1;
+    }
+
+    ioctl(v3_fd, V3_ADD_MEMORY, &mem); 
+
+
+
+    /* Close the file descriptor.  */ 
+    close(v3_fd); 
+
+
+    return 0; 
+} 
+
+
+
+int read_file(int fd, int size, unsigned char * buf) {
+    int left_to_read = size;
+    int have_read = 0;
+
+    while (left_to_read != 0) {
+       int bytes_read = read(fd, buf + have_read, left_to_read);
+
+       if (bytes_read <= 0) {
+           break;
+       }
+
+       have_read += bytes_read;
+       left_to_read -= bytes_read;
+    }
+
+    if (left_to_read != 0) {
+       printf("Error could not finish reading file\n");
+       return -1;
+    }
+    
+    return 0;
+}
diff --git a/linux_usr/v3_monitor.c b/linux_usr/v3_monitor.c
new file mode 100644 (file)
index 0000000..e2c084c
--- /dev/null
@@ -0,0 +1,73 @@
+/* 
+ * V3 Monitor utility
+ * (c) Lei Xia, 2010
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h> 
+#include <sys/ioctl.h> 
+#include <sys/stat.h> 
+#include <sys/types.h> 
+#include <unistd.h>
+#include <string.h>
+#include<linux/unistd.h>
+
+#include "v3_ctrl.h"
+
+int main(int argc, char* argv[]) {
+    int vm_fd;
+    int cons_fd;
+    fd_set rset;
+    char *vm_dev = NULL;
+    char *stream;
+
+    if (argc <= 3) {
+       printf("Usage: ./v3_cons vm_device stream_name\n");
+       return -1;
+    }
+
+    vm_dev = argv[1];
+    stream = argv[2];
+
+    vm_fd = open(vm_dev, O_RDONLY);
+    if (vm_fd == -1) {
+       printf("Error opening VM device: %s\n", vm_dev);
+       return -1;
+    }
+
+    cons_fd = ioctl(vm_fd, V3_VM_CONSOLE_CONNECT, stream); 
+
+    /* Close the file descriptor.  */ 
+    close(vm_fd); 
+    if (cons_fd < 0) {
+       printf("Error opening stream Console\n");
+       return -1;
+    }
+
+    while (1) {
+       int ret; 
+       char cons_buf[1024];
+       memset(cons_buf, 0, sizeof(cons_buf));
+       int bytes_read = 0;
+
+       FD_ZERO(&rset);
+       FD_SET(cons_fd, &rset);
+       
+       ret = select(cons_fd + 1, &rset, NULL, NULL, NULL);
+       
+       if (ret == 1) {
+           bytes_read = read(cons_fd, cons_buf, 1024);
+           cons_buf[bytes_read]='\0';
+           printf("%s", cons_buf);
+       } else {
+           printf("v3_monitor ERROR: select returned %d\n", ret);
+           return -1;
+       }
+    } 
+
+
+    return 0; 
+}
+
+
diff --git a/linux_usr/v3_net.c b/linux_usr/v3_net.c
new file mode 100644 (file)
index 0000000..5449cd4
--- /dev/null
@@ -0,0 +1,64 @@
+/* 
+ * V3 Control utility for Palacios network services
+ * (c) Lei Xia, 2010
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h> 
+#include <sys/ioctl.h> 
+#include <sys/stat.h> 
+#include <sys/types.h> 
+#include <unistd.h> 
+#include <string.h>
+#include "v3_ctrl.h"
+
+struct v3_network {
+    unsigned char socket;
+    unsigned char packet;
+    unsigned char vnet;
+};
+
+int main(int argc, char* argv[]) {
+    int v3_fd = 0;
+    struct v3_network net;
+    int i;
+
+    if (argc <= 1) {
+       printf("Usage: ./v3_mem [socket] [packet] [vnet]\n");
+       return -1;
+    }
+
+    for (i = 1; i < argc; i++){
+       if(!strcasecmp (argv[i], "packet")){
+           net.packet = 1;
+       }else if(!strcasecmp (argv[i], "socket")){
+           net.socket = 1;
+       }else if(!strcasecmp (argv[i], "vnet")){
+           net.vnet = 1;
+       }else {
+           printf("unknown v3 network service: %s, ignored\n", argv[i]);
+       }
+    }
+
+    printf("Network service: socket: %d, packet: %d, vnet: %d\n", net.socket, net.packet, net.vnet);
+
+    v3_fd = open(v3_dev, O_RDONLY);
+
+    if (v3_fd == -1) {
+       printf("Error opening V3Vee control device\n");
+       return -1;
+    }
+
+    ioctl(v3_fd, V3_START_NETWORK, &net); 
+
+
+    /* Close the file descriptor.  */ 
+    close(v3_fd); 
+
+    return 0; 
+} 
+
diff --git a/linux_usr/v3_serial.c b/linux_usr/v3_serial.c
new file mode 100644 (file)
index 0000000..2f66c7f
--- /dev/null
@@ -0,0 +1,101 @@
+/* 
+ * V3 Console utility
+ * (c) Jack lange & Lei Xia, 2010
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h> 
+#include <sys/ioctl.h> 
+#include <sys/stat.h> 
+#include <sys/types.h> 
+#include <unistd.h>
+#include <string.h>
+#include <fcntl.h>
+#include <pthread.h>
+#include <errno.h>
+#include<linux/unistd.h>
+#include <curses.h>
+
+
+#include "v3_ctrl.h"
+
+static int cons_fd = -1;
+static pthread_t input_handler;
+
+void *write_handler(void *val){
+    char read;
+    printf("Write handler active\n");
+    fflush(stdout);
+    while(1){
+       read = getchar();
+       if(write(cons_fd, &read, sizeof(char)) < 0){
+           printf("WRITE ERROR");
+       }
+    }
+}
+
+
+int main(int argc, char* argv[]) {
+    int vm_fd;
+    fd_set rset;
+    char *vm_dev = NULL;
+    char *stream; 
+
+    if (argc < 2) {
+       printf("Usage: ./v3_cons vm_device serial_number\n");
+       return -1;
+    }
+
+    vm_dev = argv[1];
+    stream = argv[2];
+
+    vm_fd = open(vm_dev, O_RDONLY);
+    if (vm_fd == -1) {
+       printf("Error opening VM device: %s\n", vm_dev);
+       return -1;
+    }
+
+    cons_fd = ioctl(vm_fd, V3_VM_SERIAL_CONNECT, stream); 
+
+    /* Close the file descriptor.  */ 
+    close(vm_fd); 
+    if (cons_fd < 0) {
+       printf("Error opening stream Console\n");
+       return -1;
+    }
+
+
+    if(pthread_create(&input_handler,0,write_handler,0)){
+       perror("pthread_create");
+       exit(-1);
+    }
+
+
+    while (1) {
+       int ret; 
+       char cons_buf[1024];
+       memset(cons_buf, 0, sizeof(cons_buf));
+       int bytes_read = 0;
+
+       FD_ZERO(&rset);
+       FD_SET(cons_fd, &rset);
+       
+       ret = select(cons_fd + 1, &rset, NULL, NULL, NULL);
+       
+       if (ret == 1) {
+           bytes_read = read(cons_fd, cons_buf, 1024);
+           cons_buf[bytes_read]='\0';
+           printf("%s", cons_buf);
+       } else {
+           printf("v3_cons ERROR: select returned %d\n", ret);
+           return -1;
+       }
+    } 
+
+
+    return 0; 
+}
+
+
diff --git a/linux_usr/v3_stop.c b/linux_usr/v3_stop.c
new file mode 100644 (file)
index 0000000..b47347d
--- /dev/null
@@ -0,0 +1,51 @@
+/* 
+ * V3 Control utility
+ * (c) Jack lange, 2010
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h> 
+#include <sys/ioctl.h> 
+#include <sys/stat.h> 
+#include <sys/types.h> 
+#include <unistd.h> 
+#include <string.h>
+#include "v3_ctrl.h"
+
+int read_file(int fd, int size, unsigned char * buf);
+
+int main(int argc, char* argv[]) {
+    char * filename = argv[1];
+    int vm_fd = 0;
+
+    if (argc <= 1) {
+       printf("Usage: ./v3_stop <vm-dev>\n");
+       return -1;
+    }
+
+    printf("Stopping VM\n");
+    
+    vm_fd = open(filename, O_RDONLY);
+
+    if (vm_fd == -1) {
+       printf("Error opening V3Vee VM device\n");
+       return -1;
+    }
+
+    ioctl(vm_fd, V3_VM_STOP, NULL); 
+
+
+
+    /* Close the file descriptor.  */ 
+    close(vm_fd); 
+
+
+    return 0; 
+} 
+
+