Skip to the content.

vt

看看

https://unix.stackexchange.com/questions/32884/which-virtual-terminal-is-a-given-x-process-running-on https://stackoverflow.com/questions/3034567/how-do-i-find-the-current-virtual-terminal https://askubuntu.com/questions/33078/what-is-a-virtual-terminal-for

vt

没有图形界面,默认进入的就是 vt

bmc 的时候也是如此的

static void sysrq_handle_showregs(u8 key)
{
	struct pt_regs *regs = NULL;

	if (in_hardirq())
		regs = get_irq_regs();
	if (regs)
		show_regs(regs);
	perf_event_print_debug();
}
[  248.671749] sysrq: HELP : loglevel(0-9) reboot(b) crash(c) terminate-all-tasks(e) memory-full-oom-kill(f) kill-all
-tasks(i) thaw-filesystems(j) sak(k) show-backtrace-all-active-cpus(l) show-memory-usage(m) nice-all-RT-tasks(n) powe
roff(o) show-registers(p) show-all-timers(q) unraw(r) sync(s) show-task-states(t) unmount(u) force-fb(V) show-blocked
-tasks(w) dump-ftrace-buffer(z)
[  252.998756] sysrq: Show Regs
[  253.002434] CPU: 10 PID: 0 Comm: swapper/10 Kdump: loaded Tainted: G           OE     martins3-4.19.x86
_64 #1
[  253.014003] Hardware name: Suma R6240H0/62DB32, BIOS CXYH051029 09/06/2023
[  253.021573] RIP: 0010:native_safe_halt+0xe/0x10
[  253.026796] Code: eb bd 90 90 90 90 90 90 90 90 90 90 e9 07 00 00 00 0f 00 2d f6 0c 53 00 f4 c3 66 90 e9 07 00 00
00 0f 00 2d e6 0c 53 00 fb f4 <c3> 90 0f 1f 44 00 00 41 55 41 54 55 53 e8 b0 6f 85 ff 65 8b 2d c9
[  253.046926] RSP: 0018:ffffb2dd0025fea8 EFLAGS: 00000246 ORIG_RAX: ffffffffffffffde
[  253.055184] RAX: ffffffffa90d7160 RBX: 000000000000000a RCX: 7fffffc5f636d1aa
[  253.063021] RDX: 7fffffffffffffff RSI: 000000000000000a RDI: ffff956cff8a3d40
[  253.070862] RBP: 000000000000000a R08: ffff956cff89dc80 R09: 0000000000000000
[  253.078705] R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000000
[  253.086549] R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000
[  253.094393] FS:  00007f6d9fb79740(0000) GS:ffff956cff880000(0000) knlGS:0000000000000000
[  253.103199] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[  253.109672] CR2: 00007f6d92e31020 CR3: 0000007830c0a000 CR4: 00000000003406e0
[  253.117542] Call Trace:
[  253.120735]  default_idle+0x1c/0x140
[  253.125063]  do_idle+0x1aa/0x250
[  253.129020]  cpu_startup_entry+0x6f/0x80
[  253.133667]  start_secondary+0x18d/0x1e0
[  253.138310]  secondary_startup_64+0xb6/0xc0
[  253.143207] CPU#10: active:     0000000000000001
[  253.148535] CPU#10:   gen-PMC0 ctrl:  0000000000530076
[  253.154384] CPU#10:   gen-PMC0 count: 0000fffb7a1b6a0d
[  253.160215] CPU#10:   gen-PMC0 left:  000000051f5c2910
[  253.166032] CPU#10:   gen-PMC1 ctrl:  0000000000000000
[  253.171839] CPU#10:   gen-PMC1 count: 0000000000000000
[  253.177627] CPU#10:   gen-PMC1 left:  0000000000000000
[  253.183399] CPU#10:   gen-PMC2 ctrl:  0000000000000000
[  253.189154] CPU#10:   gen-PMC2 count: 0000000000000000
[  253.194899] CPU#10:   gen-PMC2 left:  0000000000000000
[  253.200638] CPU#10:   gen-PMC3 ctrl:  0000000000000000
[  253.206366] CPU#10:   gen-PMC3 count: 0000000000000000
[  253.212076] CPU#10:   gen-PMC3 left:  0000000000000000
[  253.217782] CPU#10:   gen-PMC4 ctrl:  0000000000000000
[  253.223474] CPU#10:   gen-PMC4 count: 0000000000000000
[  253.229152] CPU#10:   gen-PMC4 left:  0000000000000000
[  253.234811] CPU#10:   gen-PMC5 ctrl:  0000000000000000
[  253.240451] CPU#10:   gen-PMC5 count: 0000000000000000
[  253.246077] CPU#10:   gen-PMC5 left:  0000000000000000

drivers/tty/vt/keyboard.c 中

这里也会调用 show_state ,和 sysrq 一样的

如果使用 fn_show_ptregs 需要判断 in_hardirq() 吗?

sysrq_handle_showallcpus 中判断过,但是这里是没有的,而且奇怪的是,这样的话,岂不是 sysrq 和 vt 的功能是重叠的

static void fn_show_ptregs(struct vc_data *vc)
{
	struct pt_regs *regs = get_irq_regs();

	if (regs)
		show_regs(regs);
}

测试下,n100 中不要包含 drm 驱动,会有什么影响?

我猜测 vt console 直接无法显示吧

原来 drivers/tty/vt/keyboard.c 中的代码一直都是可以调用的

@[
    fn_enter+5
    kbd_event+959
    input_handle_events_default+66
    input_pass_values+289
    input_event_dispose+322
    input_event+83
    hidinput_report_event+55
    hid_report_raw_event+320
    hid_input_report+251
    hid_irq_in+464
    __usb_hcd_giveback_urb+145
    usb_giveback_urb_bh+169
    process_one_work+325
    bh_worker+555
    tasklet_hi_action+19
    handle_softirqs+220
    irq_exit_rcu+161
    common_interrupt+133
    asm_common_interrupt+38
    cpuidle_enter_state+198
    cpuidle_enter+45
    do_idle+412
    cpu_startup_entry+41
    start_secondary+247
    common_startup_64+300
]: 6

似乎 Ctrl + Alt + F2 和 Ctrl + Alt + F1 都不是一个东西

功能定位有不同的

有趣的 manual

https://manpages.ubuntu.com/manpages/plucky/man4/vt.4freebsd.html

想不到 windows 也是考虑这个的

https://learn.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences

理解这个

https://wiki.archlinux.org/title/Linux_console

这个 freebsd 也是有的

https://docs-archive.freebsd.org/doc/11.4-RELEASE/usr/local/share/doc/freebsd/handbook/consoles.html

看看,写的相当好,可以看看 vt 去掉之后的效果

https://www.reddit.com/r/linux/comments/10eccv9/config_vtn_in_2023/

依赖 VT 的一些 config

CONFIG_VT=y
CONFIG_CONSOLE_TRANSLATIONS=y
CONFIG_VT_CONSOLE=y
CONFIG_VT_CONSOLE_SLEEP=y
# CONFIG_VT_HW_CONSOLE_BINDING is not set

CONFIG_VGA_CONSOLE=y
CONFIG_DUMMY_CONSOLE=y
CONFIG_DUMMY_CONSOLE_COLUMNS=80
CONFIG_DUMMY_CONSOLE_ROWS=25

注意, 把 VT 去掉之后,console=ttyS0 不受影响

只有 vnc 功能收到影响

忽然意识到,vt 是非常复杂的,他是需要键盘鼠标的

在 vnc 中 enter 的效果

@[
    fn_enter+5
    kbd_event+959
    input_handle_events_default+66
    input_pass_values+289
    input_event_dispose+322
    input_event+83
    atkbd_receive_byte+1689
    ps2_interrupt+158
    serio_interrupt+71
    i8042_handle_data+240
    i8042_interrupt+17
    __handle_irq_event_percpu+71
    handle_irq_event+56
    handle_edge_irq+139
    __common_interrupt+59
    common_interrupt+128
    asm_common_interrupt+38
    default_idle+15
    default_idle_call+48
    do_idle+437
    cpu_startup_entry+41
    start_secondary+247
    common_startup_64+300
]: 5

原来如此:

@[
    fbcon_putcs+0
    con_write+32
    n_tty_write+380
    file_tty_write.isra.0+300
    redirected_tty_write+268
    vfs_write+544
    ksys_write+120
    __arm64_sys_write+36
    invoke_syscall.constprop.0+88
    do_el0_svc+72
    el0_svc+64
    el0t_64_sync_handler+268
    el0t_64_sync+408
]: 1
🧀  cat /sys/class/vtconsole/vtcon*/name
(S) dummy device
(M) frame buffer device
🧀  ls /sys/class/graphics/fb*
/sys/class/graphics/fb0:
bits_per_pixel  console  dev     mode   name  power   state   subsystem  virtual_size
blank           cursor   device  modes  pan   rotate  stride  uevent

/sys/class/graphics/fbcon:
cursor_blink  power  rotate  rotate_all  subsystem  uevent

cat /sys/class/graphics/fb*/name hibmcdrmfb

i915drmfb : intel 机器

🧀  ls -la /sys/class/drm/
lrwxrwxrwx    - root  6 Apr 14:46 card0 -> ../../devices/pci0000:00/0000:00:11.0/0000:03:00.0/drm/card0
lrwxrwxrwx    - root  6 Apr 14:46 card0-VGA-1 -> ../../devices/pci0000:00/0000:00:11.0/0000:03:00.0/drm/card0/card0-VGA-1
.r--r--r-- 4.1k root  6 Apr 14:46 version

大致的关联关系是这个样子的: /dev/tty0 -> /sys/devices/virtual/tty/tty0 -> vtcon1 -> /sys/class/graphics/fb0 -> /sys/class/drm/card0

VT 与 QEMU 串口前端

VT 是本机图形/键盘控制台路径:tty0、vtcon、fbcon 和 DRM/VNC 都属于 这一层。QEMU 的 serial layout 是另一层:-serial chardev:X 创建传统 UART, guest 通常看到 /dev/ttyS0;-device virtio-serial 只创建 virtio-serial bus, -device virtconsole,chardev=X 才创建 /dev/hvc0,而 virtserialport 创建的是 /dev/virtio-ports/<name>,不是 tty。

因此去掉 VT/DRM 会影响 VNC 和 tty0,但不会让 console=ttyS0 失效;同理, hvc0 依赖 virtio-serial frontend,不依赖 VT。host 侧的 stdio、socket、PTY 是 backend,决定 QEMU 字节从哪里进出,不决定 guest 使用 ttyS0、hvc0 还是 virtio-ports。

vt 是的确是可以控制键盘的

对,你的理解基本正确:VT 把键盘输入和屏幕输出组合成一个 TTY,所以它确实包含键盘处理逻辑。 但键盘硬件的驱动由 input 子系统负责,VT 接收的是 input 层提供的按键事件。

对应用程序来说,两种情况都表现为一个可以读写的终端:

终端 输入来源 输出去向 ━━━━━━━━━━━━━━━━━━━━━━━━━━━ ━━━━━━━━━━━━━━━━━━━━━━━━━━ ━━━━━━━━━━━━━━━━━━━━ 串口 TTY,例如 /dev/ttyS0 UART 接收的数据 UART 发送的数据 ─────────────────────────── ────────────────────────── ──────────────────── VT,例如 /dev/tty1 键盘事件经转换得到的字符 显示后端绘制的文字

TTY 抽象并不要求输入和输出来自同一个物理设备。

VT 的键盘路径

USB 键盘 / PS/2 键盘 ↓ usbhid / atkbd 等硬件协议驱动 ↓ input 子系统:按键码、按下/松开事件 ↓ drivers/tty/vt/keyboard.c 处理键盘映射、Shift/Ctrl、组合键、VT 切换等 ↓ 当前前台 VT 的 tty_port 接收缓冲区 ↓ TTY line discipline(通常是 N_TTY) 行编辑、回显、Ctrl-C 信号等 ↓ 应用程序 read(/dev/ttyN)

具体代码中:

• kbd_handler (drivers/tty/vt/keyboard.c:1690) 是一个 input_handler,通过 input 框架连接键盘并接收事件。 • kbd_keycode() (drivers/tty/vt/keyboard.c:1429) 选择 vc_cons[fg_console],处理当前前台 VT 的按键。 • put_queue() (drivers/tty/vt/keyboard.c:326) 通过 tty_insert_flip_char() 和 tty_flip_buffer_push() 把转换后的字节 送进 TTY。

例如,在通常的文本模式下,键盘按下 A 键,VT 根据 Shift、Caps Lock 和键盘映射决定输入 a 还是 A。若开启规范模式,之 后由 N_TTY 缓存这一行,直到回车才交给应用读取。

VT 的显示路径

应用程序 write(/dev/ttyN) ↓ TTY 层 ↓ vt.c:con_write() → do_con_write() 解析字符和终端转义序列,更新光标、颜色、屏幕内容 ↓ vc->vc_sw:struct consw 显示后端接口 ↓ fbcon / vgacon 等 ↓ 屏幕

写操作注册在 con_ops (drivers/tty/vt/vt.c:3912)。所以你说的 keyboard + framebuffer 是典型组合,不过显示后端也可以 是 VGA 文本控制台等,并不限定为 framebuffer。

键盘和输出也不是直接相连的:通常是键盘输入进入 N_TTY 后,由 N_TTY 的回显机制再走 VT 输出路径,把字符显示出来。

多个 VT 各自保存终端状态,共享键盘和显示设备;切换 VT 时,键盘输入随前台 VT 切换,屏幕展示也随之切换。没有连接实体 键盘时,VT 仍然可以存在并显示输出。

为什么 vt 存在 tty0 这种这种特殊的 tty ,但是 ttyS0 不存在

因为多个 VT 是在共享一套本地显示和键盘,需要“切换当前使用哪一个”;多个串口则是独立的通信端口,没有统一的“当前串口”。 tty0 就是把 VT 的 这个“当前”状态暴露给程序。

在典型的本地控制台上:

tty1 ─┐ tty2 ─┼─ 前台选择 ─ 显示器、键盘 tty3 ─┘ ↑ tty0 打开时选中它

你按 Alt+F2,是把前台切到 tty2。其他 VT 的程序仍然能运行,只是没有占据当前显示和键盘输入。

而串口是:

ttyS0 ─ 串口 A ─ 外部设备 A ttyS1 ─ 串口 B ─ 外部设备 B ttyUSB0 ─ USB 串口 ─ 外部设备 C

dev/tty 也是一个特殊文件了

ssh 到机器上,然后:

# cd /dev
# for i in tty*; do echo $i > $i ; done
tty

chvt

https://github.com/legionus/kbd/blob/master/src/chvt.c

不用键盘的按,就来切换

这个目录中内容看看 drivers/video/console/

drivers/video/console/vgacon.c

是一定会走到这个地方吗?

ctrl-alt-del

内核路径是:

EV_KEY(KEY_LEFTCTRL) EV_KEY(KEY_LEFTALT) EV_KEY(KEY_DELETE) | v drivers/tty/vt/keyboard.c:kbd_event() | v kbd_keycode() 根据 modifier 查 VT keymap | v Ctrl+Alt+Delete -> K_BOOT | v fn_boot_it() | v ctrl_alt_del()

默认 keymap 明确把 Delete 键映射为 Boot:

drivers/tty/vt/defkeymap.map:246

control alt keycode 111 = Boot

对应的处理函数在:

drivers/tty/vt/keyboard.c:614

static void fn_boot_it(struct vc_data *vc) { ctrl_alt_del(); }

ctrl_alt_del() 有两条分支:

kernel/reboot.c:828

if (C_A_D) schedule_work(&cad_work); else kill_cad_pid(SIGINT, 1);

• /proc/sys/kernel/ctrl-alt-del = 1:排队执行 kernel_restart(NULL),也就是内核直接重启。 • /proc/sys/kernel/ctrl-alt-del = 0:向 /proc/sys/kernel/cad_pid 指定的进程发送 SIGINT。默认 cad_pid 在启动时设置为 PID 1:init/ main.c:1639。

我在 sysrq-lab-20260925 中做了两次测试:

  1. ctrl-alt-del=1:通过 guest 内的 uinput 创建虚拟键盘,发送真实的 Ctrl、Alt、Delete 事件。QEMU PID 没变,但 guest boot ID 从 630c… 变成 d235…,uptime 重新从约 766 秒开始,确认发生了 guest 重启。

  2. ctrl-alt-del=0:把 cad_pid 临时指向测试进程,发送同样的事件,测试进程记录到:

pid=591 signal=2

说明第二条 SIGINT 路径也生效了。最后已恢复:

kernel.ctrl-alt-del = 1 kernel.cad_pid = 1

有一个调试细节:这个 VM 使用 -display none,所以 QMP 的 send-key 虽然返回成功,但不会产生 guest 输入事件;evtest 看不到任何键。实际测 试必须使用 guest 内的 uinput,或者启动带真实显示/输入路由的 QEMU。当前内核源码和 VM 配置都没有留下修改,工作树也是干净的。

再次确认下,vt 就是在 内核实现这些工作

为什么这个东西是 https://web.git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=50145474f6ef4a9c19205b173da6264a644c7489

两行经常遇到的日志

[   11.528480] fbcon: Taking over console
[   11.537260] Console: switching to colour frame buffer device 480x135

两条日志都属于 fbcon(framebuffer 控制台)接管 VT 控制台 的过程,一条是“准备接管”的提示,一条是“实际切换完成”的提示。

  1. fbcon: Taking over console
  static int fbcon_output_notifier(struct notifier_block *nb,
               unsigned long action, void *data)
  {
     WARN_CONSOLE_UNLOCKED();

     pr_info("fbcon: Taking over console\n");

     dummycon_unregister_output_notifier(&fbcon_output_nb);
     schedule_work(&fbcon_deferred_takeover_work);   // 真正接管被延迟到工作队列里执行
     return NOTIFY_OK;
  }
  1. Console: switching to colour frame buffer device 480x135
     pr_info("Console: switching ");
     if (!deflt)
        pr_cont("consoles %d-%d ", first + 1, last + 1);
     if (j >= 0) {
        struct vc_data *vc = vc_cons[j].d;

        pr_cont("to %s %s %dx%d\n",
           vc->vc_can_do_color ? "colour" : "mono",
           desc, vc->vc_cols, vc->vc_rows);
        ...

调用链

  fbcon_output_notifier()                     fbcon.c:3340  ← 打印 "Taking over console"(延迟接管路径)
    └─ schedule_work(fbcon_deferred_takeover_work)
         └─ fbcon_register_existing_fbs()      fbcon.c:3311
              └─ do_fb_registered() → do_fbcon_takeover()  fbcon.c:606
                   └─ do_take_over_console(&fb_con, ...)   vt.c:4581
                        ├─ do_register_con_driver()
                        └─ do_bind_con_driver()            vt.c:3989
                             ├─ csw->con_startup()  (= fbcon_startup, 返回 "frame buffer device")
                             └─ pr_info("Console: switching to colour frame buffer device 480x135\n")

简单说:第一条说明 fbcon 收到了第一次控制台输出、开始(延迟)接管;第二条说明 fbcon 已经真正绑定到 VT,并且报告了它把屏幕初始化为 480 列 × 135 行的彩色 文本控制台。 两者之间隔着一个调度到工作队列的异步步骤,所以时间戳上会略有先后。

TODO

https://news.ycombinator.com/item?id=41483789

其中分析到了 tty 相关的东西:

有趣的东西,又是 framebuffer ,又是 tty 的

https://news.ycombinator.com/item?id=43931845

vt100

首先,我们发现 pstree -h 提到了 vt100

pstree –help

  -G, --vt100         use VT100 line drawing characters

[!NOTE] 参考神奇海螺的意见,有待验证

是的,VT100 最初是一台真实的硬件终端。今天仍有实物保存,但日常软件中出现的“VT100”,更多是在说它留下来的兼容规则。它由 DEC 在 1978 年推出,外形是一个厚重的 CRT 屏幕配一把键盘,计算机历史博物馆有实物照片 (https://www.computerhistory.org/revolution/input-output/14/349/1697)。

理解它,要先看当时人与计算机如何交互。一台主机运行操作系统和应用,用户通过接在主机上的终端操作它:

用户 ⇄ VT100 的键盘和屏幕 ⇄ 串口 ⇄ 主机上的 shell、程序

你在 VT100 上敲下命令,终端把按键传给主机;主机执行命令,再把结果传回来,由终端显示。它自身也有处理器,主要负责通信、键盘和屏幕控制。这个使用体验和今天 通过 SSH 操作另一台机器很接近。

这里有个关键问题:主机传回来的内容,既包含文字,也包含“怎么显示”的指令。例如显示 hello、移动光标、清屏、让文字加下划线、切换到画线字符集。这些指令以特殊的字节序列发送,也就是前面提到的“转义序列”。VT100 用户手册 (https://vt100.net/docs/vt100-ug/chapter3.html)

后来,个人电脑能够用一个软件窗口承担原来那台硬件终端的工作。软件接收同样的字符和控制指令,在窗口里画出结果,所以称为 terminal emulator,终端模拟器。例如 xterm 就明确模拟 DEC 的 VT 系列终端,并支持后续型号的功能。xterm 官方说明 (https://invisible-island.net/xterm/)

因此,“终端”和“shell”也各有职责:终端负责接收按键、显示内容;bash、zsh 这样的 shell 负责理解命令、启动程序。以前它们分处终端硬件和主机,今天可以一起运 行在你的电脑里。

回到 pstree -G:它选择的是按 VT100 的画线规则输出数据。原来的硬件终端可以解释这些数据,支持该规则的软件终端也可以。一个硬件产品的名称,就这样延续成了软 件兼容性的名称。

vt 由于在内核中实现,导致 console font 都需要实现在内核中

这里的 console font 指 Linux 本地文字控制台的字体,比如按 Ctrl+Alt+F3 后看到的登录界面,以及屏幕上的内核启动日志。

关键在于:内核不仅管理终端的输入输出,也能直接在屏幕上绘制文字。

可以分两种情况理解:

场景 谁把字符画到屏幕上 谁负责字体 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ━━━━━━━━━━━━━━━━━━━━━━ ━━━━━━━━━━━━━━━━━━━━ GNOME Terminal、Kitty 等图形终端 用户态终端程序 用户态程序和字体库 ────────────────────────────────── ────────────────────── ──────────────────── Linux 文字控制台,如 /dev/tty1 内核的控制台显示驱动 内核

对于图形终端,shell 通过 PTY 传输字符,终端程序收到字符后绘制。内核的 PTY 层处理字节流,不需要知道“A”长什么样。

对于 Linux 文字控制台,典型的显示路径是:

程序输出字符 ↓ 内核 VT 层:处理字符、光标、换行、终端控制序列 ↓ fbcon:查询字体位图,把字符转换成像素 ↓ framebuffer → 屏幕

因此,fbcon 要显示一个 A,必须有描述它形状的字模。你当前源码里的 drivers/video/fbdev/core/bitblit.c:129 就从 vc_font.data 取出字符 位图,再调用显示驱动绘制。内核自带字库,也让文字输出可以在用户态尚未启动、不可用或系统发生 panic 时使用。

“Terminus 10x18”就是新增了一套字模:每个字符占宽 10、高 18 像素的固定格子。 它是位图字体; 源码中的 字体描述 (lib/fonts/font_ter10x18.c:5133) 明确记录了这些尺寸。

以 1440×900 的显示模式计算:

字体尺寸 大约能显示的列数 × 行数 ━━━━━━━━━━ ━━━━━━━━━━━━━━━━━━━━━━━━━ 8×16 180 × 56 ────────── ───────────────────────── 10×18 144 × 50 ────────── ───────────────────────── 16×32 90 × 28

这次改动的动机是:8×16 在相关笔记本屏幕上显得太小,16×32 又占空间太多;Terminus 10×18 提供一个更容易辨认、同时保留足够行数的选择。补丁还指出,已有的另一套 10×18 字体可读性较差,所以改善也来自字形设计。原始补丁说明 (https://lkml.rescloud.iu.edu/2511.2/01022.html)

所以,这项改动影响的是由内核绘制的文字界面;你在 Kitty 等图形终端里选择的字体,仍由那个终端程序负责。

可以看看内核代码 /lib/fonts/

基本流程

每次 kmalloc 之后 pr_info 一次,perf 了一下,基本上所有的时间都是在 print 上。

  100.00%     0.00%  insmod   [unknown]          [k] 0x20646564616f6c00
     0x20646564616f6c00
   - syscall
      - 99.90% init_module
         - 99.90% printk
              vprintk_emit
              console_unlock
            - vt_console_print
               - 93.99% lf
                    con_scroll
                  - fbcon_scroll
                     - 93.01% fbcon_redraw.isra.19
                        - 90.32% fbcon_putcs
                           - 87.55% bit_putcs
                              - 84.48% drm_fb_helper_cfb_imageblit
                                   cfb_imageblit
                                1.47% drm_fb_helper_dirty.isra.27
                             0.73% get_color
                          1.28% console_conditional_schedule
                     - 0.95% bit_clear
                          drm_fb_helper_cfb_fillrect
                          cfb_fillrect
                          bitfill_aligned
               - 5.86% fbcon_putcs
                    bit_putcs
                    drm_fb_helper_cfb_imageblit
                    cfb_imageblit

本站所有文章转发 CSDN 将按侵权追究法律责任,其它情况随意。