[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, ¶m);
> }
> @@ -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