Recentemente comecei a aprender sobre sistemas operacionais e o kernel do Linux. Eu estava interessado em terminais, então comecei por lá, no entanto, rapidamente me deparei com um problema. Escrevi uma pergunta um pouco mais longa, porque queria que você visse exatamente onde o problema potencialmente surgiu no meu entendimento e soubesse exatamente o que não está claro para mim. Obrigado antecipadamente :)
Li os seguintes artigos e perguntas/respostas:
No entanto, estou tendo dificuldades para entender exatamente onde a disciplina da linha terminal (tty) está localizada logicamente porque encontrei uma inconsistência (como eu ingenuamente entendi) entre o 1º artigo e a resposta de Stéphane Chazelas.
O TTY desmistificado usa primeiro a seguinte imagem:
Ele diz que o driver TTY é representado por tty_io.c
, enquanto a disciplina de linha padrão é representada por n_tty.c
. Processos (como bash) se comunicam com o driver TTY ( tty_io.c
). Na verdade, na prática, com um arquivo que representa o dispositivo inteiro (driver UART + disciplina de linha + driver TTY). O driver UART é uma classe "serial" de driver que se comunica com a linha física (e terminal adicional) de um lado e a disciplina de linha do outro.
A próxima imagem do The TTY demystified é:
Tudo é o mesmo, exceto que agora temos um emulador e um terminal virtual. A única diferença é que o driver UART não será usado, mas o driver "console".
A última imagem mostra a situação pseudo-terminal. Nesse caso, temos um lado mestre e um lado escravo. O emulador de terminal é "empurrado" para o espaço do usuário. Além disso, temos dois arquivos onde o emulador interage com o arquivo mestre ( /dev/ptmx
), enquanto os processos (shell) interagem com o arquivo escravo ( /dev/pts/..
). Nesse caso, o driver pty é usado e eu diria que logicamente, como nos casos anteriores, está no lugar onde "PTY master side" está escrito na imagem.
Tudo estava funcionando para mim (ou pelo menos acho que estava), e então me deparei com uma resposta de Stéphane Chazelas :
Muita inteligência está na disciplina de linha tty. A disciplina de linha é um módulo de software (residindo no driver, no kernel) empurrado para cima de um dispositivo serial/pty que fica entre esse dispositivo e a linha/fio (o lado mestre para um pty).
De acordo com as imagens, temos um "dispositivo" serial/console/pty representado através do driver no kernel (driver UART na primeira, emulador na segunda e "lado mestre" na terceira imagem) e então disciplina de linha depois (como parte do driver, em cima dele). Entretanto, o próximo componente nas imagens é o driver TTY ( tty_io.c
), não linha/fio como Stéphane Chazelas escreveu... Talvez Stéphane pense no driver TTY quando ele diz "dispositivo serial/pty", mas isso não faz sentido para mim, já que então teríamos, por exemplo, UART (serial) driver <-> line discipline <-> TTY driver/UART (serial) driver
. Adicionalmente, nas imagens, o driver TTY não faz diferença entre eles, é apenastty_io.c
Estou muito confuso. O que estou esquecendo? Onde a disciplina da linha tty está exatamente "logicamente" localizada?
Então, na verdade, o primeiro caso é a configuração completa, e os dois segundos casos virtualizam partes do primeiro caso.
Para os dois segundos casos, pense na UART como o centro das coisas, mas quando ela é virtualizada, ela desaparece e fica de fora do diagrama.
No segundo caso, o terminal de hardware é virtualizado no emulador de terminal com o hardware vga e teclado atuando como o vídeo e teclado de um terminal real. O UART, se fosse representado, estaria entre a disciplina de linha e o emulador de terminal.
No terceiro caso, o vídeo e o teclado também são virtualizados, pelo driver de pseudo terminal com software de nível de usuário (xterm, screen, o que for) virtualizando as mesmas coisas que o driver de console do kernel virtualiza no segundo caso. A UART, se fosse representada, estaria na verdade entre a disciplina de linha e o lado mestre PTY.
Se você aumentasse o detalhe no primeiro diagrama, você realmente descobriria que o primeiro dispositivo dentro do terminal é outro UART, e se você aumentasse ainda mais, você descobriria que cada UART tem um driver de linha entre ele e a linha física. Então a primeira coisa a desaparecer quando o hardware é virtualizado é a conexão (uart<->line driver <->physical line <->line driver <->uart). O driver de linha pode até incluir dois modems com a linha sendo uma linha telefônica.
Cave um pouco mais fundo e você verá que muitos terminais de hardware foram implementados com CPUs 6502. Qualquer coisa mais profunda do que isso pertence a https://retrocomputing.stackexchange.com/
Não vejo nada de errado com a resposta de Stéphane Chazelas. Ele está apenas usando uma perspectiva unilateral, olhando apenas para o que está entre a uart local e o processo do usuário, em vez de todo o caminho. Dessa perspectiva, há pouca diferença entre a UART e a linha serial, está tudo na mesma caixa preta.
Além disso, em um terminal tradicional, você não teria muito de um driver serial no terminal, porque ele não está rodando unix, é um sistema embarcado rodando um programa monolítico sem nenhum driver de software separado. Embora você possa ter duas UARTs, você não tem dois drivers seriais.
Referi-lo como "dispositivo serial/pty" está correto...porque o pty está emulando/virtualizando as partes seriais do hardware. Lembre-se de que quando você virtualiza isso, tudo entre os dois UARTS, incluindo os uarts, evapora.