Messages in this thread |  | | Date | Thu, 28 Sep 2000 10:20:55 -0700 | From | "Martin J. Bligh" <> | Subject | Re: [DOC] Debugging early kernel hangs |
| |
> If a kernel hangs early in the boot process (before the console has > been initialized) then printk is no use because you never see the > output. There is a technique for using the video display to indicate > boot progress so you can localize the problem. Reporting "my kernel > hangs during boot at line nnn in routine xyz" is a lot better than "my > kernel hangs during boot".
I was doing some similar debug work, and stole some code from the early boot decompress stuff, and munged it. It's a nasty hack that only works on x86 (probably), and hardcodes video addresses, etc. But you might find it useful to print out addresses, etc with.
There are routines to print things, scroll the screen, clear the screen, and spin for a specified number of seconds (so that you can actually read the output ;-) )
Martin.
/* Martin J. Bligh <mbligh@us.ibm.com> */
#define VIDMEMBUF 0xB800
int orig_x = 0; int orig_y = 0; int vidport = 0x3d4;
void early_scroll(void) { int i, cols = 80, lines = 25; unsigned char *vidmem = phys_to_virt(VIDMEMBUF);
memcpy ( vidmem, vidmem + cols * 2, ( lines - 1 ) * cols * 2 ); for ( i = ( lines - 1 ) * cols * 2; i < lines * cols * 2; i += 2 ) vidmem[i] = ' '; }
void clearvidmem(void) { int x, y, pos = 0; unsigned char *vidmem = phys_to_virt(VIDMEMBUF);
for (x = 0; x < 80; x++) { for (y = 0; y < 25; y++) { vidmem [ ( x + 80 * y ) * 2 ] = ' '; } } orig_x = 0; orig_y = 0;
/* Update cursor position */ outb_p(14, vidport); outb_p(0xff & (pos >> 9), vidport+1); outb_p(15, vidport); outb_p(0xff & (pos >> 1), vidport+1); }
void pokevidmem(int x, int y, char c) { unsigned char *vidmem = phys_to_virt(VIDMEMBUF);
vidmem [ ( x + 80 * y ) * 2 ] = c; }
void spin_on_me(int howlong) { int i, j;
for (i=0; i<howlong; ++i) for (j=0; j<10000; ++j) /* spin 1 sec */ udelay(100); }
void early_puts(const char *s) { int x,y,pos, cols = 80, lines = 25; char c;
x = orig_x; y = orig_y;
while ( ( c = *s++ ) != '\0' ) { if ( c == '\n' ) { x = 0; if ( ++y >= lines ) { early_scroll(); y--; } } else { pokevidmem (x, y, c); if ( ++x >= cols ) { x = 0; if ( ++y >= lines ) { early_scroll(); y--; } } } }
orig_x = x; orig_y = y;
pos = (x + cols * y) * 2; /* Update cursor position */ outb_p(14, vidport); outb_p(0xff & (pos >> 9), vidport+1); outb_p(15, vidport); outb_p(0xff & (pos >> 1), vidport+1); }
void early_printk(const char *fmt, ...) { va_list args; int i; char buf[1024];
va_start(args, fmt); i = vsprintf(buf, fmt, args); /* hopefully i < sizeof(buf)-4 */ va_end(args); early_puts(buf); printk(buf); }
- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org Please read the FAQ at http://www.tux.org/lkml/
|  |