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.
This commit is contained in:
parent
93ebd6307e
commit
6c7a932d0b
@ -204,6 +204,7 @@ typedef struct teken_gfx {
|
|||||||
struct gen_fb tg_fb;
|
struct gen_fb tg_fb;
|
||||||
teken_funcs_t *tg_functions;
|
teken_funcs_t *tg_functions;
|
||||||
void *tg_private;
|
void *tg_private;
|
||||||
|
bool tg_kernel_supported; /* Loaded kernel is supported */
|
||||||
} teken_gfx_t;
|
} teken_gfx_t;
|
||||||
|
|
||||||
extern font_list_t fonts;
|
extern font_list_t fonts;
|
||||||
|
@ -39,6 +39,7 @@ __FBSDID("$FreeBSD$");
|
|||||||
#include <stand.h>
|
#include <stand.h>
|
||||||
#define FREEBSD_ELF
|
#define FREEBSD_ELF
|
||||||
#include <sys/link_elf.h>
|
#include <sys/link_elf.h>
|
||||||
|
#include <gfx_fb.h>
|
||||||
|
|
||||||
#include "bootstrap.h"
|
#include "bootstrap.h"
|
||||||
|
|
||||||
@ -84,12 +85,14 @@ typedef struct elf_file {
|
|||||||
|
|
||||||
static int __elfN(loadimage)(struct preloaded_file *mp, elf_file_t ef,
|
static int __elfN(loadimage)(struct preloaded_file *mp, elf_file_t ef,
|
||||||
uint64_t loadaddr);
|
uint64_t loadaddr);
|
||||||
static int __elfN(lookup_symbol)(struct preloaded_file *mp, elf_file_t ef,
|
static int __elfN(lookup_symbol)(elf_file_t ef, const char* name,
|
||||||
const char* name, Elf_Sym* sym);
|
Elf_Sym *sym, unsigned char type);
|
||||||
static int __elfN(reloc_ptr)(struct preloaded_file *mp, elf_file_t ef,
|
static int __elfN(reloc_ptr)(struct preloaded_file *mp, elf_file_t ef,
|
||||||
Elf_Addr p, void *val, size_t len);
|
Elf_Addr p, void *val, size_t len);
|
||||||
static int __elfN(parse_modmetadata)(struct preloaded_file *mp, elf_file_t ef,
|
static int __elfN(parse_modmetadata)(struct preloaded_file *mp, elf_file_t ef,
|
||||||
Elf_Addr p_start, Elf_Addr p_end);
|
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 symaddr_fn __elfN(symaddr);
|
||||||
static char *fake_modname(const char *name);
|
static char *fake_modname(const char *name);
|
||||||
|
|
||||||
@ -872,12 +875,24 @@ __elfN(loadimage)(struct preloaded_file *fp, elf_file_t ef, uint64_t off)
|
|||||||
ef->buckets = ef->hashtab + 2;
|
ef->buckets = ef->hashtab + 2;
|
||||||
ef->chains = ef->buckets + ef->nbuckets;
|
ef->chains = ef->buckets + ef->nbuckets;
|
||||||
|
|
||||||
if (__elfN(lookup_symbol)(fp, ef, "__start_set_modmetadata_set",
|
gfx_state.tg_kernel_supported = false;
|
||||||
&sym) != 0)
|
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;
|
return 0;
|
||||||
p_start = sym.st_value + ef->off;
|
p_start = sym.st_value + ef->off;
|
||||||
if (__elfN(lookup_symbol)(fp, ef, "__stop_set_modmetadata_set",
|
if (__elfN(lookup_symbol)(ef, "__stop_set_modmetadata_set", &sym,
|
||||||
&sym) != 0)
|
STT_NOTYPE) != 0)
|
||||||
return ENOENT;
|
return ENOENT;
|
||||||
p_end = sym.st_value + ef->off;
|
p_end = sym.st_value + ef->off;
|
||||||
|
|
||||||
@ -1072,6 +1087,36 @@ __elfN(load_modmetadata)(struct preloaded_file *fp, uint64_t dest)
|
|||||||
return (err);
|
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
|
int
|
||||||
__elfN(parse_modmetadata)(struct preloaded_file *fp, elf_file_t ef,
|
__elfN(parse_modmetadata)(struct preloaded_file *fp, elf_file_t ef,
|
||||||
Elf_Addr p_start, Elf_Addr p_end)
|
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)
|
static const char __elfN(bad_symtable)[] = "elf" __XSTRING(__ELF_WORD_SIZE)
|
||||||
"_lookup_symbol: corrupt symbol table\n";
|
"_lookup_symbol: corrupt symbol table\n";
|
||||||
int
|
int
|
||||||
__elfN(lookup_symbol)(struct preloaded_file *fp, elf_file_t ef,
|
__elfN(lookup_symbol)(elf_file_t ef, const char* name, Elf_Sym *symp,
|
||||||
const char* name, Elf_Sym *symp)
|
unsigned char type)
|
||||||
{
|
{
|
||||||
Elf_Hashelt symnum;
|
Elf_Hashelt symnum;
|
||||||
Elf_Sym sym;
|
Elf_Sym sym;
|
||||||
@ -1213,7 +1258,7 @@ __elfN(lookup_symbol)(struct preloaded_file *fp, elf_file_t ef,
|
|||||||
free(strp);
|
free(strp);
|
||||||
if (sym.st_shndx != SHN_UNDEF ||
|
if (sym.st_shndx != SHN_UNDEF ||
|
||||||
(sym.st_value != 0 &&
|
(sym.st_value != 0 &&
|
||||||
ELF_ST_TYPE(sym.st_info) == STT_FUNC)) {
|
ELF_ST_TYPE(sym.st_info) == type)) {
|
||||||
*symp = sym;
|
*symp = sym;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -41,6 +41,16 @@ __FBSDID("$FreeBSD$");
|
|||||||
void
|
void
|
||||||
bi_load_vbe_data(struct preloaded_file *kfp)
|
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()) {
|
if (vbe_available()) {
|
||||||
file_addmetadata(kfp, MODINFOMD_VBE_FB,
|
file_addmetadata(kfp, MODINFOMD_VBE_FB,
|
||||||
sizeof(gfx_state.tg_fb), &gfx_state.tg_fb);
|
sizeof(gfx_state.tg_fb), &gfx_state.tg_fb);
|
||||||
|
@ -17,23 +17,32 @@ CFLAGS.pnglite.c+= -DHAVE_MEMCPY -I${SRCTOP}/sys/contrib/zlib
|
|||||||
.if ${MACHINE} == "i386" || ${MACHINE_CPUARCH} == "amd64"
|
.if ${MACHINE} == "i386" || ${MACHINE_CPUARCH} == "amd64"
|
||||||
SRCS+= load_elf32.c load_elf32_obj.c reloc_elf32.c
|
SRCS+= load_elf32.c load_elf32_obj.c reloc_elf32.c
|
||||||
SRCS+= load_elf64.c load_elf64_obj.c reloc_elf64.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"
|
.elif ${MACHINE_CPUARCH} == "aarch64"
|
||||||
SRCS+= load_elf64.c reloc_elf64.c
|
SRCS+= load_elf64.c reloc_elf64.c
|
||||||
|
CFLAGS.load_elf64.c += -I$(SRCTOP)/sys/teken -I${SRCTOP}/contrib/pnglite
|
||||||
.elif ${MACHINE_CPUARCH} == "arm"
|
.elif ${MACHINE_CPUARCH} == "arm"
|
||||||
SRCS+= load_elf32.c reloc_elf32.c
|
SRCS+= load_elf32.c reloc_elf32.c
|
||||||
|
CFLAGS.load_elf32.c += -I$(SRCTOP)/sys/teken -I${SRCTOP}/contrib/pnglite
|
||||||
.elif ${MACHINE_CPUARCH} == "powerpc"
|
.elif ${MACHINE_CPUARCH} == "powerpc"
|
||||||
SRCS+= load_elf32.c reloc_elf32.c
|
SRCS+= load_elf32.c reloc_elf32.c
|
||||||
SRCS+= load_elf64.c reloc_elf64.c
|
SRCS+= load_elf64.c reloc_elf64.c
|
||||||
SRCS+= metadata.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*} != ""
|
.elif ${MACHINE_ARCH:Mmips64*} != ""
|
||||||
SRCS+= load_elf64.c reloc_elf64.c
|
SRCS+= load_elf64.c reloc_elf64.c
|
||||||
SRCS+= metadata.c
|
SRCS+= metadata.c
|
||||||
|
CFLAGS.load_elf64.c += -I$(SRCTOP)/sys/teken -I${SRCTOP}/contrib/pnglite
|
||||||
.elif ${MACHINE} == "mips"
|
.elif ${MACHINE} == "mips"
|
||||||
SRCS+= load_elf32.c reloc_elf32.c
|
SRCS+= load_elf32.c reloc_elf32.c
|
||||||
SRCS+= metadata.c
|
SRCS+= metadata.c
|
||||||
|
CFLAGS.load_elf32.c += -I$(SRCTOP)/sys/teken -I${SRCTOP}/contrib/pnglite
|
||||||
.elif ${MACHINE_CPUARCH} == "riscv"
|
.elif ${MACHINE_CPUARCH} == "riscv"
|
||||||
SRCS+= load_elf64.c reloc_elf64.c
|
SRCS+= load_elf64.c reloc_elf64.c
|
||||||
SRCS+= metadata.c
|
SRCS+= metadata.c
|
||||||
|
CFLAGS.load_elf64.c += -I$(SRCTOP)/sys/teken -I${SRCTOP}/contrib/pnglite
|
||||||
.endif
|
.endif
|
||||||
|
|
||||||
.if ${LOADER_DISK_SUPPORT:Uyes} == "yes"
|
.if ${LOADER_DISK_SUPPORT:Uyes} == "yes"
|
||||||
|
Loading…
Reference in New Issue
Block a user