当前位置:网站首页>Enter a command with the keyboard
Enter a command with the keyboard
2022-07-05 16:31:00 【CSDN cloud computing】
author | Dodger
source | Low concurrency programming
Create a very simple info.txt file .
name:flash
age:28
language:java
Enter a very simple command on the command line .
[[email protected]] cat info.txt | wc -l
3
This command means to read the just info.txt file , Output its rows .
Let's start with the initial state .
The initial state , There is only one sentence in front of the computer screen .
[[email protected]]
then , We press the button 'c', It will be like this .
[[email protected]] c
Let's press again 'a'
[[email protected]] ca
Next , Then we press 't'、 Space 、'i' wait , That's what happened .
[[email protected]] cat info.txt | wc -l
We are going to explain this today. It looks very " normal " The process of .
Why should we press the keyboard , Such changes will appear on the screen ? Is it stipulated by God ?
We'll start by pressing on the keyboard 'c' The key starts talking .
First , Thanks to the The first 16 return | Console initialization tty_init A line of code described in .
// console.c
void con_init(void) {
...
set_trap_gate(0x21,&keyboard_interrupt);
...
}
We successfully bound the keyboard interrupt to keyboard_interrupt On this interrupt handler , That is, when we press the keyboard 'c' when ,CPU The interrupt mechanism of will be triggered , Finally, this keyboard_interrupt Function .
We are here keyboard_interrupt Function to find out .
// keyboard.s
keyboard_interrupt:
...
// Read the keyboard scan code
inb $0x60,%al
...
// Call the handler of the corresponding key
call *key_table(,%eax,4)
...
// 0 As a parameter , call do_tty_interrupt
pushl $0
call do_tty_interrupt
...
It's simple , First, through IO Port operation , Read the newly generated keyboard scan code from the keyboard , Just press 'c' Keyboard scan code generated when .
And then , stay key_table Search for different processing functions corresponding to different keys , For example, the character corresponding to a common letter 'c' The processing function of is do_self, This function converts the scan code to ASCII Character code , And put yourself in a queue , We will talk about the details of this part later .
Next , It's called do_tty_interrupt function , See the meaning of the name is to process the interrupt processing function of the terminal , Notice that a parameter is passed here 0.
Let's continue to explore , open do_tty_interrupt function .
// tty_io.c
void do_tty_interrupt(int tty) {
copy_to_cooked(tty_table+tty);
}
void copy_to_cooked(struct tty_struct * tty) {
...
}
This function does almost nothing , take keyboard_interrupt Is the parameter passed in 0, As tty_table The index of , find tty_table No 0 As the input parameter of the next function , That's it .
tty_table yes Terminal equipment list , stay Linux 0.11 Three items are defined in , Namely Console 、 Serial terminal 1 and Serial terminal 2.
// tty.h
struct tty_struct tty_table[] = {
{
{...},
0, /* initial pgrp */
0, /* initial stopped */
con_write,
{0,0,0,0,""}, /* console read-queue */
{0,0,0,0,""}, /* console write-queue */
{0,0,0,0,""} /* console secondary queue */
},
{...},
{...}
};
The terminal we use to output content to the screen , Namely 0 Console terminal at index position No , So I omit the code defined by the other two terminals .
tty_table Structure of each item in the terminal equipment table , yes tty_struct, Used to describe the properties of a terminal .
struct tty_struct {
struct termios termios;
int pgrp;
int stopped;
void (*write)(struct tty_struct * tty);
struct tty_queue read_q;
struct tty_queue write_q;
struct tty_queue secondary;
};
struct tty_queue {
unsigned long data;
unsigned long head;
unsigned long tail;
struct task_struct * proc_list;
char buf[TTY_BUF_SIZE];
};
Talk about some of the key .
termios It defines various modes of the terminal , Including read mode 、 Write mode 、 Control mode, etc , Let's talk about it later .
void (*write)(struct tty_struct * tty) It's an interface function , In just tty_table We can also see that it is defined as con_write, That is to say, in the future, we will call this 0 During the write operation of terminal , What will be called is this con_write function , This is the idea of interface .
There are also three queues Read the queue read_q, Write a queue write_q And one. Secondary queue secondary.
What's the use of these , We'll talk about it later , Follow me and watch .
// tty_io.c
void do_tty_interrupt(int tty) {
copy_to_cooked(tty_table+tty);
}
void copy_to_cooked(struct tty_struct * tty) {
signed char c;
while (!EMPTY(tty->read_q) && !FULL(tty->secondary)) {
// from read_q Middle out character
GETCH(tty->read_q,c);
...
// A lot of rule processing code is omitted here
...
// Put the processed characters into secondary
PUTCH(c,tty->secondary);
}
wake_up(&tty->secondary.proc_list);
}
an copy_to_cooked We find that , A general framework has been established .
stay copy_to_cooked Function is a big loop , Just read the queue read_q Not empty , And auxiliary queue secondary Not full , From read_q Middle out character , After a big lump of treatment , write in secondary In the queue .
otherwise , Wake up and wait for the auxiliary queue secondary The process of , What to do next is up to the process itself .
Let's move on , What did the big lump in the middle do ?
This big lump has too many if Judge , But they all revolve around the same purpose , Let's give a simple example .
#define IUCLC 0001000
#define _I_FLAG(tty,f) ((tty)->termios.c_iflag & f)
#define I_UCLC(tty) _I_FLAG((tty),IUCLC)
void copy_to_cooked(struct tty_struct * tty) {
...
// A lot of rule processing code is omitted here
if (I_UCLC(tty))
c=tolower(c);
...
}
In short , By judgment tty Medium termios, To determine the characters read c Do something about it .
ad locum , It is judgement. termios Medium c_iflag No 4 Whether a is 1, To decide whether to read the characters c From uppercase to lowercase .
This termios It defines the terminal Pattern .
struct termios {
unsigned long c_iflag; /* input mode flags */
unsigned long c_oflag; /* output mode flags */
unsigned long c_cflag; /* control mode flags */
unsigned long c_lflag; /* local mode flags */
unsigned char c_line; /* line discipline */
unsigned char c_cc[NCCS]; /* control characters */
};
For example, whether you want to change uppercase to lowercase , Whether to replace carriage return character with newline character , Whether to accept keyboard control character signals, such as ctrl + c etc. .
These patterns are not Linux 0.11 I dreamed it up , It's about achieving POSIX.1 Stipulated in termios standard , For details, please refer to :
https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap11.html#tag_11
Okay , We can conclude at present , What did you do after pressing the keyboard .
Here we should have a few questions .
One 、 Read the queue read_q When were the characters in it put in ?
Do you remember what I first said keyboard_interrupt function , We have a method that we haven't discussed .
// keyboard.s
keyboard_interrupt:
...
// Read the keyboard scan code
inb $0x60,%al
...
// Call the handler of the corresponding key
call *key_table(,%eax,4)
...
// 0 As a parameter , call do_tty_interrupt
pushl $0
call do_tty_interrupt
...
This is this. key_table, We expand it .
// keyboard.s
key_table:
.long none,do_self,do_self,do_self /* 00-03 s0 esc 1 2 */
.long do_self,do_self,do_self,do_self /* 04-07 3 4 5 6 */
...
.long do_self,do_self,do_self,do_self /* 20-23 d f g h */
...
It can be seen that , Ordinary characters abcd such , The corresponding processing function is do_self, Let's continue .
// keyboard.s
do_self:
...
// The scan code is converted to ASCII code
lea key_map,%ebx
1: movb (%ebx,%eax),%al
...
// Put in queue
call put_queue
You can see the last call put_queue function , seeing the name of a thing one thinks of its function Put in queue , It seems that we are going to find the answer , Continue to expand .
// tty_io.c
struct tty_queue * table_list[]={
&tty_table[0].read_q, &tty_table[0].write_q,
&tty_table[1].read_q, &tty_table[1].write_q,
&tty_table[2].read_q, &tty_table[2].write_q
};
// keyboard.s
put_queue:
...
movl table_list,%edx # read-queue for console
movl head(%edx),%ecx
...
It can be seen that ,put_queue It is the operation of us tty_table Zero position in the array , That is, console terminal tty Of read_q queue , Join the team .
The answer is out , Then our overall flow chart can also be enriched .
Two 、 Put in secondary After the queue ?
After pressing the keyboard , A series of codes put our characters in secondary In line , so what ?
This involves the upper process calling the terminal's read function , Take this character away .
The upper layer passes through the library function 、 File system functions, etc , Will eventually be called to tty_read function , Change characters from secondary Take it from the queue .
// tty_io.c
int tty_read(unsigned channel, char * buf, int nr) {
...
GETCH(tty->secondary,c);
...
}
What will you do after taking it , That's what the upper application decides .
If you want to write to the console terminal , Then the upper application will pass through the library function 、 File system functions are called layer by layer , Finally call to tty_write function .
// tty_io.
int tty_write(unsigned channel, char * buf, int nr) {
...
PUTCH(c,tty->write_q);
...
tty->write(tty);
...
}
This function first converts the character c Put in write_q This line , And then call tty It's set in write function .
Terminal console tty We said that before , The initialization of the write The function is con_write, That is to say console Write function of .
// console.c
void con_write(struct tty_struct * tty) {
...
}
Finally, it will cooperate with the graphics card , Output the characters we give on our screen .
Then our picture can be supplemented .
The core point is three queues read_q,secondary as well as write_q.
among read_q After the keyboard presses the key , Enter the keyboard interrupt handler keyboard_interrupt in , Finally through put_queue Put function characters into read_q This line .
secondary yes read_q Unprocessed characters in the queue , adopt copy_to_cooked function , After a certain termios After standard treatment , Put the processed characters into secondary.( After processing, the characters become " Ripe " The characters of , So called cooked, It's not very image ?)
then , Process passing tty_read from secondary Read character inside , adopt tty_write Write characters to write_q, Final write_q Characters in can be passed through con_write This console writes functions , Print characters on the display .
This completes a cycle from keyboard input to display output , That is what this time is about .
Okay , Now we have succeeded in inputting such a string and displaying it back on the display .
[[email protected]] cat info.txt | wc -l
So next ,shell How does the program read this string , How to deal with it after reading it ?
Previous recommendation
read How much disk does a byte of file actually take place on IO?
Docker Why is the container proud ? All supported by mirror image !
Redis What to do when the memory is full ? This is the correct setting !
The original hand of cloud 、 Good hands and bad hands
Share
Point collection
A little bit of praise
Click to see
边栏推荐
- Use of set tag in SQL
- yarn 常用命令
- scratch五彩糖葫芦 电子学会图形化编程scratch等级考试三级真题和答案解析2022年6月
- Transaction rollback exception
- What is the difference between EDI license and ICP business license
- Cheer yourself up
- sql中查询最近一条记录
- 2020-2022两周年创作纪念日
- 《MongoDB入门教程》第04篇 MongoDB客户端
- The new version of effect editor is online! 3D rendering, labeling, and animation, this time an editor is enough
猜你喜欢
Single merchant v4.4 has the same original intention and strength!
Win11如何给应用换图标?Win11给应用换图标的方法
Research and practice of super-resolution technology in the field of real-time audio and video
2020-2022两周年创作纪念日
五种常见的咨询公司谈判策略以及如何维护自己的利益
ES6深入—ES6 Generator 函数
普洛斯数据中心发布DC Brain系统,科技赋能智慧化运营管理
【刷题篇】鹅厂文化衫问题
Parameter type setting error during batch update in project SQL
Oneforall installation and use
随机推荐
Flet教程之 11 Row组件在水平数组中显示其子项的控件 基础入门(教程含源码)
【刷题篇】鹅厂文化衫问题
DeSci:去中心化科学是Web3.0的新趋势?
Practice independent and controllable 3.0 and truly create the open source business of the Chinese people
ES6深入—ES6 Generator 函数
Apple 已弃用 NavigationView,使用 NavigationStack 和 NavigationSplitView 实现 SwiftUI 导航
【漏洞预警】CVE-2022-26134 Confluence 远程代码执行漏洞POC验证与修复过程
面对新的挑战,成为更好的自己--进击的技术er
企业级备份软件Veritas NetBackup(NBU) 8.1.1服务端的安装部署
Parameter type setting error during batch update in project SQL
Apiccloud cloud debugging solution
Record a 'very strange' troubleshooting process of cloud security group rules
The visual experience has been comprehensively upgraded, and Howell group and Intel Evo 3.0 have jointly accelerated the reform of the PC industry
obj解析为集合
漫画:什么是蓝绿部署?
Seaborn draws 11 histograms
详解SQL中Groupings Sets 语句的功能和底层实现逻辑
Batch update in the project
【学术相关】多位博士毕业去了三四流高校,目前惨不忍睹……
Quelques réflexions cognitives