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

📄 console.c

📁 讲述linux的初始化过程
💻 C
📖 第 1 页 / 共 5 页
字号:
			return __put_user(data, (char *) arg);		case 7:			data = mouse_reporting();			return __put_user(data, (char *) arg);		case 10:			set_vesa_blanking(arg);			return 0;		case 11:	/* set kmsg redirect */			if (!suser())				return -EPERM;			if (get_user(data, (char *)arg+1))					return -EFAULT;			kmsg_redirect = data;			return 0;		case 12:	/* get fg_console */			return fg_console;	}	return -EINVAL;}/* *	/dev/ttyN handling */static int con_write(struct tty_struct * tty, int from_user,		     const unsigned char *buf, int count){	int	retval;	pm_access(pm_con);	retval = do_con_write(tty, from_user, buf, count);	con_flush_chars(tty);	return retval;}static void con_put_char(struct tty_struct *tty, unsigned char ch){	pm_access(pm_con);	do_con_write(tty, 0, &ch, 1);}static int con_write_room(struct tty_struct *tty){	if (tty->stopped)		return 0;	return 4096;		/* No limit, really; we're not buffering */}static int con_chars_in_buffer(struct tty_struct *tty){	return 0;		/* we're not buffering */}/* * con_throttle and con_unthrottle are only used for * paste_selection(), which has to stuff in a large number of * characters... */static void con_throttle(struct tty_struct *tty){}static void con_unthrottle(struct tty_struct *tty){	struct vt_struct *vt = (struct vt_struct *) tty->driver_data;	wake_up_interruptible(&vt->paste_wait);}/* * Turn the Scroll-Lock LED on when the tty is stopped */static void con_stop(struct tty_struct *tty){	int console_num;	if (!tty)		return;	console_num = MINOR(tty->device) - (tty->driver.minor_start);	if (!vc_cons_allocated(console_num))		return;	set_vc_kbd_led(kbd_table + console_num, VC_SCROLLOCK);	set_leds();}/* * Turn the Scroll-Lock LED off when the console is started */static void con_start(struct tty_struct *tty){	int console_num;	if (!tty)		return;	console_num = MINOR(tty->device) - (tty->driver.minor_start);	if (!vc_cons_allocated(console_num))		return;	clr_vc_kbd_led(kbd_table + console_num, VC_SCROLLOCK);	set_leds();}static void con_flush_chars(struct tty_struct *tty){	unsigned long flags;	struct vt_struct *vt = (struct vt_struct *)tty->driver_data;	pm_access(pm_con);	spin_lock_irqsave(&console_lock, flags);	set_cursor(vt->vc_num);	spin_unlock_irqrestore(&console_lock, flags);}/* * Allocate the console screen memory. */static 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 = video_num_lines;		tty->winsize.ws_col = video_num_columns;	}	if (tty->count == 1)		vcs_make_devfs (currcons, 0);	return 0;}static void con_close(struct tty_struct *tty, struct file * filp){	if (!tty)		return;	if (tty->count != 1) return;	vcs_make_devfs (MINOR (tty->device) - tty->driver.minor_start, 1);	tty->driver_data = 0;}static void vc_init(unsigned int currcons, unsigned int rows, unsigned int cols, int do_clear){	int j, k ;	video_num_columns = cols;	video_num_lines = rows;	video_size_row = cols<<1;	screenbuf_size = video_num_lines * video_size_row;	set_origin(currcons);	pos = origin;	reset_vc(currcons);	for (j=k=0; j<16; j++) {		vc_cons[currcons].d->vc_palette[k++] = default_red[j] ;		vc_cons[currcons].d->vc_palette[k++] = default_grn[j] ;		vc_cons[currcons].d->vc_palette[k++] = default_blu[j] ;	}	def_color       = 0x07;   /* white */	ulcolor		= 0x0f;   /* bold white */	halfcolor       = 0x08;   /* grey */	init_waitqueue_head(&vt_cons[currcons]->paste_wait);	reset_terminal(currcons, do_clear);}/* * This routine initializes console interrupts, and does nothing * else. If you want the screen to clear, call tty_write with * the appropriate escape-sequence. */struct tty_driver console_driver;static int console_refcount;DECLARE_TASKLET_DISABLED(console_tasklet, console_softint, 0);void __init con_init(void){	const char *display_desc = NULL;	unsigned int currcons = 0;	if (conswitchp)		display_desc = conswitchp->con_startup();	if (!display_desc) {		fg_console = 0;		return;	}	memset(&console_driver, 0, sizeof(struct tty_driver));	console_driver.magic = TTY_DRIVER_MAGIC;	console_driver.name = "vc/%d";	console_driver.name_base = 1;	console_driver.major = TTY_MAJOR;	console_driver.minor_start = 1;	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;	/* Tell tty_register_driver() to skip consoles because they are	 * registered before kmalloc() is ready. We'll patch them in later. 	 * See comments at console_init(); see also con_init_devfs(). 	 */	console_driver.flags |= TTY_DRIVER_NO_DEVFS;	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.close = con_close;	console_driver.write = con_write;	console_driver.write_room = con_write_room;	console_driver.put_char = con_put_char;	console_driver.flush_chars = con_flush_chars;	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");	init_timer(&console_timer);	console_timer.function = blank_screen;	if (blankinterval) {		mod_timer(&console_timer, jiffies + blankinterval);	}	/*	 * kmalloc is not running yet - we use the bootmem allocator.	 */	for (currcons = 0; currcons < MIN_NR_CONSOLES; currcons++) {		vc_cons[currcons].d = (struct vc_data *)				alloc_bootmem(sizeof(struct vc_data));		vt_cons[currcons] = (struct vt_struct *)				alloc_bootmem(sizeof(struct vt_struct));		visual_init(currcons, 1);		screenbuf = (unsigned short *) alloc_bootmem(screenbuf_size);		kmalloced = 0;		vc_init(currcons, video_num_lines, video_num_columns, 			currcons || !sw->con_save_screen);	}	currcons = fg_console = 0;	master_display_fg = vc_cons[currcons].d;	set_origin(currcons);	save_screen(currcons);	gotoxy(currcons,x,y);	csi_J(currcons, 0);	update_screen(fg_console);	printk("Console: %s %s %dx%d",		can_do_color ? "colour" : "mono",		display_desc, video_num_columns, video_num_lines);	printable = 1;	printk("\n");#ifdef CONFIG_VT_CONSOLE	register_console(&vt_console_driver);#endif	tasklet_enable(&console_tasklet);	tasklet_schedule(&console_tasklet);}#ifndef VT_SINGLE_DRIVERstatic void clear_buffer_attributes(int currcons){	unsigned short *p = (unsigned short *) origin;	int count = screenbuf_size/2;	int mask = hi_font_mask | 0xff;	for (; count > 0; count--, p++) {		scr_writew((scr_readw(p)&mask) | (video_erase_char&~mask), p);	}}/* *	If we support more console drivers, this function is used *	when a driver wants to take over some existing consoles *	and become default driver for newly opened ones. */void take_over_console(const struct consw *csw, int first, int last, int deflt){	int i, j = -1;	const char *desc;	desc = csw->con_startup();	if (!desc) return;	if (deflt)		conswitchp = csw;	for (i = first; i <= last; i++) {		int old_was_color;		int currcons = i;		con_driver_map[i] = csw;		if (!vc_cons[i].d || !vc_cons[i].d->vc_sw)			continue;		j = i;		if (IS_VISIBLE)			save_screen(i);		old_was_color = vc_cons[i].d->vc_can_do_color;		vc_cons[i].d->vc_sw->con_deinit(vc_cons[i].d);		visual_init(i, 0);		update_attr(i);		/* If the console changed between mono <-> color, then		 * the attributes in the screenbuf will be wrong.  The		 * following resets all attributes to something sane.		 */		if (old_was_color != vc_cons[i].d->vc_can_do_color)			clear_buffer_attributes(i);		if (IS_VISIBLE)			update_screen(i);	}	printk("Console: switching ");	if (!deflt)		printk("consoles %d-%d ", first+1, last+1);	if (j >= 0)		printk("to %s %s %dx%d\n",		       vc_cons[j].d->vc_can_do_color ? "colour" : "mono",		       desc, vc_cons[j].d->vc_cols, vc_cons[j].d->vc_rows);	else		printk("to %s\n", desc);}void give_up_console(const struct consw *csw){	int i;	for(i = 0; i < MAX_NR_CONSOLES; i++)		if (con_driver_map[i] == csw)			con_driver_map[i] = NULL;}#endif/* *	Screen blanking */static void set_vesa_blanking(unsigned long arg){    char *argp = (char *)arg + 1;    unsigned int mode;    get_user(mode, argp);    vesa_blank_mode = (mode < 4) ? mode : 0;}/* We can't register the console with devfs during con_init(), because it * is called before kmalloc() works.  This function is called later to * do the registration. */void __init con_init_devfs (void){	int i;	for (i = 0; i < console_driver.num; i++)		tty_register_devfs (&console_driver, DEVFS_FL_AOPEN_NOTIFY,				    console_driver.minor_start + i);}static void vesa_powerdown(void){    struct vc_data *c = vc_cons[fg_console].d;    /*     *  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 VESA_NO_BLANKING:	    c->vc_sw->con_blank(c, VESA_VSYNC_SUSPEND+1);	    break;	case VESA_VSYNC_SUSPEND:	case VESA_HSYNC_SUSPEND:	    c->vc_sw->con_blank(c, VESA_POWERDOWN+1);	    break;    }}static void vesa_powerdown_screen(unsigned long dummy){	console_timer.function = unblank_screen_t;	/* I don't have a clue why this is necessary */	vesa_powerdown();}static void timer_do_blank_screen(int entering_gfx, int from_timer_handler){	int currcons = fg_console;	int i;	if (console_blanked)		return;	/* entering graphics mode? */	if (entering_gfx) {		hide_cursor(currcons);		save_screen(currcons);		sw->con_blank(vc_cons[currcons].d, -1);		console_blanked = fg_console + 1;		set_origin(currcons);		return;	}	/* don't blank graphics */	if (vcmode != KD_TEXT) {		console_blanked = fg_console + 1;		return;	}	hide_cursor(currcons);	if (!from_timer_handler)		del_timer_sync(&console_timer);	if (vesa_off_interval) {		console_timer.function = vesa_powerdown_screen;		mod_timer(&console_timer, jiffies + vesa_off_interval);	} else {		if (!from_timer_handler)			del_timer_sync(&console_timer);		console_timer.function = unblank_screen_t;	}	save_screen(currcons);	/* In case we need to reset origin, blanking hook returns 1 */	i = sw->con_blank(vc_cons[currcons].d, 1);	console_blanked = fg_console + 1;	if (i)		set_origin(currcons);	if (console_blank_hook && console_blank_hook(1))		return;    	if (vesa_blank_mode)		sw->con_blank(vc_cons[currcons].d, vesa_blank_mode + 1);}void do_blank_screen(int entering_gfx){	timer_do_blank_screen(entering_gfx, 0);}static void unblank_screen_t(unsigned long dummy){	unblank_screen();}void unblank_screen(void){	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;	}	console_timer.function = blank_screen;	if (blankinterval) {		mod_timer(&console_timer, jiffies + blankinterval);	}	currcons = fg_console;	console_blanked = 0;	if (console_blank_hook)		console_blank_hook(0);	set_palette(currcons);	if (sw->con_blank(vc_cons[currcons].d, 0))		/* Low-level driver cannot restore -> do it ourselves */		update_screen(fg_console);	set_cursor(fg_console);}static void blank_screen(unsigned long dummy){	timer_do_blank_screen(0, 1);}void poke_blanked_console(void){	del_timer(&console_timer);	/* Can't use _sync here: called from tasklet */	if (vt_cons[fg_console]->vc_mode == KD_GRAPHICS)		return;	if (console_blanked) {		console_timer.function = unblank_screen_t;		mod_timer(&console_timer, jiffies);	/* Now */	} else if (blankinterval) {		mod_timer(&console_timer, jiffies + blankinterval);	}}/* *	Palettes */void set_palette(int currcons){	if (vcmode != KD_GRAPHICS)		sw->con_set_palette(vc_cons[currcons].d, color_table);}static int set_get_cmap(unsigned char *arg, int set){    int i, j, k;    for (i = 0; i < 16; i++)	if (set) {	    get_user(default_red[i], arg++);	    get_user(default_grn[i], arg++);	    get_user(default_blu[i], arg++);	} else {	    put_user(default_red[i], arg++);	    put_user(default_grn[i], arg++);	    put_user(default_blu[i], arg++);	}    if (set) {	for (i = 0; i < MAX_NR_CONSOLES; i++)	    if (vc_cons_allocated(i)) {		for (j = k = 0; j < 16; j++) {		    vc_cons[i].d->vc_palette[k++] = default_red[j];		    vc_cons[i].d->vc_palette[k++] = default_grn[j];		    vc_cons[i].d->vc_palette[k++] = default_blu[j];		}		set_palette(i);	    }    }    return 0;}/* * Load palette into the DAC registers. arg points to a colour * map, 3 bytes per colour,

⌨️ 快捷键说明

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