Hacker News new | ask | show | jobs
by peter_d_sherman 825 days ago
A future simple linux-like (or unix-like) OS -- could theoretically be created with only 4 syscalls:

open() read() write() close()

Such a theoretical linux-like or unix-like OS would assume quite literally that "everything is a file" -- including the ability to perform all other syscall/API calls/functions via special system files, probably located in /proc and/or /sys and/or other special directories, as other posters have previously alluded to...

Also, these 4 syscalls could theoretically be combined into a single syscall -- something like (I'll use a Pascal-like syntax here because it will read easier):

FileHandleOrResult = OpenOrReadOrWriteOrClose(FileHandle: Integer; Mode: Integer; pData: Pointer; pDataLen: Integer);

if Mode = 1 then open();

if Mode = 2 then read();

if Mode = 3 then write();

if Mode = 4 then close();

FileHandle is the handle for the file IF we have one; that's for read() write() and close() -- for open() it could be -1, or whatever...

Mode is the mode, as previously enumerated.

pData is a pointer to a pre-allocated data buffer, the data to read or write, or the full filename when opening...

(And of course, the OS could overwrite it with text strings of any error messages that occur... if errors should occur...)

pDataLen is the size of that buffer in bytes.

When the Mode is open(), pData contains a string of the path and file to open.

When Mode is read(), pData is read to, that is, overwritten.

When Mode is write(), pData is used to write from.

All in all, pretty simple, pretty straightforward...

A "one syscall Linux or Unix (or Linux-like or Unix-like) operating system", if you will... for simplicity and understanding!

(Andrew Tannenbaum would be pleased!)

Related: "One-instruction set computer" (OISC): https://en.wikipedia.org/wiki/One-instruction_set_computer

3 comments

That's already kind of how syscalls work - you shove the syscall number in a register, and then call an interrupt.
You've effectively reinvented 9p here. Which is good!

There are some differences which may interest you: https://9fans.github.io/plan9port/man/man9/intro.html

I think you may find that some of the additional complexity of 9p is necessary, but perhaps not all of it.

I had considered that too, but what I had also considered, and that I think is better, is a different single syscall, which is more like a actor model or like a capability-based system. (One problem with the "everything is a file" like Plan9 is that then the operating system has to parse the file paths every time you want to do any I/O; what I describe below ignores that problem since you can link directly to objects instead.)

A process has access to a set of capabilities (if it does not have any capabilities, then it is automatically terminated (unless a debugger is attached), since there is nothing for the program to do).

A "message" consists of a sequence of bytes and/or capabilities. (The message format will be system-independent (e.g. the endianness is always the same) so that it works with emulation and network transparency, described below.)

A process can send messages to capabilities it has access to, receive messages from capabilities it has access to, create new capabilities (called "proxy capabilities"), discard capabilities, and wait for capabilities.

Terminating the process is equivalent to a mandatory blocking wait for an empty set of capabilities; discarding all capabilities also terminates the process. A non-blocking wait for an empty set of capabilities means that you wish to yield, so that other processes get a chance to run, before this process continues.

Some further options may be needed to handle multiple locking and transactions, and to avoid some kinds of race conditions, but mostly that is just it.

This is useful for many things, including sandboxing, emulation, network transparency (this can be done by one program keeping track of which capabilities need to be sent across the network link and assign an index number to each one, and then the other end will create a proxy capability for each index number and use that number when it wants to send back), security with user accouts, etc; the kernel does not need to know about all of these things since they can be implemented in user code.

Other things (outside of the kernel) can also be implemented in terms of proxy capabilities, and I had ideas about those other parts of the operating system too, for example it has a hypertext file system (with no file names, but files can contain multiple numbered streams, which can include both bytes and links to other files (which can be either to the current version or to a fixed version; if to a fixed version then copy-on-write will be used if the file is modified)), and the "foreign links table", and a common (binar) data format, and a command shell with some similarities than Nushell (but also many differences), and the system uses the "Extended TRON Code" character set, and details about the working of the package manager and IME and window manager, etc.