Wiem tylko, że Interruptjest to hardware signal assertionspowodowane pinem procesora. Ale chciałbym wiedzieć, jak radzi sobie z tym Linux OS.
Co się dzieje, gdy pojawia się przerwanie?
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:
„Górna połowa” to moduł obsługi przerwań. Robi minimum niezbędnego, zwykle komunikuje się ze sprzętem i ustawia flagę gdzieś w pamięci jądra.
„Dolna połowa” wykonuje inne niezbędne przetwarzanie, na przykład kopiuje dane do pamięci procesu, aktualizuje struktury danych jądra itp. Może to zająć trochę czasu, a nawet zablokować oczekiwanie na inną część systemu, ponieważ działa z włączonymi przerwaniami.
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ń:
Synchroniczne przerwanie (wyjątek) generowane przez procesor podczas przetwarzania instrukcji
Przerwanie asynchroniczne (Przerwanie) wydane przez inne urządzenia sprzętowe
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:
Wykryty przez procesor wyjątek generowany przez procesor podczas wykrywania anomalnego stanu; podzielony na trzy grupy: Usterki można zasadniczo naprawić, Pułapki zgłaszają wykonanie, Przerwania są poważnymi błędami.
Zaprogramowany wyjątek zgłoszony przez programistę, traktowany jak pułapka.
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:
Przerwania mogą wystąpić w dowolnym momencie, jądro próbuje usunąć go jak najszybciej
Przerwanie może zostać przerwane przez inne przerwanie
W jądrze znajdują się regiony, których nie wolno w ogóle przerywać
Zdefiniowano dwa różne poziomy przerwań:
Przerywalne generowane przez urządzenia We / Wy; może być w dwóch stanach, maskowany lub zdemaskowany. Przetwarzane są tylko niemaskowane przerwania.
Przerwania niemożliwe do wykonania ; krytyczne awarie (np. awaria sprzętu); zawsze przetwarzane przez CPU.
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?
CPU sprawdza po każdej instrukcji, czy istnieje IRQ z (A) PIC
Jeśli tak, konsultuje IDT w celu mapowania odebranego wektora na funkcję
Sprawdza, czy przerwanie zostało wydane przez autoryzowane źródło
Zapisuje rejestry przerwanego procesu
Wywołaj odpowiednią funkcję, aby obsłużyć przerwanie
Załaduj ostatnio zapisane rejestry przerwanego procesu i spróbuj go wznowić
Czy możesz wyjaśnić „Procesor sprawdza po każdej instrukcji, czy istnieje IRQ z (A) PIC” . Jak to dokładnie się dzieje? Czy ma to związek z VIP-flag w rejestrze flag czy coś takiego ? Z góry
dziękuję
7
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 ...
automat
3
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
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ń.
źródło
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?
źródło
VIP
-flag w rejestrze flag czy coś takiego ? Z góryPrzede 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.
źródło
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ń
źródło