Velkommen tilbage til denne serie indlรฆg med titlen "Emulating Linus Torvalds". I dag vil vi se GDT. Fรธrst skal vi se, hvad GDT er. Ifรธlge Wikipedia:
Global deskriptor-tabel or GDT er en datastruktur, der bruges af Intel x86-familieprocessorer, der starter med 80286 for at definere karakteristika for de forskellige hukommelsesomrรฅder, der bruges under programudfรธrelse, inklusive baseadresse, stรธrrelse og adgangsrettigheder som eksekverbarhed og skrivbarhed
Hvad der oversรฆttes ville vรฆre en Global Descriptor Table, en datastruktur, der er brugt i Intel x86-processorer siden 80286 til at definere karakteristika for forskellige hukommelsesomrรฅder, der bruges under programudfรธrelse.
Kort sagt, hvis vi bruger en Intel x86-processor, skal vi definere en GDT til korrekt brug af hukommelse. Vi kommer ikke til at gรธre meget komplikationer, og vi definerer 3 poster i tabellen:
- En NULL-post, krรฆvet til alle tabeller.
- En billet til sektionen data, vi bruger det maksimale, som i 32 bit er 4 GB.
- En billet til sektionen kode, vi bruger det maksimale, som i 32 bit er 4 GB.
Som du kan se, bruger data og kode det samme rum. Ok, nu skal vi implementere det. Til dette vil vi bruge to strukturer, den fรธrste har ansvaret for at indeholde en markรธr til de reelle data i vores GDT. Og den anden vil vรฆre en matrix med GDT-poster. Lad os definere dem fรธrst
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));
Du har mรฅske bemรฆrket en nysgerrig __attribut __ ((pakket)) i slutningen af โโstrukturer. Dette fortรฆller GCC, at de ikke skal optimere strukturerne, fordi det, vi รธnsker, er at videregive dataene som til processoren. Nu skal vi lave en funktion til at installere GDT. Fรธr vi skulle have erklรฆret strukturerne, skal vi nu initialisere dem.
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;
}
Sรฅledes fรฅr vi opbygget markรธren, der gรฅr til vores 3-input tabel.
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;
}
Og vi kalder det 3 gange fra installationsfunktionen
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 */
Endelig skal vi fortรฆlle processoren, at vi har en GDT, sรฅ den kan indlรฆse den, og i vores tilfรฆlde nรฅr du indlรฆser kernen med GRUB, overskriver du GRUB GDT. For at indlรฆse GDT er der en instruktion i asm kaldet lgdt (eller lgdtl afhรฆngigt af syntaksen), vi skal bruge den.
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"
);
Nรฅr vi er fรฆrdige med dette, har vores system allerede GDT. I det nรฆste kapitel ser vi IDT, en tabel, der ligner GDT, men med afbrydelser. Jeg har lagt nogle status- og bekrรฆftelsesmeddelelser med GDT, sรฅ NextDivel ser nu sรฅdan ud:
Mรฅske er en 64-bit struktur mere egnet til disse tider, det er et efterslรฆb at fortsรฆtte med at bruge 8086.
Jeg har ledt efter oplysninger om GDT i x86_64, og jeg tror, โโat den fรธlger den gamle model med et specielt flag. En 32-bit adresse bruges stadig. Nu ved jeg ikke nรธjagtigt, hvordan man gรธr det korrekt. Nogle links:
http://wiki.osdev.org/Entering_Long_Mode_Directly
http://f.osdev.org/viewtopic.php?f=1&t=16275
Den fรธrste meget gode dine bidrag, men jeg synes titlen skulle vรฆre
"Efterligning af Richard Stallman" eller i det mindste tror jeg det ,,,
hilsen
Linus oprettede Linux-kernen, Stallman oprettede GNU, som er Unix-vรฆrktรธjer og kommandoer.
Titlen er passende, fordi du opretter en kerne.
Greetings!
Mange tak for at have besvaret alle mine spรธrgsmรฅl og vรฆre tรฅlmodig, jeg kender kun det grundlรฆggende som en assembler og nรฆsten intet om C, men jeg kan godt lide det meget, nu er jeg lidt forvirret med GDT, lad os se om jeg forstรฅr .
GDT vil have de globale 'deskriptorer', der altid kan tilgรฅs af ethvert program, og disse deskriptorer peger pรฅ det afsnit, hvor (programmet) skal udfรธres? eller det er ellers.