NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

kern/46525: splash: early splash screen



>Number:         46525
>Category:       kern
>Synopsis:       splash: early splash screen
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    kern-bug-people
>State:          open
>Class:          change-request
>Submitter-Id:   net
>Arrival-Date:   Sat Jun 02 17:30:00 +0000 2012
>Originator:     Nat Sloss
>Release:        NetBSD Current 6.99.6
>Organization:
>Environment:
NetBSD beast 6.99.6 NetBSD 6.99.6 (LOCKDEBUG) #54: Sat Jun  2 17:32:26 EST 2012 
 build@beast:/usr/src/sys/arch/i386/compile/obj/LOCKDEBUG i386

>Description:
After playing around with the new splash screen code (boot loader support for 
loading images etc) I noticed that you still get kernel messages until genfb 
attaches so it was kind of pointless to have a splashscreen as you still saw 
the kernel messages.
>How-To-Repeat:
Boot with a splash screen and you'll still get kernel messages.
>Fix:
What I did was to modify vcons so I could get vcons functionality in consinit 
and to load the image at preattach and display it.

Here are my patches:
===================================================================
RCS file: /cvsroot/src/sys/dev/wscons/wsdisplay_vcons.c,v
retrieving revision 1.27
diff -u -r1.27 wsdisplay_vcons.c
--- sys/dev/wscons/wsdisplay_vcons.c    4 Jan 2012 08:25:03 -0000       1.27
+++ sys/dev/wscons/wsdisplay_vcons.c    2 Jun 2012 17:08:22 -0000
@@ -114,6 +114,37 @@
 #endif

 int
+vcons_init_tiny(struct vcons_data *vd, void *cookie,
+    struct wsscreen_descr *def, struct wsdisplay_accessops *ao)
+{
+
+       /* zero out everything so we can rely on untouched fields being 0 */
+       memset(vd, 0, sizeof(struct vcons_data));
+
+       vd->cookie = cookie;
+
+       vd->init_screen = vcons_dummy_init_screen;
+       vd->show_screen_cb = NULL;
+
+       /* keep a copy of the accessops that we replace below with our
+        * own wrappers */
+       vd->ioctl = ao->ioctl;
+
+       /* configure the accessops */
+       ao->ioctl = vcons_ioctl;
+       ao->alloc_screen = vcons_alloc_screen;
+       ao->free_screen = vcons_free_screen;
+       ao->show_screen = vcons_show_screen;
+
+       LIST_INIT(&vd->screens);
+       vd->active = NULL;
+       vd->wanted = NULL;
+       vd->currenttype = def;
+
+       return 0;
+}
+
+int
 vcons_init(struct vcons_data *vd, void *cookie, struct wsscreen_descr *def,
     struct wsdisplay_accessops *ao)
 {
===================================================================
RCS file: /cvsroot/src/sys/dev/wscons/wsdisplay_vconsvar.h,v
retrieving revision 1.21
diff -u -r1.21 wsdisplay_vconsvar.h
--- sys/dev/wscons/wsdisplay_vconsvar.h 4 Jan 2012 08:25:03 -0000       1.21
+++ sys/dev/wscons/wsdisplay_vconsvar.h 2 Jun 2012 17:08:34 -0000
@@ -133,6 +133,9 @@
 #endif
 };

+int    vcons_init_tiny(struct vcons_data *, void *cookie,
+    struct wsscreen_descr *, struct wsdisplay_accessops *);
+
 int    vcons_init(struct vcons_data *, void *cookie, struct wsscreen_descr *,
     struct wsdisplay_accessops *);

===================================================================
RCS file: /cvsroot/src/sys/arch/x86/pci/pci_machdep.c,v
retrieving revision 1.56
diff -u -r1.56 pci_machdep.c
--- sys/arch/x86/pci/pci_machdep.c      1 Mar 2012 20:16:27 -0000       1.56
+++ sys/arch/x86/pci/pci_machdep.c      2 Jun 2012 17:09:15 -0000
@@ -800,7 +800,7 @@
        return EINVAL;
 }

-static void
+void
 x86_genfb_set_mapreg(void *opaque, int index, int r, int g, int b)
 {
        outb(0x3c0 + VGA_DAC_ADDRW, index);
===================================================================
RCS file: /cvsroot/src/sys/arch/x86/include/genfb_machdep.h,v
retrieving revision 1.3
diff -u -r1.3 genfb_machdep.h
--- sys/arch/x86/include/genfb_machdep.h        9 Feb 2011 13:24:23 -0000       
1.3
+++ sys/arch/x86/include/genfb_machdep.h        2 Jun 2012 17:09:36 -0000
@@ -34,4 +34,7 @@
 void   x86_genfb_set_console_dev(device_t);
 void   x86_genfb_ddb_trap_callback(int);

+/* genfb functions from pci_machdep.c*/
+void x86_genfb_set_mapreg(void *opaque, int index, int r, int g, int b);
+
 #endif /* !_X86_GENFB_MACHDEP_H */

===================================================================
RCS file: /cvsroot/src/sys/arch/x86/x86/genfb_machdep.c,v
retrieving revision 1.10
diff -u -r1.10 genfb_machdep.c
--- sys/arch/x86/x86/genfb_machdep.c    1 Jul 2011 18:21:31 -0000       1.10
+++ sys/arch/x86/x86/genfb_machdep.c    2 Jun 2012 17:09:53 -0000
@@ -34,6 +34,8 @@
 __KERNEL_RCSID(0, "$NetBSD: genfb_machdep.c,v 1.10 2011/07/01 18:21:31 dyoung 
Exp $");

 #include "opt_mtrr.h"
+#include "opt_modular.h"
+#include "opt_splash.h"

 #include <sys/param.h>
 #include <sys/conf.h>
@@ -59,6 +61,10 @@
 #include "genfb.h"
 #include "acpica.h"

+#ifdef SPLASHSCREEN
+#include <dev/splash/splash.h>
+#endif
+
 #if NWSDISPLAY > 0 && NGENFB > 0
 struct vcons_screen x86_genfb_console_screen;

@@ -66,6 +72,18 @@
 extern int acpi_md_vesa_modenum;
 #endif

+#ifdef SPLASHSCREEN
+struct splash_info sc_splash;
+struct vcons_data vd;
+struct wsdisplay_accessops ao;
+struct genfb_colormap_callback gen_cmcb;
+struct genfb_softc sc;
+struct btinfo_modulelist *biml;
+struct bi_modulelist_entry *bi, *bimax;
+int i, j;
+bool DISABLESPLASH;
+#endif
+
 static device_t x86_genfb_console_dev = NULL;

 static struct wsscreen_descr x86_genfb_stdscreen = {
@@ -197,6 +215,75 @@
        ri->ri_ops.allocattr(ri, 0, 0, 0, &defattr);
        wsdisplay_preattach(&x86_genfb_stdscreen, ri, 0, 0, defattr);

+#ifdef MODULAR
+#ifdef SPLASHSCREEN
+       biml = lookup_bootinfo(BTINFO_MODULELIST);
+       if (biml == NULL) {
+               aprint_debug("No module info at boot\n");
+               goto end_splashscreen;
+       }
+
+       DISABLESPLASH = true;
+       bi = (struct bi_modulelist_entry *)((uint8_t *)biml + sizeof(*biml));
+       bimax = bi + biml->num;
+       for (; bi < bimax; bi++) {
+               if (bi->type == BI_MODULE_IMAGE) {
+                       aprint_debug("Splash image path=%s len=%d pa=%x\n",
+                           bi->path, bi->len, bi->base);
+                       KASSERT(trunc_page(bi->base) == bi->base);
+                       splash_setimage(
+                           (void *)((uintptr_t)bi->base + KERNBASE), bi->len);
+                       DISABLESPLASH = false;
+               }
+       }
+
+       if (DISABLESPLASH == false) {
+               memset(&sc, 0, sizeof(struct genfb_softc));
+               memset(&sc_splash, 0, sizeof(struct splash_info));
+
+               sc_splash.si_width = sc.sc_width = ri->ri_width;
+               sc_splash.si_height = sc.sc_height = ri->ri_height;
+               sc_splash.si_stride = sc.sc_stride = ri->ri_stride;
+               sc_splash.si_depth = sc.sc_depth = ri->ri_depth;
+               sc_splash.si_bits = ri->ri_bits;
+               sc_splash.si_hwbits = NULL;
+               sc_splash.si_fillrect = NULL;
+
+               if (sc.sc_depth == 8) {
+                       gen_cmcb.gcc_cookie = NULL;
+                       gen_cmcb.gcc_set_mapreg = x86_genfb_set_mapreg;
+                       sc.sc_cmcb = &gen_cmcb;
+               }
+
+               j = 0;
+               for (i = 0; i < min(1 << sc.sc_depth, 256); i++) {
+                       if (i >= SPLASH_CMAP_OFFSET &&
+                           i < SPLASH_CMAP_OFFSET + SPLASH_CMAP_SIZE) {
+                               splash_get_cmap(i, &sc.sc_cmap_red[i],
+                                   &sc.sc_cmap_green[i], &sc.sc_cmap_blue[i]);
+                       } else {
+                               sc.sc_cmap_red[i] = rasops_cmap[j];
+                               sc.sc_cmap_green[i] = rasops_cmap[j + 1];
+                               sc.sc_cmap_blue[i] = rasops_cmap[j + 2];
+                       }
+                       j += 3;
+               }
+               genfb_restore_palette(&sc);
+
+               vcons_init_tiny(&vd, &sc, &x86_genfb_stdscreen, &ao);
+               vcons_init_screen(&vd, &x86_genfb_console_screen, 1, &defattr);
+
+               err = splash_render(&sc_splash, SPLASH_F_CENTER|SPLASH_F_FILL);
+               if (err == 0)
+                       SCREEN_DISABLE_DRAWING(&x86_genfb_console_screen);
+               else
+                       SCREEN_ENABLE_DRAWING(&x86_genfb_console_screen);
+
+               vcons_redraw_screen(&x86_genfb_console_screen);
+       }
+end_splashscreen:
+#endif
+#endif
        return 1;
 }
 #else  /* NWSDISPLAY > 0 && NGENFB > 0 */



I don't know how correct what I have done is, but it works the splash screen is 
displayed just after boot which is neat kind of mac-ish (for those who would 
like that :) )

Note: This patch is my own work which I submit under the NetBSD license.

Regards,

Nat



Home | Main Index | Thread Index | Old Index