|
|
1.1 root 1: =============================================
2: Google Serial Graphics Adapter BIOS (SGABIOS)
3:
4: Copyright 2007 Google Inc.
5:
6: Licensed under the Apache License, Version 2.0 (the "License");
7: you may not use this file except in compliance with the License.
8: You may obtain a copy of the License at
9:
10: http://www.apache.org/licenses/LICENSE-2.0
11:
12: Unless required by applicable law or agreed to in writing, software
13: distributed under the License is distributed on an "AS IS" BASIS,
14: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15: See the License for the specific language governing permissions and
16: limitations under the License.
17: =============================================
18: Status: Implemented (as of 2007-08-08)
19:
20: Nathan Laredo <[email protected]>
21: Modified: 2008-02-14 13:45 PDT
22:
23:
24: Objective
25: ---------
26:
27: The Google Serial Graphics Adapter BIOS or SGABIOS provides a means
28: for legacy pc software to communicate with an attached serial console
29: as if a vga card is attached.
30:
31: Background
32: ----------
33:
34: The headless server problem
35:
36: When building a lot of systems for data center use, it makes
37: no sense to install hardware that will rarely if ever be used.
38: Graphics adapters are not very useful even if they are installed
39: in a data center environment since often the person interested in
40: seeing the output is separated from the device by tens to thousands
41: of miles.
42:
43: While it's possible to use remote management hardware that provides
44: a remotely accessible display and keyboard, this hardware is much
45: more expensive than the hardware that it replaces, and often this
46: hardware sends only images of the display rather than something
47: suitable for logging.
48:
49: Since most systems already have a serial port, it's an obvious
50: target as a replacement for the primary display and keyboard.
51: The problem is that while an operating system like Linux can
52: support this arrangement, all of the output that would normally
53: appear on a graphics adapter before Linux boots is lost on modern
54: x86 hardware without modifications to the system firmware.
55:
56: While some vendors provide firmware that enables the serial port to
57: be used as the primary display, this is usually a "premium" option
58: and isn't universally available for all x86 platforms. Often such
59: services aren't implemented in a way that is friendly to saving logs
60: of boot activity. One particularly ugly implementation might send
61: the same text hundreds of times as it tries to refresh the entire
62: display each timer tick. Others have ansi control sequences
63: between every single character output which, while readable in a
64: terminal, is almost unusable when referring to serial log files.
65: Behavior like this slows down the serial output by up to fifteen
66: times in some cases, using sometimes that many extra characters
67: of control sequences for each character output.
68:
69: The need for detailed system logs
70:
71: None of the vendor-supplied serial redirection implementations
72: include facilities for logging boot message for later capture by
73: an operating system. Being able to refer to the boot messages
74: after an operating system has loaded, or having a history of such
75: messages can be a useful debug, analysis, and management feature.
76:
77: Even on systems with graphics adapters attached, once the display
78: is scrolled or refreshed with enough new text, the old messages
79: are only available in the user's own brain, which often isn't
80: very good at accurately recalling more than two or three items
81: that aren't grammatically meaningful in the user's native language.
82:
83: Overview
84: ---------
85: SGABIOS is designed to be inserted into a bios as an option rom
86: to provide over a serial port the display and input capabilites
87: normally handled by a VGA adapter and a keyboard, and additionally
88: provide hooks for logging displayed characters for later collection
89: after an operating system boots.
90:
91: It is designed to handle all text mode output sent to the legacy
92: bios int 10h service routine. Int 10h is the most common method
93: for displaying characters in 16-bit legacy x86 code.
94:
95: Occasionally some code may write directly to the vga memory in
96: the interest of "speed," and this output will be missed, but
97: it's rather uncommon for any code involved in booting a system
98: to be concerned with the speed of display output. SGABIOS is not
99: designed to handle these cases since those applications that make
100: such assumptions generally write to an area of memory that typically
101: already in use for system management mode and unusable outside of
102: that mode. Paging tricks could be used to capture such output,
103: but enabling paging requires protected mode to be enabled which
104: instantly breaks all segment loads in legacy 16-bit real- mode code
105: (which is the traditional boot environment).
106:
107: Detailed Design
108: ----------------
109:
110: VGA BIOS int 10h is hooked and chained to any existing handler or
111: the default handler that the BIOS previously setup.
112:
113: During initialization, the option rom also probes the serial port
114: for reply from an attached terminal. If the terminal replies to
115: a specific sequence, the terminal size is recorded and used for
116: all future display calculations. If a VGA card is attached at
117: the same time, the width of the terminal is limited to 80 columns
118: in order to have sensible output on both the VGA card and on the
119: serial console. If no reply comes from the serial terminal within
120: a very short timeout of about 8 milliseconds (or more accurately,
121: 65536 reads of the serial status port), a default size of 80x24
122: is used. The detected size is displayed at the end of option rom
123: init to the serial console.
124:
125: Because of the way the cursor is updated, if the cursor is never
126: moved upwards or more than one line down by int 10h calls, output
127: will still be appear completely appropriate for whatever sized
128: terminal is attached but failed to get detected.
129:
130: Whenever int 10h is invoked, SGABIOS gets control first and decides
131: whether to act based on register state. With the exception of
132: functions for getting current mode info or the current cursor
133: position, whether it acts or not, register state is ultimately
134: restored to the state on entry and a far jump is made to the
135: original handler.
136:
137: SGABIOS maintains two active cursor positions. One contains the
138: traditional VGA cursor position at the traditional location in
139: the BIOS Data Area, while the other maintains the position the
140: serial console's cursor is located. The serial cursor position
141: is located in a BDA location that traditionally contains the
142: base io port address for LPT3, but since builtin printer ports are
143: disappearing over time, this location is reused. These two values
144: will often differ since serial terminal output will always move
145: the cursor to the next position on the screen while many VGA
146: operations don't update the cursor position at all, or some only
147: at the start of the string, but leave the old value at the end.
148: Keeping track of two active cursor positions means that SGABIOS
149: can collapse a string of "set cursor" calls into perhaps a single
150: one or none if the serial console cursor already happens to be at
151: the target location. Cursor movements are further optimized
152: by sending newline characters to move the cursor down one row,
153: carriage return characters to move the cursor back to column 0,
154: and backspace characters to send the cursor back one or two spaces.
155:
156: To avoid problems when a video card is connected, any Bios Data
157: Area location that would be updated by a VGA card is left alone
158: to be updated by the VGA card. SGABIOS will update the cursor
159: position as usual, but just before chaining to an existing vga
160: card's handler, it will restore the values to those on entry,
161: and for those functions that return data, it will defer completely
162: to the chained routines rather than taking those over as it does
163: when no video card is detected.
164:
165: Cursor position updates to serial console are deferred until the
166: next character of terminal output is available. This collapses
167: the cases where the cursor is updated more than one time between
168: each character output (this is surprisingly common).
169:
170: The goal of tracking the cursor so closely and minimizing the number
171: of characters required to update the cursor position is to both to
172: make the display of output as efficient and fast as possible and
173: to allow one to grep a raw log of serial console output for text
174: (which without such optimization may be impossible or extremely
175: difficult with movement escape sequences between every character).
176:
177: In the same way cursor position is tracked, vga character attributes
178: are tracked so that it's possible to minimize the number of times
179: an attribute change escape sequence is sent to the serial console.
180:
181: A BIOS Data Area location traditionally used for storing the
182: current palette value is used to store the last attribute sent to
183: the serial console. As SGABIOS processes new calls, if the value
184: is the same, after masking off bright background colors which
185: aren't supported in ansi escape codes, then no attribute update
186: is sent to the serial console, else an escape sequence is sent
187: that gives the new background and foreground colors and whether
188: the foreground is bold or not.
189:
190: Data communication
191:
192: Whenever the call is made to output text, SGABIOS first updates
193: the serial terminal cursor to match the current position of
194: the vga cursor (if necessary), outputs any attribute change if
195: applicable to the particular int 10h call made, and finally sends
196: the text character (or characters) out to the serial port, and then
197: updates its own view of where the serial console cursor is located.
198: After the text is sent, a logging routine is called to store that
199: text in a private area of memory allocated at option rom init.
200:
201: For keyboard/terminal input, SGABIOS hooks bios int 16h which is
202: typically called to poll for a keypress. Before passing the call
203: along, SGABIOS looks for any pending input on the serial port and
204: stuffs the keyboard buffer with any pending byte after translating
205: it to a compatible keyboard scancode. If the character received
206: is an escape, SGABIOS will continue to poll for up to four extra
207: characters of input for several milliseconds in order to detect
208: ANSI/VT100/xterm/etc cursor keys and function keys, looking up
209: appropriate scancodes in a table of escape sequences for all
210: known non-conflicting terminal types.
211:
212: SGABIOS also hooks the serial port interrupts, and on receiving
213: an interrupt blocks out interrupts, calls the same polling
214: routines as above, following the same processing of multi-byte
215: input as well, stuffing the keyboard buffer as appropriate,
216: and finally acknowledging the interrupt and returning from the
217: handler. [ serial port interrupts are now DISABLED ]
218:
219: Optionally the serial port input/output can be replaced with
220: a SMI trigger that calls into an EFI BIOS in order to tie into
221: its own console input and output routines rather than directly
222: hitting the serial port. In this particular case it's assumed
223: that all logging is handled in the EFI module that will be called.
224: BIOS int 15h, ax = 0d042h is used to trigger SMI. The parameters
225: passed will need to be changed to be specific to the EFI or SMI
226: handler put in place. In the example in SMBIOS, for output,
227: ebx = 0xf00d0000 | (char << 8), and for input, ebx = 0xfeed0000,
228: with the character, if any, returned in the eax register with ZF
229: set and eax=0 if no character was available.
230:
231: Summary of new enhancements
232: ---------------------------
233: SGABIOS now keeps a log of the last 256 characters written to
234: the screen and where they were written in the event an application
235: like lilo asks for the current character under the cursor. These
236: are currently stored in a 1KB EBDA allocation which can be expanded
237: as needed. This method avoids having to store a 64KB buffer for
238: the largest possible serial terminal supported (255x255).
239:
240: When lilo 22.6 is detected, SGABIOS now knows how to disable
241: lilo's serial output in favor of its own. This avoids having
242: double character output from both serial and VGABIOS interleaved.
243:
244: Possible future enhancements
245: ----------------------------
246: Previous future ideas have now been implemented.
247:
248: Known Bugs
249: ----------
250: With some versions of DOS, only the last character of every line
251: is displayed once dos boots since DOS will use direct access to
252: the VGA framebuffer until the end of line is reached, at which
253: point it will start using int 10h. Dual cursor tracking might
254: fix this issue by maintaining positions for dos that look like
255: the end of line and another for internal use to know where to
256: output next.
257:
258: Caveats
259: -------
260: It may be possible for someone to construct a terminal reply for
261: the terminal sizing code that is completely invalid and attempts
262: to either setup variables to overrun buffers or else overruns
263: the input buffer itself. This situation is currently handled
264: by limiting the reply to between eight and fourteen characters
265: and ignoring any values outside the range from ten to two hundred
266: fifty-five for both the number of rows and the number of columns.
267: In these situations a default size of 80x24 is used (unless a
268: video card is present, in which case its size is used). If the
269: resize code detects several unexpected characters during the
270: terminal size detection, it currently assumes that someone has
271: left a loopback device plugged into the serial port and redirects
272: the serial input and output to the fourth serial port at 0x2e8.
273:
274:
275: Security considerations
276: -----------------------
277: None. This is already 16-bit real-mode x86 code. The entire
278: system may be crashed or bent to do anyone's bidding at any time
279: by any other running code outside of SGABIOS.
280:
281:
282: Opensource Plan
283: ---------------
284: This source code was approved for release to the public for use under
285: the Apache License, Version 2.0 on http://code.google.com/p/sgabios
286:
287:
288: Document History
289: ----------------
290: Date Author Description
291: 2008-02-14 nil fix for release
292: 2007-10-04 nil new features
293: 2007-08-31 nil sga+vga fixes
294: 2007-08-08 nil Initial version
295:
296: $Id$
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.