A bug in BIOS causes the "invisible output from FreeBSD boot loader" problem (analysis and interim workaround inside)

View: New views
3 Messages — Rating Filter:   Alert me  

A bug in BIOS causes the "invisible output from FreeBSD boot loader" problem (analysis and interim workaround inside)

by Eugene M. Kim-7 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hello,

I just received my net5501 and have been playing with it;
unsurprisingly, the "invisible output" problem has hit me too.  :-)

After a script(1)-ed console session and a dive into the boot loader
code, I think I have found the problem: BIOS seems to incorrectly
implement the video INT 0x10 AH=0x09 "write character and attribute at
cursor position" (and possibly AH=0x0A "write character only at cursor
position" as well, as the two are very similar).

These two video INTs make BIOS write a character at the current cursor
position, /without/ advancing the cursor (unlike the "teletype" mode,
AH=0x0e).  When emulating this on the serial console, just emitting the
character is not enough, because the terminal emulator is in the
teletype mode (surprise!) and advances the cursor to the next position;
the BIOS must emulate the "cursor not moved" behavior by emitting an
escape sequence (ESC H) to restore the cursor to the previous position.
However, the current BIOS does not restore the cursor position.

FreeBSD's vidconsole library has a subroutine named curs_move() (found
at src/sys/boot/i386/libi386/vidconsole.c:209 as of revision 1.20, which
is current in all of HEAD, RELENG_7 and RELENG_6).  curs_move() uses INT
0x10 AH=0x09 internally to reset the character at the new cursor
position to ASCII space in order to ensure the cursor is visible at the
current location (this is a workaround for some buggy VGA hardware where
the cursor disappears if it is placed where a non-printable character is).

The FreeBSD boot loader interleaves calls to curs_move() and
write_char() (also in vidconsole.c) in order to print a string one
character a time, and with the Soekris BIOS not resetting the cursor
position after writing a character, only a space is displayed (by
curs_move()) at the desired position, and the real character (that
write_char() displays) ends up one column to the right, which then the
next call to curs_move() clobbers with another space.  The end result is
that whatever character displayed is immediately erased, which precisely
is the problematic symptom.

There is a workaround, although it involves recompiling boot loaders
(unfortunately): Since we are not dealing with the real video hardware,
boot loader need not reset the character at the new cursor location
after moving the cursor; this can be done by commenting out the call to
write_char() in curs_move().

Cheers,
Eugene

_______________________________________________
Soekris-tech mailing list
Soekris-tech@...
http://lists.soekris.com/mailman/listinfo/soekris-tech

Re: A bug in BIOS causes the "invisible output from FreeBSD boot loader" problem (analysis and interim workaround inside)

by Soren Kristensen :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi Eugene,

Eugene M. Kim wrote:

> Hello,
>
> I just received my net5501 and have been playing with it;
> unsurprisingly, the "invisible output" problem has hit me too.  :-)
>
> After a script(1)-ed console session and a dive into the boot loader
> code, I think I have found the problem: BIOS seems to incorrectly
> implement the video INT 0x10 AH=0x09 "write character and attribute at
> cursor position" (and possibly AH=0x0A "write character only at cursor
> position" as well, as the two are very similar).
>
> These two video INTs make BIOS write a character at the current cursor
> position, /without/ advancing the cursor (unlike the "teletype" mode,
> AH=0x0e).  When emulating this on the serial console, just emitting the
> character is not enough, because the terminal emulator is in the
> teletype mode (surprise!) and advances the cursor to the next position;
> the BIOS must emulate the "cursor not moved" behavior by emitting an
> escape sequence (ESC H) to restore the cursor to the previous position.
> However, the current BIOS does not restore the cursor position.
>
> FreeBSD's vidconsole library has a subroutine named curs_move() (found
> at src/sys/boot/i386/libi386/vidconsole.c:209 as of revision 1.20, which
> is current in all of HEAD, RELENG_7 and RELENG_6).  curs_move() uses INT
> 0x10 AH=0x09 internally to reset the character at the new cursor
> position to ASCII space in order to ensure the cursor is visible at the
> current location (this is a workaround for some buggy VGA hardware where
> the cursor disappears if it is placed where a non-printable character is).
>
> The FreeBSD boot loader interleaves calls to curs_move() and
> write_char() (also in vidconsole.c) in order to print a string one
> character a time, and with the Soekris BIOS not resetting the cursor
> position after writing a character, only a space is displayed (by
> curs_move()) at the desired position, and the real character (that
> write_char() displays) ends up one column to the right, which then the
> next call to curs_move() clobbers with another space.  The end result is
> that whatever character displayed is immediately erased, which precisely
> is the problematic symptom.
>
> There is a workaround, although it involves recompiling boot loaders
> (unfortunately): Since we are not dealing with the real video hardware,
> boot loader need not reset the character at the new cursor location
> after moving the cursor; this can be done by commenting out the call to
> write_char() in curs_move().

Very detailed, I'll look into it and fix the comBIOS....


Best Regards,


Soren Kristensen

CEO & Chief Engineer
Soekris Engineering, Inc.
_______________________________________________
Soekris-tech mailing list
Soekris-tech@...
http://lists.soekris.com/mailman/listinfo/soekris-tech

Re: A bug in BIOS causes the "invisible output from FreeBSD boot loader" problem (analysis and interim workaround inside)

by Brian Candler :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Wed, Jun 25, 2008 at 11:42:57AM +0200, Soren Kristensen wrote:
> Very detailed, I'll look into it and fix the comBIOS....

Perhaps also worth a look at int10h with ah=0fh, if you've not done so
already (I haven't checked a recent comBIOS).

The problem manifests as pxelinux writing in a tiny 15-character-wide
window. For details see the "Aside:" at the bottom of this mail:
http://lists.soekris.com/pipermail/soekris-tech/2007-November/013353.html

Regards,

Brian.
_______________________________________________
Soekris-tech mailing list
Soekris-tech@...
http://lists.soekris.com/mailman/listinfo/soekris-tech