Sobre a operação de um PC usando o exemplo do Windows 10 e o teclado, parte 1

imagem

Meu nome é Andrey Artemyev, trabalho na Microsoft no núcleo do Windows 10, trabalhei anteriormente no Windows 10x (WCOS), XBox, Windows Phone e Microsoft Edge. Eu quero que, popularmente, para fins educacionais, conte sobre como o computador funciona no exemplo de entrada de teclado e Windows 10. Esta série de artigos foi projetada principalmente para estudantes de especialidades técnicas. Vamos considerar qual caminho as informações sobre a tecla pressionada vão exibir no Notepad.exe. Devido à vastidão e interdisciplinaridade do tópico, pode haver imprecisões nos artigos, que são relatados nos comentários. Algumas informações podem estar desatualizadas devido à velocidade com que o Windows está se desenvolvendo.

Quão profundo mergulhamos no tópico?


Vamos primeiro falar sobre os níveis em que um computador pode ser considerado. Cada nível é baseado no anterior. Vamos começar do topo.

Nível de aplicação . Todos os aplicativos de usuário estão localizados aqui, este é um navegador, Microsoft Office, bloco de notas, bem como o servidor Web IIS, SQL Server, vários middlewares como Java e .Net e todas as linguagens de script, sejam Ruby, PHP ou Bat-files.

Nível do sistema operacional . O SO pode ser considerado como:

  • Gerenciador de recursos - memória, discos rígidos, impressoras, tela, teclado, recursos limitados que são compartilhados por programas em execução no computador.
  • Máquina virtual - um arquivo é um bom exemplo de um objeto virtual. Representa uma abstração de dados no disco, uma API para trabalhar com ele e também adiciona o conceito de direitos de acesso. Em vez de um arquivo, poderia haver o conceito de um contêiner de dados e uma API completamente diferente. Existem muitos desses objetos virtuais no sistema operacional.
  • Platform - OS fornece modelos de software e primitivas para a criação de programas. Por exemplo, a Estrutura de Drivers do Windows permite que você desenvolva drivers rapidamente; janelas no Windows são usadas para criar interfaces de usuário complexas. Dll - fornece um modelo para expandir a funcionalidade do programa através de plug-ins, bem como um mecanismo para implementar o leitor de tela através de traps de teclado (consulte gancho LowLevelKeyboard).
O sistema operacional é dividido em camadas e componentes. Em geral, a arquitetura do Windows 10 se parece com isso. Falaremos sobre isso em detalhes um pouco mais tarde.

imagem

Nível de arquitetura do computador . É representada por uma placa-mãe, que possui um fator de forma específico, funções internas codificadas em microcircuitos chamados chipset e portas através das quais é possível expandir a funcionalidade de um computador conectando uma placa gráfica, placa de rede, memória RAM adicional, discos rígidos, teclado, etc. As portas afetam a velocidade e os recursos do computador, que determinará sua finalidade, seja um servidor para processar milhares de solicitações por segundo, um tablet para usar a Internet ou um PC para jogos com vários vídeos arty. O SO abstrai os recursos da placa-mãe.

Os microcircuitos se parecem com a figura abaixo e são um minicomputador que executa programas simples para tarefas de baixo nível, por exemplo, lê dados do teclado e os transfere ainda mais para alcançar o processador. Como regra, eles são implementados como um microcircuito analógico não programável ou microcontrolador programável em C.

imagem


A placa-mãe pode ser considerada uma colônia de microcircuitos que se comunicam através de barramentos e através deles os dados dos dispositivos conectados ao processador e vice-versa circulam. O chipset é um tipo de sistema nervoso do computador. Todos os chips da placa-mãe foram criados originalmente para funcionar entre si. Alguns deles podem ter funções especiais, por exemplo, um timer ou armazenamento das configurações do BIOS. Talvez o mais importante deles seja o que possui um programa interno (firmware, BIOS, UEFI) que começa a funcionar assim que a eletricidade aparece. Ela encontra o disco rígido com o carregador de inicialização do Windows e transfere o controle para ele, que por sua vez inicia o arquivo executável do SO, que pode ser chamado de Windows10.exe, na verdade NtOsKrnl.exe. O BIOS sabe o que procurar graças a um acordo entre fabricantes de hardware e sistemas operacionais.

Em torno da placa-mãe, você pode montar um telefone celular, console de jogos, estação de servidor ou dispositivo inteligente. Na figura abaixo, os fatores de forma comuns das placas-mãe.

imagem

O nível da microarquitetura é representado pelo processador (CPU), este é o coração da placa-mãe e todo o conjunto de chips é necessário para atender à CPU. Um processador é um computador em um computador, um microcontrolador mais poderoso e avançado que não precisa de firmware, porque o fluxo de comandos é enviado instantaneamente quando o agendador de threads altera o contexto do processador. A funcionalidade do processador é dividida em subsistemas, por exemplo, um componente envolvido em operações matemáticas e lógicas, um coprocessador matemático e um cache. Alguns deles costumavam ser um chip separado na placa-mãe, mas agora fazem parte da CPU, por exemplo, um controlador de interrupção e um chip chamado North Bridge, que aumentam a velocidade do trabalho.

Microarquitetura não é o mesmo que arquitetura . Toda a funcionalidade da CPU é dividida em componentes que trabalham juntos. Esses componentes e sua interação são microarquitetura. No fluxograma abaixo, eles são representados por retângulos e quadrados coloridos.

imagemimagem

A arquitetura do processador é essencialmente um documento que descreve qual funcionalidade ele deve ter para corresponder, por exemplo, à arquitetura x86, x64 ou ARM usada em dispositivos móveis. Este documento descreve quais comandos, atribuições de registro e lógica de operação devem ser suportados. Os criadores dos processadores Intel, AMD, Elbrus podem implementar essa funcionalidade como quiserem e adicionar novos recursos na forma de comandos, registros, sinalizadores, interrupções e, se o sistema operacional souber sobre eles, poderá usá-lo. Em termos de POO, a arquitetura da CPU é a interface e a microarquitetura é sua implementação.

Circuitos lógicos . Retângulos coloridos do diagrama de blocos da CPU consistem em circuitos lógicos que executam suas operações em seqüências de zeros e uns. O processador vê todos os dados e instruções na forma de bits (0 e 1), de acordo com a fórmula, qualquer número decimal pode ser representado como uma sequência de 0 e 1, mas o que significa um número específico depende do contexto. Pode ser um código, número, letra. A unidade aritmética e lógica (ALU) pode adicionar dois números através de operações bit a bit. Os algoritmos bit a bit de adição, subtração, multiplicação e divisão são conhecidos há muito tempo; os desenvolvedores do circuito lógico precisam apenas implementá-los efetivamente.

imagem

Os circuitos digitais trabalham com dados no nível de zeros e uns, enquanto os circuitos analógicos dependem da exploração das leis da física. Eles executam manipulações de bits simples, como turnos, AND, OR, XOR. Através dessas primitivas, operações mais complexas são implementadas. A figura abaixo mostra o operador AND analógico implementado através de transistores. Na saída do circuito, uma tensão diferente de zero só existirá se estiver nos dois contatos de entrada (Bx1 e Bx2), caso contrário, zero volt. O operador && em C # funciona da mesma maneira. Os circuitos digitais são baseados em analógico. Elementos fisicamente lógicos em circuitos lógicos podem ser implementados não apenas de maneira eletrônica, mas também mecânica, hidráulica, óptica e outras.

imagem

O nível de radioelementos . Os circuitos fisicamente analógicos dependem de elementos de rádio que realmente exploram as leis da física. Principalmente estes são semicondutores, ou seja, sob certas condições, eles podem conduzir eletricidade, mas não podem. O diodo conduz a corrente em apenas uma direção, se não for soldada, girada 180 e soldada de volta, a corrente não passará por ela. O transistor passa corrente somente se houver tensão na perna de controle. A humanidade aprendeu a tornar os transistores microscópicos e, portanto, eles podem ser colocados em uma pequena placa aos milhões. Nas figuras abaixo, elementos de rádio semicondutores e um transistor convencional ao lado de um nano transistor sob um microscópio eletrônico.
imagem

imagem
O nível das leis da física . E, finalmente, o nível mais baixo é o nível das leis da física que estão incluídas nos radioelementos semicondutores.

imagem

Falaremos muito sobre o nível do sistema operacional e um pouco menos sobre arquitetura de computadores, microarquitetura, circuitos analógicos e elementos de rádio. Para a última parte, você deve entender como tudo isso funciona em conjunto.

Noções básicas do sistema operacional


Quando fomos para a linguagem assembly na universidade, muitos estudantes ficaram aborrecidos com palavras inteligentes como “modos de kernel e usuário”, sob as quais o sistema de autenticação de funções realmente conhecido está oculto em todos, em todos os sites há pelo menos um “Admin” com acesso a todas as páginas e o "Usuário" têm acesso limitado. Da mesma forma, a função "Núcleo" tem acesso a todos os recursos da CPU, e a função "Usuário" pode não causar todos os comandos do processador e nem todos os argumentos. Além desse modelo, o sistema operacional é construído com base no princípio da arquitetura cliente-servidor, em que o servidor é o núcleo que implementa a funcionalidade do SO e o cliente são programas de usuário. No mundo da Web, o cliente e o servidor estão fisicamente separados - são dois computadores diferentes que se comunicam pela rede. No sistema operacional, o cliente e o servidor vivem na mesma máquina e no mesmo hardware. O servidor possui uma certa API que permite que os clientes alterem seu estado, por exemplo, a API do Twitter permite criar postagens, fazer login e fazer upload de um feed de tweets para um cliente móvel. O Windows possui uma API Win, que é apenas mais complicada devido a uma gama mais ampla de tarefas; hoje, o Windows possui aproximadamente 330.000 APIs mais uma API para aplicativos UWP. Se os conceitos do Twitter são mais ou menos claros para todos - postar, usuário, feed -, os conceitos do sistema operacional podem exigir algum aprofundamento. Portanto, pode ser difícil entender as APIs do Windows sem entender a estrutura interna do sistema operacional.

Na verdade, o kernel significa três coisas diferentes. O kernel é como todo código do SO. O kernel como um subsistema responsável pelos mecanismos do SO, como o agendador de threads, alternância de contexto, manipulação de interrupção, troca de memória virtual para física (Kernel) e o subsistema do kernel para suportar outros sistemas operacionais - CSRSS.exe (Windows), PSXSS.exe (POSIX), OS2SS.exe (OS / 2) ou WSL (Windows Subsystem para Linux). Nesse contexto, o primeiro significado é entendido - todo o código do SO.

Quando uma janela aparece na tela, uma estrutura de dados aparece na parte do servidor do SO (modo kernel) que descreve essa janela - sua posição na tela, tamanho, texto do título, função da janela através da qual o SO permite que o aplicativo responda a eventos. Como existem muitos subsistemas no sistema operacional, pode haver várias estruturas de dados que descrevem um objeto, por exemplo, informações sobre o processo do usuário estão nos componentes:

  • Executivo - aqui está a lógica do sistema operacional. Essa camada verifica quais processos podem ou não fazer. Este arquivo contém informações sobre o processo pai, parâmetros de início do processo (Bloco do ambiente do processo), a conta de usuário associada, o nome do arquivo exe do processo.
  • Mecanismos de Kernel - OS, como um agendador de threads, são implementados aqui. Ele armazena quanto tempo o processo gasta no modo de usuário e kernel, ao qual processadores seus threads estão conectados, a prioridade básica dos threads do processo.
  • Subsistema de janelas - informações sobre objetos GDI usados ​​para desenhar na janela. Estes são primitivos, como pincéis, caneta, etc.
  • DirectX - tudo relacionado ao DirectX: shaders, superfícies, objetos DX, contadores de desempenho da GPU, configurações de memória para memória gráfica.
  • O subsistema Windows representado pelo processo CSRSS.exe ( subsistema de tempo de execução do servidor do cliente). O Windows suportava anteriormente o OS POSIX (processo PSXSS.exe) e OS / 2 (OS2SS.exe). Naqueles dias, surgiu a idéia de tornar o Windows o mesmo subsistema, mas isso era lento e logo parte do CSRSS.exe foi transferida para o win32k.sys, que agora está dividido em vários arquivos - win32k.sys, win32kbase.sys e win32kfull.sys. Informações sobre dados do grupo de processos, nível de desligamento, dados da sessão etc. são armazenadas aqui.

O suporte ao POSIX e OS / 2 era mais formal, porque, para transferir o programa desses sistemas operacionais, era necessário encontrar o código-fonte e recompilá-lo de uma maneira especial para obter um arquivo exe no qual todas as chamadas à API do sistema operacional eram redirecionadas para o PSXdll.dll (NETAPI.DLL e DOSCALLS.DLL para aplicativos OS / 2 e User32.dll para Windows), que era um invólucro fino sobre a API do Windows. O estado de algumas APIs foi armazenado no processo do subsistema PSXSS.exe (OS2SS.exe). Como nem todas as APIs podem ser mapeadas para 1 para 1, esse programa funcionou de maneira instável. O suporte ao Linux foi adicionado no Windows 10 e funciona de uma maneira completamente diferente. O subsistema Linux está hospedado no modo kernel e a diferença entre o Windows Subsystem para Linux e Linux é aproximadamente a mesma que entre diferentes construções. Especialmente para a WSL, um novo tipo de processo foi introduzido - processo PICO.

O que é um componente? Essa é uma funcionalidade agrupada logicamente. Um componente pode ser chamado de classe OOP, DLL, pasta, conjunto de funções com um prefixo comum, espaço para nome, camada na arquitetura.

Mais sobre particionamento cliente-servidor


A separação do cliente e do servidor é implementada usando a funcionalidade interna da CPU, compartilhamento de memória e verificações de software.

Os fabricantes de equipamentos colaboram com os desenvolvedores do sistema operacional; portanto, o processador possui mecanismos criados levando em consideração as necessidades dos criadores de sistemas operacionais. Em todos os processadores modernos, o mecanismo de função do usuário é implementado, onde o usuário é entendido como o código executável no momento. Em aplicativos da Web, a função do usuário conectado é armazenada em uma variável e, além do nome amigável Admin ou Usuário, possui um ID dessa função, que é frequentemente usada durante a autorização, porque comparar números é mais rápido e fácil do que seqüências de caracteres. No processador, a função do usuário atual é armazenada em um campo chamado “Anel de segurança”, não “CurrentUser.Role.Id”. Na maioria dos processadores, esse campo aceita quatro valores de 0 a 3. O Windows usa 0 para a função chamada "Modo Kernel", porque é o modo mais privilegiado e o maior valor para a função é "Modo Usuário", porque é a função mais limitada. As funções restantes não são usadas porque a diferença entre 0 e 1, 2 e 3 é insignificante. Essas funções limitam as páginas da memória que podem ser endereçadas, você não pode chamar algumas instruções ou não pode chamá-las com certos argumentos. Também há restrições no uso da tecnologia de portas de E / S para a troca de dados com dispositivos como um teclado, mas ela não é usada há 10 anos. A mudança para o modo kernel ocorre através do comando syscall, que pelo índice encontra a função a ser chamada na matriz de ponteiros para as APIs do Windows. Um ponteiro para esta matriz é armazenado em um registro especial do processador durante a inicialização do SO.

Eu chamei especificamente a CPU registrar um campo. Ao escrever um programa em C #, você pode adicionar quantos campos quiser à sua classe e dar nomes amigáveis. Para processadores e microcontroladores, os campos são chamados de registradores. Ao projetar um pedaço de ferro, você já precisa entender, nesta fase, quantos registros (campos) você precisa, qual o tamanho que eles devem ter e que funcionalidade atribuir a eles, para que isso seja suficiente em todas as ocasiões para todas as situações imagináveis ​​e inconcebíveis. Imagine que você precise escrever um programa em uma linguagem de programação semelhante a C #, com 16 campos predefinidos na classe e não possa usar variáveis ​​locais. I.e. o mesmo campo pode ser usado para armazenar o usuário conectado, a matriz classificada, os dados temporários ou o resultado do método. Os nomes desses campos devem ser os mais comuns possíveis, em vez de tempData, funcResult, haverá nomes estranhos EAX, AH, AL, DX, etc. Se você escreveu um emulador do processador na arquitetura x86 em C #, o código pode se parecer com isso (DIV - divide, comando divisão inteira):

imagem

Para ilustrar, eu adicionei uma verificação do modo do kernel. Se ocorrer um erro de divisão por zero, o processador notifica o sistema operacional através de uma interrupção (lança um evento). No momento da inicialização, o sistema operacional fornece ao processador uma matriz unidimensional de ponteiros para uma função chamada vetor de interrupção, em que cada índice corresponde a algum tipo de evento, por exemplo, divisão por zero. O sistema operacional conhece a arquitetura do processador em que está sendo executado e pode organizar indicadores de função em uma matriz. A CPU chama essa função e o sistema operacional tem seu próprio código. Por exemplo, o Windows verifica no registro se um depurador está instalado e exibe uma mensagem informando que ocorreu um erro e é possível executar um depurador para verificar o local em que ocorreu. Uma interrupção é chamada de interrupção porque interfere no curso normal da execução do programa e possibilita a execução do manipulador de interrupções e somente após sua conclusão o processador pode retornar à execução do programa.

As interrupções podem ser geradas não apenas pelo processador, mas também por dispositivos externos (teclado, mouse) ou código de programa. O agendador de encadeamentos define um cronômetro que, a intervalos de um quantum (por padrão, cerca de 15ms no Windows Server mais) gera uma interrupção para atribuir outro encadeamento a ser executado pelo algoritmo interno. A execução passo a passo do programa no Visual Studio também conta com o mecanismo de interrupção - o sinalizador é definido no processador, que, após cada comando, causa uma interrupção que é processada pelo mecanismo de depuração do Windows e notificada por meio da API do Visual Studio.

O compartilhamento de memória é implementado graças à memória virtual. Eu disse anteriormente que o sistema operacional é um gerenciador de recursos e uma máquina virtual. Mesmo que você tenha 1 GB de RAM, o Windows 32 bits funcionará como se você tivesse 4 GB de RAM, ou seja, você realmente tem 1 GB e praticamente 4 GB. Os computadores modernos são baseados no modelo teórico de uma máquina de Turing ou na arquitetura de von Neumann (com algumas modificações). De acordo com esses modelos, a memória no computador é uma fita composta por células do tamanho de um byte. Essas células são agrupadas em páginas, geralmente 4096 bytes (4Kb), porque:

  • . . CPU , . , , , , . .
  • , . RAM 4. RAM , .
  • , ( new ++) / . Exe- , c . .
  • Simulação de uso exclusivo de RAM por cada processo. Quando o agendador de encadeamentos agenda um encadeamento para execução, ele carrega informações no mapeamento das páginas virtuais do processo em páginas físicas nos registros do processador e quando o código do encadeamento tenta ler / gravar algum endereço, o processador o traduz corretamente. Além dos processos, as emulações contam com o uso exclusivo da RAM para contar com sessões que contêm código e dados específicos de um usuário individual, como uma fila de mensagens global. O Windows 10 possui um contexto de thread, processo e sessão.

O Windows 10 usa células no início da fita para espaço do usuário e no final para si (espaço no modo kernel), no qual os objetos que descrevem o estado do sistema são armazenados.
imagemimagem
Um endereço de 64 bits permite endereçar 16 exabytes, que são 18.446.744.073.709.551.616 células de memória. Os processadores modernos ainda não suportam tanta RAM e, portanto, usam apenas os 48 bits inferiores do endereço, os 16 restantes são preenchidos com alta ordem. Portanto, o Win x64 simplesmente não usa parte dos endereços marcados em preto na figura acima. Mas isso não significa que o Windows de 64 bits "veja" 256 TB de RAM. Máximo de 8 TB de memória virtual na arquitetura IA64 e 7 TB em x64. O limite de memória física suportada pelo Windows 10 é de 2 TB, porque com um grande número de Windows não foi testado. A quantidade de RAM suportada no Windows 10 é amplamente determinada pela edição do sistema operacional, quanto mais caro, mais.

(HEX) , ? , . , — . CPU — CPU . HEX . , 32 ( 64) . — , HEX , .

O método do software de dividir em um cliente-servidor (modo kernel-usuário) é muito mais chato do que os mecanismos acima. Processos e threads podem ser marcados com atributos especiais, ou podemos armazenar uma lista de ponteiros para threads / processos e verificá-los no código. Se você já fez uma autorização em um aplicativo Web, entendeu bem do que estou falando.

Do que o Windows é composto?


Há abstração ou divisão em componentes em todas as áreas da programação e é intuitivamente claro que o Windows também está dividido em alguns componentes. Um componente refere-se a alguma unidade de funcionalidade - classe OOP, arquivo, DLL, pasta. Os componentes no diagrama abaixo podem ser arquivos * .sys, * .dll individuais ou apenas um conjunto de APIs agrupadas logicamente, adicionando um prefixo ao nome da função, a parte antiga do sistema é escrita em C e não suporta classes. Novas peças são frequentemente escritas em C ++. Em uma exibição ampliada, o Windows fica assim:

imagem

Vamos analisar rapidamente seus componentes de baixo para cima:

  • Hyper-V Hypervisor — Windows . , Hyper-V , , .
  • HAL.dll — Hardware Abtraction Layer — — , , — Windows HAL.dll, . , , . , - ACPI.sys.

    Advanced Configuration and Power Interface? 1996 UI, .
    imagem

    1996 ACPI, , .. . ACPI , CD drive, .. .
  • Device Drivers — . *.sys, , . Process Explorer SysInternals .
  • KernelKernel Mode Execution Environment , , , , . .
  • Executive — , - .
  • Windowing & Graphics — DirectX .
  • NtDll.dll — . dll , ( .. dll) . Nt Native, Native American. I.e. API , . dll Nt (NtDestroyMenu). Win API User32.dll. NtDll.dll, Nt* (level of indirection) — subsystem dll User32.dll PSXdll.dll DOSCALLS.DLL Windows. NtDll.dll ( S ession M anagement S ub S ystem .exe , Win dows Init itialize .exe .), .
  • SubSystem dlls — . Windows User32.dll. - API , Nt* NtDll.dll, CreateFile NtCreateFile).
  • Environment Subsystems — CSRSS.exe, Windows. POSIX ( PSXSS.exe) OS/2 (OS2SS.exe). Windows Subsystem for Linux -.
  • System Processes — , LSASS.exe (Local Security Authority SubSystem) .
  • Processos de serviço - Anteriormente, os serviços do Windows (como o Plug and Play Manager) trabalham em seus processos e eram arquivos * .exe. Com o tempo, apareceu o processo SvcHost.exe, que pode hospedar vários componentes implementados como arquivos * .dll de uma só vez. Portanto, quase todos os componentes do sistema foram movidos para o SvcHosts.
  • Processos do usuário - processos do usuário. Os mesmos que usam todos os dias - navegadores, jogos, programas de escritório etc. Eles contaminam com infraestrutura instalada nos modelos anteriores.

Nisto terminarei a primeira parte. No próximo, vamos ver onde o caminho da chave começa.

Source: https://habr.com/ru/post/pt483330/


All Articles