编写设备驱动程序

VIS_DEVINIT

VIS_DEVINIT ioctl 命令将帧缓存器驱动程序初始化为系统控制台设备。该 ioctl 将传递 vis_devinit 结构的地址。

tem 首先将其视频模式更改回调函数的地址装入 vis_devinit 结构的 modechg_cb 字段,再将其软状态装入 modechg_arg 字段。然后,tem 发出 VIS_DEVINIT ioctl 命令。接下来,帧缓存器驱动程序初始化自身,并通过设置 vis_devinit 结构中的 version widthheightlinebytesdepthmodepolledio 字段将自身的配置摘要返回到 tem。以下代码中显示了 vis_devinit 结构。

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 */
};

要在控制台帧缓存器驱动程序中实现 VIS_DEVINIT ioctl 命令,请按照以下通用步骤操作:

  1. 定义一个 struct 以包含特定于控制台的状态。该结构由控制台帧缓存器驱动程序专用。在本附录中,该结构称为 consinfoconsinfo 结构包含诸如以下的信息:

    • 位块传输 (blit) 缓冲区的当前大小

    • 指向位块传输 (blit) 缓冲区的指针

    • 色彩表信息

    • 呈现模式信息(如行间距)的驱动程序

    • 背景色

    • 视频内存地址

    • 终端仿真器回调地址

  2. 分配内存:

    1. 分配足够大的位块传输 (blit) 缓冲区,以便以最高的视频深度存储像素的合理的、缺省大小的矩形区。如果传入的请求超出缓冲区的大小,可以分配额外的内存。帧缓存器驱动程序的最大字体大小为 12×22。假设 DEFAULT_HEIGHT 为 12,DEFAULT_WIDTH 为 22,最大视频深度为 32,那么,缓冲区大小应为 8448 个字节 (DEFAULT_HEIGHT × DEFAULT_WIDTH × 32)。

    2. 分配 vis_polledio 结构。

    3. 分配缓冲区以用于保持光标。该缓冲区的大小应相当于最大字符的大小。该缓冲区的大小将不会发生变化。

  3. modechg_cbmodechg_ctx 获取 tem 的视频更改回调地址和回调上下文,并将这些信息存储在 consinfo 结构中。

  4. 使用轮询式显示、副本和光标函数的入口点地址填充 vis_polledio 结构。

  5. tem 传递给驱动程序的 vis_devinit 结构的字段中提供相应信息:

    1. version 字段设置为 VIS_CONS_REV,这是 /usr/include/sys/visual_io.h 头文件中定义的一个常量。

    2. mode 字段设置为 VIS_PIXEL

    3. polledio 字段设置为 vis_polledio 结构的地址。

    4. height 字段设置为视频模式高度(以像素为单位)。

    5. width 字段设置为视频模式宽度(以像素为单位)。

    6. depth 字段设置为帧缓存器像素深度,单位为字节(例如,32 位像素深度将为 4 个字节)。

    7. linebytes 字段设置为 height × width × depth 的值。

      将会使用 vis_devinit 结构将这些信息从驱动程序发送到 tem。通过这些信息,终端仿真器可知道如何呈现信息以及如何将信息传递给图形驱动程序。

    每当控制台帧缓存器驱动程序更改视频模式(具体而言,heightwidthdepth)时,它都必须调用 tem 的视频模式更改回调函数,以更新 vis_devinit 结构,并将此结构传递回给终端仿真器。终端仿真器将其模式更改回调函数地址传入 vis_devinit 结构的 modechg_cb 字段。模式更改回调函数具有以下函数签名:

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

    如前面的 typedef 中所述,模式更改回调函数使用两个参数。第一个参数为 modechg_arg,第二个参数为 vis_devinit 结构。modechg_arg 会在 VIS_DEVINIT ioctl 命令初始化期间从 tem 发送到驱动程序。驱动程序必须通过每个视频模式更改回调将 modechg_arg 发送回给 tem

  6. 初始化内核控制台的上下文。具体的要求会随图形设备的功能而异。例如,该初始化的步骤可能包括:设置绘制引擎状态、初始化调色板,或者定位和映射视频内存或呈现引擎,以便数据能够以位块传输到屏幕。

  7. vis_devinit 结构返回给调用方。