Page 1 of 1

basic kernel functions

Posted: Mon Aug 22, 2005 7:25 am
by datajack
Im am quite new to OSD, although I have developed with c before. I need to know how one would code functions such as memcpy, memset, memsetw, strlen. I have gone as far as this:

Code: Select all

unsigned char *memcpy(unsigned char *dest, const unsigned char *src, int count)
{

}

unsigned char *memset(unsigned char *dest, unsigned char val, int count)
{

}

unsigned short *memsetw(unsigned short *dest, unsigned short val, int count)
{

}

int strlen(const char *str)
{

}

Re:basic kernel functions

Posted: Mon Aug 22, 2005 7:30 am
by oswizard
Don't expect to get too many replies giving you code, but I'll give you a simple, very basic implementation of strlen. If you've developed with C before, you should be able to take it from there.

Code: Select all

int strlen(const char *s)
{
    int i;
    for (i = 0; s[i] != 0; i++);  // yes, no loop body - loops until s[i] is null
    return i;
}
More info will probably be found in the FAQ (click the forum banner at the top)

Good luck,
Mike

Re:basic kernel functions

Posted: Mon Aug 22, 2005 7:32 am
by Pype.Clicker
you should find any of them in a good book about C programming (e.g. the Kernighan & Ritchie).

You could also use bits of your brain and come with
unsigned strlen (const char* str)
{
// hmm. let's see how far from str we can go before we encounter
// a nul character:
unsigned len=0;
while (*str!=0) {
len++;
str++;
}
return len;
}
or you could head yourself to the FAQ, get the all-in-one introduction page, and discover that we're indeed missing a fast way to find a free implementation of that d*mn stuff everyone needs.

So i suggest you the OSLib if what's above don't fit you.

Re:basic kernel functions

Posted: Mon Aug 22, 2005 7:35 am
by datajack
i dont want the code, i would like an explaination of how to do what i need to do...

Code: Select all

unsigned char *memcpy(unsigned char *dest, const unsigned char *src, int count)
{
    /* the code here is to copy 'count' bytes of data from 'src' to
    *  'dest', finally return 'dest' */
}

unsigned char *memset(unsigned char *dest, unsigned char val, int count)
{
    /* the code here is to set 'count' bytes in 'dest' to 'val'.
    *  Again, return 'dest' */
}

unsigned short *memsetw(unsigned short *dest, unsigned short val, int count)
{
    /* Same as above, but this time, im working with a 16-bit
    *  'val' and dest pointer.*/
}

int strlen(const char *str)
{
    /* This needs to loop through character array 'str', returning how
    *  many characters it needs to check before it finds a 0.
    *  In simple words, it returns the length in bytes of a string */
}
and thanks, i can definintly use these examples to craft my code.

Re:basic kernel functions

Posted: Mon Aug 22, 2005 7:39 am
by Pype.Clicker
basically, those functions are
- either built using inline assembly and dedicated opcode such as 'stosb', 'rep movsd', etc.
- or built using bare stuff such as "*src=*dst" and pointers arithmetics.

Oh, and may i suggest you thoroughly test them with the debugger of your choice in user-land of your host OS before integrating that code into the kernel ?

or did i *again* completely miss the point of your question ?

Re:basic kernel functions

Posted: Mon Aug 22, 2005 8:15 am
by datajack
in memcpy:
if count = 4096
what it needs to do is, copy 4096bytes from src var, to the dest var, and return the value of dest.

in memset:
if count = 4096
what this need to do is, copy 4096bytes in dest to val, and return dest

in memsetw:
same as above but with val as 16bit

int strlen:
this needs to loop through chars untill it reaches NULL(0) and return the length in bytes.

mainly i guess is info on accessing memory and copying values from place to place...

hmm...this is more a c problem that as osd problem....

when i think about it, it might not be that hard as i make it seem...

i think i only need to know how to copy only "count" bytes of data other than all of it...

Re:basic kernel functions

Posted: Mon Aug 22, 2005 8:31 am
by Pype.Clicker
what might enlight you is that (assuming src and dst are char*)

Code: Select all

    char c=*src; // reads character at address <src> into <c>
    src++;          // advance <src> to the next character's address
    *dst=c;         // writes character <c> at address <dst>
and indeed, this is _much_ a C problem so rushing to the library and borrowing "The C programming Language, 2nd edition" by Brian W. Kernighan and Denis M. Ritchie will probably leaves huge amount of mysteries around it.

Re:basic kernel functions

Posted: Mon Aug 22, 2005 8:37 am
by datajack
yes, _much_ a c problem, ill use the _c_ forum next time :)

just a little quickie, is every adress in memory 1 byte?

0x00100000 is one byte and 0x00100001 a whole different byte?

Re:basic kernel functions

Posted: Mon Aug 22, 2005 10:26 am
by ___pissed
Dear friend, no offence what so ever, but shouldn't you tighten your C skills before trying to write an OS?

Asking how to implement memcpy or strlen indicates that you've hardly done any C code at all, not knowing such elementary things how would you go and write an operating system? Don't you think that with such lack of knowledge its a little bit hmmm.. ambitious?

Writing an operating system requires you to master the programming language you write it in, and since you've chosen C I would strongly suggest you grab a C book and go knock down some printf("Hello world\n") programs.

Regards

Re:basic kernel functions

Posted: Mon Aug 22, 2005 12:30 pm
by datajack
lol, im sorry, i dident know what i was thinking when i asked that...i got it, and it works too :) sorry for the stupid(extreamly) question :)

Code: Select all

#include <system.h>

unsigned char *memcpy(unsigned char *dest, const unsigned char *src, int count)
{
    const char *sp = (const char *)src;
    char *dp = (char *)dest;
    for(; count != 0; count--) *dp++ = *sp++;
    return dest;
}

unsigned char *memset(unsigned char *dest, unsigned char val, int count)
{
    char *temp = (char *)dest;
    for( ; count != 0; count--) *temp++ = val;
    return dest;
}

unsigned short *memsetw(unsigned short *dest, unsigned short val, int count)
{
    unsigned short *temp = (unsigned short *)dest;
    for( ; count != 0; count--) *temp++ = val;
    return dest;
}

int strlen(const char *str)
{
    int retval;
    for(retval = 0; *str != '\0'; str++) retval++;
    return retval;
}

unsigned char inportb (unsigned short _port)
{
    unsigned char rv;
    __asm__ __volatile__ ("inb %1, %0" : "=a" (rv) : "dN" (_port));
    return rv;
}

void outportb (unsigned short _port, unsigned char _data)
{
    __asm__ __volatile__ ("outb %1, %0" : : "dN" (_port), "a" (_data));
}

void main()
{
    init_video();

    puts("Hello World!\n");

    for (;;);
}
had to studie memory system crap... and i found my mistake...
i think this question has been answerd, and i will no longer view the thread, if you have any other scornfull suggestions, please, send them to me. :)

--:;Datajack Keeper:;--

Re:basic kernel functions

Posted: Mon Aug 22, 2005 1:27 pm
by NotTheCHEAT
OS dev also requires thorough knowledge of assembly, even if you don't intend to write the main portion of your OS in assembly.
0x00100000 is one byte and 0x00100001 a whole different byte?
You can address locations as bytes, words, or dwords. A word is 2 bytes, a dword 4 bytes. So if you access 0x00100000 as a word, then you automatically access 0x00100001 also (they are one word, but two separate bytes). Accessing 0x00100000 as a dword results in actually accessing 0x00100000, 0x00100001, 0x00100002, 0x00100003. So yes, the memory address is atomic as a byte, but depending on how you access an address, several other addresses are accessed simultaneously, since they're all stored together.