Odpowiedzi:
Oto ogólny widok przetwarzania niskiego poziomu. Opisuję prostą typową architekturę, prawdziwe architektury mogą być bardziej złożone lub różnić się w sposób, który nie ma znaczenia na tym poziomie szczegółowości.
Gdy wystąpi przerwanie , procesor sprawdza, czy przerwania są maskowane. Jeśli tak, nic się nie dzieje, dopóki nie zostaną zdemaskowane. Gdy przerwania stają się zdemaskowane, jeśli są jakieś przerwania, procesor wybiera jedno z nich.
Następnie procesor wykonuje przerwanie poprzez rozgałęzienie do określonego adresu w pamięci. Kod pod tym adresem jest nazywany modułem obsługi przerwań . Kiedy procesor rozgałęzia się tam, maskuje przerwania (dzięki czemu program obsługi przerwań ma wyłączną kontrolę) i zapisuje zawartość niektórych rejestrów w jednym miejscu (zwykle w innych rejestrach).
Procedura obsługi przerwań robi to, co musi zrobić, zazwyczaj komunikując się z urządzeniem peryferyjnym, które wyzwoliło przerwanie w celu wysyłania lub odbierania danych. Jeśli przerwanie zostało zgłoszone przez licznik czasu, program obsługi może uruchomić harmonogram systemu operacyjnego, aby przejść do innego wątku. Gdy moduł obsługi zakończy wykonywanie, wykonuje specjalną instrukcję powrotu z przerwania, która przywraca zapisane rejestry i odblokowuje przerwania.
Program obsługi przerwań musi działać szybko, ponieważ uniemożliwia uruchomienie innego przerwania. W jądrze Linux przetwarzanie przerwań jest podzielone na dwie części:
Jak zwykle w tym temacie, aby uzyskać więcej informacji, przeczytaj Linux Device Drivers ; rozdział 10 dotyczy przerwań.
Gilles opisał już ogólny przypadek przerwania, poniższe dotyczy konkretnie Linuksa 2.6 w architekturze Intela (część tego jest również oparta na specyfikacjach Intela).
Przerwanie to zdarzenie, które zmienia sekwencję instrukcji wykonywanych przez procesor.
Istnieją dwa różne rodzaje przerwań:
Wyjątki są spowodowane błędami programowania (Fe błędu Divide , Page Fault , przelewowy ), które muszą być obsługiwane przez jądro. Wysyła sygnał do programu i próbuje naprawić błąd.
Zaklasyfikowane są następujące dwa wyjątki:
Przerwania mogą być wydawane przez urządzenia we / wy (klawiatura, karta sieciowa, ..), liczniki czasu i (w systemach wieloprocesorowych) inne procesory. Kiedy wystąpi przerwanie, CPU musi zatrzymać swoją bieżącą instrukcję i wykonać nowo przybyłe przerwanie. Musi zapisać stary przerwany proces, aby (prawdopodobnie) wznowić go po zakończeniu obsługi przerwania.
Obsługa przerwań jest delikatnym zadaniem:
Zdefiniowano dwa różne poziomy przerwań:
Każde urządzenie sprzętowe ma własną linię żądania przerwania (IRQ). Przerwania IRQ są numerowane począwszy od 0. Wszystkie linie przerwań IRQ są podłączone do programowalnego kontrolera przerwań (PIC). PIC nasłuchuje na przerwaniach IRQ i przypisuje je do CPU. Możliwe jest również wyłączenie określonej linii IRQ.
Nowoczesne wieloprocesorowe systemy Linux zazwyczaj obejmują nowszą Advanced PIC (APIC), która rozdziela żądania IRQ równo między procesory.
Pośrednim krokiem między przerwaniem lub wyjątkiem a jego obsługą jest tablica deskryptorów przerwań (IDT). Ta tabela kojarzy każdy wektor przerwania lub wyjątku (liczbę) z określonym modułem obsługi (np. Błąd dzielenia jest obsługiwany przez funkcję divide_error()
).
Za pośrednictwem IDT jądro dokładnie wie, jak obsłużyć przerwanie lub wyjątek.
Co więc robi jądro po wystąpieniu przerwania?
VIP
-flag w rejestrze flag czy coś takiego ? Z góry
Przede wszystkim uczestnicy zaangażowani w obsługę przerwań to urządzenia peryferyjne, kontroler przerwań, procesor, jądro systemu operacyjnego i sterowniki. Urządzenia peryferyjne są odpowiedzialne za generowanie przerwań. Zapewniają wiersze żądania przerwania, gdy chcą uwagi jądra systemu operacyjnego. Sygnały te są multipleksowane przez kontroler przerwań, który jest odpowiedzialny za zbieranie sygnałów przerwań. Odpowiada również za ustalenie kolejności, w której sygnały przerwania będą przekazywane do procesora. Kontroler przerwań może tymczasowo wyłączyć określoną linię żądania przerwania (IRQL) i włączyć ją ponownie (maskowanie IRQL). Kontroler przerwań przekazuje zebrane żądania przerwań do CPU sekwencyjnie. CPU po zakończeniu wykonywania każdej instrukcji CPU sprawdza, czy są jakieś oczekujące żądania przerwania od kontrolera przerwań. Jeśli procesor wykryje, że w wewnętrznym rejestrze sterującym procesora ustawiony jest komunikat Oczekiwanie Oczekiwanie ORAZ flaga aktywacji przerwania, procesor rozpoczyna obsługę przerwań. Jak widać, manipulując flagą Przerwania w CPU i komunikacją z kontrolerem przerwań, jądro Linuksa jest w stanie kontrolować akceptację przerwań. Na przykład Linux może wyłączyć akceptację przerwań z określonego urządzenia lub w ogóle wyłączyć akceptację przerwań. Jądro Linux jest w stanie kontrolować akceptację przerwań. Na przykład Linux może wyłączyć akceptację przerwań z określonego urządzenia lub w ogóle wyłączyć akceptację przerwań. Jądro Linux jest w stanie kontrolować akceptację przerwań. Na przykład Linux może wyłączyć akceptację przerwań z określonego urządzenia lub w ogóle wyłączyć akceptację przerwań.
Co się stanie, gdy procesor otrzyma żądanie przerwania? Po pierwsze, procesor automatycznie wyłącza przerwania poprzez zresetowanie flagi przerwania. Zostaną one ponownie włączone po zakończeniu obsługi przerwań. Jednocześnie procesor wykonuje minimalną ilość pracy potrzebnej do przełączenia procesora z trybu użytkownika na tryb jądra w taki sposób, aby umożliwić mu wznowienie wykonywania przerwanego kodu. CPU konsultuje się ze specjalnymi strukturami sterującymi CPU wypełnionymi przez jądro Linuksa, aby znaleźć adres kodu, na który zostanie przekazana kontrola. Ten adres jest adresem pierwszej instrukcji obsługi przerwań, która jest częścią jądra Linux.
W pierwszym etapie obsługi przerwań jądro identyfikuje wektor otrzymanego przerwania, aby określić, jakie zdarzenie miało miejsce w systemie. Wektor przerwania określa, jakie działania podejmie Linux, aby go obsłużyć. W drugim kroku Linux zapisuje resztę rejestrów procesora (które nie zostały automatycznie zapisane przez CPU) i które potencjalnie mogą być wykorzystane przez przerwany program. Jest to bardzo ważne działanie, ponieważ pozwala Linuksowi na obsługę przerwań w sposób przejrzysty w odniesieniu do przerwanego programu. W trzecim kroku Linux dokonuje przejścia do trybu jądra, ustawiając środowisko jądra i ustawiając wymagany dla niego stan procesora. Na koniec wywoływana jest funkcja obsługi przerwań zależna od wektora. (Możesz spojrzeć na makro BUILD_INTERRUPT3 w arch \ x86 \ kernel \ entry_32. S, aby pobrać dodatkowe szczegóły dla przykładu związanego z architekturą x86). W przypadku urządzeń peryferyjnych jest to procedura do_IRQ (). (Zajrzyj do arch \ x86 \ kernel \ irq.c)
Zależny od wektora moduł obsługi przerwań zwykle jest zawijany przez wywołania irq_enter () i irq_exit (). Obszar kodu zamknięty w parze tych funkcji jest atomowy w odniesieniu do wszelkich innych takich obszarów, a także jest atomowy w odniesieniu do par cli / sti. Irq_enter () i irq_exit () również przechwytują niektóre statystyki związane z obsługą przerwań. Na koniec jądro sprawdza tablicę vector_irq w celu znalezienia numeru irq przypisanego do wektora otrzymanego przerwania i wywołania metody handle_irq () (z arch \ x86 \ kernel \ irq_32.c).
W tym momencie wspólna część obsługi przerwań w Linuksie kończy się, ponieważ jądro wygląda na zależną od urządzenia procedurę obsługi przerwań zainstalowaną przez sterownik urządzenia jako część deskryptora irq i wywołuje ją. Jeśli taki moduł obsługi nie został zainstalowany przez sterownik, jądro po prostu potwierdza przerwanie na kontrolerze przerwań i przechodzi do wyjścia z ogólnego modułu obsługi przerwań.
Po zakończeniu obsługi przerwania jądro przywraca wcześniej przerwany program i wznawia wykonywanie programu.
CPU consults with special CPU control structures filled by Linux kernel to find an address of code to which control will be passed.
Tak! Zastanawiam się, jakie są te specjalne struktury kontrolne ...
Z teoretycznego punktu widzenia prawie wszystko zostało wyjaśnione. Ale jeśli szukasz wyjaśnienia na temat struktury kodu obsługi przerwań jądra, skorzystaj z poniższego linku: Wejdź do kodu obsługi przerwań jądra
A jeśli nadal zastanawiasz się nad teorią przerwań i programów obsługi przerwań, to polecam przeczytanie tego: Zrozumienie przerwań i programów obsługi przerwań