lkml.org 
[lkml]   [2000]   [Sep]   [28]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
/
Date
From
SubjectRe: [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/

\
 
 \ /
  Last update: 2005-03-22 12:38    [W:0.046 / U:20.344 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site