Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 24 Feb 2021 18:38:59 GMT
From:      Toomas Soome <tsoome@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org
Subject:   git: ce132d4aab67 - releng/13.0 - loader: start kernel in text mode when there is no vbefb vt driver
Message-ID:  <202102241838.11OIcxHX091156@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch releng/13.0 has been updated by tsoome:

URL: https://cgit.FreeBSD.org/src/commit/?id=ce132d4aab6762d7287eca1e0f0ade5cf4d7576e

commit ce132d4aab6762d7287eca1e0f0ade5cf4d7576e
Author:     Toomas Soome <tsoome@FreeBSD.org>
AuthorDate: 2021-01-26 22:47:56 +0000
Commit:     Toomas Soome <tsoome@FreeBSD.org>
CommitDate: 2021-02-23 07:41:09 +0000

    loader: start kernel in text mode when there is no vbefb vt driver
    
    If kernel is built without VT vbefb driver, make sure
    we start kernel in text mode.
    
    (cherry picked from commit 6c7a932d0b8baaaee16eca0ba061bfa6e0e57bfd)
    
    Approved by: re (gjb)
---
 stand/common/gfx_fb.h         |  1 +
 stand/common/load_elf.c       | 63 ++++++++++++++++++++++++++++++++++++-------
 stand/i386/libi386/bootinfo.c | 10 +++++++
 stand/loader.mk               |  9 +++++++
 4 files changed, 74 insertions(+), 9 deletions(-)

diff --git a/stand/common/gfx_fb.h b/stand/common/gfx_fb.h
index c62c6441f8ad..04076a2c6d38 100644
--- a/stand/common/gfx_fb.h
+++ b/stand/common/gfx_fb.h
@@ -216,6 +216,7 @@ typedef struct teken_gfx {
 	struct gen_fb	tg_fb;
 	teken_funcs_t	*tg_functions;
 	void		*tg_private;
+	bool		tg_kernel_supported;	/* Loaded kernel is supported */
 } teken_gfx_t;
 
 extern font_list_t fonts;
diff --git a/stand/common/load_elf.c b/stand/common/load_elf.c
index cb542718fe2f..62fdb560ecff 100644
--- a/stand/common/load_elf.c
+++ b/stand/common/load_elf.c
@@ -39,6 +39,7 @@ __FBSDID("$FreeBSD$");
 #include <stand.h>
 #define FREEBSD_ELF
 #include <sys/link_elf.h>
+#include <gfx_fb.h>
 
 #include "bootstrap.h"
 
@@ -84,12 +85,14 @@ typedef struct elf_file {
 
 static int __elfN(loadimage)(struct preloaded_file *mp, elf_file_t ef,
     uint64_t loadaddr);
-static int __elfN(lookup_symbol)(struct preloaded_file *mp, elf_file_t ef,
-    const char* name, Elf_Sym* sym);
+static int __elfN(lookup_symbol)(elf_file_t ef, const char* name,
+    Elf_Sym *sym, unsigned char type);
 static int __elfN(reloc_ptr)(struct preloaded_file *mp, elf_file_t ef,
     Elf_Addr p, void *val, size_t len);
 static int __elfN(parse_modmetadata)(struct preloaded_file *mp, elf_file_t ef,
     Elf_Addr p_start, Elf_Addr p_end);
+static bool __elfN(parse_vt_drv_set)(struct preloaded_file *mp, elf_file_t ef,
+    Elf_Addr p_start, Elf_Addr p_end);
 static symaddr_fn __elfN(symaddr);
 static char	*fake_modname(const char *name);
 
@@ -872,12 +875,24 @@ nosyms:
 	ef->buckets = ef->hashtab + 2;
 	ef->chains = ef->buckets + ef->nbuckets;
 
-	if (__elfN(lookup_symbol)(fp, ef, "__start_set_modmetadata_set",
-	    &sym) != 0)
+	gfx_state.tg_kernel_supported = false;
+	if (__elfN(lookup_symbol)(ef, "__start_set_vt_drv_set", &sym,
+	    STT_NOTYPE) == 0) {
+		p_start = sym.st_value + ef->off;
+		if (__elfN(lookup_symbol)(ef, "__stop_set_vt_drv_set", &sym,
+		    STT_NOTYPE) == 0) {
+			p_end = sym.st_value + ef->off;
+			gfx_state.tg_kernel_supported =
+			    __elfN(parse_vt_drv_set)(fp, ef, p_start, p_end);
+		}
+	}
+
+	if (__elfN(lookup_symbol)(ef, "__start_set_modmetadata_set", &sym,
+	    STT_NOTYPE) != 0)
 		return 0;
 	p_start = sym.st_value + ef->off;
-	if (__elfN(lookup_symbol)(fp, ef, "__stop_set_modmetadata_set",
-	    &sym) != 0)
+	if (__elfN(lookup_symbol)(ef, "__stop_set_modmetadata_set", &sym,
+	    STT_NOTYPE) != 0)
 		return ENOENT;
 	p_end = sym.st_value + ef->off;
 
@@ -1072,6 +1087,36 @@ out:
 	return (err);
 }
 
+/*
+ * Walk through vt_drv_set, each vt driver structure starts with
+ * static 16 chars for driver name. If we have "vbefb", return true.
+ */
+static bool
+__elfN(parse_vt_drv_set)(struct preloaded_file *fp, elf_file_t ef,
+    Elf_Addr p_start, Elf_Addr p_end)
+{
+	Elf_Addr v, p;
+	char vd_name[16];
+	int error;
+
+	p = p_start;
+	while (p < p_end) {
+		COPYOUT(p, &v, sizeof(v));
+
+		error = __elfN(reloc_ptr)(fp, ef, p, &v, sizeof(v));
+		if (error == EOPNOTSUPP)
+			v += ef->off;
+		else if (error != 0)
+			return (false);
+		COPYOUT(v, &vd_name, sizeof(vd_name));
+		if (strncmp(vd_name, "vbefb", sizeof(vd_name)) == 0)
+			return (true);
+		p += sizeof(Elf_Addr);
+	}
+
+	return (false);
+}
+
 int
 __elfN(parse_modmetadata)(struct preloaded_file *fp, elf_file_t ef,
     Elf_Addr p_start, Elf_Addr p_end)
@@ -1185,8 +1230,8 @@ elf_hash(const char *name)
 static const char __elfN(bad_symtable)[] = "elf" __XSTRING(__ELF_WORD_SIZE)
     "_lookup_symbol: corrupt symbol table\n";
 int
-__elfN(lookup_symbol)(struct preloaded_file *fp, elf_file_t ef,
-    const char* name, Elf_Sym *symp)
+__elfN(lookup_symbol)(elf_file_t ef, const char* name, Elf_Sym *symp,
+    unsigned char type)
 {
 	Elf_Hashelt symnum;
 	Elf_Sym sym;
@@ -1213,7 +1258,7 @@ __elfN(lookup_symbol)(struct preloaded_file *fp, elf_file_t ef,
 			free(strp);
 			if (sym.st_shndx != SHN_UNDEF ||
 			    (sym.st_value != 0 &&
-			    ELF_ST_TYPE(sym.st_info) == STT_FUNC)) {
+			    ELF_ST_TYPE(sym.st_info) == type)) {
 				*symp = sym;
 				return 0;
 			}
diff --git a/stand/i386/libi386/bootinfo.c b/stand/i386/libi386/bootinfo.c
index 71e07cfb9702..57f926b76589 100644
--- a/stand/i386/libi386/bootinfo.c
+++ b/stand/i386/libi386/bootinfo.c
@@ -41,6 +41,16 @@ __FBSDID("$FreeBSD$");
 void
 bi_load_vbe_data(struct preloaded_file *kfp)
 {
+	if (!gfx_state.tg_kernel_supported) {
+		/*
+		 * Loaded kernel does not have vt/vbe backend,
+		 * switch console to text mode.
+		 */
+		if (vbe_available())
+			bios_set_text_mode(VGA_TEXT_MODE);
+		return;
+	}
+
 	if (vbe_available()) {
 		file_addmetadata(kfp, MODINFOMD_VBE_FB,
 		    sizeof(gfx_state.tg_fb), &gfx_state.tg_fb);
diff --git a/stand/loader.mk b/stand/loader.mk
index cde7a31dca7e..3a38a9bc9e63 100644
--- a/stand/loader.mk
+++ b/stand/loader.mk
@@ -17,23 +17,32 @@ CFLAGS.pnglite.c+= -DHAVE_MEMCPY -I${SRCTOP}/sys/contrib/zlib
 .if ${MACHINE} == "i386" || ${MACHINE_CPUARCH} == "amd64"
 SRCS+=	load_elf32.c load_elf32_obj.c reloc_elf32.c
 SRCS+=	load_elf64.c load_elf64_obj.c reloc_elf64.c
+CFLAGS.load_elf32.c += -I$(SRCTOP)/sys/teken -I${SRCTOP}/contrib/pnglite
+CFLAGS.load_elf64.c += -I$(SRCTOP)/sys/teken -I${SRCTOP}/contrib/pnglite
 .elif ${MACHINE_CPUARCH} == "aarch64"
 SRCS+=	load_elf64.c reloc_elf64.c
+CFLAGS.load_elf64.c += -I$(SRCTOP)/sys/teken -I${SRCTOP}/contrib/pnglite
 .elif ${MACHINE_CPUARCH} == "arm"
 SRCS+=	load_elf32.c reloc_elf32.c
+CFLAGS.load_elf32.c += -I$(SRCTOP)/sys/teken -I${SRCTOP}/contrib/pnglite
 .elif ${MACHINE_CPUARCH} == "powerpc"
 SRCS+=	load_elf32.c reloc_elf32.c
 SRCS+=	load_elf64.c reloc_elf64.c
 SRCS+=	metadata.c
+CFLAGS.load_elf32.c += -I$(SRCTOP)/sys/teken -I${SRCTOP}/contrib/pnglite
+CFLAGS.load_elf64.c += -I$(SRCTOP)/sys/teken -I${SRCTOP}/contrib/pnglite
 .elif ${MACHINE_ARCH:Mmips64*} != ""
 SRCS+= load_elf64.c reloc_elf64.c
 SRCS+=	metadata.c
+CFLAGS.load_elf64.c += -I$(SRCTOP)/sys/teken -I${SRCTOP}/contrib/pnglite
 .elif ${MACHINE} == "mips"
 SRCS+=	load_elf32.c reloc_elf32.c
 SRCS+=	metadata.c
+CFLAGS.load_elf32.c += -I$(SRCTOP)/sys/teken -I${SRCTOP}/contrib/pnglite
 .elif ${MACHINE_CPUARCH} == "riscv"
 SRCS+=	load_elf64.c reloc_elf64.c
 SRCS+=	metadata.c
+CFLAGS.load_elf64.c += -I$(SRCTOP)/sys/teken -I${SRCTOP}/contrib/pnglite
 .endif
 
 .if ${LOADER_DISK_SUPPORT:Uyes} == "yes"



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202102241838.11OIcxHX091156>