kernel functions?

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
McZ

kernel functions?

Post by McZ »

well, I have been thinking.. while I have been reading different posts the standard functions provided in the c-library like printf would be something like this

void printf(const char *, ... )
{
// fix the va_list stuff
...

// then write to the video memory
char *vidmem = 0xb8000;
...
}

altough this writes directly to the memory which I don't understand? that would imply that the userspace-application will have direct memory access!?

and another thing, lets say I go through the kernel doing like this:

void printf(const char *str, ... )
{
// do the va_list stuff
...

// write finished string using a kernel print function
k_printstr( str_buff );
}

but how do I get the user-app to use the kernels print string function? if I link the c-lib directly to the source file of the k_printstr(...); function it won't work as it suppose to becouse if I do like that the k_printstr would be linked to the user-app at compile time and that would make the k_printstr function run in user space which would stop the app from writing to memory.

so then the kernel functions must be aviable through a dynamicly linking, which would allow the c-lib to dynamicly resolve the kernel-k_printstr function.

or is this faaaar from what it "should" be ? ::)
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Re:kernel functions?

Post by Solar »

Somewhere in the guts of fprintf() (for which printf() is a mere wrapper implicitly setting the file descriptor to stdout), there is a system call.

Once everything is done, and you have the readily expanded char* "string" to be printed - you call a kernel function to actually do the printing. Like, write( int fd, char * ). (That's POSIX IIRC.)

How to call a kernel function is an ABI thing, and has nothing to do with the language used (i.e., doesn't necessarily follow C conventions).

Perhaps you put the "magic code" for the function "write()" and its two parameters into registers and then call an interrupt. (AFAIK Linux does it this way.)

Doing the ABI stuff is the C Library - OS interface, or "glue code", which is why you have to write / port a C library for your OS. At the bottom of each C library, there are a dozen or so system calls required to actually implement the whole C lib shebang.

You might want to check out the newlib docs describing the newlib - OS interface, i.e. the required wrappers for system calls (required from any OS that wants to use newlib).

That "glue code" is what gets linked into the application. The "other side" of the call is kernel space.

In the case described above, the interrupt handler could perhaps check whether the application is authorized to call the function, performs the action, puts the return code into a register, and returns.

The C library "glue" code would then take the return code from the register, and properly return from fprintf().

HTH.
Every good solution is obvious once you've found it.
McZ

Re:kernel functions?

Post by McZ »

ahh, now the light came on :)

so the printf opens the stdout using fprintf, is the stdout a static/global filehandle to an existing "file"? or does it act as an file? or is that one up to me?

and I totally forgot about those interupts :o not a good thing when working with an OS ::)
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Re:kernel functions?

Post by Solar »

McZ wrote:
so the printf opens the stdout using fprintf...
Actually:

int printf( char * ctrlstr, ... )
{
va_list ap;
va_start( ap, ctrlstr );
return vfprintf( stdout, ctrlstr, ap );
}

That's it. (Improvised, and possibly wrong - haven't played with va_list yet.)
is the stdout a static/global filehandle to an existing "file"? or does it act as an file? or is that one up to me?
The C runtime environment is expected to provide three predefined file handles (FILE*), them being stdin, stdout, and stderr (which defaults to unbuffered stdout).

Traditionally, the FILE structure (file handle) contains a file descriptor (taking the form of an int), which identifies the "file" to the kernel. The rest of FILE is flags, buffers and the like.

In Unix, traditionally, the value for stdin is 0, stdout is 1, stderr is 2. (Hence the '2>&1' shell output redirection in Unix shells.) The rest is for user-defined file handles.

Whether the kernel handles them as files, or prints to some shell or whatever, is basically up to the kernel.
Every good solution is obvious once you've found it.
Post Reply