Page 1 of 1

connection between C lib and kernel?

Posted: Tue Feb 21, 2006 1:52 am
by McZ
I have looked around altough I can't figure out how the connection between the C library and the kernel works.

as far as I have understand this function needs to "call" the kernel: fopen, fprint, malloc and so on.

but how does this work? is this the ABI I have seen a few people here talked about. is this worked out by using interrupts like DOS int 21h (if I remember correct)

Re:connection between C lib and kernel?

Posted: Tue Feb 21, 2006 2:23 am
by Solar
OK, I guess this is my take. ;-)

Every OS has some way to make a "system call", i.e. calling a kernel function from user space. How that is done is OS-specific. You can place the parameters in registers and call INT 0x80. You can place the parameters in some memory area and call INT 21h. You can place the parameters on a hard drive sectore and trigger a fault handler. (NO!) You can... whatever. Somehow you have to:
  • define which kernel function to call,
  • define which parameters to pass to the function,
  • tell the kernel it should execute the function.
Typically, these system calls are provided as C functions, which internally do the "call-the-kernel-magic" with a bit of ASM (system call stubs). As I said, what has to be done is OS specific. The C library then uses some "glue code" to interface its low-level functions with the system call stubs.

E.g. fopen() - while it has some additional work to do in user space, like setting up buffers etc., it has to tell the kernel to actually open the file, and deliver a file descriptor (on POSIX systems, an integer), which is then stored in the FILE struct for later reference by fread(), fwrite() etc.

When I want my PDCLib to work with Unixes, fopen() will call open(). When I want my PDCLib to work with Win32, I'd call CreateFile() or something like that.

In that regard, this part of the OS API (the system call stubs) is located below the standard library, while the rest of the OS API (that what makes the OS different from others) is either above the standard library, or alongside it.

I hope I make myself clear.

Re:connection between C lib and kernel?

Posted: Tue Feb 21, 2006 2:33 am
by distantvoices
I second that.

The C-Library hides away the "I call the kernel" pecularities.

It also provides parameter checking. althou the called kernel function should check the parameters also - security - better check twice. what if someone finds out how to call the kernel directly and passes some weird stuff?

You will find many purposes to create generalized functions which you want to put into a library to link your executables against. It's a matter of Reusability and flexibility.

Say you implement a widget class which does the very basic things of a. retrieve the clip list from the server and b. calls a widget->draw( widget ) function - and then c. calls the server again after all the dirty work is done with expose( ) - you will find that it is way easier to put this into a library.

Well - I do as much general stuff as possible in library functions.

You 'll also include a function in your library - as solar has stated - which provides the call to the kernel. Mostly its an "int 0xXX" call with parameters passed along either in a structure and a pointer to this structure placed in some all purpose register - or all parameters (if possible) passed along in registers.

So - upon calling the kernel - your c library function tests parameters, prepares - if necessary - a structure - and calls the kernel - either to do grunt work or to pass a message forward to a service.

Well - If I have not just restated what solar has said, I'm a nerd and a git - but me being tired might be an apology, eh?

STay safe

Re:connection between C lib and kernel?

Posted: Tue Feb 21, 2006 2:54 am
by Solar
Just one addition to what BI said here: the system call stubs are to be provided by the kernel; they aren't in the domain of the C library IMHO. The lib provides the "glue code", the OS the stub.

Example from PDCLib work I did this morning (pseudocode):

Code: Select all

#include <errno.h>


/* This is the standard lib function, called regardless of the underlying OS */
int remove( const char * filename )
{
    FILE * fh = getHandleIfOpen( filename ); /* internal PDCLib function */
    if ( fh != NULL )
    {
        /* file is currently open */
        fflush( fh );
        fclose( fh );
    }
    return _PDCLIB_remove( filename ); /* glue function */
}

/* This is the glue function, adapting this particular version of the PDCLib to Linux kernels */
int unlink( const char * filename );
int rmdir( const char * dirname );

int _PDCLIB_remove( const char * filename )
{
    int rc;
    errno = 0;
    rc = unlink( filename );
    if ( errno == EISDIR )
    {
        return rmdir( filename );
    }
    else
    {
        return rc;
    }
}
The functions unlink() and rmdir() are system call stubs. (I hope.) But I think the way the C lib is "glued" to a specific OS becomes clear. (And 'ere you copy this code, take note that Linux isn't POSIX-compliant here - POSIX kernels should set errno to EPERM, and know nothing about EISDIR...)

Re:connection between C lib and kernel?

Posted: Tue Feb 21, 2006 3:09 am
by distantvoices
Yeah, that's the so called kernel library (where the os specific stuff is done). Have forgotten about that, how can I dare ;-)

Re:connection between C lib and kernel?

Posted: Tue Feb 21, 2006 3:22 am
by McZ
Thank you for fast and good answers :)

So if I understand you correct there would be a glue library that does the magic, in the last example code for your PDCLib the glue code for the linux kernel is the remove and unlink functions and those functions will do an interrupt call with specefic input in respective registers so the kernel knows what to do with the data.

so it would be like this:

Code: Select all

/* kernel glue lib */
openfile( const char *file )
{
 /* here we would put the filename
     in a register and call an interrupt.

     And then the kernels interrupt handler 
     for that specefic interrupt will know what to do
 */
  ...
}

/* Kernels interrupt handler */
void interrupt_handler( ... )
{
  /* Check which interrupt */
  ...

 /* call another function for that specefic interrupt */
 ...
}

/* C lib */
fopen(...)
{
 /* do user space stuff */
 ...

 /* Call kernel glue function */
 openfile(...);
}

Re:connection between C lib and kernel?

Posted: Tue Feb 21, 2006 4:32 am
by Solar
Exactly.