Module syscall

Module syscall 

Source
Expand description

§System call abi for x86_64.

Operating systems provide an abstraction of hardware resources to user programs, allowing them to interact with hardware without needing to understand its complexities. The kernel is responsible for managing resources such as memory, processes, and input/output devices, while offering a simplified interface for user programs. System calls serve as a crucial interface between user applications and the kernel, providing an additional layer of abstraction that enables programs to request services like file I/O and process management, without directly dealing with the hardware.

§System Call Details

The operating system deals with software exceptions, which occur due to program execution errors such as a page fault or division by zero. Exceptions are also the mechanism by which a user program requests services from the operating system. These service requests are system calls.

In traditional x86 architecture, system calls were handled like any other software exception through the int instruction. However, in x86-64 architecture, manufacturers introduced the syscall instruction, which provides a fast and efficient way to invoke system calls.

In modern systems, the syscall instruction is the most commonly used means of invoking system calls. When a user program wants to make a system call, it invokes the syscall instruction. The system call number and any additional arguments are placed in registers before invoking syscall. Here are the key details:

  1. The system call number is passed in the %rax register.
  2. The arguments are passed in the registers %rdi, %rsi, %rdx, %r10, %r8, and %r9. Specifically:
    • %rdi: First argument
    • %rsi: Second argument
    • %rdx: Third argument
    • %r10: Fourth argument
    • %r8: Fifth argument
    • %r9: Sixth argument
  3. The return value is stored to the %rax register.

§Handling System Call in KeOS

When the syscall instruction is invoked, the KeOS kernel serves the requests by calling the Task::syscall method with the state of the CPU captured in a structure called Registers. This structure contains the state of all registers, which is accessible to the handler and allows for the manipulation of register values (including the return value) within the handler.

On the beginning of the Task::syscall method, KeOS parses the arguments of the system call by calling the SyscallAbi::from_registers, which is currently marked with todo!(). Your job is to extend this to retrieve system call number and arguments according to the abi.

After acquiring the SyscallAbi struct, KeOS dispatches the system call handler based on the parsed system call number. This system call handler handles the requests and returns the Result<usize, KernelError> to indicate the result.

§Error Handling via Result Type

Proper error handling is crucial for maintaining system stability and ensuring that unexpected conditions do not lead to crashes or undefined behavior. Errors incured by user MUST NOT stop the kernel. When an error occurs, ensure that the system call returns an appropriate error code rather than panicking or causing undefined behavior. Providing meaningful error messages can also improve debugging and user experience. Properly handling edge cases will help ensure a robust and stable kernel implementation.

To this end, KeOS combines the rust’s Result type with KernelError type to enumerate all possible errors that kernel can make. For example, when implementing system call handlers, you can consider the following error conditions:

During the execution of a function, you might confront the errors. In such cases, you should never handle the errors by panicking the kernel. Instead, you propagates the error with ? operator to the Task::syscall, which conveys the error code to the userspace. Consult with Rust Book for how to use ? operator.

§Returning Value to User

The epilog of the Task::syscall captures both the result and error of the function, interprets them in to the usize, and return the values into the user space. You can update the user program’s registers by directly modify the fields of Registers captured in the SyscallAbi.

§Implementation Requirements

You need to implement the followings:

After implementing both methods, move on to the next Section.

Structs§

SyscallAbi
A struct representing the system call ABI (Application Binary Interface).