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

Laipni lūdzam atpakaļ šajā ierakstu sērijā ar nosaukumu "Līnusa Torvalda atdarināšana". Šodien mēs redzēsim GDT. Vispirms mums jāskatās, kas ir GDT. Saskaņā ar Wikipedia:

Jūsu darbs IR Klientu apkalpošana Globālā deskriptoru tabula or GDT ir datu struktūra, kuru izmanto Intel x86- ģimenes procesori, sākot ar 80286 lai noteiktu programmas izpildes laikā izmantoto dažādu atmiņas apgabalu īpašības, tostarp bāzes adresi, lielumu un piekļuves tiesības, piemēram, izpildāmību un rakstāmību

Tulkotā būtu globālā deskriptoru tabula, datu struktūra, ko Intel x86 procesoros izmanto kopš 80286. gada, lai noteiktu dažādu atmiņas apgabalu īpašības, kuras tiek izmantotas programmas izpildes laikā.

Kopumā, ja mēs izmantojam Intel x86 procesoru, mums ir jādefinē GDT pareizai atmiņas lietošanai. Mēs nedarīsim daudz sarežģījumu, un mēs definēsim 3 tabulas ierakstus:

  • NULL ieraksts, kas nepieciešams visām tabulām.
  • Biļete uz sadaļu dati, mēs izmantosim maksimālo, kas 32 bitos ir 4 GB.
  • Biļete uz sadaļu kods, mēs izmantosim maksimālo, kas 32 bitos ir 4 GB.

Kā redzat, dati un kods izmantos vienu un to pašu vietu. Labi, tagad mēs to īstenosim. Šim nolūkam mēs izmantosim divas struktūras, no kurām pirmā būs atbildīga par rādītāja ievietošanu mūsu GDT reālajos datos. Un otrais būs masīvs ar GDT ierakstiem. Vispirms tos definēsim

struct Entry{
uint16_t limit_low;
uint16_t base_low;
uint8_t base_middle;
uint8_t access;
uint8_t granularity;
uint8_t base_high;
} __attribute__((packed));
struct Ptr{
uint16_t limit;
uint32_t base;
} __attribute__((packed));

Iespējams, struktūru beigās esat pamanījis ziņkārīgu __attribute __ ((iepakotu)). Tas liek GCC neoptimizēt struktūras, jo mēs vēlamies nodot datus procesoram. Tagad mēs izveidosim funkciju GDT instalēšanai. Pirms mums vajadzēja deklarēt struktūras, tagad mēs tos inicializēsim.

struct ND::GDT::Entry gdt[3];
struct ND::GDT::Ptr gp;
void ND::GDT::Install()
{
gp.limit=(sizeof(struct ND::GDT::Entry)*3)-1;
gp.base=(uint32_t)&gdt;
}

Tādējādi mēs izveidojam rādītāju, kas nonāk mūsu 3 ievades tabulā.

Ja kompilējat, izmantojot 64 bitus, visticamāk, tas šeit neizdosies. Tas ir tāpēc, ka 64 bitu sistēmu rādītāji acīmredzami ir 64 biti, un šeit mēs izmantojam 32 bitu tipus. Pagaidām var būt noderīga opcijas -m32 izmantošana
Tagad mēs definējam kopēju funkciju, lai datus ievietotu ievados

void ND::GDT::SetGate(int num, uint32_t base, uint32_t limit, uint8_t access,uint8_t gran)
{
gdt[num].base_low=(base & 0xFFFF);
gdt[num].base_middle=(base >> 16) & 0xFF;
gdt[num].base_high=(base >> 24) & 0xFF;
gdt[num].limit_low=(limit & 0xFFFF);
gdt[num].granularity=(limit >> 16) & 0x0F;
gdt[num].granularity |= (gran & 0xF0);
gdt[num].access=access;
}

Un mēs to saucam 3 reizes no instalēšanas funkcijas

ND::GDT::SetGate(0,0,0,0,0); /* NULL segmente entry */
ND::GDT::SetGate(1,0,0xFFFFFFFF,0x9A,0xCF); /* 4 GiB for Code Segment */
ND::GDT::SetGate(2,0,0xFFFFFFFF,0x92,0xCF); /* 4 GiB for Data segment */

Visbeidzot, mums procesoram jāpasaka, ka mums ir GDT, lai tas to varētu ielādēt, un mūsu gadījumā, ielādējot kodolu ar GRUB, jāpārraksta GRUB GDT. Lai ielādētu GDT, ASM ir instrukcija, ko sauc par lgdt (vai lgdtl atkarībā no sintakses), mēs to izmantosim.

asm volatile("lgdtl (gp)");
asm volatile(
"movw $0x10, %ax \n"
"movw %ax, %ds \n"
"movw %ax, %es \n"
"movw %ax, %fs \n"
"movw %ax, %gs \n"
"movw %ax, %ss \n"
"ljmp $0x08, $next \n"
"next: \n"
);

Nu, kad mēs to būsim pabeiguši, mūsu sistēmai jau būs GDT. Nākamajā nodaļā mēs redzēsim IDT - tabulu, kas ir ļoti līdzīga GDT, bet ar pārtraukumiem. Esmu ievietojis dažus statusa un apstiprinājuma ziņojumus GDT, tāpēc NextDivel tagad izskatās šādi:

NākamaisDivel-GDT


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.   Sērons teica

    Varbūt šajos laikos vairāk piemērota ir 64 bitu struktūra, un tas ir neizpildīts, lai turpinātu izmantot 8086.

    1.    AdrianArroyoStreet teica

      Esmu meklējis informāciju par GDT failā x86_64, un es domāju, ka tas seko vecajam modelim ar īpašu karodziņu. Joprojām tiek izmantota 32 bitu adrese. Tagad es nezinu, kā to pareizi izdarīt. Dažas saites:
      http://wiki.osdev.org/Entering_Long_Mode_Directly
      http://f.osdev.org/viewtopic.php?f=1&t=16275

  2.   geronimo teica

    Pirmais ļoti labs jūsu ieguldījums, bet es domāju, ka nosaukumam vajadzētu būt
    "Ričarda Stallmana atdarināšana" vai vismaz es tā domāju ,,,
    Sveicieni

    1.    abimaelmartell teica

      Linuss izveidoja Linux kodolu, Stalmens - GNU, kas ir Unix rīki un komandas.

      Virsraksts ir piemērots, jo jūs veidojat kodolu.

      Sveicieni!

  3.   rubīns teica

    Liels paldies, ka atbildējāt uz visiem maniem jautājumiem un esat pacietīgs, es zinu tikai pamatus kā montētājs un gandrīz neko nezinu par C, bet man tas ļoti patīk, tagad esmu mazliet sajaucies ar GDT, paskatīsimies, vai es saprast.

    GDT būs globālie “deskriptori”, kuriem vienmēr var piekļūt jebkura programma, un šie deskriptori norāda uz sadaļu, kurā (programma) tiks izpildīta? vai ir citādi.