当前位置:   article > 正文

当我们切换linux终端时,背后发生了什么?_linux consw

linux consw

虚拟终端(/dev/tty*)

用户登录时,使用的是虚拟终端。使用Ctcl+Alt+[F1—F6]组合键时,我们就可以切换到tty1、tty2、tty3等上面去。此时显示器的内容发生了变化,那这个和显卡驱动,是如何关联的?

事实上,我们切换的时候需要调用到显卡驱动中的接口,重新设置显示器的输出,也就是定位到不同的显存内容,并且原理的显存应该保留,以便切换回来后依然是原来的内容。

显示器的终端驱动drivers/tty/vt/vt.c:

切换的试过键盘接收到中断,调用vt驱动中的schedule_console_callback.启动工作项。

  1. void schedule_console_callback(void)
  2. {
  3. schedule_work(&console_work);
  4. }
static DECLARE_WORK(console_work, console_callback);

从键盘输入ctrl_alt_fN 发生的dump_stack:

(关于键盘驱动可参考Linux input系统数据上报流程【转】 - sky-heaven - 博客园 (cnblogs.com)

  1. [ 754.930558] ===schedule_console_callback
  2. [ 754.930560] CPU: 6 PID: 1440 Comm: kworker/6:1 Not tainted 4.19.152+ #19
  3. [ 754.930561] Hardware name: PHYTIUM LTD D2000/D2000, BIOS
  4. [ 754.930563] Workqueue: events console_callback
  5. [ 754.930564] Call trace:
  6. [ 754.930565] dump_backtrace+0x0/0x198
  7. [ 754.930566] show_stack+0x24/0x30
  8. [ 754.930568] dump_stack+0x9c/0xd0
  9. [ 754.930569] schedule_console_callback+0x20/0x44
  10. [ 754.930570] kbd_event+0xc0/0x4b8
  11. [ 754.930572] input_to_handler+0xf0/0x118
  12. [ 754.930573] input_pass_values.part.2+0x130/0x148
  13. [ 754.930575] input_handle_event+0x114/0x548
  14. [ 754.930576] input_event+0x7c/0xb0
  15. [ 754.930578] hidinput_report_event+0x4c/0x68
  16. [ 754.930579] hid_report_raw_event+0x210/0x400
  17. [ 754.930581] hid_input_report+0x104/0x1b0
  18. [ 754.930582] hid_irq_in+0x94/0x230
  19. [ 754.930584] __usb_hcd_giveback_urb+0x7c/0x138
  20. [ 754.930585] usb_hcd_giveback_urb+0x168/0x188
  21. [ 754.930587] xhci_giveback_urb_in_irq.isra.22+0x98/0x160
  22. [ 754.930589] xhci_td_cleanup+0x118/0x1a8
  23. [ 754.930591] finish_td+0xf8/0x130
  24. [ 754.930592] handle_tx_event+0x24c/0x11b8
  25. [ 754.930594] xhci_irq+0x1fc/0x4a0
  26. [ 754.930596] xhci_msi_irq+0x20/0x118
  27. [ 754.930597] __handle_irq_event_percpu+0x78/0x248
  28. [ 754.930599] handle_irq_event_percpu+0x40/0x98
  29. [ 754.930601] handle_irq_event+0x50/0xd0
  30. [ 754.930602] handle_fasteoi_irq+0xd4/0x1a8
  31. [ 754.930604] generic_handle_irq+0x34/0x50
  32. [ 754.930606] __handle_domain_irq+0x6c/0xc0
  33. [ 754.930607] gic_handle_irq+0x84/0x180
  34. [ 754.930608] el1_irq+0xb0/0x140
  35. [ 754.930610] console_unlock+0x374/0x590
  36. [ 754.930611] console_callback+0xa4/0x158
  37. [ 754.930613] process_one_work+0x1ac/0x3e0
  38. [ 754.930614] worker_thread+0x44/0x448
  39. [ 754.930616] kthread+0x130/0x138
  40. [ 754.930617] ret_from_fork+0x10/0x18

后续内容和drm驱动相关的dump_stack:

1:创建agetty程序时通过console_callback,系统起来的时候没有agetty。切换的时候tty驱动会创建该进程:

  1. [ 220.466929] ===ast_primary_plane_helper_atomic_check
  2. [ 220.466935] CPU: 5 PID: 1941 Comm: kworker/5:3 Kdump: loaded Tainted: G E 5.10.0.anolis+ #8
  3. [ 220.466937] Hardware name: PHYTIUM LTD Phytium S2500/64/Phytium S2500/64, BIOS V2.2 Feb 9 2021
  4. [ 220.466950] Workqueue: events console_callback
  5. [ 220.466953] Call trace:
  6. [ 220.466958] dump_backtrace+0x0/0x210
  7. [ 220.466960] show_stack+0x20/0x68
  8. [ 220.466965] dump_stack+0xd8/0x130
  9. [ 220.466971] ast_primary_plane_helper_atomic_check+0x3c/0xa8 [ast]
  10. [ 220.467003] drm_atomic_helper_check_planes+0xe0/0x200 [drm_kms_helper]
  11. [ 220.467020] drm_atomic_helper_check+0x58/0xb0 [drm_kms_helper]
  12. [ 220.467077] drm_atomic_check_only+0x454/0x770 [drm]
  13. [ 220.467114] drm_atomic_commit+0x24/0x68 [drm]
  14. [ 220.467146] drm_client_modeset_commit_atomic.isra.14+0x1ec/0x290 [drm]
  15. [ 220.467175] drm_client_modeset_commit_locked+0x68/0x1a8 [drm]
  16. [ 220.467201] drm_fb_helper_pan_display+0xc0/0x1e0 [drm_kms_helper]
  17. [ 220.467205] fb_pan_display+0x94/0x108
  18. [ 220.467208] bit_update_start+0x28/0x50
  19. [ 220.467210] fbcon_switch+0x320/0x4b0
  20. [ 220.467212] redraw_screen+0x148/0x280
  21. [ 220.467215] complete_change_console+0x50/0xf0
  22. [ 220.467217] change_console+0x74/0xa8
  23. [ 220.467219] console_callback+0x158/0x170
  24. [ 220.467223] process_one_work+0x1c0/0x428
  25. [ 220.467224] worker_thread+0x158/0x510
  26. [ 220.467227] kthread+0x118/0x120
  27. [ 220.467230] ret_from_fork+0x10/0x18
  28. [ 220.467234] ===ast_crtc_helper_atomic_check
  29. [ 220.467237] CPU: 5 PID: 1941 Comm: kworker/5:3 Kdump: loaded Tainted: G E 5.10.0.anolis+ #8
  30. [ 220.467239] Hardware name: PHYTIUM LTD Phytium S2500/64/Phytium S2500/64, BIOS V2.2 Feb 9 2021
  31. [ 220.467246] Workqueue: events console_callback
  32. [ 220.467248] Call trace:
  33. [ 220.467250] dump_backtrace+0x0/0x210
  34. [ 220.467252] show_stack+0x20/0x68
  35. [ 220.467254] dump_stack+0xd8/0x130
  36. [ 220.467258] ast_crtc_helper_atomic_check+0x30/0x1454 [ast]
  37. [ 220.467275] drm_atomic_helper_check_planes+0x140/0x200 [drm_kms_helper]
  38. [ 220.467289] drm_atomic_helper_check+0x58/0xb0 [drm_kms_helper]
  39. [ 220.467326] drm_atomic_check_only+0x454/0x770 [drm]
  40. [ 220.467356] drm_atomic_commit+0x24/0x68 [drm]
  41. [ 220.467384] drm_client_modeset_commit_atomic.isra.14+0x1ec/0x290 [drm]
  42. [ 220.467414] drm_client_modeset_commit_locked+0x68/0x1a8 [drm]
  43. [ 220.467432] drm_fb_helper_pan_display+0xc0/0x1e0 [drm_kms_helper]
  44. [ 220.467434] fb_pan_display+0x94/0x108
  45. [ 220.467437] bit_update_start+0x28/0x50
  46. [ 220.467439] fbcon_switch+0x320/0x4b0
  47. [ 220.467441] redraw_screen+0x148/0x280
  48. [ 220.467444] complete_change_console+0x50/0xf0
  49. [ 220.467446] change_console+0x74/0xa8
  50. [ 220.467448] console_callback+0x158/0x170
  51. [ 220.467450] process_one_work+0x1c0/0x428
  52. [ 220.467451] worker_thread+0x158/0x510
  53. [ 220.467454] kthread+0x118/0x120
  54. [ 220.467456] ret_from_fork+0x10/0x18
  55. [ 220.467459] ===drm_atomic_helper_commit
  56. [ 220.467462] CPU: 5 PID: 1941 Comm: kworker/5:3 Kdump: loaded Tainted: G E 5.10.0.anolis+ #8
  57. [ 220.467463] Hardware name: PHYTIUM LTD Phytium S2500/64/Phytium S2500/64, BIOS V2.2 Feb 9 2021
  58. [ 220.467470] Workqueue: events console_callback
  59. [ 220.467472] Call trace:
  60. [ 220.467474] dump_backtrace+0x0/0x210
  61. [ 220.467475] show_stack+0x20/0x68
  62. [ 220.467477] dump_stack+0xd8/0x130
  63. [ 220.467492] drm_atomic_helper_commit+0x3c/0x14c [drm_kms_helper]
  64. [ 220.467524] drm_atomic_commit+0x54/0x68 [drm]
  65. [ 220.467554] drm_client_modeset_commit_atomic.isra.14+0x1ec/0x290 [drm]
  66. [ 220.467584] drm_client_modeset_commit_locked+0x68/0x1a8 [drm]
  67. [ 220.467600] drm_fb_helper_pan_display+0xc0/0x1e0 [drm_kms_helper]
  68. [ 220.467603] fb_pan_display+0x94/0x108
  69. [ 220.467605] bit_update_start+0x28/0x50
  70. [ 220.467607] fbcon_switch+0x320/0x4b0
  71. [ 220.467610] redraw_screen+0x148/0x280
  72. [ 220.467612] complete_change_console+0x50/0xf0
  73. [ 220.467614] change_console+0x74/0xa8
  74. [ 220.467616] console_callback+0x158/0x170
  75. [ 220.467618] process_one_work+0x1c0/0x428
  76. [ 220.467620] worker_thread+0x158/0x510
  77. [ 220.467622] kthread+0x118/0x120
  78. [ 220.467624] ret_from_fork+0x10/0x18
  79. [ 220.467635] ===drm_atomic_helper_commit_tail_rpm
  80. [ 220.467638] CPU: 5 PID: 1941 Comm: kworker/5:3 Kdump: loaded Tainted: G E 5.10.0.anolis+ #8
  81. [ 220.467639] Hardware name: PHYTIUM LTD Phytium S2500/64/Phytium S2500/64, BIOS V2.2 Feb 9 2021
  82. [ 220.467646] Workqueue: events console_callback
  83. [ 220.467648] Call trace:
  84. [ 220.467650] dump_backtrace+0x0/0x210
  85. [ 220.467651] show_stack+0x20/0x68
  86. [ 220.467654] dump_stack+0xd8/0x130
  87. [ 220.467669] drm_atomic_helper_commit_tail_rpm+0x30/0x98 [drm_kms_helper]
  88. [ 220.467683] commit_tail+0xac/0x1a8 [drm_kms_helper]
  89. [ 220.467697] drm_atomic_helper_commit+0x120/0x14c [drm_kms_helper]
  90. [ 220.467731] drm_atomic_commit+0x54/0x68 [drm]
  91. [ 220.467762] drm_client_modeset_commit_atomic.isra.14+0x1ec/0x290 [drm]
  92. [ 220.467791] drm_client_modeset_commit_locked+0x68/0x1a8 [drm]
  93. [ 220.467809] drm_fb_helper_pan_display+0xc0/0x1e0 [drm_kms_helper]
  94. [ 220.467811] fb_pan_display+0x94/0x108
  95. [ 220.467814] bit_update_start+0x28/0x50
  96. [ 220.467816] fbcon_switch+0x320/0x4b0
  97. [ 220.467818] redraw_screen+0x148/0x280
  98. [ 220.467820] complete_change_console+0x50/0xf0
  99. [ 220.467822] change_console+0x74/0xa8
  100. [ 220.467824] console_callback+0x158/0x170
  101. [ 220.467827] process_one_work+0x1c0/0x428
  102. [ 220.467828] worker_thread+0x158/0x510
  103. [ 220.467830] kthread+0x118/0x120
  104. [ 220.467832] ret_from_fork+0x10/0x18
  105. [ 220.467836] ===ast_primary_plane_helper_atomic_update gpu_addr 0 comm kworker/5:3
  106. [ 220.467838] CPU: 5 PID: 1941 Comm: kworker/5:3 Kdump: loaded Tainted: G E 5.10.0.anolis+ #8
  107. [ 220.467840] Hardware name: PHYTIUM LTD Phytium S2500/64/Phytium S2500/64, BIOS V2.2 Feb 9 2021
  108. [ 220.467847] Workqueue: events console_callback
  109. [ 220.467849] Call trace:
  110. [ 220.467851] dump_backtrace+0x0/0x210
  111. [ 220.467852] show_stack+0x20/0x68
  112. [ 220.467855] dump_stack+0xd8/0x130
  113. [ 220.467859] ast_primary_plane_helper_atomic_update+0x188/0x2b0 [ast]
  114. [ 220.467875] drm_atomic_helper_commit_planes+0xf0/0x218 [drm_kms_helper]
  115. [ 220.467888] drm_atomic_helper_commit_tail_rpm+0x58/0x98 [drm_kms_helper]
  116. [ 220.467902] commit_tail+0xac/0x1a8 [drm_kms_helper]
  117. [ 220.467915] drm_atomic_helper_commit+0x120/0x14c [drm_kms_helper]
  118. [ 220.467949] drm_atomic_commit+0x54/0x68 [drm]
  119. [ 220.467979] drm_client_modeset_commit_atomic.isra.14+0x1ec/0x290 [drm]
  120. [ 220.468007] drm_client_modeset_commit_locked+0x68/0x1a8 [drm]
  121. [ 220.468022] drm_fb_helper_pan_display+0xc0/0x1e0 [drm_kms_helper]
  122. [ 220.468024] fb_pan_display+0x94/0x108
  123. [ 220.468027] bit_update_start+0x28/0x50
  124. [ 220.468029] fbcon_switch+0x320/0x4b0
  125. [ 220.468031] redraw_screen+0x148/0x280
  126. [ 220.468033] complete_change_console+0x50/0xf0
  127. [ 220.468035] change_console+0x74/0xa8
  128. [ 220.468037] console_callback+0x158/0x170
  129. [ 220.468040] process_one_work+0x1c0/0x428
  130. [ 220.468041] worker_thread+0x158/0x510
  131. [ 220.468043] kthread+0x118/0x120
  132. [ 220.468045] ret_from_fork+0x10/0x18
  133. [ 220.468059] ===ast_crtc_helper_atomic_flush
  134. [ 220.468062] CPU: 5 PID: 1941 Comm: kworker/5:3 Kdump: loaded Tainted: G E 5.10.0.anolis+ #8
  135. [ 220.468063] Hardware name: PHYTIUM LTD Phytium S2500/64/Phytium S2500/64, BIOS V2.2 Feb 9 2021
  136. [ 220.468070] Workqueue: events console_callback
  137. [ 220.468072] Call trace:
  138. [ 220.468073] dump_backtrace+0x0/0x210
  139. [ 220.468075] show_stack+0x20/0x68
  140. [ 220.468077] dump_stack+0xd8/0x130
  141. [ 220.468081] ast_crtc_helper_atomic_flush+0x3c/0x160 [ast]
  142. [ 220.468097] drm_atomic_helper_commit_planes+0x15c/0x218 [drm_kms_helper]
  143. [ 220.468112] drm_atomic_helper_commit_tail_rpm+0x58/0x98 [drm_kms_helper]
  144. [ 220.468125] commit_tail+0xac/0x1a8 [drm_kms_helper]
  145. [ 220.468139] drm_atomic_helper_commit+0x120/0x14c [drm_kms_helper]
  146. [ 220.468175] drm_atomic_commit+0x54/0x68 [drm]
  147. [ 220.468206] drm_client_modeset_commit_atomic.isra.14+0x1ec/0x290 [drm]
  148. [ 220.468237] drm_client_modeset_commit_locked+0x68/0x1a8 [drm]
  149. [ 220.468256] drm_fb_helper_pan_display+0xc0/0x1e0 [drm_kms_helper]
  150. [ 220.468258] fb_pan_display+0x94/0x108
  151. [ 220.468261] bit_update_start+0x28/0x50
  152. [ 220.468263] fbcon_switch+0x320/0x4b0
  153. [ 220.468265] redraw_screen+0x148/0x280
  154. [ 220.468268] complete_change_console+0x50/0xf0
  155. [ 220.468270] change_console+0x74/0xa8
  156. [ 220.468272] console_callback+0x158/0x170
  157. [ 220.468275] process_one_work+0x1c0/0x428
  158. [ 220.468276] worker_thread+0x158/0x510
  159. [ 220.468278] kthread+0x118/0x120
  160. [ 220.468280] ret_from_fork+0x10/0x18

总结流程: 

  1. console_callback
  2. change_console
  3. complete_change_console
  4. redraw_screen
  5. fbcon_switch
  6. bit_update_start
  7. fb_pan_display
  8. drm_fb_helper_pan_display
  9. drm_client_modeset_commit_locked
  10. drm_client_modeset_commit_atomic
  11. drm_atomic_commit
  12. drm_atomic_check_only
  13. drm_atomic_helper_check
  14. drm_atomic_helper_check_planes //调用drm_xx_helper_funcs->atomic_check
  15. ast_primary_plane_helper_atomic_check //plane
  16. ast_crtc_helper_atomic_check //crtc
  17. drm_atomic_helper_commit
  18. commit_tail
  19. drm_atomic_helper_commit_tail_rpm
  20. drm_atomic_helper_commit_planes //调用crtc的atomic_begin。plane的atomic_update,crtc的atomic_flush
  21. ast_primary_plane_helper_atomic_update
  22. ast_crtc_helper_atomic_flush

上面是ctrl+alt+Fx 后 直到agetty程序启动前。下面是agetty启动后字符界面出现内容,如果之前以及切换过,也就是agetty起来了,则不会走下面的了。

2:agetty程序启动后tty_write

  1. [ 221.249372] ===ast_primary_plane_helper_atomic_check
  2. [ 221.249386] CPU: 105 PID: 3477 Comm: (agetty) Kdump: loaded Tainted: G E 5.10.0.anolis+ #8
  3. [ 221.249389] Hardware name: PHYTIUM LTD Phytium S2500/64/Phytium S2500/64, BIOS V2.2 Feb 9 2021
  4. [ 221.249393] Call trace:
  5. [ 221.249409] dump_backtrace+0x0/0x210
  6. [ 221.249412] show_stack+0x20/0x68
  7. [ 221.249423] dump_stack+0xd8/0x130
  8. [ 221.249436] ast_primary_plane_helper_atomic_check+0x3c/0xa8 [ast]
  9. [ 221.249503] drm_atomic_helper_check_planes+0xe0/0x200 [drm_kms_helper]
  10. [ 221.249522] drm_atomic_helper_check+0x58/0xb0 [drm_kms_helper]
  11. [ 221.249635] drm_atomic_check_only+0x454/0x770 [drm]
  12. [ 221.249678] drm_atomic_commit+0x24/0x68 [drm]
  13. [ 221.249708] drm_client_modeset_commit_atomic.isra.14+0x1ec/0x290 [drm]
  14. [ 221.249736] drm_client_modeset_commit_locked+0x68/0x1a8 [drm]
  15. [ 221.249774] drm_fb_helper_pan_display+0xc0/0x1e0 [drm_kms_helper]
  16. [ 221.249785] fb_pan_display+0x94/0x108
  17. [ 221.249802] bit_update_start+0x28/0x50
  18. [ 221.249805] fbcon_switch+0x320/0x4b0
  19. [ 221.249814] csi_J+0x1c8/0x1d8
  20. [ 221.249819] do_con_trol+0x1388/0x1478
  21. [ 221.249821] do_con_write+0x208/0x930
  22. [ 221.249823] con_write+0x20/0x70
  23. [ 221.249831] n_tty_write+0x19c/0x468
  24. [ 221.249835] tty_write+0x184/0x340
  25. [ 221.249842] vfs_write+0xc8/0x2b8
  26. [ 221.249844] ksys_write+0x70/0xf8
  27. [ 221.249846] __arm64_sys_write+0x24/0x30
  28. [ 221.249854] el0_svc_common.constprop.3+0xa4/0x1f8
  29. [ 221.249857] do_el0_svc+0x2c/0x98
  30. [ 221.249862] el0_svc+0x28/0x68
  31. [ 221.249864] el0_sync_handler+0x90/0xb8
  32. [ 221.249868] el0_sync+0x158/0x180
  33. [ 221.249875] ===ast_crtc_helper_atomic_check
  34. [ 221.249878] CPU: 105 PID: 3477 Comm: (agetty) Kdump: loaded Tainted: G E 5.10.0.anolis+ #8
  35. [ 221.249881] Hardware name: PHYTIUM LTD Phytium S2500/64/Phytium S2500/64, BIOS V2.2 Feb 9 2021
  36. [ 221.249883] Call trace:
  37. [ 221.249885] dump_backtrace+0x0/0x210
  38. [ 221.249887] show_stack+0x20/0x68
  39. [ 221.249889] dump_stack+0xd8/0x130
  40. [ 221.249895] ast_crtc_helper_atomic_check+0x30/0x1454 [ast]
  41. [ 221.249915] drm_atomic_helper_check_planes+0x140/0x200 [drm_kms_helper]
  42. [ 221.249929] drm_atomic_helper_check+0x58/0xb0 [drm_kms_helper]
  43. [ 221.249975] drm_atomic_check_only+0x454/0x770 [drm]
  44. [ 221.250016] drm_atomic_commit+0x24/0x68 [drm]
  45. [ 221.250047] drm_client_modeset_commit_atomic.isra.14+0x1ec/0x290 [drm]
  46. [ 221.250089] drm_client_modeset_commit_locked+0x68/0x1a8 [drm]
  47. [ 221.250125] drm_fb_helper_pan_display+0xc0/0x1e0 [drm_kms_helper]
  48. [ 221.250129] fb_pan_display+0x94/0x108
  49. [ 221.250134] bit_update_start+0x28/0x50
  50. [ 221.250136] fbcon_switch+0x320/0x4b0
  51. [ 221.250140] csi_J+0x1c8/0x1d8
  52. [ 221.250143] do_con_trol+0x1388/0x1478
  53. [ 221.250145] do_con_write+0x208/0x930
  54. [ 221.250147] con_write+0x20/0x70
  55. [ 221.250151] n_tty_write+0x19c/0x468
  56. [ 221.250154] tty_write+0x184/0x340
  57. [ 221.250157] vfs_write+0xc8/0x2b8
  58. [ 221.250159] ksys_write+0x70/0xf8
  59. [ 221.250161] __arm64_sys_write+0x24/0x30
  60. [ 221.250166] el0_svc_common.constprop.3+0xa4/0x1f8
  61. [ 221.250169] do_el0_svc+0x2c/0x98
  62. [ 221.250176] el0_svc+0x28/0x68
  63. [ 221.250178] el0_sync_handler+0x90/0xb8
  64. [ 221.250181] el0_sync+0x158/0x180
  65. [ 221.250278] ===drm_atomic_helper_commit
  66. [ 221.250288] CPU: 105 PID: 3477 Comm: (agetty) Kdump: loaded Tainted: G E 5.10.0.anolis+ #8
  67. [ 221.250290] Hardware name: PHYTIUM LTD Phytium S2500/64/Phytium S2500/64, BIOS V2.2 Feb 9 2021
  68. [ 221.250292] Call trace:
  69. [ 221.250298] dump_backtrace+0x0/0x210
  70. [ 221.250300] show_stack+0x20/0x68
  71. [ 221.250304] dump_stack+0xd8/0x130
  72. [ 221.250345] drm_atomic_helper_commit+0x3c/0x14c [drm_kms_helper]
  73. [ 221.250438] drm_atomic_commit+0x54/0x68 [drm]
  74. [ 221.250487] drm_client_modeset_commit_atomic.isra.14+0x1ec/0x290 [drm]
  75. [ 221.250535] drm_client_modeset_commit_locked+0x68/0x1a8 [drm]
  76. [ 221.250567] drm_fb_helper_pan_display+0xc0/0x1e0 [drm_kms_helper]
  77. [ 221.250572] fb_pan_display+0x94/0x108
  78. [ 221.250576] bit_update_start+0x28/0x50
  79. [ 221.250578] fbcon_switch+0x320/0x4b0
  80. [ 221.250583] csi_J+0x1c8/0x1d8
  81. [ 221.250585] do_con_trol+0x1388/0x1478
  82. [ 221.250587] do_con_write+0x208/0x930
  83. [ 221.250590] con_write+0x20/0x70
  84. [ 221.250596] n_tty_write+0x19c/0x468
  85. [ 221.250600] tty_write+0x184/0x340
  86. [ 221.250606] vfs_write+0xc8/0x2b8
  87. [ 221.250608] ksys_write+0x70/0xf8
  88. [ 221.250610] __arm64_sys_write+0x24/0x30
  89. [ 221.250619] el0_svc_common.constprop.3+0xa4/0x1f8
  90. [ 221.250621] do_el0_svc+0x2c/0x98
  91. [ 221.250624] el0_svc+0x28/0x68
  92. [ 221.250626] el0_sync_handler+0x90/0xb8
  93. [ 221.250629] el0_sync+0x158/0x180
  94. [ 221.250653] ===drm_atomic_helper_commit_tail_rpm
  95. [ 221.250656] CPU: 105 PID: 3477 Comm: (agetty) Kdump: loaded Tainted: G E 5.10.0.anolis+ #8
  96. [ 221.250658] Hardware name: PHYTIUM LTD Phytium S2500/64/Phytium S2500/64, BIOS V2.2 Feb 9 2021
  97. [ 221.250659] Call trace:
  98. [ 221.250662] dump_backtrace+0x0/0x210
  99. [ 221.250664] show_stack+0x20/0x68
  100. [ 221.250668] dump_stack+0xd8/0x130
  101. [ 221.250692] drm_atomic_helper_commit_tail_rpm+0x30/0x98 [drm_kms_helper]
  102. [ 221.250708] commit_tail+0xac/0x1a8 [drm_kms_helper]
  103. [ 221.250726] drm_atomic_helper_commit+0x120/0x14c [drm_kms_helper]
  104. [ 221.250798] drm_atomic_commit+0x54/0x68 [drm]
  105. [ 221.250840] drm_client_modeset_commit_atomic.isra.14+0x1ec/0x290 [drm]
  106. [ 221.250881] drm_client_modeset_commit_locked+0x68/0x1a8 [drm]
  107. [ 221.250917] drm_fb_helper_pan_display+0xc0/0x1e0 [drm_kms_helper]
  108. [ 221.250919] fb_pan_display+0x94/0x108
  109. [ 221.250922] bit_update_start+0x28/0x50
  110. [ 221.250924] fbcon_switch+0x320/0x4b0
  111. [ 221.250927] csi_J+0x1c8/0x1d8
  112. [ 221.250930] do_con_trol+0x1388/0x1478
  113. [ 221.250932] do_con_write+0x208/0x930
  114. [ 221.250935] con_write+0x20/0x70
  115. [ 221.250940] n_tty_write+0x19c/0x468
  116. [ 221.250942] tty_write+0x184/0x340
  117. [ 221.250946] vfs_write+0xc8/0x2b8
  118. [ 221.250947] ksys_write+0x70/0xf8
  119. [ 221.250949] __arm64_sys_write+0x24/0x30
  120. [ 221.250954] el0_svc_common.constprop.3+0xa4/0x1f8
  121. [ 221.250956] do_el0_svc+0x2c/0x98
  122. [ 221.250961] el0_svc+0x28/0x68
  123. [ 221.250967] el0_sync_handler+0x90/0xb8
  124. [ 221.250969] el0_sync+0x158/0x180
  125. [ 221.250979] ===ast_primary_plane_helper_atomic_update gpu_addr 0 comm (agetty)
  126. [ 221.250982] CPU: 105 PID: 3477 Comm: (agetty) Kdump: loaded Tainted: G E 5.10.0.anolis+ #8
  127. [ 221.250984] Hardware name: PHYTIUM LTD Phytium S2500/64/Phytium S2500/64, BIOS V2.2 Feb 9 2021
  128. [ 221.250986] Call trace:
  129. [ 221.250987] dump_backtrace+0x0/0x210
  130. [ 221.250989] show_stack+0x20/0x68
  131. [ 221.250993] dump_stack+0xd8/0x130
  132. [ 221.251002] ast_primary_plane_helper_atomic_update+0x188/0x2b0 [ast]
  133. [ 221.251024] drm_atomic_helper_commit_planes+0xf0/0x218 [drm_kms_helper]
  134. [ 221.251038] drm_atomic_helper_commit_tail_rpm+0x58/0x98 [drm_kms_helper]
  135. [ 221.251051] commit_tail+0xac/0x1a8 [drm_kms_helper]
  136. [ 221.251065] drm_atomic_helper_commit+0x120/0x14c [drm_kms_helper]
  137. [ 221.251122] drm_atomic_commit+0x54/0x68 [drm]
  138. [ 221.251159] drm_client_modeset_commit_atomic.isra.14+0x1ec/0x290 [drm]
  139. [ 221.251187] drm_client_modeset_commit_locked+0x68/0x1a8 [drm]
  140. [ 221.251205] drm_fb_helper_pan_display+0xc0/0x1e0 [drm_kms_helper]
  141. [ 221.251207] fb_pan_display+0x94/0x108
  142. [ 221.251211] bit_update_start+0x28/0x50
  143. [ 221.251217] fbcon_switch+0x320/0x4b0
  144. [ 221.251220] csi_J+0x1c8/0x1d8
  145. [ 221.251222] do_con_trol+0x1388/0x1478
  146. [ 221.251223] do_con_write+0x208/0x930
  147. [ 221.251232] con_write+0x20/0x70
  148. [ 221.251235] n_tty_write+0x19c/0x468
  149. [ 221.251237] tty_write+0x184/0x340
  150. [ 221.251240] vfs_write+0xc8/0x2b8
  151. [ 221.251242] ksys_write+0x70/0xf8
  152. [ 221.251244] __arm64_sys_write+0x24/0x30
  153. [ 221.251248] el0_svc_common.constprop.3+0xa4/0x1f8
  154. [ 221.251250] do_el0_svc+0x2c/0x98
  155. [ 221.251252] el0_svc+0x28/0x68
  156. [ 221.251254] el0_sync_handler+0x90/0xb8
  157. [ 221.251257] el0_sync+0x158/0x180
  158. [ 221.251509] ===ast_crtc_helper_atomic_flush
  159. [ 221.251513] CPU: 105 PID: 3477 Comm: (agetty) Kdump: loaded Tainted: G E 5.10.0.anolis+ #8
  160. [ 221.251514] Hardware name: PHYTIUM LTD Phytium S2500/64/Phytium S2500/64, BIOS V2.2 Feb 9 2021
  161. [ 221.251515] Call trace:
  162. [ 221.251517] dump_backtrace+0x0/0x210
  163. [ 221.251519] show_stack+0x20/0x68
  164. [ 221.251521] dump_stack+0xd8/0x130
  165. [ 221.251526] ast_crtc_helper_atomic_flush+0x3c/0x160 [ast]
  166. [ 221.251552] drm_atomic_helper_commit_planes+0x15c/0x218 [drm_kms_helper]
  167. [ 221.251569] drm_atomic_helper_commit_tail_rpm+0x58/0x98 [drm_kms_helper]
  168. [ 221.251590] commit_tail+0xac/0x1a8 [drm_kms_helper]
  169. [ 221.251612] drm_atomic_helper_commit+0x120/0x14c [drm_kms_helper]
  170. [ 221.251677] drm_atomic_commit+0x54/0x68 [drm]
  171. [ 221.251718] drm_client_modeset_commit_atomic.isra.14+0x1ec/0x290 [drm]
  172. [ 221.251755] drm_client_modeset_commit_locked+0x68/0x1a8 [drm]
  173. [ 221.251782] drm_fb_helper_pan_display+0xc0/0x1e0 [drm_kms_helper]
  174. [ 221.251786] fb_pan_display+0x94/0x108
  175. [ 221.251789] bit_update_start+0x28/0x50
  176. [ 221.251792] fbcon_switch+0x320/0x4b0
  177. [ 221.251795] csi_J+0x1c8/0x1d8
  178. [ 221.251798] do_con_trol+0x1388/0x1478
  179. [ 221.251800] do_con_write+0x208/0x930
  180. [ 221.251807] con_write+0x20/0x70
  181. [ 221.251810] n_tty_write+0x19c/0x468
  182. [ 221.251818] tty_write+0x184/0x340
  183. [ 221.251821] vfs_write+0xc8/0x2b8
  184. [ 221.251823] ksys_write+0x70/0xf8
  185. [ 221.251825] __arm64_sys_write+0x24/0x30
  186. [ 221.251829] el0_svc_common.constprop.3+0xa4/0x1f8
  187. [ 221.251831] do_el0_svc+0x2c/0x98
  188. [ 221.251835] el0_svc+0x28/0x68
  189. [ 221.251838] el0_sync_handler+0x90/0xb8
  190. [ 221.251840] el0_sync+0x158/0x180

tty参考:Linux 终端初始化 console_init 及 tty 驱动框架 - 腾讯云开发者社区-腾讯云 (tencent.com)

printk打印:【转载】从printk到framebuff - hydah - 博客园 (cnblogs.com)

“printk打印需要调用console_driver。而vt.c代表的显示器控制台也注册了,因此prink会往显示器输出,最终调用consw的接口来写。consw的提供有很多在drivers/video下面

28c0f0bb796146088473a4b52fd4ac9a.png

显示器输出需要结合framebuffer。因此framebuffr需要调用vt提供的接口注册(do_take_over_console),将consw fb_con注册。vt的打印调用consw的接口来操作framebuffer,再操作drm。。。。”

  1. static int __init con_init(void)
  2. {
  3. ...
  4. #ifdef CONFIG_VT_CONSOLE
  5. register_console(&vt_console_driver);
  6. #endif
  7. return 0;
  8. }
  9. static struct console vt_console_driver = {
  10. .name = "tty",
  11. .write = vt_console_print, //printk调用这个写函数
  12. .device = vt_console_device,
  13. .unblank = unblank_screen,
  14. .flags = CON_PRINTBUFFER,
  15. .index = -1,
  16. };
  17. static void vt_console_print(struct console *co, const char *b, unsigned count)
  18. {
  19. struct vc_data *vc = vc_cons[fg_console].d;
  20. vc->vc_sw->con_putcs(vc, start, cnt, vc->vc_y, vc->vc_x); //调用consw 的con_putc函数
  21. }

drivers/video 下提供console的有多个:

0c82ce46f01e45bfa53cab915a00a52f.png

 其中我们如果是framebuffer的话,在fbdev下面。通过register_framebuffer通用注册。efifb和drm都是一样。

  1. [ 12.653736] do_take_over_console+0x158/0x240 //drivers/tty/vt/vt.c
  2. [ 12.653739] do_fbcon_takeover+0x74/0xe0 //drivers/tty/vt/vt.c
  3. [ 12.653741] fbcon_event_notify+0x858/0x8c8
  4. [ 12.653744] notifier_call_chain+0x5c/0x98
  5. [ 12.653746] blocking_notifier_call_chain+0x64/0xa0
  6. [ 12.653748] fb_notifier_call_chain+0x30/0x40
  7. [ 12.653750] register_framebuffer+0x2b4/0x340 //drivers/video/fbdev/core/fbmem.c

但如果是framebuffer的话 (在fbdev下面),只能支持一个(efifb或者显卡驱动注册的register_framebuffer)。因为vt.c中的registered_con_driver总共16个且不能重复。意味着如果efifb注册了。后面的将无法注册。除非将efifb干掉。因此。通过drm启动后efifb会被移除。参考后面的do_take_over_console

可以博客写了tty的显示过程。

(126条消息) tty0 显示的过程_tiantao2012的博客-CSDN博客

显示控制台的驱动是:drivers/tty/vt/vt.c:

其中定义了一个工作队列:console_work

  1. static DECLARE_WORK(console_work, console_callback); //work工作项
  2. console_callback是其工作函数。每次切换终端将调用: 对应了前面的dump_stack
  3. void schedule_console_callback(void)
  4. {
  5. schedule_work(&console_work); //调用
  6. }
  7. static void console_callback(struct work_struct *ignored)
  8. {
  9. console_lock();
  10. if (want_console >= 0) {
  11. if (want_console != fg_console &&
  12. vc_cons_allocated(want_console)) {
  13. hide_cursor(vc_cons[fg_console].d);
  14. change_console(vc_cons[want_console].d); //执行切换。
  15. /* we only changed when the console had already
  16. been allocated - a new console is not created
  17. in an interrupt routine */
  18. }
  19. want_console = -1;
  20. }
  21. if (do_poke_blanked_console) { /* do not unblank for a LED change */
  22. do_poke_blanked_console = 0;
  23. poke_blanked_console();
  24. }
  25. if (scrollback_delta) {
  26. struct vc_data *vc = vc_cons[fg_console].d;
  27. clear_selection();
  28. if (vc->vc_mode == KD_TEXT && vc->vc_sw->con_scrolldelta)
  29. vc->vc_sw->con_scrolldelta(vc, scrollback_delta);
  30. scrollback_delta = 0;
  31. }
  32. if (blank_timer_expired) {
  33. do_blank_screen(0);
  34. blank_timer_expired = 0;
  35. }
  36. notify_update(vc_cons[fg_console].d);
  37. console_unlock();
  38. }
vc_cons:
struct vc vc_cons [MAX_NR_CONSOLES]; 总共63个从tty1->tty63 
  1. #define MIN_NR_CONSOLES 1 /* must be at least 1 */
  2. #define MAX_NR_CONSOLES 63 /* serial lines start at 64 */

 其中tty和tty0 是特殊用。Ctrl+alt+fx 对应ttyx

7ee3ffdfcf8047bebc8248dc2ef965d0.png

下面是/dev/目录下的ttyX。 drivers/vt/vt.c对应的是ttyX

8f34f35c2d4d4f4cab2ab2490f165c4c.png

再看一下drivers/vt/vt.c 中的

  1. #define MAX_NR_CON_DRIVER 16
  2. struct con_driver {
  3. const struct consw *con;
  4. const char *desc;
  5. struct device *dev;
  6. int node;
  7. int first;
  8. int last;
  9. int flag;
  10. };
  11. static struct con_driver registered_con_driver[MAX_NR_CON_DRIVER]; //总共可以注册的consw为16个。且需要不同。比如fb_con。sti_con,mda_con,newport_con,dummy_con等等
  12. const struct consw *conswitchp;
  13. struct vc vc_cons [MAX_NR_CONSOLES]; //总共的终端时63个。
  14. #ifndef VT_SINGLE_DRIVER
  15. static const struct consw *con_driver_map[MAX_NR_CONSOLES]; //总共63个,在do_bind_con_driver函数中会预先设置consw。参考 do_bind_con_driver
  16. #endif

do_take_over_console 注册:

  1. int do_take_over_console(const struct consw *csw, int first, int last, int deflt)
  2. {
  3. int err;
  4. err = do_register_con_driver(csw, first, last); // 注册consw。如果已经有相同的consw将返回失败。
  5. /*
  6. * If we get an busy error we still want to bind the console driver
  7. * and return success, as we may have unbound the console driver
  8. * but not unregistered it.
  9. */
  10. if (err == -EBUSY)
  11. err = 0;
  12. if (!err)
  13. do_bind_con_driver(csw, first, last, deflt);
  14. return err;
  15. }

do_register_con_driver:注册consw到 registered_con_driver中。无法重复注册(register_framebuffer背后使用的consw是一个fb_con)

  1. static int do_register_con_driver(const struct consw *csw, int first, int last)
  2. {
  3. struct module *owner = csw->owner;
  4. struct con_driver *con_driver;
  5. const char *desc;
  6. int i, retval;
  7. WARN_CONSOLE_UNLOCKED();
  8. if (!try_module_get(owner))
  9. return -ENODEV;
  10. for (i = 0; i < MAX_NR_CON_DRIVER; i++) {
  11. con_driver = &registered_con_driver[i];
  12. /* already registered */
  13. if (con_driver->con == csw) { //如果已经存在。。。。这返回。
  14. retval = -EBUSY;
  15. goto err;
  16. }
  17. }
  18. desc = csw->con_startup();
  19. if (!desc) {
  20. retval = -ENODEV;
  21. goto err;
  22. }
  23. retval = -EINVAL;
  24. for (i = 0; i < MAX_NR_CON_DRIVER; i++) {
  25. con_driver = &registered_con_driver[i];
  26. if (con_driver->con == NULL &&
  27. !(con_driver->flag & CON_DRIVER_FLAG_ZOMBIE)) {
  28. con_driver->con = csw;
  29. con_driver->desc = desc;
  30. con_driver->node = i;
  31. con_driver->flag = CON_DRIVER_FLAG_MODULE |
  32. CON_DRIVER_FLAG_INIT;
  33. con_driver->first = first;
  34. con_driver->last = last;
  35. retval = 0;
  36. break;
  37. }
  38. }
  39. if (retval)
  40. goto err;
  41. con_driver->dev =
  42. device_create_with_groups(vtconsole_class, NULL,
  43. MKDEV(0, con_driver->node),
  44. con_driver, con_dev_groups,
  45. "vtcon%i", con_driver->node);
  46. if (IS_ERR(con_driver->dev)) {
  47. pr_warn("Unable to create device for %s; errno = %ld\n",
  48. con_driver->desc, PTR_ERR(con_driver->dev));
  49. con_driver->dev = NULL;
  50. } else {
  51. vtconsole_init_device(con_driver);
  52. }
  53. err:
  54. module_put(owner);
  55. return retval;
  56. }

do_bind_con_driver:绑定从first到last范围内的所有ttyX设备的consw。当然前提是该设备已经创建。 

  1. static int do_bind_con_driver(const struct consw *csw, int first, int last,
  2. int deflt) //deflt是否为默认consw。通常注册的都是,比如fb_con
  3. {
  4. struct module *owner = csw->owner;
  5. const char *desc = NULL;
  6. struct con_driver *con_driver;
  7. int i, j = -1, k = -1, retval = -ENODEV;
  8. if (!try_module_get(owner))
  9. return -ENODEV;
  10. WARN_CONSOLE_UNLOCKED();
  11. /* check if driver is registered */
  12. for (i = 0; i < MAX_NR_CON_DRIVER; i++) {
  13. con_driver = &registered_con_driver[i];
  14. if (con_driver->con == csw) {
  15. desc = con_driver->desc;
  16. retval = 0;
  17. break;
  18. }
  19. }
  20. if (retval)
  21. goto err;
  22. if (!(con_driver->flag & CON_DRIVER_FLAG_INIT)) {
  23. csw->con_startup();
  24. con_driver->flag |= CON_DRIVER_FLAG_INIT;
  25. }
  26. if (deflt) {
  27. if (conswitchp)
  28. module_put(conswitchp->owner);
  29. __module_get(owner);
  30. conswitchp = csw; //替换为默认
  31. }
  32. first = max(first, con_driver->first);
  33. last = min(last, con_driver->last);
  34. for (i = first; i <= last; i++) {
  35. int old_was_color;
  36. struct vc_data *vc = vc_cons[i].d; //63个ttyX 初始化数据
  37. if (con_driver_map[i])
  38. module_put(con_driver_map[i]->owner);
  39. __module_get(owner);
  40. con_driver_map[i] = csw;
  41. if (!vc || !vc->vc_sw) //如果对应的ttyX没有创建,则不需要,一般系统并不会创建全部。
  42. continue;
  43. j = i;
  44. if (con_is_visible(vc)) {
  45. k = i;
  46. save_screen(vc);
  47. }
  48. old_was_color = vc->vc_can_do_color;
  49. vc->vc_sw->con_deinit(vc);
  50. vc->vc_origin = (unsigned long)vc->vc_screenbuf;
  51. visual_init(vc, i, 0); //配置
  52. set_origin(vc);
  53. update_attr(vc);
  54. /* If the console changed between mono <-> color, then
  55. * the attributes in the screenbuf will be wrong. The
  56. * following resets all attributes to something sane.
  57. */
  58. if (old_was_color != vc->vc_can_do_color)
  59. clear_buffer_attributes(vc);
  60. }
  61. pr_info("Console: switching ");
  62. if (!deflt)
  63. pr_cont("consoles %d-%d ", first + 1, last + 1);
  64. if (j >= 0) {
  65. struct vc_data *vc = vc_cons[j].d;
  66. pr_cont("to %s %s %dx%d\n",
  67. vc->vc_can_do_color ? "colour" : "mono",
  68. desc, vc->vc_cols, vc->vc_rows);
  69. if (k >= 0) {
  70. vc = vc_cons[k].d;
  71. update_screen(vc);
  72. }
  73. } else {
  74. pr_cont("to %s\n", desc);
  75. }
  76. retval = 0;
  77. err:
  78. module_put(owner);
  79. return retval;
  80. };

do_bind_con_driver后谁最后调用,将使用谁的consw,如果通过register_framebuffer注册的consw是用一个,因此如果efifb先注册,则使用efifb,drm注册的可能用不到。

 

打印:do_bind_con_driver

  1. [ 17.211099] ===fbcon_fb_registered idx 0 info_idx -1
  2. [ 17.211210] ===do_bind_con_driver ffff800010e15818 first 0 last 62
  3. [ 17.211212] ===visual_init vc->vc_num 0 vc->vc_sw ffff800010e15818
  4. [ 17.211221] ===fbcon_init
  5. [ 21.177371] ===do_bind_con_driver ffff800010e14368 first 0 last 62
  6. [ 21.177376] ===visual_init vc->vc_num 0 vc->vc_sw ffff800010e14368
  7. [ 22.140147] ===fbcon_fb_registered idx 0 info_idx -1
  8. [ 22.141070] ===do_bind_con_driver ffff800010e15818 first 0 last 62
  9. [ 22.141073] ===visual_init vc->vc_num 0 vc->vc_sw ffff800010e15818
  10. [ 22.141074] ===fbcon_init
  11. [ 108.158192] ===visual_init vc->vc_num 1 vc->vc_sw ffff800010e15818
  12. [ 108.158194] ===fbcon_init
  13. [ 108.265646] ===visual_init vc->vc_num 2 vc->vc_sw ffff800010e15818
  14. [ 108.265648] ===fbcon_init
  15. [ 108.374542] ===visual_init vc->vc_num 3 vc->vc_sw ffff800010e15818
  16. [ 108.374543] ===fbcon_init
  17. [ 108.477747] ===visual_init vc->vc_num 4 vc->vc_sw ffff800010e15818
  18. [ 108.477749] ===fbcon_init
  19. [ 108.585954] ===visual_init vc->vc_num 5 vc->vc_sw ffff800010e15818
  20. [ 108.585955] ===fbcon_init

上述两个consw:分别可以打印出来,其vc_num:中0-5的6个分别代表tty1-6.

  1. root@wzm-phytium-d2000:~# cat /proc/kallsyms |grep ffff800010e14368
  2. ffff800010e14368 D dummy_con
  3. root@wzm-phytium-d2000:~# cat /proc/kallsyms |grep ffff800010e15818
  4. ffff800010e15818 d fb_con

前面分析切换终端调用fbcon_switch:

  1. static int fbcon_switch(struct vc_data *vc)
  2. {
  3. struct fb_info *info, *old_info = NULL;
  4. struct fbcon_ops *ops;
  5. struct fbcon_display *p = &fb_display[vc->vc_num];
  6. struct fb_var_screeninfo var;
  7. int i, ret, prev_console, charcnt = 256;
  8. info = registered_fb[con2fb_map[vc->vc_num]]; //根据vc_num 计算出registered_fb。进而找出fbcon_ops
  9. 。。。。
  10. }

con2fb_map数组中的值在do_fbcon_takeover中设置。

  1. static int do_fbcon_takeover(int show_logo)
  2. {
  3. int err, i;
  4. if (!num_registered_fb)
  5. return -ENODEV;
  6. if (!show_logo)
  7. logo_shown = FBCON_LOGO_DONTSHOW;
  8. for (i = first_fb_vc; i <= last_fb_vc; i++) //0-62
  9. con2fb_map[i] = info_idx; //info_idx 的值通常就是0,在函数fbcon_fb_registered中先从-1 设置为0.
  10. err = do_take_over_console(&fb_con, first_fb_vc, last_fb_vc,
  11. fbcon_is_default);
  12. 。。。
  13. }

本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号