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.