Operating-System Structures

Operating-System Structures

  • An environment for the execution of programs and services to programs and users
  • Providing functions that are helpful to the user:
    • User interface
    • Program execution
    • I/O operations
    • File-system manipulation
    • Communications
    • Error detection

Operating System Services (Cont.)

  • Another set of OS functions exists to ensure the efficient operation of the system itself via resource-sharing
    • Resource allocation
    • Protection and security
    • Protection involves ensuring that all access to system resources is controlled
    • Security of the system from outsiders requires user authentication extends to defending external I/O devices from invalid access attempts

A View of Operating System Services

User Operating System Interface - CLI

  • CLI or command interpreter allows direct command entry
  • Sometimes implemented in kernel, sometimes by systems program
  • Sometimes multiple flavors implemented – shells
  • Primarily fetches a command from user and executes it
  • Sometimes commands built-in, sometimes just names of programs
  • If the latter, adding new features doesn’ t require shell modification

Bourne Shell Command Interpreter

System Calls

  • Programming interface to the services provided by the OS Typically written in a high-level language (C or C++)

  • Mostly accessed by programs via a high-level Application Programming Interface (API) rather than direct system call use

  • Three most common APIs are Win32 API for Windows, POSIX API for POSIX-based systems (including virtually all versions of UNIX, Linux, and Mac OS X), and Java API for the Java virtual machine (JVM)

System Calls

  • System call sequence to copy the contents of one file to another file

Application Programming Interface

  • Typically, application developers design programs according to an application programming interface (API).
  • The API specifies a set of functions available to an application programmer, including the parameters that are passed to each function and the return values the programmer can expect.
  • A programmer accesses an API via a library of code provided by the operating system. In the case of UNIX and Linux for programs written in the C language, the library is called libc.

Application Programming Interface

  • Why would an application programmer prefer programming according to an API rather than invoking actual system calls?

    • Program portability

    • Actual system calls can often be more detailed and difficult to work with than the API.

    • A strong correlation between a function in the API and its associated system call within the kernel.

System Call Implementation

  • Typically, a number associated with each system call System-call interface maintains a table indexed according to these numbers

  • The system call interface invokes the intended system call in OS kernel and returns the status of the system call and any return values The caller needs to know nothing about how the system call is implemented

  • Most details of OS interface hidden from programmer by API
    Managed by run-time support library (set of functions built into libraries included with compiler)

Example of Standard API

API – System Call – OS Relationship

Types of System Calls

  • Process control
    • create process, terminate process
    • end, abort
    • load, execute
    • get process attributes, set process attributes
    • wait for time
    • wait event, signal event
    • allocate and free memory
    • Dump memory if error
    • Debugger for determining bugs, single step execution
    • Locks for managing access to shared data between processes

Types of System Calls (Cont.)

  • File management
    • create file, delete file
    • open, close file
    • read, write, reposition
    • get and set file attributes

Types of System Calls (Cont.)

  • Protection
    • Control access to resources
    • Get and set permissions
    • Allow and deny user access

Standard C Library Example

  • C program invoking printf() library call, which calls write() system call

C Libraries

System Calls and I/O Operations for Files

creat

  • This system call creates a new empty file with a system call. It is available in the fcntl.h library, which is a file handling library for Unix and Linux.

  • The return type for this function is an integer. If file creation is successful, it returns a non-negative integer. If the creation of the file fails, it returns -1.

  • The following shows the syntax. int creat(char *filename, mode_t mode);

  • The first parameter in the creat function is the name of a file.

creat contd…

  • The second parameter, mode, deals with the permissions of the file. The permission modes are different from normal Linux file system permissions. There are various modes available for this flag, but the following are the most common modes.

  • O_RDONLY: If you set this flag mode to the creat function, the file has read-only permission.

  • O_WRONLY: This mode gives write permissions.

  • O_RDWR: This mode gives both read and write permissions.

  • O_EXCL: This flag mode prevents the creation of a file if it already exists.

  • O_APPEND: This mode appends the content to existing file data without overriding it.

  • O_CREAT: This flag mode creates a file if it does not exist.

  • If you want to use multiple modes at the same time, you can use the bitwise OR operator.

Example: create.c

open

  • The open system call function opens a file and can perform read and write operations based on the mode set to the function. An open system call can also create a file.

  • If the specified filename is not available, then it automatically creates a new file with the given name. The return type of this function is an integer.

  • If the file opens successfully, it returns a positive integer value; otherwise, it returns -1.

  • The following shows the syntax.

int open(const char *filepath, int flags, ...);

  • The first parameter deals with the absolute path of a file that you want to open.

  • The flags that are passed as a second argument are O_RDONLY, O_ WRONLY, O_RDWR, and so forth.

  • Example: open.c

close

  • This system call closes the file descriptor that was created to open, create, or read the contents in a file. The return type of this function is an integer.

  • If the file descriptor is closed successfully, it returns 0; otherwise, it returns -1.

  • The following shows the syntax.

    int close(int file_descriptor);

  • file_descriptor is an integer value that identifies the open file in a process.

  • Example: close.c

read

This function system call reads the content of a file that was indicated by a file descriptor. The return type of this function is an integer. It returns -1 if an error occurs or when any signal interrupt occurs during a read operation. A successful read of a file returns the number of bytes read during the operation.

The following shows the syntax.

size_t read (int file_descriptor, void* buffer, size_t size);

  • file_descriptor is a unique integer value that identifies the open file in a process.

  • The buffer argument reads the file data.

  • size is the third argument indicates the size of the buffer that you want to read from the file.

Example:read.c

write

  • This function writes content to a given file descriptor.

  • The return type of this file is an integer. It returns -1 for an error or if any signal interrupt is raised; otherwise, it returns the number of bytes that are returned to a file.

  • The following shows the syntax.

size_t write (int file_descriptor, void* buffer, size_t size);

  • This function syntax is the same as the read function. However, the key difference is that it writes the content in a file using the buffer. The read function reads the content from a file using a buffer.

  • Example: write.c

System Calls for Directories: Creating a Directory

  • The creation of a directory is done with the mkdir function, which is available in the sys/ stat.h library. The return type of this function is an integer.
  • It returns 0 on the successful creation of a directory; it returns -1 for a failure.

int mkdir(const char *path, mode_t mode);

  • path is the first argument that describes the path and the new directory name to create in the system.

  • mode represents the permissions to give to a new directory.

Deleting a Directory

  • The deletion of a directory is done with the rmdir function, which is available in the sys/stat.h library. The return type of this function is an integer.

  • It returns 0 on the successful deletion of a directory; it returns -1 if a failure.

  • The following shows the syntax.

int rmdir(const char *pathname);

  • pathname determines the directory name with the absolute path to remove from the system.

Getting the Current Working Directory

  • The getcwd function gets the current working directory.
  • It is available in the unistd.h library. The return of this function is a character data type. It returns the program’s current working directory.

char getcwd(char *buffer, size_t buffersize);

  • buffer is the first argument; it describes the char array that stores the buffer content.

  • buffersize is the second argument; it is the length of the buffer.

Changing Directory

  • There is a chdir system call that changes directory in your operating system. It is available in the unistd.h library.

  • The return type of this function is an integer. It returns 0 on the successful change in a directory; it returns -1 for a failure.

  • The following shows the syntax.

int chdir(const char *path);

  • path describes the path to change.

Reading a Directory

  • There are two types of functions that read the content in directories: opendir and readdir.
  • They are available in the dirent.h library. The return type of the opendir function is the directory stream.
  • A directory stream is an ordered sequence of all directory entries in a directory. A directory entry represents the files. This directory stream points to the start position.
  • The return type of readdir is a dirent structure, which returns NULL if the directory reaches its end. Dirent is a built-in structure that is implemented in the dirent.h library.
  • The following shows the syntax.

DIR *opendir(const char *path);

Reading a Directory Contd..

  • The path argument indicates the value that you want to open.

struct dirent *readdir(DIR* directorypointer);

  • The directorypointer argument should contain the directory stream pointer, which is a return value of the opendir function.

  • The internal structure of dirent is as follows.

struct dirent{

ino_t d_ino; // inode number

off_t d_off; // offset to the next dirent unsigned short d_reclen; // length of this record unsigned char d_type; // type of file;

char d_name[256]; // filename

};

Closing a Directory

  • The closedir function closes the directory stream that is running in a process. The return type of this function is an integer.
  • It returns 0 on the successful closing of a directory; it returns -1 for a failure.
  • The following shows the syntax.

int closedir(DIR *directorypointer);

  • directorypointer is an argument that contains the directory stream pointer, which is simply a return value of the opendir function.

System Programs

  • Provide a convenient environment for program development and execution
    • File management
    • Programming-language support
    • Program loading and execution
    • Communications

Linker loader

  • A loader is used to load the binary executable file into memory, where it is eligible to run on a CPU core.
    • An activity associated with linking and loading is relocation , which assigns final addresses to the program parts and adjusts code and data in the program to match those addresses.
    • Most systems allow a program to dynamically linked libraries ( DLLs ) as the program is loaded.
    • Object files and executable files typically have standard formats that include the compiled machine code and a symbol table containing metadata about functions and variables that are referenced in the program.
    • For UNIX and Linux systems, this standard format is known as ELF (for Executable and Linkable Format ).

Linker and Loaders

Operating System Design: Monolithic UNIX System Structure

  • Beyond simple but not fully layered

Linux System Structure

Layered Approach

Microkernel System Structure

  • Darwin macOS is example of microkernel OS

Hybrid Systems

  • Hybrid combines multiple approaches to address performance, security, usability needs
  • Apple Mac OS X hybrid, layered, Aqua UI plus Cocoa programming environment Two system call interfaces: Mach traps and BSD

Window Subsystem for Linux

System Boot

  • Bootloader is the first program that executes after power, and it never relies on the kernel. Like Uboot, Vivi, BIOS
  • Bootstrap, the second stage boot loader, belongs to kernel code that act as a link between bootloader and kernel mirroring.
  • Bootstrap typically verifies kernel mirroring, compresses kernel mirroring, deploys kernel mirroring to memory, and provides the appropriate context for kernel execution Execution Process –>bootloader–>bootstrap (HEAD.O)–> kernel vmlinux (HEAD.O)–> kernel Start_kernel (MAIN.O)

Performance monitoring tools

  • Counters
    • Operating systems keep track of system activity through a series of counters.
    • Per-Process
    • ps —reports information for a single process or selection of processes
    • top—reports real-time statistics for current processes

Performance monitoring tools

  • System-Wide
    • vmstat —reports memory-usage statistics
    • netstat—reports statistics for network interfaces
    • iostat —reports I/O usage for disks
    • Most of the counter-based tools on Linux systems read statistics from the /proc file system. /proc is a “pseudo” file system

Performance monitoring tools

  • Tracing
    • Whereas counter-based tools simply inquire on the current value of certain statistics that are maintained by the kernel, tracing tools collect data for a specific event—such as the steps involved in a system-call invocation.
    • Per-Process
    • strace —traces system calls invoked by a process
    • gdb —a source-level debugger
    • System-Wide
    • perf—a collection of Linux performance tools
    • tcpdump —collects network packets

BCC (BPF Compiler Collection)

  • On virtualBox Ubuntu look at /usr/share/bcc/tools to see tools

  • The details for the tools are given at https://github.com/iovisor/bcc

References

  • A. Silberschatz, P.B. Galvin, and G. Gagne. Operating System Concepts , 10th Edition; 2018; John Wiley and Sons.
  • W. Stallings. Operating Systems: Internals and Design Principles. Prentice Hall, Upper Saddle River, NJ, Eigth edition, 2014.
  • K.A. Robbins and S. Robbins. UNIX Systems Programming: Concurrency, Communication, and Threads. Prentice Hall, Upper Saddle River, NJ, Second edition, 2003