Writing Device Drivers for Oracle® Solaris 11.2

Exit Print View

Updated: September 2014
 
 

Console Frame Buffer Drivers

Drivers for frame buffers that are used for the system console must provide interfaces to enable the system to display text on the console. The Oracle Solaris OS provides enhanced visual I/O interfaces to enable the kernel terminal emulator to display text directly on the console frame buffer. This appendix describes how to add the necessary interfaces to a frame buffer driver to enable the driver to interact with the Oracle Solaris kernel terminal emulator.

Oracle Solaris Consoles and the Kernel Terminal Emulator

The role of the kernel terminal emulator is to render text onto the console frame buffer in the proper position and representation determined by the frame buffer's screen height, width, and pixel depth mode. The terminal emulator also drives scrolling, controls a software cursor, and interprets ANSI terminal escape sequences. The terminal emulator accesses the console frame buffer in either VGA text mode or pixel mode, depending upon the graphics card. To be used as a Oracle Solaris console frame buffer driver, your frame buffer driver must be compatible with the Oracle Solaris kernel terminal emulator. The target platform is the most significant factor that determines whether you need to modify your frame buffer driver to make your driver compatible with the Oracle Solaris kernel terminal emulator.

  • x86 platforms – Console frame buffer drivers do not need to be modified because x86 console frame buffer drivers already support the console frame buffer interfaces.

  • SPARC platforms – Console frame buffer drivers should use the interfaces described in this appendix to enable the driver to interact with the Oracle Solaris kernel terminal emulator.

x86 Platform Console Communication

On x86 platforms, the Oracle Solaris kernel terminal emulator module (tem) uses VGA text mode exclusively to interact with the vgatext module. The vgatext module uses industry standard VGA text mode to interact with x86 compatible frame buffer devices. Because the vgatext module already supports the console frame buffer interfaces, x86 frame buffer drivers are compatible with the kernel tem module. You do not need to add special interfaces to x86 frame buffer drivers.

The remainder of this appendix applies to SPARC platforms only.

SPARC Platform Console Communication

SPARC frame buffer drivers typically do not operate in VGA text mode. SPARC frame buffer drivers typically are required to send pixel patterns that depict the text and images displayed. The kernel tem requires SPARC drivers to support specific interfaces to facilitate rendering data to the screen, perform scrolling, and display a text cursor. How the driver actually renders data sent from the tem onto the screen depends on the device. The driver typically draws the data into video memory according to the hardware and video mode.

The Oracle Solaris OS provides interfaces that enable the kernel terminal emulator to drive compatible console frame buffers directly. The advantages of converting a driver to be compatible with the kernel terminal emulator are:

  • Dramatically improved performance, particularly for scrolling

  • Enhanced ANSI text color capabilities

  • The ability to start a login session on the console frame buffer even when the system console stream is directed out the serial port

SPARC console frame buffer drivers are not required to be compatible with the kernel terminal emulator. If the console frame buffer driver is not compatible with the kernel terminal emulator, the system uses the FCode terminal emulator in the OpenBoot PROM.

The console frame buffer is identified through the EEPROM screen environment variable. The system determines whether the console frame buffer is compatible with the kernel terminal emulator module by checking whether the frame buffer driver exports the tem-support DDI property. If the tem-support property is exported, then the system issues the VIS_DEVINIT I/O control (ioctl) command to the frame buffer driver during system boot, while configuring the console. If the tem-support DDI property is exported and the VIS_DEVINIT ioctl command succeeds and returns a compatible version number to the tem, the system configures the system console to utilize that frame buffer driver through the kernel terminal emulator. See the ioctl(9E) man page for information about the I/O control driver entry point.

SPARC drivers that support the kernel terminal emulator should export the tem-support DDI property. This property indicates that the driver supports the kernel terminal emulator. If a frame buffer driver exports the tem-support DDI property, then that driver will be handled early in the boot process, while the console is being configured. If a frame buffer driver does not export the tem-support property, then that driver might not be handled early enough in the boot process.

tem-support

When set to 1, this DDI property indicates that this driver is compatible with the console kernel frame buffer interface.

The kernel terminal emulator module interacts with the console frame buffer driver through two major interfaces:

  • Through ioctl interfaces during normal system operation

  • Through polled I/O interfaces during standalone mode

The following section provides detailed information.

Console Visual I/O Interfaces

The kernel terminal emulator interacts with the console frame buffer driver through two interfaces. During normal system activity (after a successful boot of the system), communication between the kernel terminal emulator and the console frame buffer driver is through ioctl interfaces. During standalone mode (before system boot or during debugging), communication between the kernel terminal emulator and the console frame buffer driver is through polled I/O interfaces. All activity between the kernel terminal emulator and the console frame buffer driver is initiated by the kernel terminal emulator, with the exception of a callback function used by the console frame buffer driver to notify the kernel terminal emulator of changes in the video mode.

The console visual I/O interfaces are documented in detail in the visual_io(7I) man page. For more information on the video mode change callback function, see Video Mode Change Callback Interface.

I/O Control Interfaces

During normal system activity, the kernel terminal emulator communicates with the console frame buffer driver through the ioctl interfaces listed in the following table:

ioctl Name
Corresponding Data Structure
Description
VIS_DEVINIT
vis_devinit
Initializes the session between the terminal emulator module and the frame buffer. See VIS_DEVINIT.
VIS_DEVFINI
Not Applicable
Terminates the session between the terminal emulator module and the frame buffer. See VIS_DEFINI.
VIS_CONSDISPLAY
vis_consdisplay
Displays pixels as a rectangle. See VIS_CONSDISPLAY.
VIS_CONSCOPY
vis_conscopy
Copies a rectangle of pixels (scroll). See VIS_CONSCOPY.
VIS_CONSCURSOR
vis_conscursor
Displays or hides a text cursor. See VIS_CONSCURSOR.
VIS_PUTCMAP
vis_cmap
Sends the terminal emulator module color map to the frame buffer driver. See VIS_PUTCMAP.
VIS_GETCMAP
vis_cmap
Reads the terminal emulator module color map from the frame buffer. See VIS_GETCMAP.

Polled I/O Interfaces

The polled I/O interfaces provide the same functionality as the VIS_CONSDISPLAY, VIS_CONSCOPY, and VIS_CONSCURSOR ioctl interfaces. The polled I/O interfaces are called only when the operating system is quiesced and in standalone mode. See Implementing Polled I/O in Console Frame Buffer Drivers for more information.

While in standalone mode, the kernel terminal emulator communicates with the console frame buffer driver through the polled I/O interfaces listed in the following table:

Polled I/O Function
Corresponding Data Structure
Description
(*display)()
vis_consdisplay
Displays pixels as a rectangle.
(*copy)()
vis_conscopy
Copies a rectangle of pixels (scroll).
(*cursor)()
vis_conscursor
Displays or hides a text cursor.

Video Mode Change Callback Interface

The console frame buffer driver and the kernel terminal emulator must be in agreement about the video mode at all times. Video mode includes the console screen height, width, and depth in pixels. Video mode also includes whether communication between the kernel terminal emulator and the console frame buffer is in VGA text mode or pixel mode.

In order for the console frame buffer driver to notify the kernel terminal emulator of changes in the video mode, the console frame buffer driver is initialized with the address of the (*modechg_cb)() kernel terminal emulator callback function described in the following table:

Callback Function
Corresponding Data Structures
Description
(*modechg_cb)()
vis_modechg_arg
vis_devinit
Keep the terminal emulator module synchronized with the driver video mode (screen height, width, and pixel depth).

Implementing the Visual I/O Interfaces in Console Frame Buffer Drivers

Except for the video mode change callback, all activity between the driver and the kernel terminal emulator is initiated by the tem (terminal emulator module). This means that the tem issues all of the ioctl commands described in this document. The following sections provide implementation details for each ioctl command. For more information, see the visual_io(7I) man page and the /usr/include/sys/visual_io.h include file. See Video Mode Change Callback Interface for detailed information about the video mode change callback function.


Note - Each ioctl command should determine whether the FKIOCTL is set in the ioctl flag argument and return EPERM if that bit is not set.

VIS_DEVINIT

The VIS_DEVINIT ioctl command initializes the frame buffer driver as the system console device. This ioctl passes the address of a vis_devinit structure.

The tem first loads the address of its video mode change callback function into the modechg_cb field of the vis_devinit structure and loads its soft state into the modechg_arg field. The tem then issues the VIS_DEVINIT ioctl command. The frame buffer driver then initializes itself and returns a summary of its configuration back to the tem by setting the version, width, height, linebytes, depth, mode, and polledio fields in the vis_devinit structure. The vis_devinit structure is shown in the following code.

struct vis_devinit {
      /*
       * This set of fields are used as parameters passed from the
       * layered frame buffer driver to the terminal emulator.
       */
      int             version;        /* Console IO interface rev */
      screen_size_t   width;          /* Width of the device */
      screen_size_t   height;         /* Height of the device */
      screen_size_t   linebytes;      /* Bytes per scan line */
      int             depth;          /* Device depth */
      short           mode;           /* Display mode Mode */
      struct vis_polledio *polledio;  /* Polled output routines */
      /*
       * The following fields are used as parameters passed from the
       * terminal emulator to the underlying frame buffer driver.
       */
      vis_modechg_cb_t modechg_cb;   /* Video mode change callback */
      struct vis_modechg_arg *modechg_arg;  /* Mode change cb arg */
};

To implement the VIS_DEVINIT ioctl command in the console frame buffer driver, follow these general steps:

  1. Define a struct to contain the console-specific state. This structure is private to the console frame buffer driver. This structure is referred to as consinfo in this appendix. The consinfo structure contains information such as:

    • Current size of the blit buffer

    • Pointer to the blit buffer

    • Color map information

    • Driver rendering mode information such as line pitch

    • Background color

    • Video memory address

    • Terminal emulator callback address

  2. Allocate memory:

    1. Allocate a blit buffer large enough to store a reasonable default sized rectangle of pixels at the highest video depth. Additional memory can be allocated if an incoming request exceeds the size of the buffer. The frame buffer driver's largest font is 12×22. Assuming DEFAULT_HEIGHT is 12, DEFAULT_WIDTH is 22, and the maximum video depth is 32, the buffer size should be 8448 bytes (DEFAULT_HEIGHT × DEFAULT_WIDTH × 32).

    2. Allocate a vis_polledio structure.

    3. Allocate a buffer to hold a cursor. This buffer should be the size of the largest character. This buffer will not change size.

  3. Obtain the video change callback address and callback context of the tem from modechg_cb and modechg_ctx and store this information in the consinfo structure.

  4. Populate the vis_polledio structure with entry point addresses for the polled display, copy, and cursor functions.

  5. Provide the appropriate information in the fields of the vis_devinit structure that was passed to the driver by the tem:

    1. Set the version field to VIS_CONS_REV, which is a constant defined in the /usr/include/sys/visual_io.h header file.

    2. Set the mode field to VIS_PIXEL.

    3. Set the polledio field to the address of the vis_polledio structure.

    4. Set the height field to the video mode height in pixels.

    5. Set the width field to the video mode width in pixels.

    6. Set the depth field to the frame buffer pixel depth in bytes (for example, a 32-bit pixel depth would be 4 bytes).

    7. Set the linebytes field to the value of height × width × depth.

      This information is sent from the driver to the tem by using the vis_devinit structure. This information tells the terminal emulator how to render information and pass it to the graphics driver.

    Whenever the console frame buffer driver changes its video mode (specifically height, width, or depth), the driver must call the video mode change callback function of the tem to update the vis_devinit structure and to pass this structure back to the terminal emulator. The terminal emulator passes its mode change callback function address in the modechg_cb field of the vis_devinit structure. The mode change callback function has the following function signature:

    typedef void (*vis_modechg_cb_t)
          (struct vis_modechg_arg *, struct vis_devinit *);

    As shown in the preceding typedef, the mode change callback function takes two arguments. The first argument is the modechg_arg and the second argument is the vis_devinit structure. The modechg_arg is sent from the tem to the driver during the VIS_DEVINIT ioctl command initialization. The driver must send the modechg_arg back to the tem with each video mode change callback.

  6. Initialize the context of the kernel console. Specific requirements vary depending upon the capability of the graphics device. This initialization might include such steps as setting the draw engine state, initializing the palette, or locating and mapping video memory or the rendering engine so that data can be blitted onto the screen.

  7. Return the vis_devinit structure to the caller.

VIS_DEFINI

The VIS_DEFINI ioctl command releases the driver's console resources and finishes the session.

To implement the VIS_DEVFINI ioctl command in the console frame buffer driver, follow these general steps:

  1. Reset the console frame buffer driver state.

  2. Clear the polled I/O entry points and the kernel terminal emulator video change function callback address.

  3. Release memory.

VIS_CONSDISPLAY

The VIS_CONSDISPLAY ioctl command displays a rectangle of pixels at a specified location. This display is also referred to as blitting a rectangle. The vis_consdisplay structure contains the information necessary to render a rectangle at the video depth that both the driver and the tem are using. The vis_consdisplay structure is shown in the following code.

struct vis_consdisplay {
      screen_pos_t    row;      /* Row (in pixels) to display data at */
      screen_pos_t    col;      /* Col (in pixels) to display data at */
      screen_size_t   width;    /* Width of data (in pixels) */
      screen_size_t   height;   /* Height of data (in pixels) */
      unsigned char   *data;    /* Address of pixels to display */
      unsigned char   fg_color; /* Foreground color */
      unsigned char   bg_color; /* Background color */
};

To implement the VIS_CONSDISPLAY ioctl command in the console frame buffer driver, follow these general steps:

  1. Copy the vis_consdisplay structure.

  2. Validate the display parameters. Return an error if any of the display parameters is out of range.

  3. Calculate the size of the rectangle to be blitted into video memory. Validate this size against the size of the blit buffer created during VIS_DEVINIT. Allocate additional memory for the blit buffer if necessary.

  4. Retrieve the blit data. This data has been prepared by the kernel terminal emulator at the agreed upon pixel depth. That depth is the same pixel depth that was conveyed by the tem during VIS_DEVINIT. The pixel depth is updated whenever the device driver changes video modes through callback to the tem. Typical pixel depths are 8-bit color map indexed, and 32-bit TrueColor.

  5. Invalidate any user context so that user applications cannot simultaneously access the frame buffer hardware through user memory mappings. This step is neither allowed nor necessary in polled I/O mode because user applications are not running. Be sure to hold a lock so that users cannot restore the mapping through a page fault until the VIS_CONSDISPLAY ioctl completes.

  6. Establish the driver-specific console rendering context.

  7. If the frame buffer is running in 8-bit color indexed mode, restore the kernel console color map that the tem set up through a previous VIS_PUTCMAP ioctl. A lazy color map loading scheme is recommended to optimize performance. In a lazy scheme, the console frame buffer only restores colors it has actually used since the VIS_DEVINIT ioctl was issued.

  8. Display the data passed from the tem at the pixel coordinates sent by the tem. You might need to transform the RGB pixel data byte order.

VIS_CONSCOPY

The VIS_CONSCOPY ioctl command copies a rectangular region of pixels from one location to another location. One use for this ioctl is to scroll.

To implement the VIS_CONSCOPY ioctl command in the console frame buffer driver, follow these general steps:

  1. Copy the vis_conscopy structure. The vis_conscopy structure describes the source and target rectangle sizes and locations.

  2. Validate the display parameters. Return an error if any of the display parameters is out of range.

  3. Invalidate any user context so that user applications cannot simultaneously access the frame buffer hardware through user memory mappings. This step is neither allowed nor necessary in polled I/O mode because user applications are not running. Be sure to hold a lock so that users cannot restore the mapping through a page fault until the VIS_CONSDISPLAY ioctl completes.

  4. Call the function to copy the rectangle.


    Note - For optimal performance, use the rendering engine of the graphic device to implement the copy function. You need to decide how to do the context management within the driver to set up the rendering engine for best performance.

VIS_CONSCURSOR

The VIS_CONSCURSOR ioctl command displays or hides a cursor. The vis_conscursor structure is shown in the following code.

struct vis_conscursor {
      screen_pos_t    row;      /* Row to display cursor (in pixels) */
      screen_pos_t    col;      /* Col to display cursor (in pixels) */
      screen_size_t   width;    /* Width of cursor (in pixels) */
      screen_size_t   height;   /* Height of cursor (in pixels) */
      color_t         fg_color; /* Foreground color */
      color_t         bg_color; /* Background color */
      short           action;   /* Show or Hide cursor */
};

To implement the VIS_CONSCOPY ioctl command in the console frame buffer driver, follow these general steps:

  1. Copy the vis_conscursor structure from the kernel terminal emulator.

  2. Validate the display parameters. Return an error if any of the display parameters are out of range.

  3. Invalidate any user context so that user applications cannot simultaneously access the frame buffer hardware through user memory mappings. This step is neither allowed nor necessary in polled I/O mode because user applications are not running. Be sure to hold a lock so that users cannot restore the mapping through a page fault until the VIS_CONSDISPLAY ioctl completes.

  4. The terminal emulator can call the VIS_CONSCOPY ioctl with one of the following two actions: SHOW_CURSOR and HIDE_CURSOR. The following steps describe how to implement this functionality by reading and writing video memory. You might also be able to use the rendering engine to do this work. Whether you can use the rendering engine depends on the frame buffer hardware.

    Take these steps to implement the SHOW_CURSOR functionality:

    1. Save the pixels within the rectangle where the cursor will be drawn. These saved pixels will be needed to hide the cursor.

    2. Scan all the pixels on the screen bounded by the rectangle where the cursor will be drawn. Within this rectangle, replace the pixels that match the specified cursor foreground color (fg_color) with white pixels. Replace the pixels that match the specified cursor background color (bg_color) with black pixels. The visual effect is of a black cursor over white text. This method works with any foreground and background color of text. Attempting to invert colors based upon color map position is not feasible. More sophisticated strategies, such as attempting color inversion using HSB coloring (Hue, Saturation, Brightness), are not necessary.

    To implement the HIDE_CURSOR functionality, replace the pixels beneath the cursor rectangle with the pixels saved from the previous SHOW_CURSOR action.

VIS_PUTCMAP

The VIS_PUTCMAP ioctl command establishes the console color map. The terminal emulator calls this function to set up the color map of the kernel. The vis_cmap structure is shown in the following code. This structure only applies to 8-bit color indexed mode.

struct vis_cmap {
      int             index;  /* Index into colormap to start updating */
      int             count;  /* Number of entries to update */
      unsigned char   *red;   /* List of red values */
      unsigned char   *green; /* List of green values */
      unsigned char   *blue;  /* List of blue values */
};

The VIS_PUTCMAP ioctl command is similar to the FBIOPUTCMAP command. The VIS_PUTCMAP command is specific to the frame buffer terminal-emulator compatible console code.

VIS_GETCMAP

The terminal emulator calls the VIS_GETCMAP ioctl command to retrieve the console color map.

Implementing Polled I/O in Console Frame Buffer Drivers

The polled I/O interfaces are implemented as functions in the driver and are called directly by the kernel terminal emulator. The driver passes the address of its polled I/O entry points to the terminal emulator during the execution of the VIS_DEVINIT ioctl command. The VIS_DEVINIT command is initiated by the terminal emulator.

The vis_polledio structure is shown in the following code.

typedef void * vis_opaque_arg_t;

struct vis_polledio {
      struct vis_polledio_arg *arg;
      void    (*display)(vis_opaque_arg_t, struct vis_consdisplay *);
      void    (*copy)(vis_opaque_arg_t, struct vis_conscopy *);
      void    (*cursor)(vis_opaque_arg_t, struct vis_conscursor *);
};

The polled I/O interfaces provide the same functionality as the VIS_CONSDISPLAY, VIS_CONSCOPY, and VIS_CONSCURSOR ioctl interfaces. The polled I/O interfaces should follow the same steps that are described above for the respective ioctl commands. The polled I/O interfaces must very strictly adhere to the additional restrictions that are described in the remainder of this section.

The polled I/O interfaces are called only when the operating system is quiesced and in standalone mode. The system enters standalone mode whenever the user enters OpenBoot PROM or enters the kmdb debugger, or when the system panics. Only one CPU and one thread are active. All other CPUs and threads are stopped. Timesharing, DDI interrupts, and system services are turned off.

Standalone mode severely restricts driver functionality but simplifies driver synchronization requirements. For example, a user application cannot access the console frame buffer driver by way of the driver's memory mappings from within a polled I/O routine.

In standalone mode, the console frame buffer driver must not perform any of the following actions:

  • Wait for interrupts

  • Wait for mutexes

  • Allocate memory

  • Use DDI or LDI interfaces

  • Use system services

These restrictions are not difficult to obey since the polled I/O functions are relatively simple operations. For example, when working with the rendering engine, the console frame buffer driver can poll a bit in the device rather than wait for an interrupt. The driver can use pre-allocated memory to render blit data. DDI or LDI interfaces should not be needed.

Frame Buffer Specific Configuration Module

When the driver-specific fbconfig() module causes a change in resolution or color depth, that fbconfig() module must send an ioctl to the frame buffer driver. This ioctl triggers the frame buffer driver to call the terminal emulator's mode change callback function with the new screen size and depth. The frame buffer driver and the terminal emulator must agree about the video mode at all times. When the frame buffer driver and the terminal emulator do not agree about the video mode, the information on the screen is illegible and meaningless.

The X Window System Frame Buffer Specific DDX Module

When the X Window System exits to the command line, the frame buffer's DDX module must send an ioctl to the frame buffer driver. This ioctl triggers the frame buffer driver to call the terminal emulator's mode change callback function. This communication keeps the frame buffer driver and the terminal emulator in agreement about the video mode if the X Window System starts and then changes the video resolution before exiting. The frame buffer driver and the terminal emulator must agree about the video mode at all times. When the frame buffer driver and the terminal emulator do not agree about the video mode, the information on the screen is illegible and meaningless.

Developing, Testing, and Debugging Console Frame Buffer Drivers

Debugging a console frame buffer driver on an active system can be problematic.

  • Errors that are encountered in the early stages of booting the system do not generate a core dump.

  • Error or informative messages might not be displayed correctly on the screen.

  • USB keyboard input might fail.

This section offers some suggestions to help you develop, test, and debug console frame buffer drivers.

Testing the I/O Control Interfaces

To test the ioctl commands, create additional ioctl entry points that are callable from a user application. Be sure to copy in the arguments appropriately. Use the ddi_copyin(9F) and ddi_copyout(9F) routines to transfer data to and from user address space. Then write an application to validate rendering, scrolling, and cursor behavior. This way, these ioctl commands do not affect your console while you develop and test the commands.

To ensure that the ioctl commands are working correctly, boot the system and log in. Check whether you get expected behavior when you execute commands such as prstat(1M), ls(1), vi(1), and man(1).

Execute the following script to validate that ANSI color is working correctly:

#!/bin/bash
printf "\n\n\n\e[37;40m             Color List       \e[m\n\n"
printf "\e[30m Color 30 black\e[m\n"
printf "\e[31m Color 31 red\e[m\n"
printf "\e[32m Color 32 green\e[m\n"
printf "\e[33m Color 33 yellow\e[m\n"
printf "\e[34m Color 34 blue\e[m\n"
printf "\e[35m Color 35 purple\e[m\n"
printf "\e[36m Color 36 cyan\e[m\n"
printf "\e[37m Color 37 white\e[m\n\n"
printf "\e[40m Backlight 40 black \e[m\n"
printf "\e[41m Backlight 41 red   \e[m\n"
printf "\e[34;42m Backlight 42 green \e[m\n"
printf "\e[43m Backlight 43 yellow\e[m\n"
printf "\e[37;44m Backlight 44 blue  \e[m\n"
printf "\e[45m Backlight 45 purple\e[m\n"
printf "\e[30;46m Backlight 46 cyan  \e[m\n"
printf "\e[30;47m Backlight 47 white \e[m\n\n"

Testing the Polled I/O Interfaces

The polled I/O interfaces are only available under the following circumstances:

  • When you enter the OpenBoot PROM by using the L1+A keystroke sequence

  • When you boot the system with a standalone debugger such as kmdb(1)

  • When the system panics

The polled I/O interfaces only become available at a certain point in the boot process. Polled I/O requests issued from the OpenBoot PROM before the system is running are not rendered. Similarly, kmdb prompts issued before the console is configured are not rendered.

To test the polled I/O interfaces, enter the OpenBoot PROM by using the L1+A keystroke sequence. To validate that the polled I/O interfaces are being used, type the following command at the OpenBoot PROM ok prompt:

ok 1b emit ." [32m This is a test" 1b emit ." [m"

The polled I/O interfaces are working properly if the following statements are true:

  • The result of the above command is that the phrase This is a test is displayed in green.

  • The OpenBoot PROM continues to function correctly.

  • Scrolling performs as expected.

  • The cursor displays correctly.

  • The system can be reentered and continued repeatedly.

Testing the Video Mode Change Callback Function

To determine whether the video mode change callback function is working properly, log in to the system and use fbconfig(1M) to change the resolution and depth of the frame buffer several times. If the console continues to display text properly, the video mode change callback function is working correctly. The kernel terminal emulator might adjust the font size to accommodate different screen sizes, but that is not significant to the console frame buffer driver.

To determine whether the X Window System and the console frame buffer driver interact correctly, switch between the X Window System and the command line several times while modifying the X Window System's video resolution and the command line resolution in different ways. If the X Window System exits and the console characters are not displayed correctly, either the X Window System did not notify the driver console code that the video mode changed or the driver did not call the kernel terminal emulator's video mode change callback function.

Additional Suggestions for Testing Console Frame Buffer Drivers

During boot, the system sends messages to /var/adm/messages if the system fails to locate or successfully load a kernel terminal emulator compatible frame buffer driver. To monitor these messages, type the following command in a separate window:

% tail -f /var/adm/messages

To avoid problems with USB while debugging the driver, change the EEPROM input-device NVRAM configuration parameter to use a serial port instead of the keyboard. See the eeprom(1M) man page for more information about this parameter.