Title: The
1The system-call interface
- We see how an application program can invoke
privileged kernel services
2Recall our previous lesson
- First, we presented a (simplified) diagram of the
major components in a modern OS - Then, we focused our attention on one of the
kernels interfaces, namely, its role in
controlling hardware devices (specifically the
IDE fixed disk). We saw typical code for
performing an actual device-command. - Today we look at another kernel interface.
3A Modern OS Design
Application
Application
Application
Shared Runtime Libraries
user-mode
supervisor-mode
System Call Interface
memory manager
task manager
file manager
network manager
Device Driver Components
OS Kernel
Hardware
4Our demo bypassed the OS
Application
Application
Application (idnumber)
Shared Runtime Libraries
user-mode
supervisor-mode
System Call Interface
Required IOPL3
memory manager
task manager
file manager
network manager
Device Driver Components
OS Kernel
Hardware
5Role of runtime libraries
- To understand what role is played by the kernels
interface with runtime libraries, lets see how
we could go around them. - We can create a demo-program that does not need
to use the standard C library it will perform
all their work on its own. - If you fire your janitor, you will very quickly
come to appreciate all that he did for you!
6Demo will call kernel directly
Application
Application
Application demo
Shared Runtime Libraries
user-mode
supervisor-mode
System Call Interface
memory manager
task manager
file manager
network manager
Device Driver Components
OS Kernel
Hardware
7A normal C program example
- include ltunistd.hgt // for write()
- include ltstdlib.hgt // for exit()
- char message Hello!\n
- int main( void )
-
- write( 1, message, 7 )
- exit( 0 )
8Standard device-files
- Whenever a new program is launched, the operating
system will automatically open three
device-files, named stdin, stdout, and
stderr, using file-drescriptors 0, 1, 2. - stdin is the standard input device (keyboard)
- stdout is the standard output device (screen)
- stderr is the standard error device (screen)
9Standard C library functions
- The functions write() and exit() were not
actually defined within our program-code - They are examples of external functions
- Header-files let the compiler know how to
generate assembler code that calls them - Their actual definitions are part of the standard
GNU/C runtime-library (glibc) - The linker connects our code to glibc
10The function prototypes
- int write( int fd, char buf, int count )
- void exit( int status )
- The C compiler needs this information to
correctly generate the machine-code for - calls to these external library-functions.
11C program example revised(weve omitted the
header-files)
- extern int write( int, char , int )
- extern void exit( int )
- char message Hello!\n
- int main( void )
-
- write( 1, message, 7 )
- exit( 0 )
12How these calls get compiled
- pushl 7 parameter no. 3
- pushl buf parameter no. 2
- pushl 1 parameter no. 1
- call write call to C
library - addl 12, esp discard params
- pushl 0 parameter no. 1
- call exit call to C
library
13Stacks layout on entering write
32-bits
Parameter number 3 (count)
Parameter number 2 (buf)
parameter number 1 (fd)
Return-address (from EIP)
ESP
14What write function does
- write pushl ebp save callers EBP
- movl esp, ebp point EBP to stacktop
- copy the parameters into general registers
- movl 4, eax sys_WRITE ID-number
- movl 8(ebp), ebx parameter no. 1 to EBX
- movl 12(ebp), ecx parameter no. 2 to ECX
- movl 16(ebp), edx parameter no. 3 to EDX
- int 0x80 enter the linux kernel
- popl ebp restore previous EBP
- ret return to the caller
15What exit function does
- exit pushl ebp save callers EBP
- movl esp, ebp point EBP to stacktop
- copy the parameter into a general registers
- movl 1, eax sys_EXIT ID-number
- movl 8(ebp), ebx parameter no. 1 to EBX
- int 0x80 enter the linux kernel
- Note The exit() function never returns to
the application
16So we dont really need library
- If we are willing to rewrite our program using
assembly language (so that we can refer to cpu
registers by name), we can make system-calls
directly to the kernel (using the int 0x80
trap-instruction) without needing to link our
code to those shared C library functions - Doing this helps us convince ourselves that we do
indeed understand what the role of the C runtime
function-library is its a programming
convenience (puts a pretty face on ugly code).
17Program portability
- If we want a program that can be compiled and
executed on machines with different CPU designs
(e.g., PCs versus MACs), then we will need to
avoid using register-names in our program-code
(i.e., the PCs EAX register doesnt exist on the
MAC) - The shared library hides the differences
between CPUs, since all the CPU-specific work is
done by code within the library
18POSIX
- The Portable Operating System Interface
- Defines a conformance standard that lets
application programmers write code which is
portable across differing architectures - Implemented with header-files and shared runtime
libraries - Documented as an ANSI standard
- Online reference available via man pages
19Frequently needed functions
- Here are a few of the POSIX standard functions
which are most frequently used by applications - open()
- read()
- write()
- close()
- exit()
- Its advisable to learn them! (will save you time)
20Their C function-prototypes
- void exit( int status )
- int read( int fd, char buf, int count )
- int write( int fd, char buf, int count )
- int open( char fname, int flags, )
- int close( int fd )
- NOTE These POSIX functions correspond directly
to Linux kernel system-calls
21function semantics
- We will give a rough general description of the
actions taken by the kernel when these five
frequently needed functions are called - Additional details about each function can be
found online, using the man command - Example man 2 read
22int write( int fd, char buf, int count )
- This function asks the kernel to transfer count
bytes from the array pointed to by buf to the
previously-opened file specified by the
file-descriptor fd. - If the kernel cannot transfer any bytes, it
returns the value -1 otherwise it returns the
number of bytes that the kernel was able to
transfer successfully and advances the
file-pointer accordingly.
23int read( int fd, char buf, int count )
- This function asks the kernel to transfer count
bytes into the array pointed to by buf from the
previously-opened file specified by fd. - If the kernel cannot transfer any bytes, it
returns a value of -1 -- unless the file-pointer
is already at the end of the file otherwise, it
returns the number of bytes successfully
transferred and advances the file-pointer
accordingly.
24int open( char fname, int flags, )
- This function asks the kernel to set up an
internel record establishing a connection between
the file named fname and an unused nonnegative
integer known as a file-descriptor, provided the
files access permissions allow the kind of
access that is specified by the flags argument - The function returns -1 if it cannot perform this
operation otherwise, it returns the
file-descriptor value. - An additional argument when creating a new file
25int close( int fd )
- This function asks the kernel to remove the
connection it had previously set up between the
file-descriptor fd and the internal kernel
record of an associated file. - The value -1 is returned if the kernel was not
succesful in performing this operation (e.g., the
file had already been closed) otherwise, this
function returns 0.
26void exit( int status )
- This function asks the kernel to terminate the
current program, and place the value of status
into the internal record that the kernel had
associated with this program when it was first
launched. - This function will not return any value (because
it does not return at all!)
27In-class exercises
- Modify the mywrite.c demo (see class website)
so it that writes to device 2 instead of device 1 - Try using the debugging tool to single-step
through the execution of filedemo. Watch which
values the kernel returns (in EAX) after each
int 0x80 trap-instruction. Verify that it
indeed created the testfile.dat file. - Write a short program (named myread.c) which
uses standard C library functions to read the
testfile.dat file and write its contents to
stdout