Emulating Linus Torvalds: Cruthaigh do chóras oibriúcháin féin ó 0 (V)

Sa chúigiú tráthchuid seo feicfimid tábla atá cosúil go leor leis an GDT go teoiriciúil agus in úsáid, déanaimid tagairt don IDT. Seasann IDT do Cur isteach ar an Tábla Tuairisc is tábla é y a úsáidtear chun briseadh isteach a tharlaíonn a láimhseáil. Mar shampla, déanann duine deighilt faoi 0, tugtar an fheidhm atá i gceannas ar phróiseáil. Is iad na feidhmeanna seo an ISR (Gnáthaimh Seirbhíse Idirbhriste). Mar sin, déanaimis an IDT a chruthú agus roinnt ISR a chur leis.

Ar dtús táimid chun na struchtúir a fhreagraíonn don IDT a dhearbhú:

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

Mar atá le feiceáil má dhéanann tú é a chur i gcomparáid leis an GDT, tá an struchtúr Ptr comhionann agus tá an Iontráil cosúil go leor. Dá bhrí sin tá na feidhmeanna a bhaineann le hiontráil a chur (SetGate) agus a shuiteáil (Suiteáil) an-chosúil.

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

Suiteáil:

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

Má fhéachaimid feicfimid go n-úsáideann an fheidhm suiteála an fheidhm ND :: Cuimhne :: Socraigh a bhí dearbhaithe againn sa phost eile. Is féidir linn a fheiceáil freisin conas nach ndéanaimid aon ghlaonna ar SetGate fós agus tugaimid ND :: IDT :: Flush, don fheidhm seo bainimid úsáid as an ráiteas luaineach asm arís:

asm volatile("lidtl (idtptr)");

Má éiríonn go maith le gach rud agus má dhéanaimid socrú aeistéitiúil ba chóir go mbeadh an chuma air:

NextDivel-IDT

Ceart go leor, anois táimid chun tosú ag líonadh an IDT le cur isteach. Nílim chun ach ceann amháin a chruthú ach don chuid eile bheadh ​​sé mar an gcéanna. Táim chun an deighilt a dhéanamh le briseadh nialasach. Mar is eol duit sa mhatamaitic, ní féidir uimhir a roinnt ar 0. Má tharlaíonn sé seo sa phróiseálaí, gintear eisceacht ós rud é nach féidir léi leanúint ar aghaidh. In IDT comhfhreagraíonn an chéad bhriseadh isteach ar liosta (0) don teagmhas seo.

Cuirimid é seo idir an socrú cuimhne agus an dúiseacht laistigh d'fheidhm Suiteála an IDT:

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

Is é ND :: ISR :: ISR1 an fheidhm aisghlao atá simplí go leor cé go gcaithfimid ASM a úsáid:

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

ND_ISR_Common déanfaimid é a shainiú mar fheidhm i dteanga C. Chun comhaid a shábháil agus inléiteacht a fheabhsú is féidir linn an taobh amuigh «C» {} a úsáid:

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 féidir leis an gcód seo in ASM a bheith rud beag deacair a thuiscint ach tá sé seo toisc go bhfuilimid chun struchtúr i C a dhearbhú chun rochtain a fháil ar na sonraí a ghineann an cur isteach. Ar ndóigh, mura raibh tú ag iarraidh sin, d’fhéadfá Panic Eithne a ghlaoch i ND :: ISR :: ISR1 nó rud éigin mar sin. Tá cruth ar an struchtúr sa chaoi is:

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

Agus ar deireadh déanaimid feidhm ND_ISR_Handler (le nasc C freisin) ina dtaispeánann muid scaoll eithne agus tuairisc bheag ar an mbotún de réir an chinn atá againn i liosta earráidí.

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

Go maith agus leis seo táimid in ann an cur isteach seo a láimhseáil cheana féin. Tharlódh sé mar an gcéanna leis an gcuid eile de chur isteach ach amháin go bhfuil roinnt ann a fhilleann paraiméadair agus d’úsáidfimis an struchtúr rialála chun é a fháil. Mar sin féin, b’fhéidir go gceapfá cén chaoi a bhfuil a fhios againn an n-oibríonn sé i ndáiríre. Chun a thástáil an bhfuil sé ag obair táimid chun líne shimplí a thabhairt isteach i ndiaidh an ND :: IDT :: Suiteáil ():

int sum=10/0;

Má thiomsaímid tabharfaidh sé rabhadh dúinn agus má dhéanaimid iarracht é a fhorghníomhú gheobhaidh muid scáileán deas:

NextDivel-ISR
Agus leis seo deireadh leis an bpost seo, sílim go bhfuil sé ar cheann de na cinn is fairsinge ach is feidhmiúla.


Cloíonn ábhar an ailt lenár bprionsabail eitic eagarthóireachta. Chun earráid a thuairisciú cliceáil anseo.

5 trácht, fág mise

Fág do thrácht

Ní thabharfar do sheoladh r-phoist a fhoilsiú. Réimsí riachtanacha atá marcáilte le *

*

*

  1. Freagrach as na sonraí: Miguel Ángel Gatón
  2. Cuspóir na sonraí: SPAM a rialú, bainistíocht trácht.
  3. Legitimation: Do thoiliú
  4. Na sonraí a chur in iúl: Ní chuirfear na sonraí in iúl do thríú páirtithe ach amháin trí oibleagáid dhlíthiúil.
  5. Stóráil sonraí: Bunachar sonraí arna óstáil ag Occentus Networks (EU)
  6. Cearta: Tráth ar bith is féidir leat do chuid faisnéise a theorannú, a aisghabháil agus a scriosadh.

  1.   Mesodabler a dúirt

    Chuaigh mé chuig LFS, tá sé níos leanúnach.

  2.   eliotime3000 a dúirt

    Naofa ... Ar aon chaoi, tá na ranganna teagaisc go maith.

  3.   sc a dúirt

    An-mhaith, bhí mé á leanúint ón tús. An bhféadfá na cóid a cheangal le gach leantóir?

    1.    AdrianArroyoStreet a dúirt

      Tá an cód foinse uile ar fáil ar GitHub: http://github.com/AdrianArroyoCalle/next-divel Ón áit sin is féidir leat ZIP, TAR.GZ a íoslódáil nó git a úsáid.

  4.   nuanced a dúirt

    Hahaha an-mhaith! Ceadaigh! 🙂