帧缓冲控制台

帧缓冲控制台(fbcon),顾名思义,是一个运行在帧缓冲设备之上的文本控制台。它具有任何标准文本控制台驱动程序的功能,例如VGA控制台,并添加了可以归因于帧缓冲图形性质的附加功能。

在x86架构中,帧缓冲控制台是可选的,有些人甚至将其视为玩具。对于其他架构,它是唯一可用的显示设备,无论是文本还是图形。

fbcon有哪些功能?帧缓冲控制台支持高分辨率、变化的字体类型、显示旋转、原始多头显示等。理论上,还可以实现彩色字体、混合、抗锯齿以及底层显卡提供的任何功能。

A. 配置

可以使用您喜欢的内核配置工具启用帧缓冲控制台。它位于设备驱动程序->图形支持->控制台显示驱动程序支持->帧缓冲控制台支持下。选择“y”以静态编译支持,或选择“m”以进行模块支持。模块将是fbcon。

为了使fbcon激活,至少需要一个帧缓冲驱动程序,因此请从众多可用的驱动程序中进行选择。对于x86系统,它们几乎都具有VGA卡,因此vga16fb和vesafb始终可用。但是,使用特定于芯片组的驱动程序将为您提供更高的速度和更多功能,例如动态更改视频模式的能力。

要显示企鹅徽标,请在图形支持->启动徽标中选择任何可用的徽标。

另外,您将需要选择至少一个编译到内核中的字体,但是如果您不执行任何操作,内核配置工具将为您选择一个字体,通常是8x16字体。

注意:一个常见的错误报告是启用帧缓冲,但不启用帧缓冲控制台。根据驱动程序的不同,您可能会得到空白或乱码显示,但是系统仍然可以启动完成。如果您很幸运拥有一个不改变图形芯片的驱动程序,那么您仍然可以获得VGA控制台。

B. 加载

可能的场景

  1. 驱动程序和fbcon是静态编译的

    通常,fbcon会自动接管您的控制台。一个值得注意的例外是vesafb。需要使用vga=启动选项参数显式激活它。

  2. 驱动程序是静态编译的,fbcon是作为模块编译的

    根据驱动程序的不同,您会得到一个标准控制台或乱码显示,如上所述。要获得帧缓冲控制台,请执行“modprobe fbcon”。

  3. 驱动程序是作为模块编译的,fbcon是静态编译的

    您会得到您的标准控制台。一旦使用“modprobe xxxfb”加载驱动程序,fbcon就会自动接管控制台,但可能需要使用fbcon=map:n选项。 见下文。

  4. 驱动程序和fbcon都是作为模块编译的。

    您可以按任何顺序加载它们。一旦都加载完毕,fbcon将接管控制台。

  1. 启动选项

    帧缓冲控制台有几个很大程度上未知的启动选项,可以改变其行为。

  1. fbcon=font:<名称>

    选择要使用的初始字体。“名称”的值可以是任何编译到内核中的字体:10x18、6x10、6x8、7x14、Acorn8x8、MINI4x6、PEARL8x8、ProFont6x11、SUN12x22、SUN8x16、TER16x32、VGA8x16、VGA8x8。

    请注意,并非所有驱动程序都可以处理宽度不能被8整除的字体,例如vga16fb。

  2. fbcon=map:<0123>

    这是一个有趣的选项。它告诉哪个驱动程序被映射到哪个控制台。“0123”的值是一个序列,它会重复直到总长度为64,这是可用的控制台数量。在上面的示例中,它被扩展为012301230123...,映射将是

    tty | 1 2 3 4 5 6 7 8 9 ...
    fb  | 0 1 2 3 0 1 2 3 0 ...
    
    ('cat /proc/fb' should tell you what the fb numbers are)
    

    一个可能有用的副作用是使用超出已加载fb驱动程序数量的map值。例如,如果只有一个驱动程序可用,fb0,添加fbcon=map:1会告诉fbcon不要接管控制台。

    稍后,当您想将控制台映射到帧缓冲设备时,可以使用con2fbmap实用程序。

  3. fbcon=vc:<n1>-<n2>

    此选项告诉fbcon仅接管由值“n1”和“n2”指定的控制台范围。给定范围之外的其余控制台仍将由标准控制台驱动程序控制。

    注意:对于x86机器,标准控制台是VGA控制台,它通常位于同一视频卡上。因此,由VGA控制台控制的控制台将被损坏。

  4. fbcon=rotate:<n>

    此选项更改控制台显示的方向角度。“n”的值接受以下值

    • 0 - 正常方向(0度)

    • 1 - 顺时针方向(90度)

    • 2 - 上下颠倒方向(180度)

    • 3 - 逆时针方向(270度)

    以后可以通过将相同的数字“echo”到/sys/class/graphics/fbcon中找到的2个属性之一来随时更改角度

    • rotate - 旋转活动控制台的显示

    • rotate_all - 旋转所有控制台的显示

    只有在您的内核中编译了Framebuffer Console Rotation支持时,控制台旋转才可用。

    注意:这纯粹是控制台旋转。使用帧缓冲的任何其他应用程序将保持其“正常”方向。实际上,底层fb驱动程序完全不知道控制台旋转。

  5. fbcon=margin:<颜色>

    此选项指定边距的颜色。边距是屏幕右侧和底部的剩余区域,未被文本使用。默认情况下,此区域将为黑色。“颜色”值是一个整数,具体取决于所使用的帧缓冲驱动程序。

  6. fbcon=nodefer

    如果内核是使用延迟fbcon接管支持编译的,通常,固件/引导加载程序留在原位的帧缓冲内容将被保留,直到实际上有文本输出到控制台为止。此选项导致fbcon立即绑定到fbdev设备。

  7. fbcon=logo-pos:<位置>

    唯一可能的“位置”是“center”(不带引号),当给出该位置时,启动徽标将从默认的左上角位置移动到帧缓冲的中心。如果由于多个CPU而显示了多个徽标,则收集的徽标行将作为一个整体移动。

  8. fbcon=logo-count:<n>

    值“n”覆盖启动徽标的数量。0禁用徽标,-1给出默认值,即在线CPU的数量。

  1. 连接、分离和卸载

在继续讨论如何连接、分离和卸载帧缓冲控制台之前,对依赖关系的说明可能会有所帮助。

与大多数子系统一样,控制台层需要一个与硬件接口的驱动程序。因此,在VGA控制台中

console ---> VGA driver ---> hardware.

假设可以卸载VGA驱动程序,则必须先将VGA驱动程序与控制台层分离,然后才能卸载驱动程序。如果VGA驱动程序仍然绑定到控制台层,则无法卸载该驱动程序。(有关更多信息,请参见控制台驱动程序)。

在帧缓冲控制台(fbcon)的情况下,这更为复杂,因为fbcon是控制台和驱动程序之间的中间层

console ---> fbcon ---> fbdev drivers ---> hardware

如果fbdev驱动程序绑定到fbcon,则无法卸载它们;如果fbcon绑定到控制台层,则无法卸载fbcon。

因此,要卸载fbdev驱动程序,必须首先将fbcon与控制台分离,然后将fbdev驱动程序与fbcon分离。幸运的是,将fbcon与控制台层分离将自动将帧缓冲驱动程序与fbcon分离。因此,无需显式地将fbdev驱动程序与fbcon分离。

那么,我们如何将fbcon与控制台分离?部分答案在控制台驱动程序中。 总结一下

将一个值回显到表示帧缓冲控制台驱动程序的绑定文件。因此,假设vtcon1代表fbcon,那么

echo 1 > /sys/class/vtconsole/vtcon1/bind - attach framebuffer console to
                                           console layer
echo 0 > /sys/class/vtconsole/vtcon1/bind - detach framebuffer console from
                                           console layer

如果fbcon与控制台层分离,您的启动控制台驱动程序(通常是VGA文本模式)将接管。一些驱动程序(rivafb和i810fb)将为您恢复VGA文本模式。对于其余驱动程序,在分离fbcon之前,您必须采取一些额外的步骤来确保您的VGA文本模式已正确恢复。以下是可以执行的几种方法之一

  1. 下载或安装vbetool。此实用程序包含在当今大多数发行版中,并且通常是挂起/恢复工具的一部分。

  2. 在您的内核配置中,确保将CONFIG_FRAMEBUFFER_CONSOLE设置为“y”或“m”。 启用一个或多个您喜欢的帧缓冲驱动程序。

  3. 启动到文本模式并以root身份运行

    vbetool vbestate save > <vga state file>
    

    上面的命令将图形硬件的寄存器内容保存到<vga state file>。您只需要执行此步骤一次,因为状态文件可以重复使用。

  4. 如果将fbcon编译为模块,请通过执行以下操作来加载fbcon

    modprobe fbcon
    
  5. 现在分离fbcon

    vbetool vbestate restore < <vga state file> && \
    echo 0 > /sys/class/vtconsole/vtcon1/bind
    
  6. 就是这样,您回到了VGA模式。如果您将fbcon编译为模块,则可以通过“rmmod fbcon”卸载它。

  7. 要重新连接fbcon

    echo 1 > /sys/class/vtconsole/vtcon1/bind
    

8. 一旦fbcon被解除绑定,所有注册到系统的驱动程序也将被解除绑定。这意味着可以随意卸载或重新加载fbcon和单独的帧缓冲驱动程序。重新加载驱动程序或fbcon将自动将控制台、fbcon和驱动程序绑定在一起。卸载所有驱动程序而不卸载fbcon将使控制台无法绑定fbcon。

vesafb用户的注意事项:

不幸的是,如果您的bootline包含一个vga=xxx参数,该参数将硬件设置为图形模式,例如加载vesafb时,vgacon将无法加载。相反,vgacon会将默认的启动控制台替换为dummycon,并且在分离fbcon后您将看不到任何显示。您的机器仍然可用,因此您可以重新连接vesafb。但是,要重新连接vesafb,您需要执行以下操作之一

变体1

  1. 在分离fbcon之前,执行

    vbetool vbemode save > <vesa state file> # do once for each vesafb mode,
                                             # the file can be reused
    
  2. 按照步骤5分离fbcon。

  3. 连接fbcon

    vbetool vbestate restore < <vesa state file> && \
    echo 1 > /sys/class/vtconsole/vtcon1/bind
    

变体2

  1. 在分离fbcon之前,执行

    echo <ID> > /sys/class/tty/console/bind
    
    vbetool vbemode get
    
  2. 记下模式编号

  1. 按照步骤5分离fbcon。

  2. 连接fbcon

    vbetool vbemode set <mode number> && \
    echo 1 > /sys/class/vtconsole/vtcon1/bind
    

示例:

如果您在X86盒子上,可以使用以下2个示例bash脚本来绑定或取消绑定帧缓冲控制台驱动程序

#!/bin/bash
# Unbind fbcon

# Change this to where your actual vgastate file is located
# Or Use VGASTATE=$1 to indicate the state file at runtime
VGASTATE=/tmp/vgastate

# path to vbetool
VBETOOL=/usr/local/bin


for (( i = 0; i < 16; i++))
do
  if test -x /sys/class/vtconsole/vtcon$i; then
      if [ `cat /sys/class/vtconsole/vtcon$i/name | grep -c "frame buffer"` \
           = 1 ]; then
          if test -x $VBETOOL/vbetool; then
             echo Unbinding vtcon$i
             $VBETOOL/vbetool vbestate restore < $VGASTATE
             echo 0 > /sys/class/vtconsole/vtcon$i/bind
          fi
      fi
  fi
done

#!/bin/bash
# Bind fbcon

for (( i = 0; i < 16; i++))
do
  if test -x /sys/class/vtconsole/vtcon$i; then
      if [ `cat /sys/class/vtconsole/vtcon$i/name | grep -c "frame buffer"` \
           = 1 ]; then
        echo Unbinding vtcon$i
        echo 1 > /sys/class/vtconsole/vtcon$i/bind
      fi
  fi
done

Antonino Daplas <adaplas@pol.net>