Emulimi i Linus Torvalds: Krijoni sistemin tuaj operativ nga e para (III)

Ne vazhdojmë këtë seri postimesh se si të krijojmë sistemin tonë operativ. Sot ne nuk do të përqendrohemi në një temë por do të përcaktojmë disa funksione të dobishme tani e tutje. Së pari ne do të përcaktojmë 3 funksione që përmbushin funksionin e memecpy, 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;
}

Të gjithë ata janë vetë-zbatues. Këto funksione i kam marrë nga një bibliotekë e vogël C, zbatimi zakonisht është i ngjashëm në të gjitha sistemet operative. Tani do të bëjmë 3 funksione të simuluara, por për të manipuluar vargjet. Ata do të përmbushin funksionin e i strukur, shtiza 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;
}

Tani po shkojmë me disa funksione mjaft interesante. Me këto funksione mund të lexojmë dhe shkruajmë në portet e harduerit. Kjo zakonisht bëhet me ASM dhe korrespondon (në x86) me udhëzimet in y nga. Për të thirrur me lehtësi ASM nga C, përdorni udhëzimet ASM, me rrezikun që sjell që të mos jetë i lëvizshëm. Kësaj fjalie i shtojmë edhe i paqëndrueshëm në mënyrë që GCC të mos përpiqet ta optimizojë atë tekst. Nga ana tjetër, udhëzimi asm ka një mënyrë kurioze të pranimit të parametrave, por mendoj se kjo kuptohet më mirë duke parë shembujt.

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

Dhe deri më tani pas 3, sot ne nuk kemi bërë asgjë të dukshme por kemi përcaktuar funksione që do të vijnë në ndihmë për të ardhmen. Njoftim për përdoruesit 64-bit që jam duke punuar në rregullimin e a insekt e cila parandalon përpilimin e saktë në 64 bit. Në postimin tjetër do të shohim një përbërës të rëndësishëm të arkitekturës x86, GDT.


9 komente, lini tuajën

Lini komentin tuaj

Adresa juaj e emailit nuk do të publikohet. Fusha e kërkuar janë shënuar me *

*

*

  1. Përgjegjës për të dhënat: Miguel Ángel Gatón
  2. Qëllimi i të dhënave: Kontrolloni SPAM, menaxhimin e komenteve.
  3. Legjitimimi: Pëlqimi juaj
  4. Komunikimi i të dhënave: Të dhënat nuk do t'u komunikohen palëve të treta përveç me detyrim ligjor.
  5. Ruajtja e të dhënave: Baza e të dhënave e organizuar nga Occentus Networks (BE)
  6. Të drejtat: Në çdo kohë mund të kufizoni, rikuperoni dhe fshini informacionin tuaj.

  1.   emër dijo

    Le të shohim nëse ju komentoni se si të zgjidhni problemin, sepse unë nuk përparova nga pjesa e parë.

    1.    O_Piksot_O dijo

      Unë mendoj se ata komentuan gabimin në komentet e postimit 2. Ata menduan se ishte diçka nga grub nëse e mbaj mend mirë

  2.   Kafkë blu dijo

    Kopjoni lamtumirë në mirupafshim?

    1.    Kafkë blu dijo

      Byte me bajt dukshëm ..., 2 dështime të njëpasnjëshme nuk bëjnë sukses, konfirmuar.

  3.   ruby232 dijo

    Faleminderit shumë për postimin shumë të mirë dhe po e ndjek, kam disa pyetje:
    1. Kur thoni 'Për të thirrur ASM nga C në një mënyrë të thjeshtë, përdoret udhëzimi asm, me rrezikun që të sjellë që të mos jetë i lëvizshëm', çfarë kuptoni kur thoni 'me rrezikun që sjell që nuk është i lëvizshëm '?

    2. Nëse do të bëhej një sistem operativ 'profesional' (për të thënë kështu) kjo pjesë e hyrjes në Hardware do të bëhej në Assembler.

    3. Si do të bëhej në Assembler?

    1.    AdrianArroyoStreet dijo

      Faleminderit që e ndiqni, do t'i përgjigjem pyetjeve një nga një:
      1- Epo, problemi me udhëzimin asm është se ai nuk ekziston në asnjë standard C, kështu që secili përpilues e zbaton atë në mënyrën e vet (nëse e zbaton atë). Në këtë rast mund të përpilohet me GCC dhe Clang (duket shumë si GCC në këtë aspekt) por nuk do të jeni në gjendje të bëni në përpiluesit e tjerë si Intel C (kjo përdor Intel Sintaksën në ASM).
      2- Nga ana profesionale, një pjesë dhe tjetra duhet të ndahen qartë nga arkitekturat dhe një pjesë tjetër e përbashkët. Nuk është e nevojshme ta bëni në assembler (Linux e ka brenda në C)
      3- Në asembler është shumë e thjeshtë, por e keni në një skedar të veçantë. Nga ana tjetër, duke pasur argumente, së pari duhet ta kalojmë te regjistrat dhe kjo mund të jetë pak më e çrregullt, atëherë thirret outb ose inb dhe funksioni deklarohet si i dukshëm globalisht. Pastaj nga C do të duhet të bësh një kokë që deklaron një funksion "të jashtëm". Në NASM (Intel Sintax) do të ishte diçka e tillë:
      dalje:
      shtyn ebp
      ebp mov, esp

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

      jashtë dx, al

      mov esp, ebp
      ebp pop
      mohim

  4.   Max dijo

    Pyetje, çfarë sintakse përdorni? Nuk e kuptoj pse kaq shumë të ndryshëm asm xD MASM, FASM, NASM, AT & T ...
    Dhe nëse keni kohë, a mund ta shpjegoni vijën:
    asm e paqëndrueshme ("outb% 1,% 0" :: "dN" (port), "a" (vlera));

    Deri në "asm paqëndrueshme" e kuptova xD "outbyte 1,0?"
    Apo është 1 -> »dN» (port), 0 -> «a» (vlera)?
    Nëse është kjo e fundit, nuk e kuptoj se çfarë është "dn" dhe çfarë është "a" ...

    Faleminderit shumë për kontributet tuaja! E pabesueshme !!

    1.    AdrianArroyoStreet dijo

      Sintaksa që unë përdor është AT&T e cila është ajo që GCC përdor brenda saj edhe pse mund të bëhet pa probleme në NASM (duke përshtatur sintaksën). Lidhur me atë deklaratë komplekse të asm të paqëndrueshme, unë vetëm mund t'ju them se është kështu për shkak të GCC pasi që përdor disa parametra për të ditur se si duhet të kalohen të dhënat. Për shembull "a" është një operand special x86 që përdoret për të përfaqësuar një regjistër a. E gjithë lista është këtu: http://gcc.gnu.org/onlinedocs/gcc/Constraints.html#Constraints

  5.   zjarr karizmi52 dijo

    ok, me të vërtetë kam nevojë për ndihmë, unë jam i ri në këtë dhe nuk kam idenë më të vogël se çfarë të bëj me ato që shkruhen në terminal, a mund të më ndihmojë dikush?