Como uma interrupção é tratada no Linux?

31

Eu só sei que Interrupt é um hardware signal assertion causado em um pino do processador. Mas eu gostaria de saber como o sistema operacional Linux lida com isso.
Quais são as coisas que acontecem quando ocorre uma interrupção?

    
por Sen 13.01.2011 / 14:36

4 respostas

37

Aqui está uma visão de alto nível do processamento de baixo nível. Estou descrevendo uma arquitetura típica simples, arquiteturas reais podem ser mais complexas ou diferentes de formas que não importam neste nível de detalhe.

Quando ocorre uma interrupção , o processador verifica se as interrupções estão mascaradas. Se estiverem, nada acontece até que sejam desmascarados. Quando as interrupções são desmascaradas, se houver alguma interrupção pendente, o processador escolhe uma.

Em seguida, o processador executa a interrupção ramificando-se para um endereço específico na memória. O código nesse endereço é chamado de manipulador de interrupção . Quando o processador ramifica ali, ele mascara as interrupções (então o manipulador de interrupções tem controle exclusivo) e salva o conteúdo de alguns registradores em algum lugar (tipicamente outros registradores).

O manipulador de interrupções faz o que deve fazer, geralmente comunicando-se com o periférico que acionou a interrupção para enviar ou receber dados. Se a interrupção foi gerada pelo cronômetro, o manipulador pode acionar o agendador do sistema operacional para alternar para um segmento diferente. Quando o manipulador termina a execução, ele executa uma instrução especial de retorno-de-interrupção que restaura as interrupções de registros e unmasks salvos.

O manipulador de interrupção deve ser executado rapidamente, porque está impedindo a execução de qualquer outra interrupção. No kernel do Linux, o processamento de interrupções é dividido em duas partes:

  • A “metade superior” é o manipulador de interrupções. Ele faz o mínimo necessário, geralmente se comunica com o hardware e define um sinalizador em algum lugar na memória do kernel.
  • A "metade inferior" faz qualquer outro processamento necessário, por exemplo, copiar dados na memória de processo, atualizar estruturas de dados do kernel, etc. Pode levar tempo e até bloquear a espera de alguma outra parte do sistema, pois é executado com interrupções ativado.

Como de costume neste tópico, para obter mais informações, leia Drivers de dispositivos do Linux ; capítulo 10 é sobre interrupções.

    
por 13.01.2011 / 23:02
19

Gilles já descrito o caso geral de uma interrupção, o seguinte se aplica especificamente ao Linux 2.6 em uma arquitetura Intel (parte disso também é baseada nas especificações da Intel).

Uma interrupção é um evento que altera a sequência de instruções executadas pelo processador.
Existem dois tipos diferentes de interrupções:

  • Interrupção síncrona (Exceção) produzida pela CPU durante o processamento das instruções
  • Interrupção assíncrona (interrupção) emitida por outros dispositivos de hardware

Exceções são causadas por erros de programação (por exemplo, Divide error , Page Fault , Overflow ) que devem ser manipulados pelo kernel. Ele envia um sinal para o programa e tenta se recuperar do erro.

As duas exceções a seguir são classificadas:

  • Exceção detectada pelo processador gerada pela CPU enquanto detecta uma condição anômala; dividido em três grupos: Falhas geralmente podem ser corrigidas, Armadilhas relatam uma execução, Abortos são erros sérios.
  • Exceção programada solicitada pelo programador, tratada como uma armadilha.

Interrupções podem ser emitidas por dispositivos de E / S (teclado, adaptador de rede, ..), temporizadores de intervalo e (em sistemas com multiprocessadores) outras CPUs. Quando uma interrupção ocorre, a CPU deve parar sua instrução atual e executar a interrupção recém-chegada. Ele precisa salvar o antigo estado do processo interrompido para (provavelmente) reiniciá-lo após a interrupção da manipulação.

Lidar com interrupções é uma tarefa delicada:

  • Interrupções podem ocorrer a qualquer momento, o kernel tenta sair do caminho o mais rápido possível
  • Uma interrupção pode ser interrompida por outra interrupção
  • Existem regiões no kernel que não devem ser interrompidas em todos

Dois níveis diferentes de interrupção são definidos:

  • Interrupções mascaráveis emitidas por dispositivos de E / S; pode estar em dois estados, mascarado ou desmascarado. Apenas interrupções não mascaradas estão sendo processadas.
  • Interrupções não mascáveis ; mau funcionamento crítico (por exemplo, falha de hardware); sempre processado pela CPU.

Todo dispositivo de hardware tem sua própria linha de solicitação de interrupção (IRQ). Os IRQs são numerados a partir de 0. Todas as linhas IRQ são conectadas a um Controlador de Interrupção Programável (PIC). O PIC escuta em IRQs e atribui-os à CPU. Também é possível desativar uma linha de IRQ específica.
Os modernos sistemas Linux de multiprocessamento geralmente incluem o mais recente Advanced PIC (APIC), que distribui as solicitações de IRQ entre as CPUs.

O meio-passo entre uma interrupção ou exceção e o manuseio é a Tabela de Descritores de Interrupções (IDT). Esta tabela associa cada vetor de interrupção ou exceção (um número) a um manipulador especificado (por exemplo, Erro de divisão é tratado pela função divide_error() ).

Através do IDT, o kernel sabe exatamente como lidar com a interrupção ou exceção ocorrida.

Então, o que acontece quando ocorre uma interrupção no kernel?

  • A CPU verifica após cada instrução se há um IRQ do (A) PIC
  • Em caso afirmativo, consulta o IDT para mapear o vetor recebido para uma função
  • Verifica se a interrupção foi emitida por uma fonte autorizada
  • Salva os registros do processo interrompido
  • Chame a função de acordo para lidar com a interrupção
  • Carregue os registros recentemente salvos do processo interrompido e tente retomá-lo
por 15.01.2011 / 00:28
6

Em primeiro lugar, os participantes envolvidos no manuseio de interrupções são dispositivos de hardware periféricos, controlador de interrupção, CPU, kernel do sistema operacional e drivers. Dispositivos de hardware periférico são responsáveis pela geração de interrupções. Eles afirmam linhas de solicitação de interrupção quando querem atenção do kernel do sistema operacional. Estes sinais são multiplexados pelo controlador de interrupção, que é responsável pela coleta de sinais de interrupção. Ele também é responsável pela determinação da ordem na qual os sinais de interrupção serão passados para a CPU. O controlador de interrupção é capaz de desabilitar temporariamente a linha de solicitação de interrupção (IRQL) e reativá-la novamente (mascaramento de IRQL). A passagem do controlador de interrupção coletou pedidos de interrupção para a CPU sequencialmente. A CPU após a conclusão da execução de cada CPU de instrução verifica se há alguma solicitação de interrupção de espera do controlador de interrupção. Se a CPU descobrir que existe uma solicitação de espera E o sinalizador Interrupt Enable estiver definido no registro de controle da CPU interno, a CPU iniciará o tratamento da interrupção. Como você pode ver, pela manipulação no sinalizador de interrupção na CPU e comunicação com o controlador de interrupção, o kernel do Linux é capaz de controlar a aceitação de interrupção. Por exemplo, o Linux pode desabilitar a aceitação de interrupções do dispositivo em particular ou desabilitar a aceitação de interrupções.

O que acontece quando o processador recebe uma solicitação de interrupção? Em primeiro lugar, a CPU desabilita automaticamente as interrupções redefinindo o sinalizador de interrupção. Eles serão reativados quando o manuseio da interrupção for concluído. Ao mesmo tempo, a CPU faz uma quantidade mínima de trabalho necessária para trocar a CPU do modo de usuário para o modo kernel, de tal forma que permitirá retomar a execução do código interrompido. A CPU consulta com estruturas especiais de controle da CPU preenchidas pelo kernel Linux para encontrar um endereço de código para o qual o controle será passado. Este endereço é o endereço da primeira instrução do manipulador de interrupções, que faz parte do kernel Linux.

Como primeiro passo da interrupção, o kernel identifica o vetor da interrupção recebida para identificar que tipo de evento aconteceu no sistema. O vetor de interrupção define quais ações o Linux tomará para lidar com isso. Como segundo passo, o Linux salva o resto dos registradores da CPU (que não foram salvos automaticamente pela CPU) e que potencialmente podem ser usados pelo programa interrompido. Esta é uma ação muito importante, porque permite ao Linux lidar com interrupções de forma transparente em relação ao programa interrompido. Como terceiro passo, o Linux realiza a mudança para o modo kernel, definindo o ambiente do kernel e definindo o estado da CPU necessário para ele. E finalmente, o manipulador de interrupção dependente de vetor é chamado. (Você pode procurar na macro BUILD_INTERRUPT3 em arch \ x86 \ kernel \ entry_32.S para pegar os detalhes adicionais para o exemplo relacionado à arquitetura x86) No caso de dispositivos periféricos, essa é uma rotina do_IRQ (). (Olhe para o arch \ x86 \ kernel \ irq.c)

O manipulador de interrupção dependente de vetor geralmente é agrupado por chamadas para irq_enter () e irq_exit (). A área de código encerrada dentro de um par dessas funções, é atômica com relação a qualquer outra dessas áreas e também é atômica com relação a pares de cli / sti. Irq_enter () e irq_exit () também capturam algumas estatísticas relacionadas ao tratamento de interrupção. Finalmente, o kernel procura na tabela vector_irq para encontrar o número irq atribuído ao vetor da interrupção recebida e chamar handle_irq () (do arch \ x86 \ kernel \ irq_32.c).

Neste ponto, a parte comum do tratamento de interrupções no Linux termina, porque o kernel procura a rotina manipuladora de interrupções dependente do dispositivo instalada pelo driver de dispositivo como parte do descritor irq e invoca-a. Se tal manipulador não foi instalado pelo driver, o kernel apenas reconhece a interrupção no controlador de interrupção e vai sair do manipulador de interrupção geral.

Após o término do kernel de tratamento de interrupção, restaura o estado do programa que foi interrompido anteriormente e retoma a execução deste programa.

    
por 13.01.2014 / 15:02
2

Do ponto de vista teórico, quase tudo foi explicado. Mas se você está procurando explicação sobre a estrutura do código de manipulação de interrupção do kernel, o seguinte link deve: Um código anda dentro do tratamento de interrupção do kernel

E se você ainda está buscando teorias sobre interrupções e interrupções de manipuladores, então eu recomendo que você leia isto: Entendendo interrupções e interrupções de manipuladores

    
por 02.10.2013 / 05:55