Death to System Calls?
Death to System Calls?
I was browsing and this idea came to me and I wanted to write it down before I go to sleep to get up tomorrow.
What if, instead of a fixed set of system calls accessed via a complicated ABI, we created a kernel whose interface to the processes of the system was exposed via a scripting language? Processes would pass scripts in to have the kernel execute actions on their resources, and the kernel would execute those actions and return a result. The only system calls would be submitting a script, and possibly getting the result of the last script.
OK, that's it.
What if, instead of a fixed set of system calls accessed via a complicated ABI, we created a kernel whose interface to the processes of the system was exposed via a scripting language? Processes would pass scripts in to have the kernel execute actions on their resources, and the kernel would execute those actions and return a result. The only system calls would be submitting a script, and possibly getting the result of the last script.
OK, that's it.
- thepowersgang
- Member
- Posts: 734
- Joined: Tue Dec 25, 2007 6:03 am
- Libera.chat IRC: thePowersGang
- Location: Perth, Western Australia
- Contact:
The useful thing about system calls is that they allow for access to kernel procedures from user mode. This means that it is harder for a rouge program to damage the machine.
Although, having only a couple of system calls for simple tasks and then one for executing a script might work... Any other oppinions.
Although, having only a couple of system calls for simple tasks and then one for executing a script might work... Any other oppinions.
Kernel Development, It's the brain surgery of programming.
Acess2 OS (c) | Tifflin OS (rust) | mrustc - Rust compiler
Currently Working on: mrustc
Acess2 OS (c) | Tifflin OS (rust) | mrustc - Rust compiler
Currently Working on: mrustc
How is having a scripting language that can run the same operations as system calls be any better than just system calls. Think about it. You can't really give the script any more priveleges than what can be achieved with regular system calls because then security becomes an issue. Also, the time it will take to process a script will make the system slower than the most badly designed micro-kernel. Think about it, everytime you want to print something to the screen you'll have to make a new script, the kernel will have to process it, and then an interpreter will have to run it. Just imagine processing the same script over and over again. Personally, I'd stick with system calls because frankly there's no point to your idea.
- piranha
- Member
- Posts: 1391
- Joined: Thu Dec 21, 2006 7:42 pm
- Location: Unknown. Momentum is pretty certain, however.
- Contact:
I wanted to post this a while ago, but either my internet or the osdev server was being angry.
So, let me get this straight.
The kernel has it's own scripting language, and there is a system call that loads the script and then returns a value from it like a normal shell script that exits with a value.
I'm assuming that more than one command would get executed in this script, right?
So, lets say that a normal system-call kernel application calls the kernel several times to do stuff, each call returning a value that the application might need. How would the script return values to the application for each command in the script?
The script could be something like a bash script, having the ability to get values from calls and do stuff with them. I guess that answers the above question.
Of course, the application could call the 'load script' system call with the one command that it wanted to run and get a value, the problem with that is that there is unnecessary overhead loading the script, and executing it.
The kernel could store the returned value from every call in an array list (int **returned_values), and that could be returned to the application.
The application would then have to compile a script to be run by the kernel, slowing down a little as well.
Overall, I like the idea, however the are a few issues to work out.
-JL
So, let me get this straight.
The kernel has it's own scripting language, and there is a system call that loads the script and then returns a value from it like a normal shell script that exits with a value.
I'm assuming that more than one command would get executed in this script, right?
So, lets say that a normal system-call kernel application calls the kernel several times to do stuff, each call returning a value that the application might need. How would the script return values to the application for each command in the script?
The script could be something like a bash script, having the ability to get values from calls and do stuff with them. I guess that answers the above question.
Of course, the application could call the 'load script' system call with the one command that it wanted to run and get a value, the problem with that is that there is unnecessary overhead loading the script, and executing it.
The kernel could store the returned value from every call in an array list (int **returned_values), and that could be returned to the application.
The application would then have to compile a script to be run by the kernel, slowing down a little as well.
Overall, I like the idea, however the are a few issues to work out.
-JL
SeaOS: Adding VT-x, networking, and ARM support
dbittman on IRC, @danielbittman on twitter
https://dbittman.github.io
dbittman on IRC, @danielbittman on twitter
https://dbittman.github.io
Instead of using an actual script, bytecode could simply be passed to the kernel. That would speed it up. As for the communication, some sort of protocol would have to be established, me thinks. With that, however, you end up with yet another complicated ABI, so you're back at square one.
C8H10N4O2 | #446691 | Trust the nodes.
- karloathian
- Posts: 22
- Joined: Fri Mar 28, 2008 12:09 am
- piranha
- Member
- Posts: 1391
- Joined: Thu Dec 21, 2006 7:42 pm
- Location: Unknown. Momentum is pretty certain, however.
- Contact:
The system calls are there, however there is processing the result, so just a script might not work.as pretty much every computer program can be expressed as a series of system calls(that's what it looks like to the kernel at least), what's stopping someone from simply writing their entire application in this script.
It would be slower, but it could be useful to support it.
@OP: Do you mind if I start implementing something similar into my kernel as an experiment? (I'm kinda on a low with programming, I'd like something like this to boost my moral.)
-JL
SeaOS: Adding VT-x, networking, and ARM support
dbittman on IRC, @danielbittman on twitter
https://dbittman.github.io
dbittman on IRC, @danielbittman on twitter
https://dbittman.github.io
Pretty much what I was going to say. Realistically, the overhead of doing this would make it impractical, and the problem of the program needing specific value / address returns from parts of the script / system calls would make it very difficult to work out. The only solution would be to either run a handful of system calls in a script at a time and work out the problem of needing intermittent returns, or put the whole program in the script.iammisc wrote:@Alboin, as pretty much every computer program can be expressed as a series of system calls(that's what it looks like to the kernel at least), what's stopping someone from simply writing their entire application in this script.
Either way, performance suffers rather severely I'd imagine, and with no real tangible benefit. It wouldn't really even simplify the kernel since then you'd have to code a parser and interpreter.
At first I thought this wasn't a very feasible idea, as the overhead of interpreting a script could result in quite lackluster performance.
However, after thinking about it for a few minutes, I've changed my mind. If, rather than substituting such a system for a typical API, it was provided as a supplement, it could result in a nice performance boost in syscall-heavy applications.
Say the kernel contains a bytecode interpreter for a very, very simple language. Something about as powerful as batch, if even. It shouldn't provide more than simple branching instructions, a virtual stack, and a syscall instruction.
The calling program could compile a script either at runtime or during compilation. The resulting bytecode would be passed to the kernel, and the ring-0 interpreter would run through the bytecode and copy the results into the process' address space.
The most obvious benefit is a reduction in privilege level changes. If a process needs to issue a number of system calls in succession, such a system could provide a nice alternative to flipping back and forth between ring 0 and ring 3.
However, after thinking about it for a few minutes, I've changed my mind. If, rather than substituting such a system for a typical API, it was provided as a supplement, it could result in a nice performance boost in syscall-heavy applications.
Say the kernel contains a bytecode interpreter for a very, very simple language. Something about as powerful as batch, if even. It shouldn't provide more than simple branching instructions, a virtual stack, and a syscall instruction.
The calling program could compile a script either at runtime or during compilation. The resulting bytecode would be passed to the kernel, and the ring-0 interpreter would run through the bytecode and copy the results into the process' address space.
The most obvious benefit is a reduction in privilege level changes. If a process needs to issue a number of system calls in succession, such a system could provide a nice alternative to flipping back and forth between ring 0 and ring 3.
Yes but since this is a complete scripting language, what is the difference between a regular language and the scripting language. Alboin said he wants to use bytecode. Bytecode is usually connected with virtual machines who are turing-complete. Therefore, you could write a program in this scripting language.piranha wrote: The system calls are there, however there is processing the result, so just a script might not work.
@Alboin, how about, instead of a script you can have regular system call that execute all system calls that are in a user-supplied list.
There wouldn't be. In fact, Inferno, a friend of Plan9, used this idea for most of its applications. They were written in the Limbo programming language, and were then interpreted by the system vm.@Alboin, as pretty much every computer program can be expressed as a series of system calls(that's what it looks like to the kernel at least), what's stopping someone from simply writing their entire application in this script.
The bytecode would save the OS from interpreting the script.Yes but since this is a complete scripting language, what is the difference between a regular language and the scripting language. Alboin said he wants to use bytecode. Bytecode is usually connected with virtual machines who are turing-complete. Therefore, you could write a program in this scripting language.
That would exclude any possibility of having a 'language' surrounding the interface.iammisc wrote:@Alboin, how about, instead of a script you can have regular system call that execute all system calls that are in a user-supplied list.
As for usages of a bytecode syscall interface, Yayyak has an interesting idea. Drivers written in the bytecode would be OS independent (Granted some sort of standard was devised.) and they could easily use high level constructs at a very low level. (eg. having the bytecode compiled from a functional language, native ADT's, etc.)
Also, with a bytecode based language, certain checks could be done upon the driver that could not be otherwise done on normal x86 code.
Toodles,
Alboin
C8H10N4O2 | #446691 | Trust the nodes.
I'm currently attempting to write a kernel in managed code. The idea is that any application is just-in-time compiled to native code from an intermediate language. Using this model, each application can run in ring 0 (because memory safety is guaranteed by the JIT compiler), and I expose certain methods from the kernel that applications can call, so these comprise system calls. The only difference from a standard system call is that no ring-switching is required.
I am assuming that the only reason that you want to use this interpreted idea (which has quite a lot of similarities to safe JIT code) is to avoid unnecessary ring-switching in between sequential system calls. In that case, possibly the best idea (as previously mentioned) is to send a batch of commands to the kernel as an asynchronous request for it to have processed in order as the resources are available. However, having some sort of basic language to encode that you should only execute a certain syscall based upon successful execution of a previous one in the batch is possibly a good idea. I just don't feel that the overhead required in a complete scripting language + interpreter is worth it. It might be interesting to try doing a compile to bytecode of your script as a one off basis and then passing that to the kernel?
Regards,
John.
I am assuming that the only reason that you want to use this interpreted idea (which has quite a lot of similarities to safe JIT code) is to avoid unnecessary ring-switching in between sequential system calls. In that case, possibly the best idea (as previously mentioned) is to send a batch of commands to the kernel as an asynchronous request for it to have processed in order as the resources are available. However, having some sort of basic language to encode that you should only execute a certain syscall based upon successful execution of a previous one in the batch is possibly a good idea. I just don't feel that the overhead required in a complete scripting language + interpreter is worth it. It might be interesting to try doing a compile to bytecode of your script as a one off basis and then passing that to the kernel?
Regards,
John.