📄 console.c
字号:
{}static void con_unthrottle(struct tty_struct *tty){ struct vt_struct *vt = (struct vt_struct *) tty->driver_data; wake_up_interruptible(&vt->paste_wait);}static void vc_init(unsigned int currcons, int do_clear){ long base = (long) vc_scrbuf[currcons]; pos = (unsigned short *)(origin = (ulong)video_mem_start = base); scr_end = base + screenbuf_size; video_mem_end = base + screenbuf_size; reset_vc(currcons); def_color = 0x07; /* white */ ulcolor = 0x0f; /* bold white */ halfcolor = 0x08; /* grey */ vt_cons[currcons]->paste_wait = 0; reset_terminal(currcons, do_clear);}/* * This is the console switching bottom half handler. * * Doing console switching in a bottom half handler allows * us to do the switches asynchronously (needed when we want * to switch due to a keyboard interrupt), while still giving * us the option to easily disable it to avoid races when we * need to write to the console. */static void console_bh(void){ if (want_console >= 0) { if (want_console != fg_console) { change_console(want_console); /* we only changed when the console had already been allocated - a new console is not created in an interrupt routine */ } want_console = -1; } if (do_poke_blanked_console) { /* do not unblank for a LED change */ do_poke_blanked_console = 0; poke_blanked_console(); }}/* * unsigned long con_init(unsigned long); * * This routine initializes console interrupts, and does nothing * else. If you want the screen to clear, call tty_write with * the appropriate escape-sequence. * * Reads the information preserved by setup.s to determine the current display * type and sets everything accordingly. */unsigned long con_init(unsigned long kmem_start){#ifdef CONFIG_FRAMEBUFFER#if 0 /* Disable console unless some buttons are pressed */ { int i; for(i=0;i<200000;i++) { __asm__("nop"); if ((*(volatile unsigned char*)0xFFFFF419) & (8|1)) break; } if (!((*(volatile unsigned char*)0xFFFFF419) & (8|1))) return; } }#endif char *display_desc = "????"; unsigned int currcons = 0; extern int serial_debug; memset(&console_driver, 0, sizeof(struct tty_driver)); console_driver.magic = TTY_DRIVER_MAGIC; console_driver.name = "tty"; console_driver.name_base = 1; console_driver.major = TTY_MAJOR;#ifdef CONFIG_PILOT_CONSOLE console_driver.minor_start = 1;#else console_driver.minor_start = 2;#endif console_driver.num = MAX_NR_CONSOLES; console_driver.type = TTY_DRIVER_TYPE_CONSOLE; console_driver.init_termios = tty_std_termios; console_driver.flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_RESET_TERMIOS; console_driver.refcount = &console_refcount; console_driver.table = console_table; console_driver.termios = console_termios; console_driver.termios_locked = console_termios_locked; console_driver.open = con_open; console_driver.write = con_write; console_driver.write_room = con_write_room; console_driver.chars_in_buffer = con_chars_in_buffer; console_driver.ioctl = vt_ioctl; console_driver.stop = con_stop; console_driver.start = con_start; console_driver.throttle = con_throttle; console_driver.unthrottle = con_unthrottle; if (tty_register_driver(&console_driver)) panic("Couldn't register console driver\n"); kmem_start = conswitchp->con_startup (kmem_start, &display_desc); /*conswitchp->con_set_font (&display_desc, 0, 0, "MINI4x6");*/ timer_table[BLANK_TIMER].fn = blank_screen; timer_table[BLANK_TIMER].expires = 0; if (blankinterval) { timer_table[BLANK_TIMER].expires = jiffies + blankinterval; timer_active |= 1<<BLANK_TIMER; } /* Due to kmalloc roundup allocating statically is more efficient - so provide MIN_NR_CONSOLES for people with very little memory */ for (currcons = 0; currcons < MIN_NR_CONSOLES; currcons++) { vc_cons[currcons].d = (struct vc_data *) kmem_start; kmem_start += sizeof(struct vc_data); vt_cons[currcons] = (struct vt_struct *) kmem_start; kmem_start += sizeof(struct vt_struct); /* ++Geert: sw->con_init determines console size */ sw = conswitchp; cons_num = currcons; sw->con_init (vc_cons[currcons].d); size_row = cols<<1; screenbuf_size = rows*size_row; vc_scrbuf[currcons] = (unsigned short *) kmem_start; kmem_start += screenbuf_size; kmalloced = 0; vc_init(currcons, currcons); } currcons = fg_console = 0;#ifdef CONFIG_PILOT_CONSOLE gotoxy(currcons,0,rows-1); csi_J(currcons, 0); printable = 1; /*update_screen(fg_console);*/ sw->con_cursor(vc_cons[currcons].d, CM_DRAW); printable = 1; /* If "serdebug" cmd line option was present, don't register for printk */ if (!serial_debug) register_console(console_print); printk("Console: %s %s %ldx%ld, %d virtual console%s (max %d)\n", can_do_color ? "colour":"mono", display_desc, cols,rows, MIN_NR_CONSOLES, (MIN_NR_CONSOLES == 1) ? "" : "s", MAX_NR_CONSOLES);#else gotoxy(currcons,0, 0); printable = 1; sw->con_cursor(vc_cons[currcons].d, CM_DRAW); printable = 1; printk("Console driver (without boot console): %s %s %ldx%ld, %d virtual console%s (max %d)\n", can_do_color ? "colour":"mono", display_desc, cols,rows, MIN_NR_CONSOLES, (MIN_NR_CONSOLES == 1) ? "" : "s", MAX_NR_CONSOLES);#endif init_bh(CONSOLE_BH, console_bh);#endif return kmem_start;}void vesa_powerdown_screen(void){ int currcons = fg_console; timer_active &= ~(1<<BLANK_TIMER); timer_table[BLANK_TIMER].fn = unblank_screen; /* Power down if currently suspended (1 or 2), * suspend if currently blanked (0), * else do nothing (i.e. already powered down (3)). * Called only if powerdown features are allowed. */ switch (vesa_blank_mode) { case 0: sw->con_blank(2); break; case 1: case 2: sw->con_blank(4); break; }}void do_blank_screen(int nopowersave){#if 0 int currcons; if (console_blanked) return; if (!vc_cons_allocated(fg_console)) { /* impossible */ printk("blank_screen: tty %d not allocated ??\n", fg_console+1); return; } /* don't blank graphics */ if (vt_cons[fg_console]->vc_mode == KD_TEXT) { if (vesa_off_interval && !nopowersave) { timer_table[BLANK_TIMER].fn = vesa_powerdown_screen; timer_table[BLANK_TIMER].expires = jiffies + vesa_off_interval; timer_active |= (1<<BLANK_TIMER); } else { timer_active &= ~(1<<BLANK_TIMER); timer_table[BLANK_TIMER].fn = unblank_screen; } /* try not to lose information by blanking, and not to waste memory */ currcons = fg_console; has_scrolled = 0; sw->con_blank(1); if (!nopowersave) sw->con_blank(vesa_blank_mode + 1); } else hide_cursor(fg_console); console_blanked = fg_console + 1;#endif}void do_unblank_screen(void){#if 0 int currcons; if (!console_blanked) return; if (!vc_cons_allocated(fg_console)) { /* impossible */ printk("unblank_screen: tty %d not allocated ??\n", fg_console+1); return; } timer_table[BLANK_TIMER].fn = blank_screen; if (blankinterval) { timer_table[BLANK_TIMER].expires = jiffies + blankinterval; timer_active |= 1<<BLANK_TIMER; } currcons = fg_console; console_blanked = 0; if (sw->con_blank (0)) /* Low-level driver cannot restore -> do it ourselves */ update_screen( fg_console ); set_cursor (fg_console);#endif}void update_screen(int new_console){ int currcons = fg_console; int xx, yy, startx, attr_save; char buf[256], *bufp; unsigned short *p; static int lock = 0; if (/* new_console == fg_console || */ lock) return; if (!vc_cons_allocated(new_console)) { /* strange ... */ printk("update_screen: tty %d not allocated ??\n", new_console+1); return; } lock = 1; clear_selection(); currcons = fg_console = new_console; sw->con_cursor (vc_cons[currcons].d, CM_ERASE); sw->con_switch (vc_cons[new_console].d); /* Update the screen contents */ p = video_mem_start; attr_save = attr; for (yy = 0; yy < rows; yy++) { bufp = buf; for (startx = xx = 0; xx < cols; xx++) { if (attr != ((*p >> 8) & 0xff)) { if (bufp > buf) sw->con_putcs (vc_cons[currcons].d, buf, bufp - buf, yy, startx); startx = xx; bufp = buf; attr = (*p >> 8) & 0xff; } *bufp++ = *p++; if (bufp == buf + sizeof (buf)) { sw->con_putcs (vc_cons[currcons].d, buf, bufp - buf, yy, startx); startx = xx + 1; bufp = buf; } } if (bufp > buf) sw->con_putcs (vc_cons[currcons].d, buf, bufp - buf, yy, startx); } set_cursor (currcons); attr = attr_save; set_leds(); compute_shiftstate(); lock = 0;}/* * If a blank_screen is due to a timer, then a power save is allowed. * If it is related to console_switching, then avoid vesa_blank(). */static void blank_screen(void){ do_blank_screen(0);}static void unblank_screen(void){ do_unblank_screen();}/* * Allocate the console screen memory. */int con_open(struct tty_struct *tty, struct file * filp){ unsigned int currcons; int i; currcons = MINOR(tty->device) - tty->driver.minor_start; i = vc_allocate(currcons); if (i) return i; vt_cons[currcons]->vc_num = currcons; tty->driver_data = vt_cons[currcons]; if (!tty->winsize.ws_row && !tty->winsize.ws_col) { tty->winsize.ws_row = rows; tty->winsize.ws_col = cols; } return 0;}/* * PIO_FONT support. * * Currently we only support 8 pixels wide fonts, at a maximum height * of 32 pixels. Userspace fontdata is stored with 32 bytes reserved * for each character which is kinda wasty, but this is done in order * to maintain compatibility with the EGA/VGA fonts. It is upto the * actual low-level console-driver convert data into its favorite * format (maybe we should add a `fontoffset' field to the `display' * structure so we wont have to convert the fontdata all the time. * /Jes */#define cmapsz 8192static int set_get_font(char * arg, int set, int ch512){#ifdef CAN_LOAD_EGA_FONTS int i, unit, size; char *charmap; if (arg){ i = verify_area(set ? VERIFY_READ : VERIFY_WRITE, (void *)arg, ch512 ? 2*cmapsz : cmapsz); if (i) return i; }else return -EINVAL; size = ch512 ? 2*cmapsz : cmapsz; charmap = (char *)kmalloc(size, GFP_USER); if (set){ memcpy_fromfs(charmap, arg, size); for (unit = 32; unit > 0; unit--) for (i = 0; i < (ch512 ? 512 : 256); i++) if (charmap[32*i+unit-1]) goto nonzero; nonzero: i = conswitchp->con_set_font(vc_cons[fg_console].d, 8, unit, charmap); }else{ memset(charmap, 0, size); i = conswitchp->con_get_font(vc_cons[fg_console].d, &unit, &unit, charmap); memcpy_tofs(arg, charmap, size); } kfree(charmap); return i;#else return -EINVAL;#endif}/* * Load palette into the EGA/VGA DAC registers. arg points to a colour * map, 3 bytes per colour, 16 colours, range from 0 to 255. */int con_set_cmap (unsigned char *arg){ return -EINVAL;}int con_get_cmap (unsigned char *arg){ return -EINVAL;}void reset_palette(int currcons){}void set_palette(void){}/* * Load font into the EGA/VGA character generator. arg points to a 8192 * byte map, 32 bytes per character. Only first H of them are used for * 8xH fonts (0 < H <= 32). */int con_set_font (char *arg, int ch512){ int i; i = set_get_font (arg,1,ch512); if ( !i ) { hashtable_contents_valid = 0; video_mode_512ch = ch512; console_charmask = ch512 ? 0x1ff : 0x0ff; } return i;}int con_get_font (char *arg){ return set_get_font (arg,0,video_mode_512ch);}/* * Adjust the screen to fit a font of a certain height * * Returns < 0 for error, 0 if nothing changed, and the number * of lines on the adjusted console if changed. */int con_adjust_height(unsigned long fontheight){ return -EINVAL;}void set_vesa_blanking(int arg){ char *argp = (char *)arg + 1; unsigned int mode = get_fs_byte(argp); vesa_blank_mode = (mode < 4) ? mode : 0;}unsigned long get_video_num_lines(unsigned int currcons){ return(rows);}unsigned long get_video_num_columns(unsigned int currcons){ return(cols);}unsigned long get_video_size_row(unsigned int currcons){ return(size_row);}/* * Report the current status of the vc. This is exported to modules (ARub) */int con_get_info(int *mode, int *shift, int *col, int *row, struct tty_struct **tty){ extern int shift_state; extern struct tty_driver console_driver; struct tty_struct **console_table=console_driver.table; if (mode) *mode = vt_cons[fg_console]->vc_mode; if (shift) *shift = shift_state; if (col) *col = video_num_columns; if (row) *row = video_num_lines; if (tty) *tty = console_table[fg_console]; return fg_console;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -