loader: narrow the scope of gfx frame buffer wrt tg supported kernels
Store whether or not we found a vbefb module (eg, a tg supported kernel) in the preloaded_file structure. This automatically resets on reload and eliminates load_elf knowing about any gfx_* interface. Restrict this to i386, which is the only place it's used. Update libi386 to check in the preloaded_file struct. Eliminate this from the teken_gfx structure. Rewrite the parsing code to be more inline. Check this from the same place we check for a relocatable amd64 kernel. Sponsored by: Netflix Reviewed by: manu, tsoome Differential Revision: https://reviews.freebsd.org/D33427
This commit is contained in:
parent
e28767f0e1
commit
aaaa5a2e68
@ -232,6 +232,9 @@ struct preloaded_file
|
||||
#ifdef __amd64__
|
||||
bool f_kernphys_relocatable;
|
||||
#endif
|
||||
#if defined(__i386__)
|
||||
bool f_tg_kernel_support;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct file_format
|
||||
|
@ -219,7 +219,6 @@ typedef struct teken_gfx {
|
||||
uint32_t *tg_shadow_fb; /* units of 4 bytes */
|
||||
teken_funcs_t *tg_functions;
|
||||
void *tg_private;
|
||||
bool tg_kernel_supported; /* Loaded kernel is supported */
|
||||
} teken_gfx_t;
|
||||
|
||||
extern font_list_t fonts;
|
||||
|
@ -39,7 +39,6 @@ __FBSDID("$FreeBSD$");
|
||||
#include <stand.h>
|
||||
#define FREEBSD_ELF
|
||||
#include <sys/link_elf.h>
|
||||
#include <gfx_fb.h>
|
||||
|
||||
#include "bootstrap.h"
|
||||
|
||||
@ -91,8 +90,6 @@ 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);
|
||||
|
||||
@ -219,6 +216,43 @@ is_kernphys_relocatable(elf_file_t ef)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef __i386__
|
||||
static bool
|
||||
is_tg_kernel_support(struct preloaded_file *fp, elf_file_t ef)
|
||||
{
|
||||
Elf_Sym sym;
|
||||
Elf_Addr p_start, p_end, v, p;
|
||||
char vd_name[16];
|
||||
int error;
|
||||
|
||||
if (__elfN(lookup_symbol)(ef, "__start_set_vt_drv_set", &sym, STT_NOTYPE) != 0)
|
||||
return (false);
|
||||
p_start = sym.st_value + ef->off;
|
||||
if (__elfN(lookup_symbol)(ef, "__stop_set_vt_drv_set", &sym, STT_NOTYPE) != 0)
|
||||
return (false);
|
||||
p_end = sym.st_value + ef->off;
|
||||
|
||||
/*
|
||||
* Walk through vt_drv_set, each vt driver structure starts with
|
||||
* static 16 chars for driver name. If we have "vbefb", return true.
|
||||
*/
|
||||
for (p = p_start; p < p_end; p += sizeof(Elf_Addr)) {
|
||||
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);
|
||||
}
|
||||
|
||||
return (false);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int
|
||||
__elfN(load_elf_header)(char *filename, elf_file_t ef)
|
||||
{
|
||||
@ -448,6 +482,9 @@ __elfN(loadfile_raw)(char *filename, uint64_t dest,
|
||||
err = 0;
|
||||
#ifdef __amd64__
|
||||
fp->f_kernphys_relocatable = multiboot || is_kernphys_relocatable(&ef);
|
||||
#endif
|
||||
#ifdef __i386__
|
||||
fp->f_tg_kernel_support = is_tg_kernel_support(fp, &ef);
|
||||
#endif
|
||||
goto out;
|
||||
|
||||
@ -872,18 +909,6 @@ __elfN(loadimage)(struct preloaded_file *fp, elf_file_t ef, uint64_t off)
|
||||
ef->buckets = ef->hashtab + 2;
|
||||
ef->chains = ef->buckets + ef->nbuckets;
|
||||
|
||||
if (!gfx_state.tg_kernel_supported &&
|
||||
__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;
|
||||
@ -1084,36 +1109,6 @@ __elfN(load_modmetadata)(struct preloaded_file *fp, uint64_t dest)
|
||||
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)
|
||||
|
@ -278,8 +278,6 @@ unload(void)
|
||||
}
|
||||
loadaddr = 0;
|
||||
unsetenv("kernelname");
|
||||
/* Reset tg_kernel_supported to allow next load to check it again. */
|
||||
gfx_state.tg_kernel_supported = false;
|
||||
}
|
||||
|
||||
COMMAND_SET(unload, "unload", "unload all modules", command_unload);
|
||||
|
@ -41,7 +41,7 @@ __FBSDID("$FreeBSD$");
|
||||
void
|
||||
bi_load_vbe_data(struct preloaded_file *kfp)
|
||||
{
|
||||
if (!gfx_state.tg_kernel_supported) {
|
||||
if (!kfp->f_tg_kernel_support) {
|
||||
/*
|
||||
* Loaded kernel does not have vt/vbe backend,
|
||||
* switch console to text mode.
|
||||
|
@ -29,9 +29,6 @@ SRCS+= metadata.c
|
||||
SRCS+= load_elf64.c reloc_elf64.c
|
||||
SRCS+= metadata.c
|
||||
.endif
|
||||
# elf loaders set frame buffer things, so add includes for that.
|
||||
CFLAGS.load_elf32.c += -I$(SRCTOP)/sys/teken -I${SRCTOP}/contrib/pnglite
|
||||
CFLAGS.load_elf64.c += -I$(SRCTOP)/sys/teken -I${SRCTOP}/contrib/pnglite
|
||||
|
||||
.if ${LOADER_DISK_SUPPORT:Uyes} == "yes"
|
||||
CFLAGS.part.c+= -DHAVE_MEMCPY -I${SRCTOP}/sys/contrib/zlib
|
||||
|
Loading…
Reference in New Issue
Block a user