Re: P4 problems

From: Martin J. Bligh (Martin.Bligh@us.ibm.com)
Date: Tue Oct 16 2001 - 13:46:19 EST


> 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/



This archive was generated by hypermail 2b29 : Tue Oct 23 2001 - 21:00:15 EST