[OSDev] Multitasking + interrupt

0

Witam [!!!]

Pojawił sie problem z przerwaniami w multitaskingu. Znaczy przechwyciłem przerwanie o numerze x i przypisałem do niej jakąś procke ktora wyświetla tekst na monitorze "Dziala!!!!!".
Gdy zrobie "int x" to wyświetla sie ten tekst. Problem pojawia się właśnie w mutitaskingu, uruchamiam w nim <ort>na razie </ort>jedną procedure(wykonuje się jako kod systemowy) która ma poczekać aż użytkownik wciśnie klawisz a nastepnie wywołać przerwanie x. Niestety pojawia mi się wyjątek 13(przy int'cie), mam też problemy z przełączaniem na tryb rzeczywisty w multitaskingu(bez multitaskingu wszystko działa). Czy ja gdzieś zrobiłem błąd w kodzie? Czy może jest jakieś zabezpieczenie przy multitaskingu?

0

No skoro masz wyjątek to na pewno popełniłeś błąd i na pewno jest jakieś zabezpieczenie o którym nie wiesz.
Jak byś mógł dokładnie opisać/podać jak wygląda deskryptor przerwania.
No i w jakim języku to piszesz ?

0

Pisze w C(DJGPP) i asm(nasm).
na razie dokładnie nie opisze bo nie mam projektu pod ręką.
Mianowicie problem z trybem wirtualnym już troszkę rozwiązałem bo nie dokońca umiem przełączać na tryb rmode. Przełączyłem poziom(DPL) na 0 i już udał mi się skok do kodu 16-bitowego, ale jeszcze nie wszystko działa(teraz tak zauważyłem że trzeba chyba flagi przestawić w tss).
Z trybem wirtualnym bawie się od niedawna i troszke to dla mnie magia ;]

Robiłem tak(bez tss):

  1. Skok(jmp numer_gdt*8:0x7C0C i tu chyba powinno byc iret zamiast jmp) do kodu o adresie 0x7C0C (16-bit).
  2. Wyłączenie trybu chronionego.
  3. Skok do poprawnego kodu 16-bitowego(jmp 0:etykieta).
  4. Załadowanie starej tablicy przerwań(idt - przy starcie bootloadera zapisuje sobie(sidt))
  5. Wywołanie danego przerwania.
  6. Załadowanie "nowej" tablicy przerwań(ta co w systemie sobie ustawiłem).
  7. Uruchomienie trybu chronionego
  8. Skok(jmp numer_gdt*8:0x7CXX) do kodu 32-bitowego(tego ponizej 1MB - 0x7CXX)
  9. Powrót do kodu systemowego(robie to instrukcją ret - przed 1 punktem zapisuje na stos adres "powrotu" tak jakbym zamiast jmp robił call)

W bootloaderze zrobiłem coś takiego:

[ORG 0x7C00]
[BITS 16]
jmp start				;przy ładowaniu systemu skacze do kodu bootloadera
	reg_ax:		dw 0	;wartosci ustawiam sobie przed skokem
	reg_bx:		dw 0	;a po skoku w kodzie sobie wszystko ustawiam
	reg_cx:		dw 0	;narazie to jest zrobione eksperymentalnie
	reg_dx:		dw 0
	reg_int:		db 0
;i tu dalszy kod

Oczywiście numer_gdt (na razie wynosi nr. 3) ma ustawione że kod jest 16-bitowy.
(Ale dlaczego w trybie 16-bitowym moge używać eax itp :> )

Powyższy sposób sam ort! mając wiedze z plotek. Męczyłem się z tym kilka dni.
Na forum pewnym(ang) przeczytałem że trzeba jeszcze ustawić z flagami i użyć iret(który ma możliwość modyfikowania flagi), bo przyznam że mój sposób troszke przycina :-)

Co do przerwań nadal nie działa nawet z poziomem 0(czyli systemowym).
ort! miałem ustawiony poziom 3(czyli najniższy), gdy teraz mam 0 ustawiłem cs, es, ds itp takie jak są w systemie. Wątki dobrze działają, przełączanie też. Zrobione jest także ort!.
Każdy "wątek" ma zadeklarowane 2 tablice ldt. Jedna jest na kod druga na dane.
Pewnie błąd tkwi gdzieś przy tych DPL, flagach lub... sam nie wiem ;]

0
  1. Skok(jmp numer_gdt*8:0x7C0C i tu chyba powinno być iret zamiast jmp) do kodu o adresie 0x7C0C (16-bit).
    ...
    Oczywiście numer_gdt (na razie wynosi nr. 3) ma ustawione że kod jest 16-bitowy.

Tu numer_gdt jest inny(nr 1) który ma ustawione że kod jest 32-bitowy.

  1. Skok(jmp numer_gdt*8:0x7CXX) do kodu 32-bitowego(tego ponizej 1MB - 0x7CXX)

Bardzo przepraszam za orty [wstyd]

1 użytkowników online, w tym zalogowanych: 0, gości: 1