Page 1 of 1

What is the best way for user programs to access the kernel?

Posted: Fri Feb 07, 2014 10:37 pm
by computertrick
Lets say I have a printf function in my kernel what would be the most wise way for the user program to communicate with it. Lets assume they are using C. In the header that contains printf I could have an interrupt linking to the kernel? Or are their better ways of guiding the user program to the correct routine.

Code: Select all

#ifndef STDIO_H
#define STDIO_H
#include <interrupts.h>
void printf(const char *s, ...)
{
    Int(0x80);
}
#endif

Re: What is the best way for user programs to access the ker

Posted: Fri Feb 07, 2014 10:50 pm
by neon
There is no "best" way. This is one possible method though that might provide some ideas. Note _write and _service_request are system calls defined in your system API that provide the interface between the running processes and kernel or executive software.

Process -> _printf -> _fwrite(stdout) -> _write -> _service_request -> sysenter -> kernel sends virtual driver request. The virtual driver emulates a standard console window and displays the text. It may also be a real console driver.

Basically, you want to separate the C run time library calls from the System API calls. The actual call to kernel land can also be separated from the system API.

Re: What is the best way for user programs to access the ker

Posted: Sat Feb 08, 2014 12:23 am
by computertrick
could you provide more information?

Re: What is the best way for user programs to access the ker

Posted: Sat Feb 08, 2014 12:35 am
by windows8
I think you can write this macro to call a syscall with three parameters:

Code: Select all

#define __syscall3(ret,name,a1,__a1,a2,__a2,a3,__a3)  \
   ret name(a1 __a1,a2 __a2,a3 __a3) \
   { \
      unsigned long __ret; \
      asm volatile( \
         "int $0xff" \
         : "=a" (__ret) \
         : "a" (__NR_##name),"b" ((unsigned long)__a1), \
           "c" ((unsigned long)__a2),"d" ((unsigned long)__a3) \
      ); \
      return (ret)__ret; \
   }

Then you can write this code below easiler (the "write" syscall):

Code: Select all

#define __NR_write 0x3 

__syscall3(unsigned long,write,int,fd,const void *,buf,unsigned long,size);
In your header file:

Code: Select all

unsigned long write(int fd,const void *buf,unsigned long size);
At last,you are able to write "printf":

Code: Select all

int printf(const char *string,...)
{
   char buf[512];
   /*.....*/
   int n = vsnprinf(buf,sizeof(buf),string,va_args);
   return write(stdout,buf,n);
}

Re: What is the best way for user programs to access the ker

Posted: Sat Feb 08, 2014 1:50 am
by hometue
Just curious, if you have the same function in the C library and kernel which one would be faster/more efficient to use?

Re: What is the best way for user programs to access the ker

Posted: Sat Feb 08, 2014 2:00 am
by bluemoon
hometue wrote:Just curious, if you have the same function in the C library and kernel which one would be faster/more efficient to use?
Technically it runs at same speed.
However, the concern is on the overhead of context switch, sanity checks, extra processing and wrappers.

Re: What is the best way for user programs to access the ker

Posted: Sun Feb 09, 2014 3:11 pm
by Combuster
windows8 wrote: char buf[512];
/*.....*/
int n = vsnprinf(buf,sizeof(buf),string,va_args);
Incoming buffer overflow! :wink:

Re: What is the best way for user programs to access the ker

Posted: Sun Feb 09, 2014 3:39 pm
by neon
computertrick wrote:could you provide more information?
Thing is, I shouldn't need to. It is something that is easy to pick up from user mode programming.

Basically, no CRT routine should be calling the operating system or executive directly; _printf in particular should be calling _fwrite (stdout) which in tern should be calling your system API _write method that which can issue the operating system call and traps into kernel land. The kernel should issue a driver request to the output console virtual driver to display the message. Routines like _brk may call a system API _heap_alloc routine that which may issue the operating system call.

We also recommend the use of sysenter over software interrupts. The routine that calls the operating system should not be easily accessible by user mode software.

In other words, we have multiple layers:

1. Process, calls CRT;
2. C Run Time Library (CRT) calls System API;
3. System API calls _service_request;
4. _service_request traps into kernel land and calls the operating system;
5. Operating system performs the task or hands it off to some other process or driver to handle it.

The System API acts as the interface between the CRT/Process and the underlying operating system call. System API calls may either be real functions or forwarding functions to a look up table used by _service_request to issue the actual software interrupt or sysenter call.

Note that although this setup is fairly complicated, you never requested the easiest method.

Re: What is the best way for user programs to access the ker

Posted: Sat Feb 15, 2014 3:50 am
by rdos
There is a far easier method, which unfortunately on Intel processors (but not as much on AMD processors) have received no optimization attempts and thus typically is slower than the whole bunch of decoding needed for a central kernel entry-point. The method uses one call-gate per syscall and thus enters directly into the service routine in the device driver.