svn commit: r368184 - in head/sys: dev/vt kern sys

Toomas Soome tsoome at FreeBSD.org
Mon Nov 30 11:45:48 UTC 2020


Author: tsoome
Date: Mon Nov 30 11:45:47 2020
New Revision: 368184
URL: https://svnweb.freebsd.org/changeset/base/368184

Log:
  vt: if loader did pass the font via metadata, use it
  
  The built in 8x16 font may be way too small with large framebuffer
  resolutions, to improve readability, use loader provied font.

Modified:
  head/sys/dev/vt/vt_core.c
  head/sys/kern/subr_module.c
  head/sys/sys/font.h
  head/sys/sys/linker.h

Modified: head/sys/dev/vt/vt_core.c
==============================================================================
--- head/sys/dev/vt/vt_core.c	Mon Nov 30 10:58:06 2020	(r368183)
+++ head/sys/dev/vt/vt_core.c	Mon Nov 30 11:45:47 2020	(r368184)
@@ -39,9 +39,11 @@ __FBSDID("$FreeBSD$");
 #include <sys/consio.h>
 #include <sys/eventhandler.h>
 #include <sys/fbio.h>
+#include <sys/font.h>
 #include <sys/kbio.h>
 #include <sys/kdb.h>
 #include <sys/kernel.h>
+#include <sys/linker.h>
 #include <sys/lock.h>
 #include <sys/malloc.h>
 #include <sys/mutex.h>
@@ -163,8 +165,15 @@ extern unsigned char vt_logo_image[];
 const unsigned int vt_logo_sprite_height;
 #endif
 
-/* Font. */
+/*
+ * Console font. vt_font_loader will be filled with font data passed
+ * by loader. If there is no font passed by boot loader, we use built in
+ * default.
+ */
 extern struct vt_font vt_font_default;
+static struct vt_font vt_font_loader;
+static struct vt_font *vt_font_assigned = &vt_font_default;
+
 #ifndef SC_NO_CUTPASTE
 extern struct vt_mouse_cursor vt_default_mouse_pointer;
 #endif
@@ -1445,7 +1454,131 @@ vtterm_splash(struct vt_device *vd)
 }
 #endif
 
+static struct vt_font *
+parse_font_info_static(struct font_info *fi)
+{
+	struct vt_font *vfp;
+	uintptr_t ptr;
+	uint32_t checksum;
+
+	if (fi == NULL)
+		return (NULL);
+
+	ptr = (uintptr_t)fi;
+	/*
+	 * Compute and verify checksum. The total sum of all the fields
+	 * must be 0.
+	 */
+	checksum = fi->fi_width;
+	checksum += fi->fi_height;
+	checksum += fi->fi_bitmap_size;
+	for (unsigned i = 0; i < VFNT_MAPS; i++)
+		checksum += fi->fi_map_count[i];
+
+	if (checksum + fi->fi_checksum != 0)
+		return (NULL);
+
+	ptr += sizeof(struct font_info);
+	ptr = roundup2(ptr, 8);
+
+	vfp = &vt_font_loader;
+	vfp->vf_height = fi->fi_height;
+	vfp->vf_width = fi->fi_width;
+	for (unsigned i = 0; i < VFNT_MAPS; i++) {
+		if (fi->fi_map_count[i] == 0)
+			continue;
+		vfp->vf_map_count[i] = fi->fi_map_count[i];
+		vfp->vf_map[i] = (vfnt_map_t *)ptr;
+		ptr += (fi->fi_map_count[i] * sizeof(vfnt_map_t));
+		ptr = roundup2(ptr, 8);
+	}
+	vfp->vf_bytes = (uint8_t *)ptr;
+	return (vfp);
+}
+
+static struct vt_font *
+parse_font_info(struct font_info *fi)
+{
+	struct vt_font *vfp;
+	uintptr_t ptr;
+	uint32_t checksum;
+	size_t size;
+
+	if (fi == NULL)
+		return (NULL);
+
+	ptr = (uintptr_t)fi;
+	/*
+	 * Compute and verify checksum. The total sum of all the fields
+	 * must be 0.
+	 */
+	checksum = fi->fi_width;
+	checksum += fi->fi_height;
+	checksum += fi->fi_bitmap_size;
+	for (unsigned i = 0; i < VFNT_MAPS; i++)
+		checksum += fi->fi_map_count[i];
+
+	if (checksum + fi->fi_checksum != 0)
+		return (NULL);
+
+	ptr += sizeof(struct font_info);
+	ptr = roundup2(ptr, 8);
+
+	vfp = &vt_font_loader;
+	vfp->vf_height = fi->fi_height;
+	vfp->vf_width = fi->fi_width;
+	for (unsigned i = 0; i < VFNT_MAPS; i++) {
+		if (fi->fi_map_count[i] == 0)
+			continue;
+		vfp->vf_map_count[i] = fi->fi_map_count[i];
+		size = fi->fi_map_count[i] * sizeof(vfnt_map_t);
+		vfp->vf_map[i] = malloc(size, M_VT, M_WAITOK | M_ZERO);
+		bcopy((vfnt_map_t *)ptr, vfp->vf_map[i], size);
+		ptr += size;
+		ptr = roundup2(ptr, 8);
+	}
+	vfp->vf_bytes = malloc(fi->fi_bitmap_size, M_VT, M_WAITOK | M_ZERO);
+	bcopy((uint8_t *)ptr, vfp->vf_bytes, fi->fi_bitmap_size);
+	return (vfp);
+}
+
 static void
+vt_init_font(void *arg)
+{
+	caddr_t kmdp;
+	struct font_info *fi;
+	struct vt_font *font;
+
+	kmdp = preload_search_by_type("elf kernel");
+	if (kmdp == NULL)
+		kmdp = preload_search_by_type("elf64 kernel");
+	fi = MD_FETCH(kmdp, MODINFOMD_FONT, struct font_info *);
+
+	font = parse_font_info(fi);
+	if (font != NULL)
+		vt_font_assigned = font;
+}
+
+SYSINIT(vt_init_font, SI_SUB_KMEM, SI_ORDER_ANY, vt_init_font, &vt_consdev);
+
+static void
+vt_init_font_static(void)
+{
+	caddr_t kmdp;
+	struct font_info *fi;
+	struct vt_font *font;
+
+	kmdp = preload_search_by_type("elf kernel");
+	if (kmdp == NULL)
+		kmdp = preload_search_by_type("elf64 kernel");
+	fi = MD_FETCH(kmdp, MODINFOMD_FONT, struct font_info *);
+
+	font = parse_font_info_static(fi);
+	if (font != NULL)
+		vt_font_assigned = font;
+}
+
+static void
 vtterm_cnprobe(struct terminal *tm, struct consdev *cp)
 {
 	struct vt_driver *vtd, **vtdlist, *vtdbest = NULL;
@@ -1491,9 +1624,11 @@ vtterm_cnprobe(struct terminal *tm, struct consdev *cp
 	vd->vd_windows[VT_CONSWINDOW] = vw;
 	sprintf(cp->cn_name, "ttyv%r", VT_UNIT(vw));
 
+	vt_init_font_static();
+
 	/* Attach default font if not in TEXTMODE. */
 	if ((vd->vd_flags & VDF_TEXTMODE) == 0) {
-		vw->vw_font = vtfont_ref(&vt_font_default);
+		vw->vw_font = vtfont_ref(vt_font_assigned);
 		vt_compute_drawable_area(vw);
 	}
 
@@ -2431,7 +2566,7 @@ skip_thunk:
 	}
 	case PIO_VFONT_DEFAULT: {
 		/* Reset to default font. */
-		error = vt_change_font(vw, &vt_font_default);
+		error = vt_change_font(vw, vt_font_assigned);
 		return (error);
 	}
 	case GIO_SCRNMAP: {
@@ -2691,7 +2826,7 @@ vt_allocate_window(struct vt_device *vd, unsigned int 
 	vw->vw_kbdmode = K_XLATE;
 
 	if ((vd->vd_flags & VDF_TEXTMODE) == 0) {
-		vw->vw_font = vtfont_ref(&vt_font_default);
+		vw->vw_font = vtfont_ref(vt_font_assigned);
 		vt_compute_drawable_area(vw);
 	}
 
@@ -2788,7 +2923,7 @@ vt_resize(struct vt_device *vd)
 		VT_LOCK(vd);
 		/* Assign default font to window, if not textmode. */
 		if (!(vd->vd_flags & VDF_TEXTMODE) && vw->vw_font == NULL)
-			vw->vw_font = vtfont_ref(&vt_font_default);
+			vw->vw_font = vtfont_ref(vt_font_assigned);
 		VT_UNLOCK(vd);
 
 		/* Resize terminal windows */

Modified: head/sys/kern/subr_module.c
==============================================================================
--- head/sys/kern/subr_module.c	Mon Nov 30 10:58:06 2020	(r368183)
+++ head/sys/kern/subr_module.c	Mon Nov 30 11:45:47 2020	(r368184)
@@ -295,6 +295,7 @@ preload_bootstrap_relocate(vm_offset_t offset)
 	    /* Deal with the ones that we know we have to fix */
 	    switch (hdr[0]) {
 	    case MODINFO_ADDR:
+	    case MODINFO_METADATA|MODINFOMD_FONT:
 	    case MODINFO_METADATA|MODINFOMD_SSYM:
 	    case MODINFO_METADATA|MODINFOMD_ESYM:
 		ptr = (vm_offset_t *)(curp + (sizeof(uint32_t) * 2));

Modified: head/sys/sys/font.h
==============================================================================
--- head/sys/sys/font.h	Mon Nov 30 10:58:06 2020	(r368183)
+++ head/sys/sys/font.h	Mon Nov 30 11:45:47 2020	(r368184)
@@ -57,6 +57,14 @@ enum vfnt_map_type {
 	VFNT_MAPS		/* Number of maps. */
 };
 
+struct font_info {
+	int32_t fi_checksum;
+	uint32_t fi_width;
+	uint32_t fi_height;
+	uint32_t fi_bitmap_size;
+	uint32_t fi_map_count[VFNT_MAPS];
+};
+
 struct vfnt_map {
 	uint32_t	 vfm_src;
 	uint16_t	 vfm_dst;

Modified: head/sys/sys/linker.h
==============================================================================
--- head/sys/sys/linker.h	Mon Nov 30 10:58:06 2020	(r368183)
+++ head/sys/sys/linker.h	Mon Nov 30 11:45:47 2020	(r368184)
@@ -226,6 +226,7 @@ void *linker_hwpmc_list_objects(void);
 #define MODINFOMD_CTORS_SIZE	0x000b		/* size of .ctors */
 #define MODINFOMD_FW_HANDLE	0x000c		/* Firmware dependent handle */
 #define MODINFOMD_KEYBUF	0x000d		/* Crypto key intake buffer */
+#define MODINFOMD_FONT		0x000e		/* Console font */
 #define MODINFOMD_NOCOPY	0x8000		/* don't copy this metadata to the kernel */
 
 #define MODINFOMD_DEPLIST	(0x4001 | MODINFOMD_NOCOPY)	/* depends on */


More information about the svn-src-all mailing list