make panic() work for multiboot/elf case
. we cannot use the boot monitor to print the system diag buffer . for serial, we do nothing, just reset, everything is already printed . for not-serial, we print the current diag buffer using direct video memory access from the kernel
This commit is contained in:
parent
a73c217bf6
commit
2487445f5f
5 changed files with 118 additions and 70 deletions
|
@ -25,6 +25,7 @@
|
|||
#include "oxpcie.h"
|
||||
#include "kernel/proc.h"
|
||||
#include "kernel/debug.h"
|
||||
#include "mb_utils.h"
|
||||
#include <machine/multiboot.h>
|
||||
|
||||
#include "glo.h"
|
||||
|
@ -85,15 +86,14 @@ PUBLIC int cpu_has_tsc;
|
|||
|
||||
PUBLIC __dead void arch_shutdown(int how)
|
||||
{
|
||||
static char mybuffer[sizeof(params_buffer)];
|
||||
u16_t magic;
|
||||
vm_stop();
|
||||
|
||||
/* Mask all interrupts, including the clock. */
|
||||
outb( INT_CTLMASK, ~0);
|
||||
|
||||
#if USE_BOOTPARAM
|
||||
if(minix_panicing) {
|
||||
unsigned char unused_ch;
|
||||
/* We're panicing? Then retrieve and decode currently
|
||||
* loaded segment selectors.
|
||||
*/
|
||||
|
@ -102,8 +102,22 @@ PUBLIC __dead void arch_shutdown(int how)
|
|||
if(read_ds() != read_ss()) {
|
||||
printseg("ss: ", 0, NULL, read_ss());
|
||||
}
|
||||
|
||||
/* Printing is done synchronously over serial. */
|
||||
if (do_serial_debug)
|
||||
reset();
|
||||
|
||||
/* Print accumulated diagnostics buffer and reset. */
|
||||
mb_cls();
|
||||
mb_print("Minix panic. System diagnostics buffer:\n\n");
|
||||
mb_print(kmess_buf);
|
||||
mb_print("\nSystem has panicked, press any key to reboot");
|
||||
while (!mb_read_char(&unused_ch))
|
||||
;
|
||||
reset();
|
||||
}
|
||||
|
||||
#if USE_BOOTPARAM
|
||||
if (how == RBT_DEFAULT) {
|
||||
how = mon_return ? RBT_HALT : RBT_RESET;
|
||||
}
|
||||
|
@ -119,37 +133,7 @@ PUBLIC __dead void arch_shutdown(int how)
|
|||
*/
|
||||
if (how != RBT_MONITOR)
|
||||
arch_set_params("", 1);
|
||||
if(minix_panicing) {
|
||||
int source, dest;
|
||||
const char *lead = "echo \\n*** kernel messages:\\n";
|
||||
const int leadlen = strlen(lead);
|
||||
strcpy(mybuffer, lead);
|
||||
|
||||
#define DECSOURCE source = (source - 1 + _KMESS_BUF_SIZE) % _KMESS_BUF_SIZE
|
||||
|
||||
dest = sizeof(mybuffer)-1;
|
||||
mybuffer[dest--] = '\0';
|
||||
|
||||
source = kmess.km_next;
|
||||
DECSOURCE;
|
||||
|
||||
while(dest >= leadlen) {
|
||||
const char c = kmess.km_buf[source];
|
||||
if(c == '\n') {
|
||||
mybuffer[dest--] = 'n';
|
||||
mybuffer[dest] = '\\';
|
||||
} else if(isprint(c) &&
|
||||
c != '\'' && c != '"' &&
|
||||
c != '\\' && c != ';') {
|
||||
mybuffer[dest] = c;
|
||||
} else mybuffer[dest] = ' ';
|
||||
|
||||
DECSOURCE;
|
||||
dest--;
|
||||
}
|
||||
|
||||
arch_set_params(mybuffer, strlen(mybuffer)+1);
|
||||
}
|
||||
if (mon_return)
|
||||
arch_monitor();
|
||||
|
||||
|
@ -157,14 +141,7 @@ PUBLIC __dead void arch_shutdown(int how)
|
|||
* depending on the parameters
|
||||
*/
|
||||
if (how == RBT_MONITOR) {
|
||||
mybuffer[0] = '\0';
|
||||
arch_get_params(mybuffer, sizeof(mybuffer));
|
||||
if (strstr(mybuffer, "boot") ||
|
||||
strstr(mybuffer, "menu") ||
|
||||
strstr(mybuffer, "reset"))
|
||||
how = RBT_RESET;
|
||||
else
|
||||
how = RBT_HALT;
|
||||
how = RBT_RESET;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -643,8 +620,6 @@ PUBLIC void arch_ack_profile_clock(void)
|
|||
|
||||
#endif
|
||||
|
||||
#define COLOR_BASE 0xB8000L
|
||||
|
||||
/* Saved by mpx386.s into these variables. */
|
||||
u32_t params_size, params_offset, mon_ds;
|
||||
|
||||
|
|
12
kernel/arch/i386/mb_utils.h
Normal file
12
kernel/arch/i386/mb_utils.h
Normal file
|
@ -0,0 +1,12 @@
|
|||
#ifndef MB_UTILS_H
|
||||
#define MB_UTILS_H
|
||||
|
||||
#include "kernel/kernel.h"
|
||||
|
||||
_PROTOTYPE(void mb_cls, (void));
|
||||
_PROTOTYPE(void mb_print, (char*));
|
||||
_PROTOTYPE(void mb_print_char, (char));
|
||||
_PROTOTYPE(int mb_read_char, (unsigned char*));
|
||||
|
||||
|
||||
#endif
|
|
@ -16,6 +16,8 @@
|
|||
#include "string.h"
|
||||
#include "arch_proto.h"
|
||||
#include "libexec.h"
|
||||
#include "mb_utils.h"
|
||||
#include "serial.h"
|
||||
#include <machine/multiboot.h>
|
||||
|
||||
#if USE_SYSDEBUG
|
||||
|
@ -38,8 +40,6 @@
|
|||
#define mb_save_phymem(buf, phy, len) \
|
||||
phys_copy((u32_t)(buf), (phy), (len))
|
||||
|
||||
FORWARD _PROTOTYPE(void mb_print, (char *str));
|
||||
|
||||
PRIVATE void mb_itoa(u32_t val, char * out)
|
||||
{
|
||||
char ret[ITOA_BUFFER_SIZE];
|
||||
|
@ -117,50 +117,104 @@ PRIVATE char mb_get_char(int line, int col)
|
|||
|
||||
/* Give non-zero values to avoid them in BSS */
|
||||
PRIVATE int print_line = 1, print_col = 1;
|
||||
|
||||
#include <sys/video.h>
|
||||
|
||||
PRIVATE void mb_cls(void)
|
||||
PUBLIC void mb_cls(void)
|
||||
{
|
||||
#if MULTIBOOT_VERBOSE
|
||||
int i, j;
|
||||
/* Clear screen */
|
||||
for (i = 0; i < MULTIBOOT_CONSOLE_LINES; i++ )
|
||||
for (j = 0; j < MULTIBOOT_CONSOLE_COLS; j++ )
|
||||
mb_put_char(0, i, j);
|
||||
print_line = print_col = 0;
|
||||
#endif
|
||||
|
||||
/* Tell video hardware origin is 0. */
|
||||
outb(C_6845+INDEX, VID_ORG);
|
||||
outb(C_6845+DATA, 0);
|
||||
outb(C_6845+INDEX, VID_ORG+1);
|
||||
outb(C_6845+DATA, 0);
|
||||
}
|
||||
|
||||
PRIVATE void mb_scroll_up(int lines)
|
||||
{
|
||||
int i, j;
|
||||
for (i = 0; i < MULTIBOOT_CONSOLE_LINES - lines; i++ ) {
|
||||
for (j = 0; j < MULTIBOOT_CONSOLE_COLS; j++ )
|
||||
mb_put_char(mb_get_char(i + lines, j), i, j);
|
||||
for (i = 0; i < MULTIBOOT_CONSOLE_LINES; i++ ) {
|
||||
for (j = 0; j < MULTIBOOT_CONSOLE_COLS; j++ ) {
|
||||
char c = 0;
|
||||
if(i < MULTIBOOT_CONSOLE_LINES-lines)
|
||||
c = mb_get_char(i + lines, j);
|
||||
mb_put_char(c, i, j);
|
||||
}
|
||||
}
|
||||
print_line-= lines;
|
||||
}
|
||||
|
||||
PRIVATE void mb_print(char *str)
|
||||
PUBLIC void mb_print_char(char c)
|
||||
{
|
||||
#if MULTIBOOT_VERBOSE
|
||||
while (*str) {
|
||||
if (*str == '\n') {
|
||||
str++;
|
||||
while (print_col < MULTIBOOT_CONSOLE_COLS)
|
||||
mb_put_char(' ', print_line, print_col++);
|
||||
print_line++;
|
||||
print_col = 0;
|
||||
continue;
|
||||
}
|
||||
mb_put_char(*str++, print_line, print_col++);
|
||||
if (print_col >= MULTIBOOT_CONSOLE_COLS) {
|
||||
print_line++;
|
||||
print_col = 0;
|
||||
}
|
||||
while (print_line >= MULTIBOOT_CONSOLE_LINES)
|
||||
mb_scroll_up(1);
|
||||
while (print_line >= MULTIBOOT_CONSOLE_LINES)
|
||||
mb_scroll_up(1);
|
||||
|
||||
if (c == '\n') {
|
||||
while (print_col < MULTIBOOT_CONSOLE_COLS)
|
||||
mb_put_char(' ', print_line, print_col++);
|
||||
print_line++;
|
||||
print_col = 0;
|
||||
return;
|
||||
}
|
||||
#endif /* MULTIBOOT_VERBOSE */
|
||||
|
||||
mb_put_char(c, print_line, print_col++);
|
||||
|
||||
if (print_col >= MULTIBOOT_CONSOLE_COLS) {
|
||||
print_line++;
|
||||
print_col = 0;
|
||||
}
|
||||
|
||||
while (print_line >= MULTIBOOT_CONSOLE_LINES)
|
||||
mb_scroll_up(1);
|
||||
}
|
||||
|
||||
PUBLIC void mb_print(char *str)
|
||||
{
|
||||
while (*str) {
|
||||
mb_print_char(*str);
|
||||
str++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Standard and AT keyboard. (PS/2 MCA implies AT throughout.) */
|
||||
#define KEYBD 0x60 /* I/O port for keyboard data */
|
||||
#define KB_STATUS 0x64 /* I/O port for status on AT */
|
||||
#define KB_OUT_FULL 0x01 /* status bit set when keypress char pending */
|
||||
#define KB_AUX_BYTE 0x20 /* Auxiliary Device Output Buffer Full */
|
||||
|
||||
PUBLIC int mb_read_char(unsigned char *ch)
|
||||
{
|
||||
unsigned long b, sb;
|
||||
#ifdef DEBUG_SERIAL
|
||||
u8_t c, lsr;
|
||||
|
||||
if (do_serial_debug) {
|
||||
lsr= inb(COM1_LSR);
|
||||
if (!(lsr & LSR_DR))
|
||||
return 0;
|
||||
c = inb(COM1_RBR);
|
||||
return 1;
|
||||
}
|
||||
#endif /* DEBUG_SERIAL */
|
||||
|
||||
sb = inb(KB_STATUS);
|
||||
|
||||
if (!(sb & KB_OUT_FULL)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
b = inb(KEYBD);
|
||||
|
||||
if (!(sb & KB_AUX_BYTE))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
PRIVATE void mb_print_hex(u32_t value)
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
EXTERN struct kinfo kinfo; /* kernel information for users */
|
||||
EXTERN struct machine machine; /* machine information for users */
|
||||
EXTERN struct kmessages kmess; /* diagnostic messages in kernel */
|
||||
EXTERN char kmess_buf[80*25]; /* printable copy of message buffer */
|
||||
EXTERN struct k_randomness krandom; /* gather kernel random information */
|
||||
EXTERN struct loadinfo kloadinfo; /* status of load average */
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ PUBLIC void panic(const char *fmt, ...)
|
|||
va_list arg;
|
||||
/* The system has run aground of a fatal kernel error. Terminate execution. */
|
||||
if (minix_panicing == ARE_PANICING) {
|
||||
arch_monitor();
|
||||
reset();
|
||||
}
|
||||
minix_panicing = ARE_PANICING;
|
||||
if (fmt != NULL) {
|
||||
|
@ -53,6 +53,8 @@ int c; /* character to append */
|
|||
* to the output driver if an END_OF_KMESS is encountered.
|
||||
*/
|
||||
if (c != END_OF_KMESS) {
|
||||
static int blpos = 0;
|
||||
int maxblpos = sizeof(kmess_buf) - 2;
|
||||
#ifdef DEBUG_SERIAL
|
||||
if (do_serial_debug) {
|
||||
if(c == '\n')
|
||||
|
@ -61,9 +63,13 @@ int c; /* character to append */
|
|||
}
|
||||
#endif
|
||||
kmess.km_buf[kmess.km_next] = c; /* put normal char in buffer */
|
||||
kmess_buf[blpos] = c;
|
||||
if (kmess.km_size < sizeof(kmess.km_buf))
|
||||
kmess.km_size += 1;
|
||||
kmess.km_next = (kmess.km_next + 1) % _KMESS_BUF_SIZE;
|
||||
if(blpos == maxblpos) {
|
||||
memmove(kmess_buf, kmess_buf+1, sizeof(kmess_buf)-1);
|
||||
} else blpos++;
|
||||
} else {
|
||||
int p;
|
||||
endpoint_t outprocs[] = OUTPUT_PROCS_ARRAY;
|
||||
|
|
Loading…
Reference in a new issue