Vel, etter en liten parentes fortsetter vi med vår opplæringsserie. Hvis vi går tilbake til forrige kode, må vi ha ISR for divisjonen med null. Nå må vi fylle ut resten av ISR-ene som vi hadde postet en melding for (de første 32). Vel, nå skal vi fortsette å programmere forstyrrelser, vi skal gjøre IRQ-ene også kjent som Avbryter forespørsler. Disse IRQ-ene genereres av maskinvareenheter som tastaturer, mus, skrivere, etc. Opprinnelig blir de første 8 IRQ-ene automatisk kartlagt til IDT-posisjonene 8 til 15. Siden vi har brukt de første 32 for unntak, må vi kartlegge dem på nytt. Vi vil sette IRQ fra 32 til 45. For dette må vi først kartlegge IRQene:
void ND::IRQ::Remap(int pic1, int pic2)
{
#define PIC1 0x20
#define PIC2 0xA0
#define ICW1 0x11
#define ICW4 0x01
/* send ICW1 */
ND::Ports::OutputB(PIC1, ICW1);
ND::Ports::OutputB(PIC2, ICW1);
/* send ICW2 */
ND::Ports::OutputB(PIC1 + 1, pic1); /* remap */
ND::Ports::OutputB(PIC2 + 1, pic2); /* pics */
/* send ICW3 */
ND::Ports::OutputB(PIC1 + 1, 4); /* IRQ2 -> connection to slave */
ND::Ports::OutputB(PIC2 + 1, 2);
/* send ICW4 */
ND::Ports::OutputB(PIC1 + 1, ICW4);
ND::Ports::OutputB(PIC2 + 1, ICW4);
/* disable all IRQs */
ND::Ports::OutputB(PIC1 + 1, 0xFF);
}
Nå oppretter vi en funksjon for å installere IRQ-ene:
void ND::IRQ::Install()
{
ND::Screen::SetColor(ND_SIDE_FOREGROUND,ND_COLOR_BLACK);
ND::Screen::PutString("\nInstalling IRQ...");
ND::IRQ::Remap(0x20,0x28);
ND::IDT::SetGate(32,(unsigned)ND::IRQ::IRQ1,0x08,0x8E);
ND::IDT::SetGate(33,(unsigned)ND::IRQ::IRQ2,0x08,0x8E);
ND::IDT::SetGate(34,(unsigned)ND::IRQ::IRQ3,0x08,0x8E);
ND::IDT::SetGate(35,(unsigned)ND::IRQ::IRQ4,0x08,0x8E);
ND::IDT::SetGate(36,(unsigned)ND::IRQ::IRQ5,0x08,0x8E);
ND::IDT::SetGate(37,(unsigned)ND::IRQ::IRQ6,0x08,0x8E);
ND::IDT::SetGate(38,(unsigned)ND::IRQ::IRQ7,0x08,0x8E);
ND::IDT::SetGate(39,(unsigned)ND::IRQ::IRQ8,0x08,0x8E);
ND::IDT::SetGate(40,(unsigned)ND::IRQ::IRQ9,0x08,0x8E);
ND::IDT::SetGate(41,(unsigned)ND::IRQ::IRQ10,0x08,0x8E);
ND::IDT::SetGate(42,(unsigned)ND::IRQ::IRQ11,0x08,0x8E);
ND::IDT::SetGate(43,(unsigned)ND::IRQ::IRQ12,0x08,0x8E);
ND::IDT::SetGate(44,(unsigned)ND::IRQ::IRQ13,0x08,0x8E);
ND::IDT::SetGate(45,(unsigned)ND::IRQ::IRQ14,0x08,0x8E);
ND::IDT::SetGate(46,(unsigned)ND::IRQ::IRQ15,0x08,0x8E);
ND::IDT::SetGate(47,(unsigned)ND::IRQ::IRQ16,0x08,0x8E);
ND::Screen::SetColor(ND_SIDE_FOREGROUND,ND_COLOR_GREEN);
ND::Screen::PutString("done");
asm volatile("sti");
}
Setningen til asm sti vi aktiverer IRQ-ene. Vel, nå går vi med noe som ligner på ISR. Funksjonene til en grunnleggende IRQ:
void ND::IRQ::IRQ1()
{
asm volatile(
"cli \n"
"pushl 0\n"
"pushl 32\n"
"jmp ND_IRQ_Common"
);
}
En vanlig del (samme som ISR):
extern "C"
void ND_IRQ_Common()
{
asm volatile(
"pusha \n"
"push %ds\n"
"push %es\n"
"push %fs\n"
"push %gs\n"
"movw $0x10, %ax \n"
"movw %ax, %ds \n"
"movw %ax, %es \n"
"movw %ax, %fs \n"
"movw %ax, %gs \n"
"movl %esp, %eax \n"
"push %eax \n"
"movl $ND_IRQ_Handler, %eax \n"
"call *%eax \n"
"popl %eax \n"
"popl %ds \n"
"popl %es \n"
"popl %fs \n"
"popl %gs \n"
"popa \n"
"addl 8, %esp \n"
"iret \n"
);
}
Og en grunnleggende handler:
extern "C"
void ND_IRQ_Handler(struct regs* r)
{
void (*handler)(struct regs *r);
if(r->int_no >= 40)
{
ND::Ports::OutputB(0xA0,0x20);
}
ND::Ports::OutputB(0x20,0x20);
}
Med dette bør vi allerede ha IRQ aktivert selv om de fremdeles ikke gjør noe. I neste kapittel vil vi se hvordan du får tak i data fra disse IRQ-ene, for eksempel klokken eller tastaturet.
Og med dette ender dagens innlegg. Som du ser nå skriver jeg mindre regelmessig på grunn av andre problemer. Likevel vil jeg fortsette til jeg har et mer komplett operativsystem
Tusen takk Adrian, så snart jeg har litt tid (jeg er ganske opptatt nå, blant annet også med et operativsystem) vil jeg begynne å teste opplæringen trinn for trinn.
Tusen takk for tuten.
Et spørsmål jeg gjør et prosjekt basert på disse programmeringsspråkene
* Html5
* Css3
* Java
Spørsmålet mitt er at jeg vil at dette prosjektet skal kjøres, så brukerne bruker det i operativsystemer som linux og windows, kan du fortelle meg hvordan jeg gjør det
Det har ingenting med dette å gjøre, men jeg svarer deg uansett. Jeg antar at det vil være HTML5, CSS3 og JavaScript ikke Java, ettersom HTML5 og Java kommer fatalt sammen. Med HTML5 kan du opprette nettsteder som før som er tilgjengelige fra internett. Hvis du vil gjøre det lokalt, kan du pakke det som en Firefox OS- og Chrome OS-app. Hvis det du ønsker er at i hvert operativsystem er det en kjørbar titt på XUL Runner som er et verktøy for å utføre XUL (og derfor HTML5 inne i elementet) med Gecko-motoren.
Java-ramme eller -panel er et veldig godt alternativ. Jeg har opprettet noen kjørbare apper i vinduet ved hjelp av java-rammeklasser som en nettleser, men i stedet for å bruke den til en hvilken som helst side, gir jeg den en direkte bane i koden, og med php utfører jeg java-setninger gjennom av en .jar som tar vare på stål. Selv om jeg vil anbefale å bruke HTML5, CSS3 og JavaScript siden Adrian Java sier at det tar Fatal med Html5 og det ga meg mange hodepine
En veiledning om hvordan du lager ditt eget programmeringsspråk ville være fint
Veldig bra denne artikkelserien om hvordan du bygger et operativsystem, du lærer mange ting. Jeg gleder meg til neste oppføring, jeg vil allerede ha et tastatur i operativsystemet. Jeg har rotet med git-koden, og jeg har ikke klart å få den til å fungere med port 0x60 og 0x64. Selv om jeg trodde at det for tastaturet var et avbrudd som ga deg den trykkte tasten.
Du kan faktisk få tastaturinngang uten avbrudd, men du må lese med ND :: Porter :: InputB på port 0x60. Imidlertid er den ideelle måten å gjøre dette på med IRQ-avbrudd. Jeg prøver for øyeblikket å gjøre det, og det tar litt lengre tid å fortsette på grunn av det.
Hei Adrian, jeg har sjekket koden og er imponert over hva den gjør og hvor godt den har hjulpet meg til å forstå noen ting.
Jeg har noen få små spørsmål om hvordan det fungerer, og kilden er den jeg fikk fra GIT:
1.- I delen av IRQ-ene nevnte du at posisjonene fra 0 til 32 av IDT ble brukt for unntak og fra 32 (0x20) til 45 (0x2D) for IRQ-ene, men IRQ-ene er totalt 16 , ville omleggingen ikke være fra 0x20 til 0x30?
2.- I IRQ-delen, merk at settportene ble sendt til IDT-seksjonen; Når du skiller dem, legg merke til at det ikke lenger produserte unntak av divisjon med 0, så det er nødvendig å legge til IDT Flush () for hver modifisering som utføres. Hvorfor endres IDT når timeren stilles inn og divisjonen mellom 0 slutter å fungere?
3.- Jeg prøvde å spore koden med litt utskrift for å ta som en indikasjon på hva den utfører (for ikke å feilsøke trinn for trinn) og jeg innså at ingen IRQ kjører, må jeg registrere noe annet til IRQ avbrudd generert?
Jeg glemte å nevne at jeg fant disse lenkene med informasjon:
http://arstechnica.com/civis/viewtopic.php?f=20&t=899001
http://www.superfrink.net/athenaeum/OS-FAQ/os-faq-pics.html
http://orga2.exp.dc.uba.ar/data/downloads/clasespracticas/interrupciones2_clase_17.pdf
http://www.intel-assembler.it/PORTALE/4/231468_8259A_PIC.pdf
Tilsynelatende for å håndtere IRQ er det nødvendig å ta hensyn til hvilken type handler som brukes hvis, PIC, APIC, IOAPIC. . .etc. Er det en måte å lage en dynamikk i IRQ-styring, eller trenger du å prøve lykken?
God ettermiddag Adrian.
Jeg så at jeg hadde problemer med IRQ-ene, og det var derfor koden ikke kunne avanseres, jeg tok en kopi av prosjektet, og jeg begynte å analysere den; Jeg la til en funksjon til skjermutskriften for å skrive ut reg-postene til struct reg, i øyeblikket for å gjøre avbruddene; Jeg fant flere ting, blant annet at et register kjører, og jeg kan fortsatt ikke finne hvorfor; endre timeravbrudd for tastaturavbrudd for å gjøre tester, og det gjør hva det skal, men jeg finner ikke problemet, kan du hjelpe meg og fortsette med dette gode innlegget? 😀
Jeg forlater lenken (den har noen endringer fordi jeg bruker Mageia og jeg bruker Grub2, jeg bruker VirtualBox for å teste den)
https://www.mediafire.com/?93psrgaoozatse8
Venter på ditt oppmerksomme svar, og hvis du har spørsmål eller trenger noe, vil jeg hjelpe 🙂
Jeg glemte å nevne at jeg også sjekket KernelPanic fordi ISR-ene ikke fungerte, og jeg har det samme problemet øverst i bunken, en verdi blir filtrert og jeg vet ikke om det er kompilatoren min, eller om det er et problem, jeg bruker GCC 4.8.2 med Mageia 4
Jeg liker veldig godt at du hjelper meg i prosjektet. Jeg satt virkelig fast i timeren, og jeg forstår ikke hvorfor det ikke fungerer. Jeg gjorde tester som endret ganske mange ting, og det gikk ikke. For øyeblikket kan jeg ikke redigere kode (jeg er på ferie borte), men jeg vil se på den så snart jeg kan. Jeg gir deg en lenke med informasjon om dette problemet som ser ut til å være noe vanlig: http://wiki.osdev.org/I_Cant_Get_Interrupts_Working
Når det gjelder unntakene, tror jeg jeg husker at du må ringe til "sti" i ASM for å aktivere dem selv om det er klart at det er noe galt et sted.
Takk for svaret og ja. Avbruddene mislyktes, men det var et problem å sette inn kodene i stabelen og et støpeproblem, jeg vil sjekke lenken og jeg skal gjøre tester. Hvis jeg løser det, vil jeg gi deg beskjed, og hvis ikke, vil jeg informere deg om fremgang. God ferie 🙂
Det vil ikke være noen måte å se den sammensatte koden på. Er det noe rart som skjer og jeg finner ikke hva? Se på dette skjermbildet (jeg setter lenken på slutten), det er noe rart siden det i IRQ 2-funksjonen (tastaturet) kommer inn i Stabl verdien 0 og 0x20 (32, så pass den til å teste), trykk deretter (32-biters GPR-registerene) etterfulgt av segmenteringsregistrene og deretter toppen av stabelen, og ring deretter IRQ Handler. Jeg begynte å se hver bunke, og tilsynelatende er den i orden, men hvis du kan se utdataene fra den virtuelle maskinen, kan du se at den stabler ett element til, jeg finner ikke hvor, jeg vet bare at det er en 0x10 og strukturen blir ute av drift. Dette er rekordstrukturen.
struct regs {
uint32_t gs, fs, es, ds; / * presset sekunder sist * /
uint32_t edi, esi, ebp, esp, ebx, edx, ecx, eax; / * presset av 'pushal' * /
uint32_t int_no, err_code; /* Feil kode */
uint32_t eip, cs, eflags, useresp, ss; / * Stablet på pause * /
};
Det gir meg en boks som setter ett element til på toppen, og jeg finner ikke hvor den er stablet hvis alt tilsynelatende er stablet som det skal være. Har du noen anelse om hva det kan være?
http://www.subeimagenes.com/img/sin-titulo-1036729.jpg
Få tastaturavbruddet til å fungere, men ikke timeren. feilen var i måten den er kompilert på, jeg brukte objdump for å se det endelige objektet, og det viste seg at hver funksjon som ble angitt til og med å bruke "asm volatile" også ble ledsaget av en pushl ebp, mov ebp, esp. Så er det bare å legge til en popl ebp til den for å gjenopprette den første stakken, og den vil passere argumentene uten å mislykkes. Her legger jeg til koden for de som ønsker å sjekke den, og hvis du kan finne ut hvorfor avbruddet ikke genereres av timeren, vil jeg gjerne vite om det og legger ved en lenke der de snakker om multitasking http://www.jamesmolloy.co.uk/tutorial_html/9.-Multitasking.html
Neste Divel
https://www.mediafire.com/?kmo83dxyzc7c3cz
Jeg har det. Det var en feil et annet sted som påvirket aktiveringen av Timer PIC, spesielt i IRQ-kartet var det to linjer som jeg måtte endre. Takket være det faktum at jeg kunne se en kode på et nettsted som på det tidspunktet hadde noe annet og klikk! Endringen var i tråd med:
ND :: Porter :: OutputB (PIC1 + 1, 0xFF);
ND :: Porter :: OutputB (PIC2 + 1, 0xFF);
Du måtte endre verdien fra 0xFF (jeg vil si det indikerer deaktivert) til 0x00 (jeg vil si det indikerer aktivert) selv om jeg ikke er helt sikker, men det fungerer. Jeg har oppdatert koden på GitHub. Tusen takk for at du hjalp meg med prosjektet som jeg hadde forlatt litt på grunn av dette problemet. H
Du er velkommen, jeg ser frem til neste oppdatering av emnet, og du kan stole på meg for hva som helst 🙂 (Y)
Endre opptaksrutinen for tastaturstrenger; fordi den leser når nøkkelen slippes og den monterer en 0 i bufferen, som gir problemer i lesingen og på slutten endrer '\ n' den til »slik at riktig utskrift fungerer
Hei, jeg leste hele innlegget ditt, selv om det i praksis ikke er mer enn 2 innlegg, det er veldig bra, lagre alt, men jeg må virkelig studere c ++ og posix for å forstå det fordi jeg vet om "c" (Jeg er fascinert av det programmeringsspråket), men selv om c ++ er c OO, har jeg egentlig aldri jobbet med det. Les meg noen veiledninger på google, og så returnerer jeg dette veldig interessant og et spørsmål, ligner oppstartsvinduet Linux?
Oppstart i Windows er likt i den forstand at dette er måten å starte et system med en x86-prosessor, og operativsystemet som er bygget på det, har liten innflytelse. Vi starter egentlig ikke opp uansett, det begynner GRUB for oss. GRUB, designet for å starte Linux, kan starte Windows og i dette tilfellet NextDivel.
ok takk, det betyr at det jeg vil gjøre er mulig. Jeg studerer allerede c ++ og jeg har opprettet noen apper og installert systemet ditt på en pendrive, og jeg studerer det mer detaljert er et veldig bra innlegg