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

Vi fortsætter denne række indlæg om, hvordan du opretter vores operativsystem. I dag vil vi ikke fokusere på et emne, men vi vil definere nogle nyttige funktioner fra nu af. Først skal vi definere 3 funktioner, der opfylder funktionen af 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;
}

Alle er selvimplementerende. Disse funktioner har jeg taget fra et lille C-bibliotek, implementeringen er normalt ens i alle operativsystemer. Nu skal vi udføre 3 simulerede funktioner, men at manipulere strenge. De ville udføre funktionen af strcpy, strcat 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;
}

Vi går nu med nogle ganske interessante funktioner. Med disse funktioner kan vi læse og skrive til hardwareporte. Dette gøres normalt med ASM og svarer (på x86) til instruktionerne in y ud. Brug instruktionen for nemt at ringe til ASM fra C ASM, med fare for, at det medfører, at det ikke er bærbart. Til denne sætning tilføjer vi flygtige så GCC ikke forsøger at optimere den tekst. På den anden side har asm-instruktionen en nysgerrig måde at acceptere parametre på, men jeg tror, ​​det forstås bedre ved at se på eksemplerne.

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;
}

Og indtil videre post 3, i dag har vi ikke gjort noget prangende, men vi har definerede funktioner, der vil være nyttige i fremtiden. Bemærk til 64-bit brugere, at jeg arbejder på at rette en bug hvilket forhindrer korrekt kompilering i 64 bit. I det næste indlæg vil vi se en vigtig komponent i x86-arkitekturen, 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.

  1.   Navn sagde han

    Lad os se, om du kommenterer, hvordan du løser fejlen, fordi jeg ikke kom videre fra første del.

    1.    O_Pixote_O sagde han

      Jeg tror, ​​de kommenterede fejlen i kommentarerne til indlæg 2. De troede, det var noget fra grubben, hvis jeg ikke husker rigtigt

  2.   Blå kranium sagde han

    Kopier farvel til farvel?

    1.    Blå kranium sagde han

      Byte for byte åbenbart ..., 2 på hinanden følgende fejl gør ikke en succes, bekræftet.

  3.   ruby232 sagde han

    Mange tak for det meget gode indlæg, og jeg følger det, jeg har nogle spørgsmål:
    1. Når du siger 'At kalde ASM fra C på en nem måde, bruges asm-instruktionen med fare for, at det medfører, at det ikke er bærbart', hvad mener du, når du siger 'med fare for, at det medfører, at det ikke er bærbart '?

    2. Hvis der skulle oprettes et 'professionelt' operativsystem (så at sige), ville denne del af adgangen til hardware ske i Assembler.

    3. Hvordan ville det gøres i Assembler?

    1.    AdrianArroyoStreet sagde han

      Tak til dig for at følge det, jeg vil besvare spørgsmålene en efter en:
      1- Nå, problemet med asm-instruktionen er, at den ikke findes i nogen C-standard, så hver compiler implementerer den på sin egen måde (hvis den implementerer den). I dette tilfælde kan det kompileres med GCC og Clang (det ligner meget GCC i denne henseende), men du kan ikke i andre compilere som Intel C (dette bruger Intel Syntax i ASM).
      2 - Professionelt skal den ene del og den anden være klart adskilt af arkitekturer og en anden fælles del. Det er ikke nødvendigt at gøre det i samler (Linux har det inde i C)
      3- I assembler er det også meget simpelt, men du har det i en separat fil. På den anden side, hvis vi har argumenter, skal vi først videregive det til registre, og det kan ødelægge lidt mere, så kaldes outb eller inb, og funktionen erklæres som globalt synlig. Derefter skal du fra C oprette et overskrift, der erklærer en "ekstern" funktion. I NASM (Intel Syntax) ville det være sådan:
      udb:
      skub ebp
      mov ebp, esp

      mov eax, [ebp + 12]
      mov edx, [ebp + 8]

      ud dx, al

      mov esp, ebp
      EBP Pop
      RET

  4.   max sagde han

    Spørgsmål, hvilken syntaks bruger du? Jeg forstår ikke, hvorfor så mange forskellige asm xD MASM, FASM, NASM, AT & T ...
    Og hvis du har tid, kan du forklare linjen:
    asm flygtige ("outb% 1,% 0" :: "dN" (port), "a" (værdi));

    Indtil "asm volatile" forstod jeg xD "outbyte 1,0?"
    Eller er det 1 -> »dN» (port), 0 -> «a» (værdi)?
    Hvis det er sidstnævnte, forstår jeg ikke, hvad der er "dn", og hvad der er "a" ...

    Mange tak for dine bidrag! Utrolig !!

    1.    AdrianArroyoStreet sagde han

      Den syntaks, jeg bruger, er AT&T, hvilket GCC bruger internt, selvom det kan gøres uden problemer i NASM (tilpasning af syntaksen). Med hensyn til den komplekse erklæring om asm-flygtig kan jeg kun fortælle dig, at det er sådan på grund af GCC, da det bruger nogle parametre til at vide, hvordan dataene skal overføres. For eksempel er "a" en speciel x86-operand, der bruges til at repræsentere et register. Hele listen er her: http://gcc.gnu.org/onlinedocs/gcc/Constraints.html#Constraints

  5.   charizardfire52 sagde han

    Nå, jeg har virkelig brug for hjælp, jeg er ny på dette, og jeg har ikke den mindste idé om, hvad jeg skal gøre med det, der står i terminalen, kan nogen hjælpe mig?