Efterligne Linus Torvalds: Opret dit eget operativsystem fra bunden (IV)

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.

Hvis du kompilerer ved hjรฆlp af 64 bits, vil det sandsynligvis mislykkes her. Dette skyldes, at henvisninger pรฅ 64-bit-systemer naturligvis er 64-bit, og vi bruger 32-bit-typer her. Brug af -m32-indstillingen kan hjรฆlpe til nu
Nu definerer vi en fรฆlles funktion til at placere dataene i input

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:

NรฆsteDivel-GDT


Efterlad din kommentar

Din e-mailadresse vil ikke blive offentliggjort. Obligatoriske felter er markeret med *

*

*

  1. Ansvarlig for dataene: Miguel รngel Gatรณn
  2. Formรฅlet med dataene: Control SPAM, management af kommentarer.
  3. Legitimering: Dit samtykke
  4. Kommunikation af dataene: Dataene vil ikke blive kommunikeret til tredjemand, undtagen ved juridisk forpligtelse.
  5. Datalagring: Database hostet af Occentus Networks (EU)
  6. Rettigheder: Du kan til enhver tid begrรฆnse, gendanne og slette dine oplysninger.

      saeron sagde han

    Mรฅske er en 64-bit struktur mere egnet til disse tider, det er et efterslรฆb at fortsรฆtte med at bruge 8086.

         AdrianArroyoStreet sagde han

      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

      Geronimo sagde han

    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

         abimaelmartell sagde han

      Linus oprettede Linux-kernen, Stallman oprettede GNU, som er Unix-vรฆrktรธjer og kommandoer.

      Titlen er passende, fordi du opretter en kerne.

      Greetings!

      Rubin sagde han

    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.