Widziałem w wielu różnych osesach (i niektórych bootloaderach), wszystkie wyłączają przerwanie (cli
), zanim przejdą do trybu chronionego z trybu rzeczywistego. Dlaczego potrzebujemy tego zrobić?Dlaczego przerwań należy wyłączyć przed przełączeniem do trybu chronionego z trybu rzeczywistego?
Odpowiedz
BIOSes używają przerwania PIT (IRQ0) do śledzenia czasu. Po wejściu w tryb chroniony obsługa przerwania w trybie rzeczywistym nie jest już ważna; CPU w trybie chronionym wymaga trybu chronionego IDT (Interrupt Descriptor Table). Po wejściu w tryb chroniony, limit IDT w IDTR (IDT Register) jest ustawiony na 0 (każdy numer przerwania powoduje, że CPU generuje wyjątek), więc gdy tylko PIT (lub cokolwiek innego) wygeneruje przerwanie, CPU wygeneruje wyjątek, który spowoduje wygenerowanie kolejnego wyjątku, wyzwalająC#DF (podwójny błąd) i, w konsekwencji, #TF (potrójny błąd).
Również IRQ0 dzieje się w trybie chronionym spowoduje wyzwolenie #DE (dzielenie wyjątku) ISR (procedura obsługi przerwania), ponieważ wektory przerwań od 0 do 31 są zarezerwowane dla wyjątków w trybie chronionym.
Tak więc (najprawdopodobniej tak samo jak inne przerywania niż PIT) kolejność rzeczy, które się zdarzają jest taka (uwaga: zakłada to, że przerwanie PIT zostanie uruchomione jako pierwsze, ale, jak powiedziałem wcześniej, może zasadniczo każde przerwanie, każde doprowadzi do błędu #DF i potrójnego błędu):
- Bit PE ustawiony jest w CR0.
- Zdarza się przerywanie PIT, PIC (Programmable Interrupt Controller) otrzymuje sygnał na jego pin # 0.
- PIC remapping nie jest ustawiony, więc wyzwala IRQ0 na CPU.
- IRQ0 (= #DE) próbuje wykonać procedurę obsługi przerwań, ale limit IDT wynosi 0, więc (IIRC) #GP (Ogólny błąd ochrony) jest generowany.
- Limit IDT wynosi 0, więc wygenerowano #DF.
- Limit IDT wynosi 0, więC#TF jest generowane.
- Procesor przestaje działać lub uruchamia się ponownie.
Dzięki za wspaniałą odpowiedź! –
IRQ0 nie wyzwoli #DE - spowoduje wyzwolenie #DF, ponieważ domyślnie IRQ0 PIC jest zmapowany do INT 8 przez BIOS. – Ruslan
@Ruslan To brzmi zupełnie arbitralnie. Każdy system BIOS może go zmapować w dowolny sposób. Również tutaj nie jest to całkiem istotne - każdy wektor inny niż #DF lub #TF wyzwoli #DF, #DF wywoła #TF, a #TF, cóż ... po prostu przeskoczy prosto do 7. Btw. co BIOS remapuje do tego konkretnego wektora? Czy masz jakieś odniesienia do tego, czy jest to tylko wartość znaleziona przez eksperymentowanie? – Griwes