Emulera Linus Torvalds: Skapa ditt eget operativsystem från 0 (V)

I den här femte delen ser vi en tabell som liknar GDT både i teorin och i användning, vi hänvisar till IDT. IDT står för Avbrott Beskrivningstabell y är en tabell som används för att hantera avbrott som uppstår. Till exempel gör någon en uppdelning med 0, funktionen som ansvarar för behandlingen kallas. Dessa funktioner är ISR (Avbryt service rutiner). Så låt oss skapa IDT och lägga till lite ISR.

Först ska vi förklara de strukturer som motsvarar IDT:

struct Entry{
uint16_t base_low;
uint16_t sel;
uint8_t always0;
uint8_t flags;
uint16_t base_high;
} __attribute__((packed));
struct Ptr{
uint16_t limit;
uint32_t base;
} __attribute__((packed));

Som man kan se om man jämför det med GDT är Ptr-strukturen identisk och posten är ganska lik. Därför är funktionerna för att placera en post (SetGate) och installera (Installera) mycket lika.

void ND::IDT::SetGate(uint8_t num,uint32_t base,uint16_t sel, uint8_t flags)
{
idt[num].base_low=(base & 0xFFFF);
idt[num].base_high=(base >> 16) & 0xFFFF;
idt[num].sel=sel;
idt[num].always0=0;
idt[num].flags=flags;
}

Installera:

idtptr.limit=(sizeof(struct ND::IDT::Entry)*256)-1;
idtptr.base=(uint32_t)&idt;
ND::Memory::Set(&idt,0,sizeof(struct ND::IDT::Entry)*256);
ND::IDT::Flush();

Om vi ​​tittar ser vi att installationsfunktionen använder ND :: Memory :: Set-funktionen som vi hade deklarerat i det andra inlägget. Vi kan också se hur vi inte gör några samtal till SetGate ännu och vi kallar ND :: IDT :: Flush, för den här funktionen använder vi asm-flyktiga uttalande igen:

asm volatile("lidtl (idtptr)");

Om allt går bra och vi gör ett estetiskt arrangemang ska det se ut så här:

NextDivel-RTD

Okej, nu ska vi börja fylla IDT med avbrott. Här ska jag bara skapa en men för resten skulle det vara detsamma. Jag ska göra delningen med noll paus. Som du väl vet i matematik kan ett tal inte delas med 0. Om detta händer i processorn genereras ett undantag eftersom det inte kan fortsätta. I IDT motsvarar det första avbrottet i listan (0) denna händelse.

Vi lägger till detta mellan minnesinställningen och spolningen inom IDT: s installationsfunktion:

ND::IDT::SetGate(0,(unsigned)ND::ISR::ISR1,0x08,0x8E);

Återuppringningsfunktionen kommer att vara ND :: ISR :: ISR1 vilket är ganska enkelt även om vi måste använda ASM:

void ND::ISR::ISR1()
{
asm volatile(
"cli \n"
"pushl 0 \n"
"pushl 0 \n"
"jmp ND_ISR_Common \n"
);
}

Vi kommer att definiera ND_ISR_Common som en funktion på språk C. För att spara filer och förbättra läsbarheten kan vi använda extern «C» {}:

extern "C"
void ND_ISR_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_ISR_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"
);
}

Den här koden i ASM kan vara lite svår att förstå men det beror på att vi kommer att förklara en struktur i C för att komma åt de data som genereras av avbrottet. Uppenbarligen, om du inte ville ha det, kan du bara ringa Kernel Panic i ND :: ISR :: ISR1 eller något liknande. Strukturen har en sådan form att:

struct regs{
uint32_t ds;
uint32_t edi, esi, ebp, esp, ebx, edx, ecx, eax;
uint32_t int_no, err_code;
uint32_t eip, cs, eflags, useresp, ss;
};

Och slutligen gör vi ND_ISR_Handler-funktionen (även med en C-länk) där vi visar en kärnpanik och en liten beskrivning av felet enligt den vi har i en lista med fel.

extern "C"
void ND_ISR_Handler(struct regs *r)
{
if(r->int_no < 32) { ND::Panic::Show(exception_messages[r->int_no]);
for(;;);
}
}

Bra och med detta kan vi redan hantera detta avbrott. Med resten av avbrott skulle det hända liknande förutom att det finns några som returnerar parametrar och vi skulle använda regstrukturen för att få den. Men du kanske undrar hur vi vet om det verkligen fungerar. För att testa om det fungerar kommer vi att införa en enkel rad efter ND :: IDT :: Install ():

int sum=10/0;

Om vi ​​sammanställer kommer det att ge oss en varning och om vi försöker genomföra den får vi en fin skärm:

NextDivel-ISR


Och med detta slutar detta inlägg, jag tror att det är en av de mest omfattande men ganska funktionella.


Lämna din kommentar

Din e-postadress kommer inte att publiceras. Obligatoriska fält är markerade med *

*

*

  1. Ansvarig för uppgifterna: Miguel Ángel Gatón
  2. Syftet med uppgifterna: Kontrollera skräppost, kommentarhantering.
  3. Legitimering: Ditt samtycke
  4. Kommunikation av uppgifterna: Uppgifterna kommer inte att kommuniceras till tredje part förutom enligt laglig skyldighet.
  5. Datalagring: databas värd för Occentus Networks (EU)
  6. Rättigheter: När som helst kan du begränsa, återställa och radera din information.

  1.   mesodabler sade

    Jag bytte till LFS, det är mer kontinuerligt.

  2.   eliotime3000 sade

    Heliga ... Hur som helst, handledningarna är bra.

  3.   sc sade

    Mycket bra, jag har följt det från början. Kan du bifoga koder på varje trailer?

    1.    AdrianArroyoStreet sade

      Du har all källkod tillgänglig på GitHub: http://github.com/AdrianArroyoCalle/next-divel Därifrån kan du ladda ner en ZIP, en TAR.GZ eller bara använda git.

  4.   nyanserad sade

    Hahaha väldigt bra! Godkänna! 🙂