Q: 程序调用read系统调用等待输入, 键盘输入1个字符后执行了哪些流程?
A: 从大的框架来看:
按键中断 –> 按键驱动程序解析key –> 投递给当前TTY驱动 –> (默认)回显字符 –> TTY驱动保存输入字符 –> (如果是换行符)唤醒read系统调用返回到用户程序继续运行
Q: 按键中断程序传递按键到TTY的接口是?
A: tty_insert_flip_char和tty_schedule_flip函数. 前者把字符插入到tty buffer, 后者唤醒tty后续处理.
Q: TTY是如何被唤醒的?
A: tty_schedule_flip会唤醒workqueue执行flush_to_ldisc, 调用receive_buf –> n_tty_receive_buf2 –> __receive_buf. 总之一路传递tty和buffer.
Q: 终端是如何回显的?
A: __receive_buf会调用n_tty_receive_buf系列函数保存输入的按键字符, 内部调用n_tty_receive_char_special.
n_tty_receive_char_special:
如果打开回显且是普通字符: echo_char会保存到tty echo buffer中.
echo_buf位于struct n_tty_data:
unsigned char echo_buf[N_TTY_BUF_SIZE];
n_tty_receive_char_special调用commit_echos函数将实现回显.
commit_echos调用__process_echoes把前面的echo_buf取出来并调用tty_put_char放到TTY中, 之后调用flush_chars回显.
Q: 除了回显, 当输入了换行, 又是如何唤醒read系统调用的?
A: 接n_tty_receive_char_special函数: 当遇到’\n’时:
wake_up_interruptible会唤醒在tty read例程.
Q: TTY read_wait在哪里设置的?
A: 调用TTY read时, 会进入n_tty_read, 在没有输入数据时进入等待状态.
OK, 结束, 一切都很安详!
作者: 陈曦
环境: MacOS 10.14.5
Apple LLVM version 10.0.1 (clang-1001.0.46.4)
Target: x86_64-apple-darwin18.6.0
Linux 3.16.83 (Ubuntu)
转载请注明出处