Līnusa Torvalda atdarināšana: izveidojiet savu operētājsistēmu no 0 (V)

Šajā piektajā daļā mēs redzēsim tabulu, kas ir diezgan līdzīga GDT gan teorētiski, gan lietojot, mēs atsaucamies uz IDT. IDT apzīmē Pārtrauc aprakstu tabulu y ir tabula, ko izmanto, lai apstrādātu pārtraukumus, kas notiek. Piemēram, kāds veic dalījumu ar 0, tiek izsaukta funkcija, kas atbild par apstrādi. Šīs funkcijas ir ISR (Pārtraukt pakalpojumu kārtību). Tātad izveidosim IDT un pievienosim dažus ISR.

Vispirms mēs deklarēsim IDT atbilstošās struktūras:

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));

Kā redzams, ja jūs salīdzināt to ar GDT, Ptr struktūra ir identiska, un Entry ir diezgan līdzīga. Tāpēc ieraksta ievietošanas (SetGate) un instalēšanas (Install) funkcijas ir ļoti līdzīgas.

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;
}

Uzstādīt:

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();

Ja paskatīsimies, redzēsim, ka instalēšanas funkcija izmanto funkciju ND :: Memory :: Set, kuru mēs paziņojām citā ziņojumā. Mēs varam arī redzēt, kā mēs vēl nezvanām uz SetGate, un mēs saucam ND :: IDT :: Flush, šai funkcijai mēs atkal izmantojam asm volatile paziņojumu:

asm volatile("lidtl (idtptr)");

Ja viss notiek labi un mēs veicam estētisku izkārtojumu, tam vajadzētu izskatīties šādi:

NākamaisDivel-IDT

Labi, tagad mēs sāksim aizpildīt IDT ar pārtraukumiem. Šeit es izveidošu tikai vienu, bet pārējiem tas būtu vienādi. Es darīšu dalījumu ar nulles pārtraukumu. Kā jūs zināt matemātikā, skaitli nevar dalīt ar 0. Ja tas notiek procesorā, tiek ģenerēts izņēmums, jo tas nevar turpināties. IDT pirmais pārtraukums sarakstā (0) atbilst šim notikumam.

Mēs to pievienojam starp atmiņas iestatījumu un IDT instalēšanas funkciju:

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

Atzvana funkcija būs ND :: ISR :: ISR1, kas ir diezgan vienkārši, lai gan mums jāizmanto ASM:

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

ND_ISR_Common mēs to definēsim kā funkciju C valodā. Lai saglabātu failus un uzlabotu lasāmību, mēs varam izmantot 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"
);
}

Šis kods ASM var būt nedaudz grūti saprotams, bet tas ir tāpēc, ka mēs paziņosim par struktūru C, lai piekļūtu pārtraukuma radītajiem datiem. Acīmredzot, ja jūs to nevēlaties, varat vienkārši piezvanīt kodola panikai ND :: ISR :: ISR1 vai tamlīdzīgi. Struktūrai ir tāda forma, ka:

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;
};

Un visbeidzot mēs veicam funkciju ND_ISR_Handler (arī ar saiti C), kurā mēs parādām kodola paniku un nelielu kļūdas aprakstu atbilstoši tam, kas mums ir kļūdu sarakstā.

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

Labi, un ar to mēs jau spējam tikt galā ar šo pārtraukumu. Ar pārējiem pārtraukumiem tas notiktu līdzīgi, izņemot to, ka ir daži, kas atgriež parametrus, un mēs to izmantotu reg struktūrā. Tomēr jums var rasties jautājums, kā mēs zinām, vai tas patiešām darbojas. Lai pārbaudītu, vai tas darbojas, mēs ieviesīsim vienkāršu rindiņu aiz ND :: IDT :: Install ():

int sum=10/0;

Ja mēs to apkoposim, tas mūs brīdinās, un, ja mēs mēģināsim to izpildīt, mēs iegūsim jauku ekrānu:

NākamaisDivel-ISR


Un ar to šis ieraksts beidzas, es domāju, ka tas ir viens no visplašākajiem, bet diezgan funkcionāls.


Atstājiet savu komentāru

Jūsu e-pasta adrese netiks publicēta. Obligātie lauki ir atzīmēti ar *

*

*

  1. Atbildīgais par datiem: Migels Ángels Gatóns
  2. Datu mērķis: SPAM kontrole, komentāru pārvaldība.
  3. Legitimācija: jūsu piekrišana
  4. Datu paziņošana: Dati netiks paziņoti trešām personām, izņemot juridiskus pienākumus.
  5. Datu glabāšana: datu bāze, ko mitina Occentus Networks (ES)
  6. Tiesības: jebkurā laikā varat ierobežot, atjaunot un dzēst savu informāciju.

  1.   mesodabler teica

    Es devos uz LFS, tas ir nepārtrauktāks.

  2.   3000 teica

    Svēts ... Jebkurā gadījumā konsultācijas ir labas.

  3.   sc teica

    Ļoti labi, es tam sekoju no sākuma. Vai jūs varētu pievienot kodus katrai piekabei?

    1.    AdrianArroyoStreet teica

      GitHub jums ir pieejams viss avota kods: http://github.com/AdrianArroyoCalle/next-divel No turienes jūs varat lejupielādēt ZIP, TAR.GZ vai vienkārši izmantot git.

  4.   niansēts teica

    Hahaha ļoti labi! Apstipriniet! 🙂