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

Soren Kristensen soren at soekris.com
Wed Jun 25 09:42:57 UTC 2008


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.


More information about the Soekris-tech mailing list