Fix vm86 initialization, part 3 of 2 and a half. (Actually, just fix

early printfs and debugging of vm86 initialization and some other early
initialization in some cases.)  Add an option debug.late_console (with
default 1=off) to move console and kdb initialization back where it was.
Do the same for amd64 although there is no vm86 there.

On my test system, debug.late_console=0 works for the syscons, sio and
uart console drivers on amd64 and i386, and for vt on i386 but not on
amd64.

The early printfs fixed by debug.late_console=0 are:
- on i386, the message about lost memory above 4G
- with -v in otherwise normal use, about 20 printfs for SMAP
- other debugging messages for memory sizing.  Mostly under -v and
  not printed in normal use.

Document in a comment how much earlier the initialization and early
printf()s can be.  That is very early for the console.  Not much more
than curthread is needed.  kdb use obviously needs to be not so early,
since it needs IDT initialization and that is done relatively late
for convenience and historical reasons.
This commit is contained in:
Bruce Evans 2016-09-25 14:56:24 +00:00
parent b9413b5512
commit f5435b8bbe
2 changed files with 64 additions and 23 deletions

View File

@ -1506,6 +1506,16 @@ native_parse_preload_data(u_int64_t modulep)
return (kmdp); return (kmdp);
} }
static void
amd64_kdb_init(void)
{
kdb_init();
#ifdef KDB
if (boothowto & RB_KDB)
kdb_enter(KDB_WHY_BOOTFLAGS, "Boot flags requested debugger");
#endif
}
u_int64_t u_int64_t
hammer_time(u_int64_t modulep, u_int64_t physfree) hammer_time(u_int64_t modulep, u_int64_t physfree)
{ {
@ -1517,6 +1527,7 @@ hammer_time(u_int64_t modulep, u_int64_t physfree)
u_int64_t msr; u_int64_t msr;
char *env; char *env;
size_t kstack0_sz; size_t kstack0_sz;
int late_console;
/* /*
* This may be done better later if it gets more high level * This may be done better later if it gets more high level
@ -1561,6 +1572,7 @@ hammer_time(u_int64_t modulep, u_int64_t physfree)
physfree += DPCPU_SIZE; physfree += DPCPU_SIZE;
PCPU_SET(prvspace, pc); PCPU_SET(prvspace, pc);
PCPU_SET(curthread, &thread0); PCPU_SET(curthread, &thread0);
/* Non-late cninit() and printf() can be moved up to here. */
PCPU_SET(tssp, &common_tss[0]); PCPU_SET(tssp, &common_tss[0]);
PCPU_SET(commontssp, &common_tss[0]); PCPU_SET(commontssp, &common_tss[0]);
PCPU_SET(tss, (struct system_segment_descriptor *)&gdt[GPROC0_SEL]); PCPU_SET(tss, (struct system_segment_descriptor *)&gdt[GPROC0_SEL]);
@ -1660,12 +1672,26 @@ hammer_time(u_int64_t modulep, u_int64_t physfree)
wrmsr(MSR_STAR, msr); wrmsr(MSR_STAR, msr);
wrmsr(MSR_SF_MASK, PSL_NT|PSL_T|PSL_I|PSL_C|PSL_D); wrmsr(MSR_SF_MASK, PSL_NT|PSL_T|PSL_I|PSL_C|PSL_D);
/*
* The console and kdb should be initialized even earlier than here,
* but some console drivers don't work until after getmemsize().
* Default to late console initialization to support these drivers.
* This loses mainly printf()s in getmemsize() and early debugging.
*/
late_console = 1;
TUNABLE_INT_FETCH("debug.late_console", &late_console);
if (!late_console) {
cninit();
amd64_kdb_init();
}
getmemsize(kmdp, physfree); getmemsize(kmdp, physfree);
init_param2(physmem); init_param2(physmem);
/* now running on new page tables, configured,and u/iom is accessible */ /* now running on new page tables, configured,and u/iom is accessible */
cninit(); if (late_console)
cninit();
#ifdef DEV_ISA #ifdef DEV_ISA
#ifdef DEV_ATPIC #ifdef DEV_ATPIC
@ -1686,13 +1712,8 @@ hammer_time(u_int64_t modulep, u_int64_t physfree)
#error "have you forgotten the isa device?"; #error "have you forgotten the isa device?";
#endif #endif
kdb_init(); if (late_console)
amd64_kdb_init();
#ifdef KDB
if (boothowto & RB_KDB)
kdb_enter(KDB_WHY_BOOTFLAGS,
"Boot flags requested debugger");
#endif
msgbufinit(msgbufp, msgbufsize); msgbufinit(msgbufp, msgbufsize);
fpuinit(); fpuinit();

View File

@ -2089,7 +2089,6 @@ getmemsize(int first)
* use that and do not make any VM86 calls. * use that and do not make any VM86 calls.
*/ */
physmap_idx = 0; physmap_idx = 0;
smapbase = NULL;
kmdp = preload_search_by_type("elf kernel"); kmdp = preload_search_by_type("elf kernel");
if (kmdp == NULL) if (kmdp == NULL)
kmdp = preload_search_by_type("elf32 kernel"); kmdp = preload_search_by_type("elf32 kernel");
@ -2223,6 +2222,9 @@ getmemsize(int first)
* highest page of the physical address space. It should be * highest page of the physical address space. It should be
* called something like "Maxphyspage". We may adjust this * called something like "Maxphyspage". We may adjust this
* based on ``hw.physmem'' and the results of the memory test. * based on ``hw.physmem'' and the results of the memory test.
*
* This is especially confusing when it is much larger than the
* memory size and is displayed as "realmem".
*/ */
Maxmem = atop(physmap[physmap_idx + 1]); Maxmem = atop(physmap[physmap_idx + 1]);
@ -2428,6 +2430,19 @@ getmemsize(int first)
} }
#endif /* PC98 */ #endif /* PC98 */
static void
i386_kdb_init(void)
{
#ifdef DDB
db_fetch_ksymtab(bootinfo.bi_symtab, bootinfo.bi_esymtab);
#endif
kdb_init();
#ifdef KDB
if (boothowto & RB_KDB)
kdb_enter(KDB_WHY_BOOTFLAGS, "Boot flags requested debugger");
#endif
}
register_t register_t
init386(first) init386(first)
int first; int first;
@ -2438,6 +2453,7 @@ init386(first)
#ifdef CPU_ENABLE_SSE #ifdef CPU_ENABLE_SSE
struct xstate_hdr *xhdr; struct xstate_hdr *xhdr;
#endif #endif
int late_console;
thread0.td_kstack = proc0kstack; thread0.td_kstack = proc0kstack;
thread0.td_kstack_pages = TD0_KSTACK_PAGES; thread0.td_kstack_pages = TD0_KSTACK_PAGES;
@ -2502,6 +2518,7 @@ init386(first)
first += DPCPU_SIZE; first += DPCPU_SIZE;
PCPU_SET(prvspace, pc); PCPU_SET(prvspace, pc);
PCPU_SET(curthread, &thread0); PCPU_SET(curthread, &thread0);
/* Non-late cninit() and printf() can be moved up to here. */
/* /*
* Initialize mutexes. * Initialize mutexes.
@ -2668,30 +2685,33 @@ init386(first)
#endif #endif
#endif #endif
/*
* The console and kdb should be initialized even earlier than here,
* but some console drivers don't work until after getmemsize().
* Default to late console initialization to support these drivers.
* This loses mainly printf()s in getmemsize() and early debugging.
*/
late_console = 1;
TUNABLE_INT_FETCH("debug.late_console", &late_console);
if (!late_console) {
cninit();
i386_kdb_init();
}
vm86_initialize(); vm86_initialize();
getmemsize(first); getmemsize(first);
init_param2(physmem); init_param2(physmem);
/* now running on new page tables, configured,and u/iom is accessible */ /* now running on new page tables, configured,and u/iom is accessible */
/* if (late_console)
* Initialize the console before we print anything out. cninit();
*/
cninit();
if (metadata_missing) if (metadata_missing)
printf("WARNING: loader(8) metadata is missing!\n"); printf("WARNING: loader(8) metadata is missing!\n");
#ifdef DDB if (late_console)
db_fetch_ksymtab(bootinfo.bi_symtab, bootinfo.bi_esymtab); i386_kdb_init();
#endif
kdb_init();
#ifdef KDB
if (boothowto & RB_KDB)
kdb_enter(KDB_WHY_BOOTFLAGS, "Boot flags requested debugger");
#endif
msgbufinit(msgbufp, msgbufsize); msgbufinit(msgbufp, msgbufsize);
#ifdef DEV_NPX #ifdef DEV_NPX