Linus Torvalds emuleren: maak uw eigen besturingssysteem helemaal opnieuw (III)

We gaan door met deze reeks berichten over het maken van ons besturingssysteem. Vandaag gaan we ons niet op één onderwerp concentreren, maar we gaan vanaf nu enkele nuttige functies definiëren. Eerst gaan we 3 functies definiëren die de functie vervullen van memcpy, memeset y memcmp:

void* ND::Memory::Set(void* buf, int c, size_t len)
{
unsigned char* tmp=(unsigned char*)buf;
while(len--)
{
*tmp++=c;
}
return buf;
}
void* ND::Memory::Copy(void* dest,const void* src, size_t len)
{
const unsigned char* sp=(const unsigned char*)src;
unsigned char* dp=(unsigned char*)dest;
for(;len!=0;len--) *dp++=*sp++;
return dest;
}
int ND::Memory::Compare(const void* p1, const void* p2, size_t len)
{
const char* a=(const char*)p1;
const char* b=(const char*)p2;
size_t i=0;
for(;i<len;i++)
{
if(a[i] < b[i]) return -1; else if(a[i] > b[i])
return 1;
}
return 0;
}

Ze implementeren allemaal zichzelf. Deze functies heb ik overgenomen van een kleine C-bibliotheek, de implementatie is meestal vergelijkbaar in alle besturingssystemen. Nu gaan we 3 gesimuleerde functies doen, maar om strings te manipuleren. Ze zouden de functie vervullen van streng, streng y strcmp.

size_t ND::String::Length(const char* src)
{
size_t i=0;
while(*src--)
i++;
return i;
}
int ND::String::Copy(char* dest, const char* src)
{
int n = 0;
while (*src)
{
*dest++ = *src++;
n++;
}
*dest = '';
return n;
}
int ND::String::Compare(const char *p1, const char *p2)
{
int i = 0;
int failed = 0;
while(p1[i] != '' && p2[i] != '')
{
if(p1[i] != p2[i])
{
failed = 1;
break;
}
i++;
}
if( (p1[i] == '' && p2[i] != '') || (p1[i] != '' && p2[i] == '') )
failed = 1;
return failed;
}
char *ND::String::Concatenate(char *dest, const char *src)
{
int di = ND::String::Length(dest);
int si = 0;
while (src[si])
dest[di++] = src[si++];
dest[di] = '';
return dest;
}

We gaan nu met een aantal behoorlijk interessante functies. Met deze functies kunnen we lezen en schrijven naar de hardwarepoorten. Dit wordt normaal gesproken gedaan met ASM en komt overeen (op x86) met de instructies in y uit. Gebruik de instructie om ASM gemakkelijk vanaf C te bellen aSM, met het gevaar dat het met zich meebrengt dat het niet draagbaar is. Aan deze zin voegen we de vluchtig zodat GCC die tekst niet probeert te optimaliseren. Aan de andere kant heeft de asm-instructie een merkwaardige manier om parameters te accepteren, maar ik denk dat dat beter wordt begrepen door de voorbeelden te zien.

void ND::Ports::OutputB(uint16_t port, uint8_t value)
{
asm volatile("outb %1, %0" : : "dN"(port), "a"(value));
}
uint8_t ND::Ports::InputB(uint16_t _port)
{
unsigned char rv;
asm volatile("inb %1, %0" : "=a"(rv) : "dN"(_port));
return rv;
}

En tot nu toe in post 3, hebben we vandaag niets opzichtigs gedaan, maar we hebben een functie gedefinieerd die van pas zal komen voor de toekomst. Bericht aan 64-bits gebruikers dat ik bezig ben met het oplossen van een kever wat het correct compileren in 64 bits verhindert. In de volgende post zullen we een belangrijk onderdeel van de x86-architectuur zien, de GDT.


Laat je reactie achter

Uw e-mailadres wordt niet gepubliceerd. Verplichte velden zijn gemarkeerd met *

*

*

  1. Verantwoordelijk voor de gegevens: Miguel Ángel Gatón
  2. Doel van de gegevens: Controle SPAM, commentaarbeheer.
  3. Legitimatie: uw toestemming
  4. Mededeling van de gegevens: De gegevens worden niet aan derden meegedeeld, behalve op grond van wettelijke verplichting.
  5. Gegevensopslag: database gehost door Occentus Networks (EU)
  6. Rechten: u kunt uw gegevens op elk moment beperken, herstellen en verwijderen.

  1.   Naam zei

    Laten we eens kijken of je commentaar geeft op het oplossen van de bug, want ik ben niet verder gegaan vanaf het eerste deel.

    1.    O_Pixote_O zei

      Ik denk dat ze commentaar gaven op de fout in de opmerkingen van post 2. Ze dachten dat het iets van grub was als ik het me goed herinner

  2.   Blauwe schedel zei

    Kopieer tot ziens?

    1.    Blauwe schedel zei

      Byte voor byte klaarblijkelijk ..., 2 opeenvolgende mislukkingen maken geen succes, bevestigd.

  3.   ruby232 zei

    Heel erg bedankt voor het zeer goede bericht en ik volg het, ik heb enkele vragen:
    1. Als u zegt 'ASM op een gemakkelijke manier bellen vanaf C, wordt de asm-instructie gebruikt, met het gevaar dat het inhoudt dat het niet draagbaar is', wat bedoel je dan als je zegt 'met het gevaar dat het met zich meebrengt dat het is niet draagbaar '?

    2. Als er een 'professioneel' besturingssysteem gemaakt zou worden (om zo te zeggen), dan zou dit deel van de toegang tot de hardware gedaan worden in Assembler.

    3. Hoe zou het worden gedaan in Assembler?

    1.    AdrianArroyoStreet zei

      Dankzij u voor het volgen, zal ik de vragen een voor een beantwoorden:
      1- Welnu, het probleem met de asm-instructie is dat deze in geen enkele C-standaard bestaat, dus elke compiler implementeert deze op zijn eigen manier (als hij deze implementeert). In dit geval kan het worden gecompileerd met GCC en Clang (het lijkt in dit opzicht veel op GCC), maar zul je niet kunnen in andere compilers zoals Intel C (dit gebruikt Intel Syntax in ASM).
      2- Professioneel gezien moeten een deel en een ander duidelijk worden gescheiden door architecturen en een ander gemeenschappelijk deel. Het is niet nodig om het in assembler te doen (Linux heeft het in C)
      3- In assembler is het ook heel eenvoudig, maar je hebt het in een apart bestand. Aan de andere kant, als we argumenten hebben, moeten we het eerst doorgeven aan de registers en dat kan een beetje meer verknoeien, dan wordt outb of inb aangeroepen en wordt de functie gedeclareerd als globaal zichtbaar. Dan moet je van C een header maken die een "externe" functie declareert. In NASM (Intel Syntax) zou het ongeveer zo zijn:
      uitb:
      duw ebp
      mov ebp, in het bijzonder

      verplaats eax, [ebp + 12]
      movedx, [ebp + 8]

      uit dx, al

      beweeg vooral, ebp
      pop eb
      roten

  4.   Max zei

    Vraag, welke syntaxis gebruik je? Ik begrijp niet waarom zoveel verschillende asm xD MASM, FASM, NASM, AT & T ...
    En als je tijd hebt, zou je de zin kunnen uitleggen:
    asm vluchtig ("outb% 1,% 0" :: "dN" (poort), "a" (waarde));

    Tot "asm vluchtig" begreep ik xD "outbyte 1,0?"
    Of is het 1 -> »dN» (poort), 0 -> «a» (waarde)?
    Als het het laatste is, begrijp ik niet wat "dn" en wat "a" is ...

    Heel erg bedankt voor je bijdragen! Ongelofelijk !!

    1.    AdrianArroyoStreet zei

      De syntaxis die ik gebruik is AT&T, wat GCC intern gebruikt, hoewel het zonder problemen kan worden gedaan in NASM (de syntaxis aanpassen). Wat betreft die complexe verklaring van asm vluchtig, kan ik je alleen vertellen dat dit zo is vanwege de GCC, omdat het enkele parameters gebruikt om te weten hoe de gegevens moeten worden doorgegeven. "A" is bijvoorbeeld een speciale x86-operand die wordt gebruikt om het a-register weer te geven. De volledige lijst is hier: http://gcc.gnu.org/onlinedocs/gcc/Constraints.html#Constraints

  5.   charizardfire52 zei

    Nou, ik heb echt hulp nodig, ik ben hier nieuw in en ik heb geen flauw idee wat ik moet doen met wat er in de terminal staat.