VGA fonts not reloading when changing back to text mode

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

VGA fonts not reloading when changing back to text mode

johnc
On a system with VGA graphics, like a VirtualBox:

Boot to X.
ctrl-alt-F1 back to text mode.
As root:
wsfontload -h 8 -e ibm /usr/share/misc/pcvtfonts/vt220l.808
wsconscfg -dF 1
wsconscfg -t 80x50 1
ctrl-alt-F2 to see the second screen in 80x50 mode
(takes a while for the getty to restart).
ctrl-alt-F5 to go back to graphics mode with X.
ctrl-alt-F2 to go back to the 80x50 text mode.

The custom font has not been reloaded, so the screen is full of trash.

Inserting a restore in vga.c:824 fixes it:
        vga_setfont(vc, scr);
+ vga_restore_fonts(vc);
        vga_restore_palette(vc);

This does cause the font to be uploaded on every virtual screen switch,
but it is only there if a custom font has already been loaded, and is
tiny in any case.

The vga_restore_fonts() function is currently only called in vga_ioctl()
for WSDISPLAYIO_SMODE when going from graphics to WSDISPLAYIO_MODE_EMUL,
which should be optimal, but this never happens -- that vga_ioctl()
happens once after boot to go into graphics mode, but never gets called
again when switching back to text mode.  Maybe something with the
integration of kms drivers changed the call semantics?







Reply | Threaded
Open this post in threaded view
|

Re: VGA fonts not reloading when changing back to text mode

Jonathan Gray-11
On Wed, May 13, 2020 at 11:11:56PM -0700, [hidden email] wrote:

> On a system with VGA graphics, like a VirtualBox:
>
> Boot to X.
> ctrl-alt-F1 back to text mode.
> As root:
> wsfontload -h 8 -e ibm /usr/share/misc/pcvtfonts/vt220l.808
> wsconscfg -dF 1
> wsconscfg -t 80x50 1
> ctrl-alt-F2 to see the second screen in 80x50 mode
> (takes a while for the getty to restart).
> ctrl-alt-F5 to go back to graphics mode with X.
> ctrl-alt-F2 to go back to the 80x50 text mode.
>
> The custom font has not been reloaded, so the screen is full of trash.
>
> Inserting a restore in vga.c:824 fixes it:
> vga_setfont(vc, scr);
> + vga_restore_fonts(vc);
> vga_restore_palette(vc);
>
> This does cause the font to be uploaded on every virtual screen switch,
> but it is only there if a custom font has already been loaded, and is
> tiny in any case.
>
> The vga_restore_fonts() function is currently only called in vga_ioctl()
> for WSDISPLAYIO_SMODE when going from graphics to WSDISPLAYIO_MODE_EMUL,
> which should be optimal, but this never happens -- that vga_ioctl()
> happens once after boot to go into graphics mode, but never gets called
> again when switching back to text mode.  Maybe something with the
> integration of kms drivers changed the call semantics?

Thanks for the report.

In xenocara/xserver/hw/xfree86/os-support/bsd/bsd_init.c
xf86OpenConsole() does the ioctl with WSDISPLAYIO_MODE_MAPPED
xf86CloseConsole() does the ioctl with WSDISPLAYIO_MODE_EMUL

however these aren't currently done for switching when xorg is running

Testing here xf86VTSwitchAway() is called when switching from xorg to VT
xf86VTSwitchTo() is called when switching back to xorg.

Adding the ioctl to these functions makes the steps you've given end in
a non trashed VT.

This is clearly a dark corner of the xserver code and suffers from
trying to support multiple systems and be compatible with USL ioctls.

Index: xserver/hw/xfree86/os-support/bsd/bsd_VTsw.c
===================================================================
RCS file: /cvs/xenocara/xserver/hw/xfree86/os-support/bsd/bsd_VTsw.c,v
retrieving revision 1.5
diff -u -p -r1.5 bsd_VTsw.c
--- xserver/hw/xfree86/os-support/bsd/bsd_VTsw.c 2 Apr 2016 14:25:10 -0000 1.5
+++ xserver/hw/xfree86/os-support/bsd/bsd_VTsw.c 14 May 2020 08:44:33 -0000
@@ -72,13 +72,20 @@ xf86VTSwitchAway(void)
 {
 #if defined (SYSCONS_SUPPORT) || defined (PCVT_SUPPORT) \
     || defined(WSCONS_SUPPORT)
+    int mode;
+
     if (xf86Info.consType == SYSCONS || xf86Info.consType == PCVT ||
         xf86Info.consType == WSCONS) {
         xf86Info.vtRequestsPending = FALSE;
         if (ioctl(xf86Info.consoleFd, VT_RELDISP, 1) < 0)
             return FALSE;
-        else
-            return TRUE;
+        
+#ifdef WSCONS_SUPPORT
+        mode = WSDISPLAYIO_MODE_EMUL;
+        ioctl(xf86Info.consoleFd, WSDISPLAYIO_SMODE, &mode);
+#endif
+
+        return TRUE;
     }
 #endif
     return FALSE;
@@ -89,13 +96,20 @@ xf86VTSwitchTo(void)
 {
 #if defined (SYSCONS_SUPPORT) || defined (PCVT_SUPPORT) \
     || defined(WSCONS_SUPPORT)
+    int mode;
+
     if (xf86Info.consType == SYSCONS || xf86Info.consType == PCVT ||
         xf86Info.consType == WSCONS) {
         xf86Info.vtRequestsPending = FALSE;
         if (ioctl(xf86Info.consoleFd, VT_RELDISP, VT_ACKACQ) < 0)
             return FALSE;
-        else
-            return TRUE;
+
+#ifdef WSCONS_SUPPORT
+        mode = WSDISPLAYIO_MODE_MAPPED;
+        ioctl(xf86Info.consoleFd, WSDISPLAYIO_SMODE, &mode);
+#endif
+
+        return TRUE;
     }
 #endif
     return TRUE;

Reply | Threaded
Open this post in threaded view
|

Re: VGA fonts not reloading when changing back to text mode

Mark Kettenis
> Date: Thu, 14 May 2020 19:20:00 +1000
> From: Jonathan Gray <[hidden email]>
>
> On Wed, May 13, 2020 at 11:11:56PM -0700, [hidden email] wrote:
> > On a system with VGA graphics, like a VirtualBox:
> >
> > Boot to X.
> > ctrl-alt-F1 back to text mode.
> > As root:
> > wsfontload -h 8 -e ibm /usr/share/misc/pcvtfonts/vt220l.808
> > wsconscfg -dF 1
> > wsconscfg -t 80x50 1
> > ctrl-alt-F2 to see the second screen in 80x50 mode
> > (takes a while for the getty to restart).
> > ctrl-alt-F5 to go back to graphics mode with X.
> > ctrl-alt-F2 to go back to the 80x50 text mode.
> >
> > The custom font has not been reloaded, so the screen is full of trash.
> >
> > Inserting a restore in vga.c:824 fixes it:
> > vga_setfont(vc, scr);
> > + vga_restore_fonts(vc);
> > vga_restore_palette(vc);
> >
> > This does cause the font to be uploaded on every virtual screen switch,
> > but it is only there if a custom font has already been loaded, and is
> > tiny in any case.
> >
> > The vga_restore_fonts() function is currently only called in vga_ioctl()
> > for WSDISPLAYIO_SMODE when going from graphics to WSDISPLAYIO_MODE_EMUL,
> > which should be optimal, but this never happens -- that vga_ioctl()
> > happens once after boot to go into graphics mode, but never gets called
> > again when switching back to text mode.  Maybe something with the
> > integration of kms drivers changed the call semantics?
>
> Thanks for the report.
>
> In xenocara/xserver/hw/xfree86/os-support/bsd/bsd_init.c
> xf86OpenConsole() does the ioctl with WSDISPLAYIO_MODE_MAPPED
> xf86CloseConsole() does the ioctl with WSDISPLAYIO_MODE_EMUL
>
> however these aren't currently done for switching when xorg is running
>
> Testing here xf86VTSwitchAway() is called when switching from xorg to VT
> xf86VTSwitchTo() is called when switching back to xorg.
>
> Adding the ioctl to these functions makes the steps you've given end in
> a non trashed VT.
>
> This is clearly a dark corner of the xserver code and suffers from
> trying to support multiple systems and be compatible with USL ioctls.

I don't think this is the right approach.  Having X involved in the VT
switch has always been a bit of an issue.  Can't be avoided completely
since X somehow needs to be told to stop messing with the display
hardware behind our back.  But I think it is best if the kernel can do
all the necessary repair by itself.  Then, if X crashes, you can still
VT-switch to another screen and have things work.

So I think John's suggestion makes sense.  The only thing that seems a
bit wrong is that the current font is set before the fonts are
actually restored.

Restoring the fonts on every VT-switch isn't a very big issue.
Nothing will happen if you didn't explicitly load an alternative font.
But if the overhead is noticable we could only do the restore when
switching away from a screen that has the SCR_GRAPHICS flag set to a
screen that doesn't.


> Index: xserver/hw/xfree86/os-support/bsd/bsd_VTsw.c
> ===================================================================
> RCS file: /cvs/xenocara/xserver/hw/xfree86/os-support/bsd/bsd_VTsw.c,v
> retrieving revision 1.5
> diff -u -p -r1.5 bsd_VTsw.c
> --- xserver/hw/xfree86/os-support/bsd/bsd_VTsw.c 2 Apr 2016 14:25:10 -0000 1.5
> +++ xserver/hw/xfree86/os-support/bsd/bsd_VTsw.c 14 May 2020 08:44:33 -0000
> @@ -72,13 +72,20 @@ xf86VTSwitchAway(void)
>  {
>  #if defined (SYSCONS_SUPPORT) || defined (PCVT_SUPPORT) \
>      || defined(WSCONS_SUPPORT)
> +    int mode;
> +
>      if (xf86Info.consType == SYSCONS || xf86Info.consType == PCVT ||
>          xf86Info.consType == WSCONS) {
>          xf86Info.vtRequestsPending = FALSE;
>          if (ioctl(xf86Info.consoleFd, VT_RELDISP, 1) < 0)
>              return FALSE;
> -        else
> -            return TRUE;
> +        
> +#ifdef WSCONS_SUPPORT
> +        mode = WSDISPLAYIO_MODE_EMUL;
> +        ioctl(xf86Info.consoleFd, WSDISPLAYIO_SMODE, &mode);
> +#endif
> +
> +        return TRUE;
>      }
>  #endif
>      return FALSE;
> @@ -89,13 +96,20 @@ xf86VTSwitchTo(void)
>  {
>  #if defined (SYSCONS_SUPPORT) || defined (PCVT_SUPPORT) \
>      || defined(WSCONS_SUPPORT)
> +    int mode;
> +
>      if (xf86Info.consType == SYSCONS || xf86Info.consType == PCVT ||
>          xf86Info.consType == WSCONS) {
>          xf86Info.vtRequestsPending = FALSE;
>          if (ioctl(xf86Info.consoleFd, VT_RELDISP, VT_ACKACQ) < 0)
>              return FALSE;
> -        else
> -            return TRUE;
> +
> +#ifdef WSCONS_SUPPORT
> +        mode = WSDISPLAYIO_MODE_MAPPED;
> +        ioctl(xf86Info.consoleFd, WSDISPLAYIO_SMODE, &mode);
> +#endif
> +
> +        return TRUE;
>      }
>  #endif
>      return TRUE;
>
>

Reply | Threaded
Open this post in threaded view
|

Re: VGA fonts not reloading when changing back to text mode

Jonathan Gray-11
On Thu, May 14, 2020 at 11:59:07AM +0200, Mark Kettenis wrote:

> > Date: Thu, 14 May 2020 19:20:00 +1000
> > From: Jonathan Gray <[hidden email]>
> >
> > On Wed, May 13, 2020 at 11:11:56PM -0700, [hidden email] wrote:
> > > On a system with VGA graphics, like a VirtualBox:
> > >
> > > Boot to X.
> > > ctrl-alt-F1 back to text mode.
> > > As root:
> > > wsfontload -h 8 -e ibm /usr/share/misc/pcvtfonts/vt220l.808
> > > wsconscfg -dF 1
> > > wsconscfg -t 80x50 1
> > > ctrl-alt-F2 to see the second screen in 80x50 mode
> > > (takes a while for the getty to restart).
> > > ctrl-alt-F5 to go back to graphics mode with X.
> > > ctrl-alt-F2 to go back to the 80x50 text mode.
> > >
> > > The custom font has not been reloaded, so the screen is full of trash.
> > >
> > > Inserting a restore in vga.c:824 fixes it:
> > > vga_setfont(vc, scr);
> > > + vga_restore_fonts(vc);
> > > vga_restore_palette(vc);
> > >
> > > This does cause the font to be uploaded on every virtual screen switch,
> > > but it is only there if a custom font has already been loaded, and is
> > > tiny in any case.
> > >
> > > The vga_restore_fonts() function is currently only called in vga_ioctl()
> > > for WSDISPLAYIO_SMODE when going from graphics to WSDISPLAYIO_MODE_EMUL,
> > > which should be optimal, but this never happens -- that vga_ioctl()
> > > happens once after boot to go into graphics mode, but never gets called
> > > again when switching back to text mode.  Maybe something with the
> > > integration of kms drivers changed the call semantics?
> >
> > Thanks for the report.
> >
> > In xenocara/xserver/hw/xfree86/os-support/bsd/bsd_init.c
> > xf86OpenConsole() does the ioctl with WSDISPLAYIO_MODE_MAPPED
> > xf86CloseConsole() does the ioctl with WSDISPLAYIO_MODE_EMUL
> >
> > however these aren't currently done for switching when xorg is running
> >
> > Testing here xf86VTSwitchAway() is called when switching from xorg to VT
> > xf86VTSwitchTo() is called when switching back to xorg.
> >
> > Adding the ioctl to these functions makes the steps you've given end in
> > a non trashed VT.
> >
> > This is clearly a dark corner of the xserver code and suffers from
> > trying to support multiple systems and be compatible with USL ioctls.
>
> I don't think this is the right approach.  Having X involved in the VT
> switch has always been a bit of an issue.  Can't be avoided completely
> since X somehow needs to be told to stop messing with the display
> hardware behind our back.  But I think it is best if the kernel can do
> all the necessary repair by itself.  Then, if X crashes, you can still
> VT-switch to another screen and have things work.
>
> So I think John's suggestion makes sense.  The only thing that seems a
> bit wrong is that the current font is set before the fonts are
> actually restored.
>
> Restoring the fonts on every VT-switch isn't a very big issue.
> Nothing will happen if you didn't explicitly load an alternative font.
> But if the overhead is noticable we could only do the restore when
> switching away from a screen that has the SCR_GRAPHICS flag set to a
> screen that doesn't.

I've committed the palette fix and this patch with the order changed
as suggested by Mark to have vga_restore_fonts() (write to video memory)
before vga_setfont() (pointing the character generator at it).

Thanks for the detailed reports and patches.