⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vl.c

📁 qemu虚拟机代码
💻 C
📖 第 1 页 / 共 5 页
字号:
    qemu_chr_write(s, buf, strlen(buf));    va_end(ap);}void qemu_chr_send_event(CharDriverState *s, int event){    if (s->chr_send_event)        s->chr_send_event(s, event);}void qemu_chr_add_read_handler(CharDriverState *s,                                IOCanRWHandler *fd_can_read,                                IOReadHandler *fd_read, void *opaque){    s->chr_add_read_handler(s, fd_can_read, fd_read, opaque);}             void qemu_chr_add_event_handler(CharDriverState *s, IOEventHandler *chr_event){    s->chr_event = chr_event;}static int null_chr_write(CharDriverState *chr, const uint8_t *buf, int len){    return len;}static void null_chr_add_read_handler(CharDriverState *chr,                                     IOCanRWHandler *fd_can_read,                                     IOReadHandler *fd_read, void *opaque){}CharDriverState *qemu_chr_open_null(void){    CharDriverState *chr;    chr = qemu_mallocz(sizeof(CharDriverState));    if (!chr)        return NULL;    chr->chr_write = null_chr_write;    chr->chr_add_read_handler = null_chr_add_read_handler;    return chr;}#ifdef _WIN32static void socket_cleanup(void){    WSACleanup();}static int socket_init(void){    WSADATA Data;    int ret, err;    ret = WSAStartup(MAKEWORD(2,2), &Data);    if (ret != 0) {        err = WSAGetLastError();        fprintf(stderr, "WSAStartup: %d\n", err);        return -1;    }    atexit(socket_cleanup);    return 0;}static int send_all(int fd, const uint8_t *buf, int len1){    int ret, len;        len = len1;    while (len > 0) {        ret = send(fd, buf, len, 0);        if (ret < 0) {            int errno;            errno = WSAGetLastError();            if (errno != WSAEWOULDBLOCK) {                return -1;            }        } else if (ret == 0) {            break;        } else {            buf += ret;            len -= ret;        }    }    return len1 - len;}void socket_set_nonblock(int fd){    unsigned long opt = 1;    ioctlsocket(fd, FIONBIO, &opt);}#elsestatic int unix_write(int fd, const uint8_t *buf, int len1){    int ret, len;    len = len1;    while (len > 0) {        ret = write(fd, buf, len);        if (ret < 0) {            if (errno != EINTR && errno != EAGAIN)                return -1;        } else if (ret == 0) {            break;        } else {            buf += ret;            len -= ret;        }    }    return len1 - len;}static inline int send_all(int fd, const uint8_t *buf, int len1){    return unix_write(fd, buf, len1);}void socket_set_nonblock(int fd){    fcntl(fd, F_SETFL, O_NONBLOCK);}#endif /* !_WIN32 */#ifndef _WIN32typedef struct {    int fd_in, fd_out;    IOCanRWHandler *fd_can_read;     IOReadHandler *fd_read;    void *fd_opaque;    int max_size;} FDCharDriver;#define STDIO_MAX_CLIENTS 2static int stdio_nb_clients;static CharDriverState *stdio_clients[STDIO_MAX_CLIENTS];static int fd_chr_write(CharDriverState *chr, const uint8_t *buf, int len){    FDCharDriver *s = chr->opaque;    return unix_write(s->fd_out, buf, len);}static int fd_chr_read_poll(void *opaque){    CharDriverState *chr = opaque;    FDCharDriver *s = chr->opaque;    s->max_size = s->fd_can_read(s->fd_opaque);    return s->max_size;}static void fd_chr_read(void *opaque){    CharDriverState *chr = opaque;    FDCharDriver *s = chr->opaque;    int size, len;    uint8_t buf[1024];        len = sizeof(buf);    if (len > s->max_size)        len = s->max_size;    if (len == 0)        return;    size = read(s->fd_in, buf, len);    if (size > 0) {        s->fd_read(s->fd_opaque, buf, size);    }}static void fd_chr_add_read_handler(CharDriverState *chr,                                     IOCanRWHandler *fd_can_read,                                     IOReadHandler *fd_read, void *opaque){    FDCharDriver *s = chr->opaque;    if (s->fd_in >= 0) {        s->fd_can_read = fd_can_read;        s->fd_read = fd_read;        s->fd_opaque = opaque;        if (nographic && s->fd_in == 0) {        } else {            qemu_set_fd_handler2(s->fd_in, fd_chr_read_poll,                                  fd_chr_read, NULL, chr);        }    }}/* open a character device to a unix fd */CharDriverState *qemu_chr_open_fd(int fd_in, int fd_out){    CharDriverState *chr;    FDCharDriver *s;    chr = qemu_mallocz(sizeof(CharDriverState));    if (!chr)        return NULL;    s = qemu_mallocz(sizeof(FDCharDriver));    if (!s) {        free(chr);        return NULL;    }    s->fd_in = fd_in;    s->fd_out = fd_out;    chr->opaque = s;    chr->chr_write = fd_chr_write;    chr->chr_add_read_handler = fd_chr_add_read_handler;    return chr;}CharDriverState *qemu_chr_open_file_out(const char *file_out){    int fd_out;    fd_out = open(file_out, O_WRONLY | O_TRUNC | O_CREAT | O_BINARY, 0666);    if (fd_out < 0)        return NULL;    return qemu_chr_open_fd(-1, fd_out);}CharDriverState *qemu_chr_open_pipe(const char *filename){    int fd;    fd = open(filename, O_RDWR | O_BINARY);    if (fd < 0)        return NULL;    return qemu_chr_open_fd(fd, fd);}/* for STDIO, we handle the case where several clients use it   (nographic mode) */#define TERM_ESCAPE 0x01 /* ctrl-a is used for escape */#define TERM_FIFO_MAX_SIZE 1static int term_got_escape, client_index;static uint8_t term_fifo[TERM_FIFO_MAX_SIZE];int term_fifo_size;void term_print_help(void){    printf("\n"           "C-a h    print this help\n"           "C-a x    exit emulator\n"           "C-a s    save disk data back to file (if -snapshot)\n"           "C-a b    send break (magic sysrq)\n"           "C-a c    switch between console and monitor\n"           "C-a C-a  send C-a\n"           );}/* called when a char is received */static void stdio_received_byte(int ch){    if (term_got_escape) {        term_got_escape = 0;        switch(ch) {        case 'h':            term_print_help();            break;        case 'x':            exit(0);            break;        case 's':             {                int i;                for (i = 0; i < MAX_DISKS; i++) {                    if (bs_table[i])                        bdrv_commit(bs_table[i]);                }            }            break;        case 'b':            if (client_index < stdio_nb_clients) {                CharDriverState *chr;                FDCharDriver *s;                chr = stdio_clients[client_index];                s = chr->opaque;                chr->chr_event(s->fd_opaque, CHR_EVENT_BREAK);            }            break;        case 'c':            client_index++;            if (client_index >= stdio_nb_clients)                client_index = 0;            if (client_index == 0) {                /* send a new line in the monitor to get the prompt */                ch = '\r';                goto send_char;            }            break;        case TERM_ESCAPE:            goto send_char;        }    } else if (ch == TERM_ESCAPE) {        term_got_escape = 1;    } else {    send_char:        if (client_index < stdio_nb_clients) {            uint8_t buf[1];            CharDriverState *chr;            FDCharDriver *s;                        chr = stdio_clients[client_index];            s = chr->opaque;            if (s->fd_can_read(s->fd_opaque) > 0) {                buf[0] = ch;                s->fd_read(s->fd_opaque, buf, 1);            } else if (term_fifo_size == 0) {                term_fifo[term_fifo_size++] = ch;            }        }    }}static int stdio_read_poll(void *opaque){    CharDriverState *chr;    FDCharDriver *s;    if (client_index < stdio_nb_clients) {        chr = stdio_clients[client_index];        s = chr->opaque;        /* try to flush the queue if needed */        if (term_fifo_size != 0 && s->fd_can_read(s->fd_opaque) > 0) {            s->fd_read(s->fd_opaque, term_fifo, 1);            term_fifo_size = 0;        }        /* see if we can absorb more chars */        if (term_fifo_size == 0)            return 1;        else            return 0;    } else {        return 1;    }}static void stdio_read(void *opaque){    int size;    uint8_t buf[1];        size = read(0, buf, 1);    if (size > 0)        stdio_received_byte(buf[0]);}/* init terminal so that we can grab keys */static struct termios oldtty;static int old_fd0_flags;static void term_exit(void){    tcsetattr (0, TCSANOW, &oldtty);    fcntl(0, F_SETFL, old_fd0_flags);}static void term_init(void){    struct termios tty;    tcgetattr (0, &tty);    oldtty = tty;    old_fd0_flags = fcntl(0, F_GETFL);    tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP                          |INLCR|IGNCR|ICRNL|IXON);    tty.c_oflag |= OPOST;    tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN);    /* if graphical mode, we allow Ctrl-C handling */    if (nographic)        tty.c_lflag &= ~ISIG;    tty.c_cflag &= ~(CSIZE|PARENB);    tty.c_cflag |= CS8;    tty.c_cc[VMIN] = 1;    tty.c_cc[VTIME] = 0;        tcsetattr (0, TCSANOW, &tty);    atexit(term_exit);    fcntl(0, F_SETFL, O_NONBLOCK);}CharDriverState *qemu_chr_open_stdio(void){    CharDriverState *chr;    if (nographic) {        if (stdio_nb_clients >= STDIO_MAX_CLIENTS)            return NULL;        chr = qemu_chr_open_fd(0, 1);        if (stdio_nb_clients == 0)            qemu_set_fd_handler2(0, stdio_read_poll, stdio_read, NULL, NULL);        client_index = stdio_nb_clients;    } else {        if (stdio_nb_clients != 0)            return NULL;        chr = qemu_chr_open_fd(0, 1);    }    stdio_clients[stdio_nb_clients++] = chr;    if (stdio_nb_clients == 1) {        /* set the terminal in raw mode */        term_init();    }    return chr;}#if defined(__linux__)CharDriverState *qemu_chr_open_pty(void){    struct termios tty;    char slave_name[1024];    int master_fd, slave_fd;        /* Not satisfying */    if (openpty(&master_fd, &slave_fd, slave_name, NULL, NULL) < 0) {        return NULL;    }        /* Disabling local echo and line-buffered output */    tcgetattr (master_fd, &tty);    tty.c_lflag &= ~(ECHO|ICANON|ISIG);    tty.c_cc[VMIN] = 1;    tty.c_cc[VTIME] = 0;    tcsetattr (master_fd, TCSAFLUSH, &tty);    fprintf(stderr, "char device redirected to %s\n", slave_name);    return qemu_chr_open_fd(master_fd, master_fd);}static void tty_serial_init(int fd, int speed,                             int parity, int data_bits, int stop_bits){    struct termios tty;    speed_t spd;#if 0    printf("tty_serial_init: speed=%d parity=%c data=%d stop=%d\n",            speed, parity, data_bits, stop_bits);#endif    tcgetattr (fd, &tty);    switch(speed) {    case 50:        spd = B50;        break;    case 75:        spd = B75;        break;    case 300:        spd = B300;        break;    case 600:        spd = B600;        break;    case 1200:        spd = B1200;        break;    case 2400:        spd = B2400;        break;    case 4800:        spd = B4800;        break;    case 9600:        spd = B9600;        break;    case 19200:        spd = B19200;        break;    case 38400:        spd = B38400;        break;    case 57600:        spd = B57600;        break;    default:    case 115200:        spd = B115200;        break;    }    cfsetispeed(&tty, spd);    cfsetospeed(&tty, spd);    tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP                          |INLCR|IGNCR|ICRNL|IXON);    tty.c_oflag |= OPOST;    tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN|ISIG);    tty.c_cflag &= ~(CSIZE|PARENB|PARODD|CRTSCTS);    switch(data_bits) {    default:    case 8:        tty.c_cflag |= CS8;        break;    case 7:        tty.c_cflag |= CS7;        break;    case 6:        tty.c_cflag |= CS6;        break;    case 5:        tty.c_cflag |= CS5;        break;    }    switch(parity) {    default:    case 'N':        break;    case 'E':        tty.c_cflag |= PARENB;        break;    case 'O':        tty.c_cflag |= PARENB | PARODD;        break;    }        tcsetattr (fd, TCSANOW, &tty);}static int tty_serial_ioctl(CharDriverState *chr, int cmd, void *arg){    FDCharDriver *s = chr->opaque;        switch(cmd) {    case CHR_IOCTL_SERIAL_SET_PARAMS:        {            QEMUSerialSetParams *ssp = arg;            tty_serial_init(s->fd_in, ssp->speed, ssp->parity,                             ssp->data_bits, ssp->stop_bits);        }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -