Messages in this thread |  | | Date | Tue, 16 Oct 2001 11:46:19 -0700 | From | "Martin J. Bligh" <> | Subject | Re: P4 problems |
| |
> The idea is to write characters direct to the video screen during > booting using a macro called VIDEO_CHAR. This macro takes a character > position and a single character value to be displayed. Use different > positions on the screen for different levels of code and use different > characters in one position to indicate which stage that level is up to. > For example, with the patch below, the string EAC at hang indicates > parse_options(), checksetup().
I have a slightly more complex verson of this which does a whole printk, and you can embed values, strings, etc. Same fundamental idea - ram stuff directly into the video buffer. It's not pretty or portable, but then again, it's for early debug only, so deal with it ;-) We really ought to make everything before console_init use early_printk, which would be #defined to printk by default, and this on x86. Maybe. One day. Maybe ;-)
Disclaimer: I tried this on 2.4.12 the other day, and didn't get it working in the 2 minutes I spent before guessing what the problem was. But it worked beautifully on 2.4.0-test8, which was last time I used it. Should work fine though .... it's pretty simple. It's not a patch style, it's a .c file that I just #include whereever I'm working (because I'm an evil dirty hacker). Feel free to make it prettier if anyone feels so inclined.
Bits of code shamelessly stolen from the bootstrap stuff.
/* Martin J. Bligh <Martin.Bligh@us.ibm.com> */ /* Bits of code shamelessly stolen from the bootstrap stuff. */
#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 More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
|  |