The question says it all. When I say interface, I mean what the user interacts with completely. I've got an extensive C background and know enough to make a rudimentary OS but I'd rather not reinvent the OS. Using a linux build (or something else if better) such as Arch I'd like to know the most appropriate and extensive way to be the lowest layer over the OS.
The closest example I can think of to what I'd like is how Android Phones have perfectly usable interfaces with user permissions handled by the OS but it's a modified linux kernel. Is modifying the kernel the best way to go about it, and if so any pointers to setting up any sort of visual system such as OpenGL.
On most systems, one accesses the operating system by triggering an exception of some kind. Usually a processor has some kind of "trigger an exception that calls a system service" instruction. Each system service is identified by a number and that number is passed as either an operating to the exception or as a register value (depending upon the processor).
The normal practice is to have a wrapper function for each system service designed to be called from some high level language. The wrapper unpacks the parameters (usually on the stack) and sets up the hardware registers using those parameters. Then it triggers the exception to invoke the system service. This causes to processor to enter a protected mode and execute the system service. When the system service completes, the wrapper extracts the return values from hardware registers, then packs the result in to the return parameters for the caller.
Related
I'm new to RISC-V and operating system developing, and I'm now trying to make a simple hypervisor-like interface in RISC-V. What stops me right now is that I have no idea about how to trigger a machine call (like RISC-SBI) which stands in firmware level and machine-mode for a user-mode applications? Since recently user-level applications communicate with kernel by system calls. However I may have to make the call skip the kernel and directly to the firmware. How to achieve this for a high-levl application?
I' really in a difficult time. So much thanks for your replies.
To make a system call, load register a0 with which call you want to make (and possibly arguments to the syscall in other registers), then execute an ecall instruction with 01 in func3, which specifies Supervisor mode. To return to user mode after executing the system call code, the OS kernel executes an sret instruction, which returns to User mode from Supervisor mode. This is documented in the Privileged Architecture specification, but I'll admit it requires a bit of knowledge ahead of time to figure out where to look.
I am new to Operating system subject. And I am having trouble in understanding system calls interface. If you could help, I will be thankful.
thanks
I have tried to simply explain the whole process of making a system call.
The kernel provides a set of interfaces by which processes running in user-space can interact with the system. These interfaces give applications controlled access to hardware, a mechanism with which to create new processes and communicate with existing ones, and the capability to request other operating system resources.
These APIs (Application Programming Interfaces) act as the messengers between applications and the kernel, the applications issues various requests and the kernel fulfills them (or returns an error).
System calls provide a layer between the hardware and user-space processes.
But System calls and APIs are not the same thing.
APIs basically are function definitions that specify "how to obtain a specific service".
You generally don't make system calls directly, instead you use an API.
Each system call has a corresponding Wrapping routine, that specifies the API that the application program must use to invoke that system call.
(Wrapper Routines are function definitions whose only purpose is to issue a system call).
However, an API does not have to correspond to a system call, an API can offer its services directly in User mode, without making any system calls, or a single API function can make several different system calls, more so different API functions can invoke the same system call.
An API defines a set of programming interfaces used by applications. Those interfaces can be implemented as a system call, implemented through multiple system calls, or implemented without the use of system calls at all. The same API can exist on multiple systems and provide the same interface to applications while the implementation of the API itself can differ greatly from system to system.
From the programmer's perspective, the distinction b/w API and System call is irrelevant, to them its just another function call all he/she needs to think about is the function name, parameter type and return values. From the kernel designer's point of view the distinction obviously is very significant.
Further, when a User Mode process invokes a system call, the CPU switches to Kernel Mode and starts the execution of a Kernel Function(which happens to be a assembly language function) called the System Call Handler. This System Call Handler has a similar structure to that of other "Exception Handlers".
This System Call Handler first saves the content of the registers in the kernel mode stack.
Then based on the system call number (each system call has a number associated with it and the user mode process must pass this number as a parameter so that the requested call can be identified) the System Call Handler calls the relevant System Call Service Routine which in Linux happens to be a C function that actually goes on to implement the functionality requested by the User Process.
After that's done, registers are loaded back to their previous values and the CPU switches back to User Mode.
The same process can also be represented in a different manner.
A system call interface is a set of functions for requesting a service from the kernel on the operating system they are executed on.It provides an essential interface between the process and the operating system.
For example:
open();
Is a system call used to provide access to a file in a file system and so on.
possibly a really dumb question, but could someone explain why one could not write assembly code to trigger system functions or control hardware? For example, would it not be possible to write code to switch screen off/on or even the device's phone?
I am not talking about jailbreaking the device, nor making an app for the app store. Normal app with assembly to call system functions.
If indeed possible, anyone have a good reference or starting point of achieve such tasks?
Thanks
iPhones use a memory-protected operating system in which each user process is contained in its own virtual memory address space. The address space is protected by the memory management unit (MMU) hardware and trying to access memory outside of regions given to the process by the OS will result in an exception. The OS reserves hardware memory ranges to itself and does not make it available to user processes. As such, it is not possible to directly interface to the hardware from a user process.
It is certainly possible to call system functions from assembly code. And what do you think a C or C++ application does? It does exactly that. C/C++ and assembly code all ultimately convert (at compile time) into machine code that the CPU executes.
I'm not sure where the guide would be for doing things like this, but you can certainly run a C program in a debugger and see how it calls various system functions or you can disassemble this program and read the disassembly without running the program in the debugger.
In any event, you will not get more control over the device from a program written in assembly than from a program written in C. The OS should restrict direct access to certain I/O devices and memory areas at the CPU level, where there's no distinction between assembly and C, it's all the same to the CPU, just a bunch of instructions in machine code.
I wanted to know is there any reason to minimize use of system call in code and what is the alternate of not using system call ,one would say use API but api in turns use system call
Is it True??
Because most system calls have an inherent overhead. A system call is a means of tapping into the kernel, a controlled gateway towards obtaining some service.
When performing a system call, some actions are taken (warning, it's a simplification):
You invoke a library (wrapper) function
The function puts the arguments where they are expected. Also the function puts the number of the system call in eax
The function calls a trap (int 0x80 or whatever)
The processor is switched to kernel mode
The kernel invokes some system_call routine
The registers are saved onto the kernel stack
The arguments are checked to be valid
The action is performed
The registers are restored from the kernel stack
The processor is returned to user mode
The function (finally...) returns
And I probably forgot some of the steps. Doesn't this sound like a lot of work ? All you wanted is the bold part. The rest is overhead.
A system call requires that the system switches from User mode to Kernel mode. This makes system calls expensive.
An article to understand this better:
Understanding User and Kernel Mode - Jeff Atwood
First, if you use framework or APIs (e.g. by using wxWidgets instead of rendering the windows manually, or the GNU C library) your code is portable between different operating systems.
Second, you if you're using APIs you won't have problems if the manufacturer changes how the operating system works under the hood, as the APIs (should) be the same as before.
The only reason that cames to my mind right now is portability issues. If you use system calls, your code will only run on that Operating System. And if you need to compile the same source to another OS, you will be in trouble, the API may be completely different.
An executable problem like exe does not work on Linux (without wine). When compiling source code compiler produce object code which is specific to a particular cpu architecture. But same application does not work with on an another OS with same CPU. I know code may include instructions to specific to the OS that will prevent executable running. But what about a simple program 2+2 ? Confusing part is what the hell that machine code prevents working. Machine code specific to cpu right? If we strip executable file format could we see same machine code (like 2 + 2) for both operating systems?
One more question: What about assembly language? DO windows and Linux use different assembly language for same cpu?.
There are many differences. Among them:
Executable Format: Every OS requires the binaries to conform to a specific binary format. For Windows, this is Portable Executable (PE) format. For Linux, it's ELF most of the time (it supports other types too).
Application Binary Interface: Each OS defines a set of primary system functions and the way a program calls them. This is fundamentally different between Linux and Windows. While the instructions that compute 2 + 2 are identical on Linux and Windows in x86 architecture, the way the application starts, the way it prints out the output, and the way it exits differs between the operating systems.
Yes, both Linux and Windows programs on x86 architecture use the instruction set that the CPU supports which is defined by Intel.
It's due to the difference of how the program is loaded into memory and given resources to run. Even the simplest programs need to have code space, data space and the ability to acquire runtime memory and do I/O. The infrastructure to do these low-level tasks is completely different between the platforms, unless you have some kind of adaptation layer, like WINE or Cygwin.
Assuming, however, that you could just inject arbitrary assembled CPU instructions into the code segment of a running process and get that code to execute, then, yes, the same code would run on either platform. However, it would be quite restricted, and doing complex things like even jumps to external modules would fail, due to how these things are done differently on different platforms.
Problem 1 is the image format. When an application is launched into execution the Os has to load the applicaiton image, find out its entry point and launch it from there. That means that the OS must understand the image format and there are different formats between various OS.
Problem 2 is access to devices. Once launched an application can read and write registries in the CPU and that's about it. To do anything interesting, like to display a character on a console, it needs access to devices and that means it has to ask for such access from the OS. Each Os has a different API that is offered to access such devices.
Problem 3 is priviledges instructions. The newly launched process would perhaps need a memory location to store something, can't accomplish everything with regiestries. This means it needs to allocate RAM and set up the translation from VA to physical address. These are priviledges operations only the OS can do and again, the API to access these services vary between OSs.
Bottom line is that applications are not writen for a CPU, but for a set of primitive services the OS offer. the alternative is to write the apps against a set of primitive services a Virtual Machine offers, and this leads to apps that are more or less portable, like Java apps.
Yes, but, the code invariably calls out to library functions to do just about anything -- like printing "4" to the terminal. And these libraries are platform-specific, and differ between Linux and Windows. This is why it's not portable -- not, indeed, an instruction-level problem.
Here are some of the reasons I can think of off the top of my head:
Different container formats (which so far seems to be the leading differentiator in this answer -- however its not the only reason).
different dynamic linker semantics.
different ABI.
different exception handling mechanisms -- windows has SEH -- upon which C++ exception handling is built
different system call semantics and different system calls -- hence different low-level libraries.
To the second question: Windows only runs on x86, x64, and IA64 (not sure about the mobile versions). For Linux, see here.