@@ -24,6 +24,7 @@ OBJS += main.o
OBJS += mmio.o
OBJS += pci.o
OBJS += util.o
+OBJS += term.o
DEPS := $(patsubst %.o,%.d,$(OBJS))
new file mode 100644
@@ -0,0 +1,17 @@
+#ifndef KVM__TERM_H
+#define KVM__TERM_H
+
+#include <sys/uio.h>
+
+#define CONSOLE_8250 1
+#define CONSOLE_VIRTIO 2
+
+int term_putc_iov(int who, struct iovec *iov, int iovcnt);
+int term_getc_iov(int who, struct iovec *iov, int iovcnt);
+int term_putc(int who, char *addr, int cnt);
+int term_getc(int who);
+
+bool term_readable(int who);
+void term_init(void);
+
+#endif /* KVM__TERM_H */
@@ -5,9 +5,9 @@
#include "kvm/disk-image.h"
#include "kvm/util.h"
#include "kvm/pci.h"
+#include "kvm/term.h"
#include <inttypes.h>
-#include <termios.h>
#include <signal.h>
#include <stdint.h>
#include <stdlib.h>
@@ -29,32 +29,6 @@ static void usage(char *argv[])
static struct kvm *kvm;
-static struct termios orig_term;
-
-static void setup_console(void)
-{
- struct termios term;
-
- if (tcgetattr(STDIN_FILENO, &orig_term) < 0)
- die("unable to save initial standard input settings");
-
- term = orig_term;
-
- term.c_lflag &= ~(ICANON|ECHO);
-
- tcsetattr(STDIN_FILENO, TCSANOW, &term);
-}
-
-static void cleanup_console(void)
-{
- tcsetattr(STDIN_FILENO, TCSANOW, &orig_term);
-}
-
-static void shutdown(void)
-{
- cleanup_console();
-}
-
static void handle_sigint(int sig)
{
exit(1);
@@ -65,7 +39,6 @@ static void handle_sigquit(int sig)
kvm__show_registers(kvm);
kvm__show_code(kvm);
kvm__show_page_tables(kvm);
-
kvm__delete(kvm);
exit(1);
@@ -92,10 +65,6 @@ int main(int argc, char *argv[])
signal(SIGQUIT, handle_sigquit);
signal(SIGINT, handle_sigint);
- setup_console();
-
- atexit(shutdown);
-
for (i = 1; i < argc; i++) {
if (option_matches(argv[i], "--kernel=")) {
kernel_filename = &argv[i][9];
@@ -138,6 +107,8 @@ int main(int argc, char *argv[])
if (!kernel_filename)
usage(argv);
+ term_init();
+
kvm = kvm__init(kvm_dev, ram_size);
if (image_filename) {
new file mode 100644
@@ -0,0 +1,89 @@
+#include <poll.h>
+#include <stdbool.h>
+#include <termios.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/uio.h>
+
+#include "kvm/read-write.h"
+#include "kvm/term.h"
+#include "kvm/util.h"
+
+static struct termios orig_term;
+
+int active_console = CONSOLE_8250;
+
+int term_getc(int who)
+{
+ int c;
+
+ if (who != active_console)
+ return -1;
+
+ if (read_in_full(STDIN_FILENO, &c, 1) < 0)
+ return -1;
+ return c;
+}
+
+int term_putc(int who, char *addr, int cnt)
+{
+ if (who != active_console)
+ return -1;
+
+ while (cnt--) {
+ fprintf(stdout, "%c", *addr++);
+ }
+
+ fflush(stdout);
+ return cnt;
+}
+
+int term_getc_iov(int who, struct iovec *iov, int iovcnt)
+{
+ if (who != active_console)
+ return -1;
+
+ return readv(STDIN_FILENO, iov, iovcnt);
+}
+
+int term_putc_iov(int who, struct iovec *iov, int iovcnt)
+{
+ if (who != active_console)
+ return -1;
+
+ return writev(STDOUT_FILENO, iov, iovcnt);
+}
+
+bool term_readable(int who)
+{
+ struct pollfd pollfd = (struct pollfd) {
+ .fd = STDIN_FILENO,
+ .events = POLLIN,
+ .revents = 0,
+ };
+
+ if (who != active_console)
+ return false;
+
+ return poll(&pollfd, 1, 0) > 0;
+}
+
+static void term_cleanup(void)
+{
+ tcsetattr(STDIN_FILENO, TCSANOW, &orig_term);
+}
+
+void term_init(void)
+{
+ struct termios term;
+
+ if (tcgetattr(STDIN_FILENO, &orig_term) < 0)
+ die("unable to save initial standard input settings");
+
+ term = orig_term;
+ term.c_lflag &= ~(ICANON |ECHO | ISIG);
+ tcsetattr(STDIN_FILENO, TCSANOW, &term);
+
+ atexit(term_cleanup);
+}
+
preparing the virtio console and 8250 serial console consolidation Signed-off-by: Asias He <asias.hejun@gmail.com> --- tools/kvm/Makefile | 1 + tools/kvm/include/kvm/term.h | 17 ++++++++ tools/kvm/main.c | 35 +--------------- tools/kvm/term.c | 89 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 110 insertions(+), 32 deletions(-) create mode 100644 tools/kvm/include/kvm/term.h create mode 100644 tools/kvm/term.c