[PATCH 1/2] UBUNTU: SAUCE: vt -- maintain bootloader screen mode and content until vt switch

Stefan Bader stefan.bader at canonical.com
Thu Jul 29 15:59:58 UTC 2010


Was confused a bit by the number of duplication in con_init but makes sense in
the light of vt_handoff possibly being above the minimum number of vt's.

Acked-by: Stefan Bader <stefan.bader at canonical.com>

On 07/29/2010 05:36 PM, Andy Whitcroft wrote:
> Introduce a new VT mode KD_TRANSPARENT which endevours to leave the current
> content of the framebuffer untouched.  This allows the bootloader to insert
> a graphical splash and have the kernel maintain it until the OS splash
> can take over.  When we finally switch away (either through programs like
> plymouth or manually) the content is lost and the VT reverts to text mode.
> 
> Signed-off-by: Andy Whitcroft <apw at canonical.com>
> ---
>  drivers/char/vt.c       |   36 +++++++++++++++++++++++++++++++-----
>  drivers/char/vt_ioctl.c |   10 +++++-----
>  include/linux/kd.h      |    1 +
>  include/linux/vt_kern.h |    2 +-
>  4 files changed, 38 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/char/vt.c b/drivers/char/vt.c
> index 7cdb6ee..2c64292 100644
> --- a/drivers/char/vt.c
> +++ b/drivers/char/vt.c
> @@ -104,6 +104,7 @@
>  #include <linux/io.h>
>  #include <asm/system.h>
>  #include <linux/uaccess.h>
> +#include <linux/screen_info.h>
>  
>  #define MAX_NR_CON_DRIVER 16
>  
> @@ -146,7 +147,7 @@ static const struct consw *con_driver_map[MAX_NR_CONSOLES];
>  
>  static int con_open(struct tty_struct *, struct file *);
>  static void vc_init(struct vc_data *vc, unsigned int rows,
> -		    unsigned int cols, int do_clear);
> +		    unsigned int cols, int do_clear, int mode);
>  static void gotoxy(struct vc_data *vc, int new_x, int new_y);
>  static void save_cur(struct vc_data *vc);
>  static void reset_terminal(struct vc_data *vc, int do_clear);
> @@ -167,6 +168,9 @@ module_param(global_cursor_default, int, S_IRUGO | S_IWUSR);
>  static int cur_default = CUR_DEFAULT;
>  module_param(cur_default, int, S_IRUGO | S_IWUSR);
>  
> +int vt_handoff = -1;
> +module_param_named(handoff, vt_handoff, int, S_IRUGO | S_IWUSR);
> +
>  /*
>   * ignore_poke: don't unblank the screen when things are typed.  This is
>   * mainly for the privacy of braille terminal users.
> @@ -676,6 +680,13 @@ void redraw_screen(struct vc_data *vc, int is_switch)
>  			save_screen(old_vc);
>  			set_origin(old_vc);
>  		}
> +		/*
> +		 * If we are switching away from a transparent VT the contents
> +		 * will be lost, convert it into a blank text console then
> +		 * it will be repainted blank if we ever switch back.
> +		 */
> +		if (old_vc->vc_mode == KD_TRANSPARENT)
> +			old_vc->vc_mode = KD_TEXT;
>  	} else {
>  		hide_cursor(vc);
>  		redraw = 1;
> @@ -784,7 +795,7 @@ int vc_allocate(unsigned int currcons)	/* return 0 on success */
>  	    if (global_cursor_default == -1)
>  		    global_cursor_default = 1;
>  
> -	    vc_init(vc, vc->vc_rows, vc->vc_cols, 1);
> +	    vc_init(vc, vc->vc_rows, vc->vc_cols, 1, KD_TEXT);
>  	    vcs_make_sysfs(currcons);
>  	    atomic_notifier_call_chain(&vt_notifier_list, VT_ALLOCATE, &param);
>  	}
> @@ -2837,7 +2848,7 @@ module_param_named(italic, default_italic_color, int, S_IRUGO | S_IWUSR);
>  module_param_named(underline, default_underline_color, int, S_IRUGO | S_IWUSR);
>  
>  static void vc_init(struct vc_data *vc, unsigned int rows,
> -		    unsigned int cols, int do_clear)
> +		    unsigned int cols, int do_clear, int mode)
>  {
>  	int j, k ;
>  
> @@ -2848,7 +2859,7 @@ static void vc_init(struct vc_data *vc, unsigned int rows,
>  
>  	set_origin(vc);
>  	vc->vc_pos = vc->vc_origin;
> -	reset_vc(vc);
> +	reset_vc(vc, mode);
>  	for (j=k=0; j<16; j++) {
>  		vc->vc_palette[k++] = default_red[j] ;
>  		vc->vc_palette[k++] = default_grn[j] ;
> @@ -2905,15 +2916,30 @@ static int __init con_init(void)
>  		mod_timer(&console_timer, jiffies + (blankinterval * HZ));
>  	}
>  
> +	if (vt_handoff >= 0) {
> +		currcons = vt_handoff;
> +		vc_cons[currcons].d = vc = kzalloc(sizeof(struct vc_data), GFP_NOWAIT);
> +		INIT_WORK(&vc_cons[currcons].SAK_work, vc_SAK);
> +		visual_init(vc, currcons, 1);
> +		vc->vc_screenbuf = kzalloc(vc->vc_screenbuf_size, GFP_NOWAIT);
> +		vc_init(vc, vc->vc_rows, vc->vc_cols, 0, KD_TRANSPARENT);
> +	}
>  	for (currcons = 0; currcons < MIN_NR_CONSOLES; currcons++) {
> +		if (currcons == vt_handoff)
> +			continue;
>  		vc_cons[currcons].d = vc = kzalloc(sizeof(struct vc_data), GFP_NOWAIT);
>  		INIT_WORK(&vc_cons[currcons].SAK_work, vc_SAK);
>  		visual_init(vc, currcons, 1);
>  		vc->vc_screenbuf = kzalloc(vc->vc_screenbuf_size, GFP_NOWAIT);
>  		vc_init(vc, vc->vc_rows, vc->vc_cols,
> -			currcons || !vc->vc_sw->con_save_screen);
> +			currcons || !vc->vc_sw->con_save_screen, KD_TEXT);
>  	}
>  	currcons = fg_console = 0;
> +	if (vt_handoff >= 0) {
> +		printk(KERN_INFO "vt handoff: transparent VT on %d\n",
> +								vt_handoff);
> +		currcons = fg_console = vt_handoff;
> +	}
>  	master_display_fg = vc = vc_cons[currcons].d;
>  	set_origin(vc);
>  	save_screen(vc);
> diff --git a/drivers/char/vt_ioctl.c b/drivers/char/vt_ioctl.c
> index 39c7e70..cb5c150 100644
> --- a/drivers/char/vt_ioctl.c
> +++ b/drivers/char/vt_ioctl.c
> @@ -1345,9 +1345,9 @@ eperm:
>  	goto out;
>  }
>  
> -void reset_vc(struct vc_data *vc)
> +void reset_vc(struct vc_data *vc, int mode)
>  {
> -	vc->vc_mode = KD_TEXT;
> +	vc->vc_mode = mode;
>  	kbd_table[vc->vc_num].kbdmode = default_utf8 ? VC_UNICODE : VC_XLATE;
>  	vc->vt_mode.mode = VT_AUTO;
>  	vc->vt_mode.waitv = 0;
> @@ -1378,7 +1378,7 @@ void vc_SAK(struct work_struct *work)
>  		 */
>  		if (tty)
>  			__do_SAK(tty);
> -		reset_vc(vc);
> +		reset_vc(vc, KD_TEXT);
>  	}
>  	release_console_sem();
>  }
> @@ -1665,7 +1665,7 @@ static void complete_change_console(struct vc_data *vc)
>  		 * this outside of VT_PROCESS but there is no single process
>  		 * to account for and tracking tty count may be undesirable.
>  		 */
> -			reset_vc(vc);
> +			reset_vc(vc, KD_TEXT);
>  
>  			if (old_vc_mode != vc->vc_mode) {
>  				if (vc->vc_mode == KD_TEXT)
> @@ -1737,7 +1737,7 @@ void change_console(struct vc_data *new_vc)
>  		 * this outside of VT_PROCESS but there is no single process
>  		 * to account for and tracking tty count may be undesirable.
>  		 */
> -		reset_vc(vc);
> +		reset_vc(vc, KD_TEXT);
>  
>  		/*
>  		 * Fall through to normal (VT_AUTO) handling of the switch...
> diff --git a/include/linux/kd.h b/include/linux/kd.h
> index 15f2853..abe298f 100644
> --- a/include/linux/kd.h
> +++ b/include/linux/kd.h
> @@ -45,6 +45,7 @@ struct consolefontdesc {
>  #define		KD_GRAPHICS	0x01
>  #define		KD_TEXT0	0x02	/* obsolete */
>  #define		KD_TEXT1	0x03	/* obsolete */
> +#define		KD_TRANSPARENT	0x04
>  #define KDGETMODE	0x4B3B	/* get current mode */
>  
>  #define KDMAPDISP	0x4B3C	/* map display into address space */
> diff --git a/include/linux/vt_kern.h b/include/linux/vt_kern.h
> index 7f56db4..b0a6148 100644
> --- a/include/linux/vt_kern.h
> +++ b/include/linux/vt_kern.h
> @@ -95,7 +95,7 @@ int con_copy_unimap(struct vc_data *dst_vc, struct vc_data *src_vc);
>  void vt_event_post(unsigned int event, unsigned int old, unsigned int new);
>  int vt_waitactive(int n);
>  void change_console(struct vc_data *new_vc);
> -void reset_vc(struct vc_data *vc);
> +void reset_vc(struct vc_data *vc, int mode);
>  extern int unbind_con_driver(const struct consw *csw, int first, int last,
>  			     int deflt);
>  int vty_init(const struct file_operations *console_fops);




More information about the kernel-team mailing list