📄 console.c
字号:
if(low <= high) set_scroll_region(con, low - 1, high - 1); break; } case 'L': { /* scroll virtual down at cursor */ int lines = (num_args > 0) ? args[0] : 1; while(lines > 0) { scrdown(con); lines--; } break; } case 'M': { /* scroll virtual up at cursor */ int lines = (num_args > 0) ? args[0] : 1; while(lines > 0) { scrup(con); lines--; } break; } case 'K': if(num_args < 0) { // erase to end of line erase_line(con, LINE_ERASE_RIGHT); } else { if(args[0] == 1) erase_line(con, LINE_ERASE_LEFT); else if(args[0] == 2) erase_line(con, LINE_ERASE_WHOLE); } break; case 'J': if(num_args < 0) { // erase to end of screen erase_screen(con, SCREEN_ERASE_DOWN); } else { if(args[0] == 1) erase_screen(con, SCREEN_ERASE_UP); else if(args[0] == 2) erase_screen(con, SCREEN_ERASE_WHOLE); } break; case 'm': if(num_args >= 0) { set_vt100_attributes(con, args, num_args); } break; default: ret = false; } } else { switch(c) { case 'c': reset_console(con); break; case 'D': rlf(con); break; case 'M': lf(con); break; case '7': save_cur(con, true); break; case '8': restore_cur(con, true); break; default: ret = false; } } return ret;}// used by kprintf() to draw directly onto the screenstatic ssize_t _console_write_raw(struct console_desc *con, const void *buf, ssize_t len){ const char *c; ssize_t pos = 0; while(pos < len) { c = &((const char *)buf)[pos++]; switch(*c) { case '\n': cr(con); lf(con); break; case 0x8: // backspace del(con); break; case '\t': tab(con); break; case '\r': case '\0': case 0x1b: break; default: console_putch(con, *c); } } return pos;}// used by kprintf_xy() to draw directly onto the screen. Do not update the console's current x y posstatic ssize_t _console_write_raw_xy(struct console_desc *in_con, const void *buf, ssize_t len, int x, int y){ const char *c; ssize_t pos = 0; struct console_desc con; memcpy(&con, in_con, sizeof(con)); // not great, but it keeps us from updating the system's x y gotoxy(&con, x, y); while(pos < len) { c = &((const char *)buf)[pos++]; switch(*c) { case '\n': cr(&con); lf(&con); break; case 0x8: // backspace del(&con); break; case '\t': tab(&con); break; case '\r': case '\0': case 0x1b: break; default: console_putch(&con, *c); } } return pos;}static ssize_t _console_write(struct console_desc *con, const void *buf, size_t len){ const char *c; size_t pos = 0; while(pos < len) { c = &((const char *)buf)[pos++]; switch(con->state) { case CONSOLE_STATE_NORMAL: // just output the stuff switch(*c) { case '\n': lf(con); break; case '\r': cr(con); break; case 0x8: // backspace del(con); break; case '\t': tab(con); break; case '\0': break; case 0x1b: // escape character con->arg_ptr = -1; con->state = CONSOLE_STATE_GOT_ESCAPE; break; default: console_putch(con, *c); } break; case CONSOLE_STATE_GOT_ESCAPE: // look for either commands with no argument, or the '[' character switch(*c) { case '[': con->state = CONSOLE_STATE_SEEN_BRACKET; break; default: process_vt100_command(con, *c, false, con->args, con->arg_ptr + 1); con->state = CONSOLE_STATE_NORMAL; } break; case CONSOLE_STATE_SEEN_BRACKET: switch(*c) { case '0'...'9': con->arg_ptr = 0; con->args[con->arg_ptr] = *c - '0'; con->state = CONSOLE_STATE_PARSING_ARG; break; default: process_vt100_command(con, *c, true, con->args, con->arg_ptr + 1); con->state = CONSOLE_STATE_NORMAL; } break; case CONSOLE_STATE_NEW_ARG: switch(*c) { case '0'...'9': con->arg_ptr++; if(con->arg_ptr == MAX_ARGS) { con->state = CONSOLE_STATE_NORMAL; break; } con->args[con->arg_ptr] = *c - '0'; con->state = CONSOLE_STATE_PARSING_ARG; break; default: process_vt100_command(con, *c, true, con->args, con->arg_ptr + 1); con->state = CONSOLE_STATE_NORMAL; } break; case CONSOLE_STATE_PARSING_ARG: // parse args switch(*c) { case '0'...'9': con->args[con->arg_ptr] *= 10; con->args[con->arg_ptr] += *c - '0'; break; case ';': con->state = CONSOLE_STATE_NEW_ARG; break; default: process_vt100_command(con, *c, true, con->args, con->arg_ptr + 1); con->state = CONSOLE_STATE_NORMAL; } } } return pos;}static ssize_t console_write(dev_cookie cookie, const void *buf, off_t pos, ssize_t len){ ssize_t err; struct console_desc *con = (struct console_desc *)cookie;// dprintf("console_write: entry, len = %d\n", *len); mutex_lock(&con->lock); update_cursor(con, -1, -1); // hide it err = _console_write(con, buf, len); update_cursor(con, con->x, con->y); mutex_unlock(&con->lock); return err;}static int console_ioctl(dev_cookie cookie, int op, void *buf, size_t len){ int err; struct console_desc *con = (struct console_desc *)cookie; switch(op) { case CONSOLE_OP_WRITEXY: { int x,y; mutex_lock(&con->lock); x = ((int *)buf)[0]; y = ((int *)buf)[1]; save_cur(con, false); gotoxy(con, x, y); if(_console_write(con, ((char *)buf) + 2*sizeof(int), len - 2*sizeof(int)) > 0) err = 0; // we're okay else err = ERR_IO_ERROR; restore_cur(con, false); mutex_unlock(&con->lock); break; } default: err = ERR_INVALID_ARGS; } return err;}static int con_kputs(const char *str){ if(!str) return 0; return _console_write_raw(&gconsole, str, strlen(str));}static int con_kputs_xy(const char *str, int x, int y){ if(!str) return 0; return _console_write_raw_xy(&gconsole, str, strlen(str), x, y);}static int con_kputchar_xy(char c, int x, int y){ struct console_desc con; memcpy(&con, &gconsole, sizeof(con)); // not great, but it keeps us from updating the system's x y gotoxy(&con, x, y); console_putch(&con, c); return 1;}static struct dev_calls console_hooks = { &console_open, &console_close, &console_freecookie, &console_seek, &console_ioctl, &console_read, &console_write, /* cannot page from /dev/console */ NULL, NULL, NULL};static kernel_console_ops k_console_ops = { &con_kputs, &con_kputs_xy, &con_kputchar_xy};int dev_bootstrap(void);int dev_bootstrap(void){#if 0 if(!ka->fb.enabled) { dprintf("con_init: mapping vid mem\n"); vm_map_physical_memory(vm_get_kernel_aspace_id(), "vid_mem", (void *)&gconsole.origin, REGION_ADDR_ANY_ADDRESS, SCREEN_END - SCREEN_START, LOCK_RW|LOCK_KERNEL, SCREEN_START); dprintf("con_init: mapped vid mem to virtual address 0x%x\n", gconsole.origin); // set up the console structure mutex_init(&gconsole.lock, "console_lock"); gconsole.attr = 0x0f; gconsole.lines = LINES; gconsole.columns = COLUMNS; gconsole.end = gconsole.origin + gconsole.columns * gconsole.lines * 2; gconsole.scroll_top = 0; gconsole.scroll_bottom = gconsole.lines - 1; gconsole.bright_attr = true; gconsole.reverse_attr = false; gotoxy(&gconsole, 0, ka->cons_line); update_cursor(&gconsole, gconsole.x, gconsole.y); save_cur(&gconsole, true); // create device node devfs_publish_device("console", (dev_ident)&gconsole, &console_hooks); }#endif // iterate through the list of console modules until we find one that accepts the job modules_cookie mc = module_open_list("console"); char buffer[SYS_MAX_PATH_LEN]; char saved[SYS_MAX_PATH_LEN]; size_t bufsize = sizeof(buffer); int found = 0; *saved = '\0'; while (!found && (read_next_module_name(mc, buffer, &bufsize) == 0)) { char *special = buffer;#if ARCH_i386 dprintf("ARCH_I386: using \"/vga_text\" as the fallback driver\n"); special = strstr(buffer, "/vga_text");#else#endif if (special && (special != buffer)) { strlcpy(saved, buffer, sizeof(saved)); dprintf("con_init: skipping %s as the fallback module\n", saved); } else { dprintf("con_init: trying module %s\n", buffer); found = (module_get(buffer, 0, (void **)&(gconsole.funcs)) == 0); } bufsize = sizeof(buffer); } close_module_list(mc); // try the fallback module, if required. if (!found && strlen(saved)) found = (module_get(saved, 0, (void **)&(gconsole.funcs)) == 0); if (found) { // set up the console structure mutex_init(&gconsole.lock, "console_lock"); gconsole.funcs->get_size(&gconsole.columns, &gconsole.lines); reset_console(&gconsole); gotoxy(&gconsole, 0, global_kernel_args.cons_line); update_cursor((&gconsole), gconsole.x, gconsole.y); save_cur(&gconsole, true); // create device node devfs_publish_device("console", (dev_ident)&gconsole, &console_hooks); } else dprintf("con_init: failed to find a suitable module :-(\n"); if(found) { // register with the kernel console con_register_ops(&k_console_ops); } return found ? 0 : -1;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -