1 / 31

Console Redirection Mechanism and Terminal Emulation Features in x86 Protected Mode

Explore the use of terminal emulation features in the console redirection mechanism when using x86 protected mode on our anchor-cluster's machines. Learn about the remote access scheme and programming hurdles encountered.

jeffriest
Download Presentation

Console Redirection Mechanism and Terminal Emulation Features in x86 Protected Mode

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Using x86 “protected mode” on our anchor-cluster’s machines A look at some terminal emulation features utilized in the “console-redirection” mechanism

  2. Our remote-access scheme sixteen Core 2 Duo systems . . . ‘anchor08’ ‘anchor07’ ‘anchor06’ student workstation ‘telnet’ application ‘anchor05’ ‘pyramid’ ‘anchor04’ CS file-server ‘anchor03’ rackmount PC system KVM cable ‘anchor02’ null-modem serial cables ‘anchor01’ ethernet cables

  3. A programming hurdle • When you try to test a ‘boot-time’ program on one of our ‘anchor’ machines, you will encounter a problem when your program enters protected-mode: you can no longer see the current screen-output, nor control your program using keyboard-input, since the normal ‘console redirection’ capability (which ‘telnet’ relies on) has been disabled

  4. The console’s output • At boot-time the ‘anchor’ machines use a ‘real-mode’ interrupt-handler in the BIOS to continually transfer information (via the null-modem serial-cable) from the display memory of the local machine to the ‘telnet’ program running on the ‘pyramid’ server • From there it gets sent over the Ethernet network to a student’s computer screen

  5. The console’s input • When a student types a keystroke, it gets sent via the network to the ‘telnet’ program running on ‘pyramid’, whereupon it then is forwarded to the ‘anchor’ machine via the null-modem serial-cable connection • This scheme allows us to do our work on the anchor-machines remotely – from our classroom or CS Labs, or even from home

  6. The IVT’s role • But this scheme relies on BIOS code that handle’s UART interrupts in ‘real-mode’ • When a program enters ‘protected-mode’, it has to switch from its Table of Interrupt Vectors (used in real-mode) to a different table for dispatching of interrupts to ISRs • At that point we lose all the functionality that BIOS’s interrupt-handlers provided!

  7. Our reimplementation • Just as we’ve seen how to regain some of the functionality provided by the real-mode BIOS code, by writing our own protected-mode interrupt-handlers for the keyboard and the timer, we can restore the basic ‘console redirection’ capability by writing our own interrupt-handler for the UART when the CPU is in its ‘protected-mode’

  8. Some details • We need to write “trivial” interrupt-handlers for a few peripherals besides the UART: • For the timer (so we can see something that’s changing on the display screen) • For the keyboard (so we can control when to quit watching our display) • For any ‘spurious’ interrupts that the 8259 PIC delivers to the CPU (so we won’t “crash” due to unwanted General Protection Exceptions)

  9. Idea for UART’s RX-interrupts • When our UART receives a new scancode sent by the ‘telnet’ program on ‘pyramid’ we need it to be treated as if it were from the anchor-machine’s keyboard – but the anchor’s keyboard is out-of-our-reach • So we issue a command to the keyboard-controller to write that scancode into its Output Buffer register (command 0xD2)

  10. Idea for UART’s TX-interrupts • When the UART issues its THRE-interrupt (Transmitter Holding Register Empty), we want to output a new byte of information from the anchor-machine’s video memory • The video memory consists of alternating ascii-codes and attribute-codes, requiring distinct treatments for proper display on the remote terminal (or Desktop window)

  11. Clearing the screen • Here is an ANSI command-sequence that clears the terminal’s display-screen: char cmd[] = “\033[2J”; int len = strlen( cmd ); write( 1, cmd, len );

  12. Reposition the cursor • Here is an ANSI command-sequence that moves the cursor to row 12, column 40: char cmd[] = “\033[12;40H”; int len = strlen( cmd ); write( 1, cmd, len );

  13. Format of ‘attribute’ bytes VGA text-color attributes byte 7 6 5 4 3 2 1 0 BLINK BG red BG green BG blue FG intense FG red FG green FG blue background color foreground color

  14. ANSI color-codes 0 = black 1 = red 2 = green 3 = brown 4 = blue 5 = magenta 6 = cyan 7 = gray

  15. Color-translation table IBM VGA DEC ANSI -------------------------------------------------------------------------------- 000 = black 000 = black 001 = blue 100 = blue 010 = green 010 = green 011 = cyan 110 = cyan 100 = red 001 = red 101 = magenta 101 = magenta 110 = brown 011 = brown 111 = gray 111 = gray --------------------------------------------------------------------------------

  16. Setting text attributes • Here is an ANSI command-sequence that sets foreground and background colors: char cmd[] = “\033[32;44m”; int len = strlen( cmd ); write( 1, cmd, len );

  17. Cursor visibility commands • Here are ANSI command-sequences that will ‘hide’ or ‘show’ the terminal’s cursor: char hide[] = “\033[?25l”; // lowercase L char show[] = “\033[?25h”; // lowercase H

  18. ‘console output’ algorithm unsigned char color_table[ 8 ] = { 0, 4, 2, 6, 1, 5, 3, 7 }; typedef struct { unsigned char ascii, color; } PEL; PEL *vram = (PEL *)0x000B8000; PEL prev = { 0, 0 }; for (int row = 0; row < 24; row++) { printf( “\033[?25l” ); // make the cursor invisible printf( “\033[%d;%dH”, row+1, 1 ); // cursor to row’s beginning for (int col = 0; col < 80; col++) { PEL curr = vram[ row*80 + col ]; if ( curr.color != prev.color ) { int fg = color_table[ (curr.color >> 0)&7 ]; int bg = color_table[ (curr.color >> 4)&7 ]; printf( “\033[%d;%dm”, fg + 30, bg + 40 ); } printf( “%c”, curr.ascii ); prev = curr; } printf( “\033[?25h” ); // make the cursor visible fflush( stdout ); // insure all data written }

  19. Programming interface The PC uses eight consecutive I/O-ports to access the UART’s registers 0x03F8 0x03F9 0x03FA 0x03FB 0x03FC 0x03FD 0x03FE 0x03FF RxD/TxD IER IIR/FCR LCR MCR LSR MSR SCR interrupt enable register line status register modem status register line control register modem control register receive buffer register and transmitter holding register (also Divisor Latch register) scratchpad register interrupt identification register and FIFO control register

  20. Modem Control Register 7 6 5 4 3 2 1 0 0 0 0 LOOP BACK OUT2 OUT1 RTS DTR Legend: DTR = Data Terminal Ready (1=yes, 0=no) RTS = Request To Send (1=yes, 0=no) OUT1 = not used (except in loopback mode) OUT2 = enables the UART to issue interrupts LOOPBACK-mode (1=enabled, 0=disabled)

  21. Modem Status Register 7 6 5 4 3 2 1 0 DCD RI DSR CTS delta DCD delta RI delta DSR delta CTS set if the corresponding bit has changed since the last time this register was read Legend: [---- loopback-mode ----] CTS = Clear To Send (1=yes, 0=no) [bit 0 in Modem Control] DSR = Data Set Ready (1=yes, 0=no) [bit 1 in Modem Control] RI = Ring Indicator (1=yes,0=no) [bit 2 in Modem Control] DCD = Data Carrier Detected (1=yes,0=no) [bit 3 in Modem Control]

  22. Line Status Register 7 6 5 4 3 2 1 0 Error in Rx FIFO Transmitter idle THR empty Break interrupt Framing error Parity error Overrun error Received Data Ready These status-bits indicate errors in the received data This status-bit indicates that the data-transmission has been completed This status-bit indicates that the Transmitter Holding Register is ready to accept a new data byte This status-bit indicates that a new byte of data has arrived (or, in FIFO-mode, that the receiver-FIFO has reached its threshold)

  23. Line Control Register 7 6 5 4 3 2 1 0 Divisor Latch access set break stick parity even parity select parity enable number of stop bits word length selection 00 = 5 bits 01 = 6 bits 10 = 7 bits 11 = 8 bits 0 = 1 stop bit 1 = 2 stop bits 0 = normal 1 = ‘break’ 0 = no parity bits 1 = one parity bit 0 = not accessible 1 = assessible 1 = even parity 0 = ‘odd’ parity

  24. Interrupt Enable Register 7 6 5 4 3 2 1 0 0 0 0 0 Modem Status change Rx Line Status change THR is empty Received data is available If enabled (by setting the bit to 1), the UART will generate an interrupt: (bit 3) whenever modem status changes (bit 2) whenever a receive-error is detected (bit 1) whenever the transmit-buffer is empty (bit 0) whenever the receive-buffer is nonempty Also, in FIFO mode, a ‘timeout’ interrupt will be generated if neither FIFO has been ‘serviced’ for at least four character-clock times

  25. FIFO Control Register 7 6 5 4 3 2 1 0 RCVR FIFO trigger-level reserved reserved DMA Mode select XMIT FIFO reset RCVR FIFO reset FIFO enable 00 = 1 byte 01 = 4 bytes 10 = 8 bytes 11 = 14 bytes NOTE: DMA is unsupported for the UART on our systems Writing 1 empties the FIFO, writing 0 has no effect Writing 0 will disable the UART’s FIFO-mode, writing 1 will enable FIFO-mode

  26. Interrupt Identification Register 7 6 5 4 3 2 1 0 0 0 ‘highest priority’ UART interrupt still pending 00 = FIFO-mode has not been enabled 11 = FIFO-mode is currently enabled highest 011 = receiver line-status 010 = received data ready 110 = character timeout 001 = Tx Holding Reg empty 000 = modem-status change lowest 1 = No UART interrupts are pending 0 = At least one UART interrupt is pending

  27. Response to UART interrupts • In order of highest-to-lowest priority: • 0x06: Receive errors (input Line Status) • 0x04: Received data (input Rx-Data) • 0x0C: FIFO Timeout (input/output Data) • 0x02: THRE (output Tx-Data, or input IIR) • 0x00: Modem state (input Modem Status)

  28. How to transmit a byte Read the Line Status Register Transmit Holding Register is Empty? NO YES Write byte to the Transmitter Data Register DONE

  29. How to receive a byte Read the Line Status Register Received Data is Ready? NO YES Read byte from the Receiver Data Register DONE

  30. Demo-program • We wrote a boot-time program (it’s called ‘xmitvram.s’) that we can run on one of our anchor-cluster machines • It shows how a protected-mode interrupt-handler for the serial UART interrupts can send ANSI terminal-control strings (along with ASCII character-codes) to the ‘telnet’ terminal emulator application on ‘pyramid’

  31. In-class exercise • Modify this simple C++ program so that it will print its “Hello” message in colors and be located in the center of the screen: #include <stdio.h> int main( void ) { printf( “Hello, world! \n” ); }

More Related