Bonvenon reen al ĉi tiu serio de afiŝoj titolita "Emulante Linus Torvalds". Hodiaŭ ni vidos la GDT. Unue ni devas vidi, kio estas la GDT. Laŭ Vikipedio:
la Tutmonda Priskriba Tabelo or GDT estas datuma strukturo uzata de intel x86-familiaj procesoroj komencante per la 80286 por difini la karakterizaĵojn de la diversaj memorareoj uzataj dum programo-ekzekuto, inkluzive de la baza adreso, la grandeco kaj aliraj privilegioj kiel plenumeblo kaj skribeblo
Kio tradukita estus Tutmonda Descripta Tablo, datuma strukturo uzata en procesoroj Intel x86 ekde 80286 por difini la karakterizaĵojn de diversaj memorareoj uzataj dum programo-ekzekuto.
Resume, se ni uzas procesoron Intel x86, ni devas difini GDT por ĝusta uzo de memoro. Ni ne faros multan komplikaĵon kaj ni difinos 3 enirojn en la tabelo:
- NULA eniro, necesa por ĉiuj tabeloj.
- Bileto por la sekcio datumoj, ni uzos la maksimumon, kiu en 32 bitoj estas 4 GB.
- Bileto por la sekcio kodo, ni uzos la maksimumon, kiu en 32 bitoj estas 4 GB.
Kiel vi povas vidi, datumoj kaj kodo uzos la saman spacon. Bone, nun ni efektivigos ĝin. Por ĉi tio ni uzos du strukturojn, la unua estos zorge enhavi montrilon al la realaj datumoj de nia GDT. Kaj la dua estos tabelo kun la GDT-eniroj. Ni unue difinu ilin
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));
Vi eble rimarkis scivoleman __atributon__ ((pakita)) ĉe la fino de la strukturoj. Ĉi tio diras al GCC ne optimumigi la strukturojn, ĉar ni volas transdoni la datumojn tiel, kiel estas al la procesoro. Nun ni plenumos funkcion por instali la GDT. Antaŭ ol ni devintus deklari la strukturojn, nun ni pravalorizos ilin.
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;
}
Do ni ekkonstruas la montrilon, kiu iras al nia 3-eniga tabelo.
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;
}
Kaj ni nomas ĝin 3 fojojn de la instalfunkcio
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 */
Fine ni devas diri al la procesoro, ke ni havas GDT, por ke ĝi povu ŝarĝi ĝin, kaj en nia kazo, kiam ni ŝarĝas la kernon per GRUB, anstataŭigu la GRUB GDT. Por ŝarĝi la GDT estas instrukcio en asm nomata lgdt (aŭ lgdtl depende de la sintakso), ni uzos ĝin.
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, post kiam ni finos ĉi tion, nia sistemo jam havos GDT. En la sekva ĉapitro ni vidos la IDT, tabelon tre similan al la GDT sed kun interrompoj. Mi metis iujn statusajn kaj konfirmajn mesaĝojn kun la GDT do NextDivel nun aspektas tiel:
5 komentoj, lasu la viajn
Eble 64-bita strukturo pli taŭgas por ĉi tiuj tempoj, ĝi estas postrestanta por daŭre uzi la 8086.
Mi serĉis informojn pri GDT en x86_64 kaj mi pensas, ke ĝi sekvas la malnovan modelon kun speciala flago. 32-bita adreso estas ankoraŭ uzata. Nun mi ne scias precize kiel fari ĝin ĝuste. Iuj ligoj:
http://wiki.osdev.org/Entering_Long_Mode_Directly
http://f.osdev.org/viewtopic.php?f=1&t=16275
La unua tre bona viaj kontribuoj, sed mi pensas, ke la titolo devas esti
"Emulante Richard Stallman" aŭ almenaŭ mi pensas ke jes,
salutoj
Linus kreis la Linuksan kernon, Stallman kreis GNU, kiuj estas la Uniksaj iloj kaj komandoj.
La titolo taŭgas ĉar vi kreas kernon.
Un saluto!
Koran dankon pro via respondo al ĉiuj miaj demandoj kaj pacienco, mi nur konas la bazojn kiel asembleo kaj mi scias preskaŭ nenion pri C, sed mi tre ŝatas ĝin, nun mi iom konfuziĝas kun la GDT, ni vidu ĉu mi komprenas.
GDT havos la tutmondajn 'priskribilojn' al kiuj ĉiam alireblas iu ajn programo, kaj ĉi tiuj priskribiloj montras la sekciojn, kie (la programo) estos plenumata? aŭ ĝi estas alimaniere.