+ All Categories
Home > Documents > Implementing a System Call on Linux 2.6 for i386

Implementing a System Call on Linux 2.6 for i386

Date post: 30-May-2018
Category:
Upload: nguyenvan-thanh
View: 220 times
Download: 0 times
Share this document with a friend

of 22

Transcript
  • 8/9/2019 Implementing a System Call on Linux 2.6 for i386

    1/22

    Chu y rang: chung ta co 2 cach de co the su dung cac dich vu cua kernel thong qua

    system call hoac la thogn qua viec doc file /proc filesystem

    1. Access the linux kernel using the /proc filesystem

    - The /proc filesystem is a virtual filesystem that permits a novel approach for

    communication between the Linux kernel and user space.

    - the content of these virtual files is dynamically created.

    - The /proc filesystem contains directories (as a way of organizing information)

    and virtual files . A virtual file can present information from the kernel to the

    user and also serve as a means of sending information from the user to the

    kernel.

    2. System call

    - A system call is used by application (user) programs to request service from the

    operating system. An operating system can access a system's hardware directly, but a user

    program is not given direct access to the hardware. This is done so that the

    kernel can keep the system safe and secure from malicious user programs.

    But often, a user program requires some information from the hardware

    (e.g., from a web camera to show you the picture), but it cannot get the

    information directly. So, it requests the operating system to supply it the

    information. This request is made by using an appropriate system call.

    - A system call executes in the kernel mode.

    Every system call has a number associated with it. This number is passedto the kernel and that's how the kernel knows which system call was made.

    When a user program issues a system call, it is actually calling a library

    routine.

    The library routine issues a trap to the Linux operating system by

    executing INT 0x80 assembly instruction.

    It also passes the system call number to the kernel using the EAX register.

    . The arguments of the system call are also passed to the kernel using other

    registers (EBX, ECX, etc.).

    The kernel executes the system call and returns the result to the userprogram using a register. If the system call needs to supply the user

    program with large amounts of data, it will use another mechanism (e.g.,

    copy_to_user call).

    - Trong he dieu hanh linux chung ta co 2 che do la user mode va kernel mode.

    User mode is non-privileged in that processes in this mode are not allowed

  • 8/9/2019 Implementing a System Call on Linux 2.6 for i386

    2/22

    to access those portions ofmemory that have been allocated to the kernel or

    to other programs.

    The kernel is a program that constitutes the core of an operating system,

    and it has complete control over all resources on the system and everythingthat occurs on it.

    When a user mode process (i.e., a process currently in user mode) wants to

    utilize a service provided by the kernel (i.e., access system resources other

    than the limited memory space that is allocated to the user program), it

    must switch temporarily into kernel mode, also called system mode, by

    means of a system call.

    Kernel mode has root (i.e., administrative) privileges, including root access

    permissions (i.e., permission to access any memory space or other resources

    on the system). This allows the operating system to perform restrictedactions such as accessing hardware devices or the memory management

    unit (MMU). When the kernel has satisfied the request made by a process,

    it restores that process to user mode

    - System calls can be classified into six groups:

    process management

    interprocess communication,

    memory management

    file system

    initialization and other.- The kernel maintains a list of all registered system calls in the system call table.

    This table assigns each valid system call a unique system call number which

    cannot be changed or recycled. Processes do not refer to system calls by name,

    but rather by their system call number.

    - Each system call is multiplexed into the kernel through a single entry point. The

    eax register is used to identify the particular system call that should be invoked,

    which is specified in the C library (per the call from the user-space application).

    When the C library has loaded the system call index and any arguments, a

    software interrupt is invoked (interrupt 0x80), which results in execution(through the interrupt handler) of the system_call function. This function

    handles all system calls, as identified by the contents of eax. After a few simple

    tests, the actual system call is invoked using the system_call_table and index

    contained in eax. Upon return from the system call, syscall_exit is eventually

    reached, and a call to resume_userspace transitions back to user-space.

  • 8/9/2019 Implementing a System Call on Linux 2.6 for i386

    3/22

    Execution resumes in the C library, which then returns to the user application.

    - This table, shown in Figure 2, uses the index provided in eax to identify which

    system call to invoke from the table (sys_call_table)

    3. Linux system calls

    - A process is able to use services provided by the kernel by making a system call [2].

    Every system call has a specific number. This number is written into the EAX

    register. There can be up to 6 parameters, which are set into the registers EBX, ECX,

  • 8/9/2019 Implementing a System Call on Linux 2.6 for i386

    4/22

    EDX, EDI, ESI and EBP. If a system call needs more than 6 values to pass, it has to

    use pointers to structures, where the additional parameters are stored.

    - To switch to kernel mode the software interrupt 0x80 is called and the system call

    handler calls the system call services routine according to the system call number

    found in the EAX register. The address of every system call service routine is stored

    in the system call table. The system calls return value is stored in the EAX register.

    4. Methods

    There are different ways to gain the system calls of a process.

    - The first idea is to catch them in kernel mode and log the received data into a file. To

    act in kernel mode its necessary to develop a driver [3]. This driver can change the

    system calls in a way that own functions were used instead of the original ones. This

    procedure is called hooking.

    - An easier way is to modify the system call service routines itself and integrate someadditional services into the kernel allowing to control and perform the logging

    process. In this method a driver must also be developed to control which process

    have to be logged.

    - The most user-friendly way would be a method just acting in user mode. Strace is

    such an application, which provides the possibility to log all system calls of a given

    process and its sons. But it doesnt offer all needed information

    - Strace uses the system call Ptrace for its procedures. So this could be a good method

    to gain all required data.

    5. List of files to be modified or createdKernel files to be modified are listed below:

    - /usr/src/linux/arch/i386/kernel/syscall_table.S

    - /usr/src/linux/include/asm-i386/unistd.h

    - /usr/src/linux/include/linux/syscalls.h

    - /usr/src/linux/Makefile

    New kernel files/directories to be created are listed below:

    - /usr/src/linux/mycall - Directory that will contain the source file, header file and

    the Makefile for our system call (You can also implement your system call in an

    existing file).- /usr/src/linux/mycall/mycall.c - Source file containing our system call code.

    - /usr/src/linux/mycall/Makefile Makefile

    New user space files, to be created, to test our system call are listed below:

    - testmycall.c Source file that will call our system call.

    - testmycall.h - Header file.

  • 8/9/2019 Implementing a System Call on Linux 2.6 for i386

    5/22

    6. /usr/src/linux/arch/i386/kernel/syscall_table.S

    - Add a line to the end of this file (Let's assume that the name of our system call is

    mycall).

    - Add ".long sys_mycall" at the end of the list.

    7. /usr/src/linux/include/asm-i386/unistd.h

  • 8/9/2019 Implementing a System Call on Linux 2.6 for i386

    6/22

    - This file contains the system call number that is passed to the kernel through

    the register (EAX) when a system call is invoked.

    - Muc dich: ta khai bao so hieu number cho system call ma chung ta tao ra

    - Add "#define __NR_mycall " at the end of the list.If the last system call defined here is:

    "#define __NR_vmsplice316", then add:

    "#define __NR_mycall317" at the end of the list.

    - Increment the "NR_syscalls" by 1. So, if NR_syscalls is defined as:

    "#define NR_syscalls 317", then change it to:

    "#define NR_syscalls 318"

    8. /usr/src/linux/include/linux/syscalls.h

    - This file contain the declarations for system calls.

    - Add the following line at the end of the file:"asmlinkage long sys_mycall(int i);"

    - Nhu vay rang khi mycall() duoc goi thi no se goi den ham duoc khai bao nhu o

    tren va duoi hinh sau

    -

    9. /usr/src/linux/Makefile

    - Add mycall/ to core-y (Search for regex: core-y.*+=). You will be creating this

    directory. This directory will contain the source file, header file and the Makefile

  • 8/9/2019 Implementing a System Call on Linux 2.6 for i386

    7/22

    for our system call.

    10./usr/src/linux/mycall (new kernel files/directories to be created)

    - Create a new directory in /usr/src/linux and name it "mycall"

    11./usr/src/linux/mycall/mycall.c- Create a source file named "mycall.c" in dir "mycall". mycall.c will have the code

    for our system call. The definition of the system call in the source file would be

    asmlinkage long sys_mycall(...){...} . It should include the file linux/linkage.h So,

    the file "mycall.c" will look like:

    - Asmlinkage is used to look for the arguments on the kernel stack.

    12./usr/src/linux/mycall/Makefile

    - The Makefile in dir "mycall" will have only one line:

    13.testmycall.h (new user space header file to be created) new user space files, to be

    created, to test our system call

    - Create a header file called testmycall.h. This header file should be included by

    any program calling our system call.- Add three lines to it

    Line 1: This is needed because we need the definition of _syscall1.

    #include

    Line 2: This is needed because we need the number of our system call.

    #define __NR_mycall 317

  • 8/9/2019 Implementing a System Call on Linux 2.6 for i386

    8/22

    Line 3: This is needed for system calls with 1 argument. It is explained in

    detail below.

    _syscall1(long, mycall, int, i)

    - So, our user header file looks like:

    14.testmycall.c (new user space source file to be created)- Create a C file called testmycall.c in the same directory as testmycall.h. The C

    file will look like:

    -

    15.Testing for new system call

    - Step 1: Recompile and install the new kernel so that our system call becomes

    available to the operating system.

    - Step 2: Compile and execute the user space C file (testmycall.c) that we createdabove.

    16._syscallN macro

    -

    17.Background User vs. Kernel mode

    - System call, all traps, & interrupts change mode from user to kernel

  • 8/9/2019 Implementing a System Call on Linux 2.6 for i386

    9/22

    - return from system call resets mode to user

    - Transition from User to Kernel Mode

    Note: each different system call has its own number or other identity

    Kernel trap handler uses syscall number to index into table of syscall

    routines- Accessing Kernel via Library interface

  • 8/9/2019 Implementing a System Call on Linux 2.6 for i386

    10/22

  • 8/9/2019 Implementing a System Call on Linux 2.6 for i386

    11/22

  • 8/9/2019 Implementing a System Call on Linux 2.6 for i386

    12/22

    - T y

    i

    y g:

    ly d

    y p g m vi

    ig

    -l v l

    ppli

    i

    P g m I

    PI

    di

    y

    m ll . W

    y

    PI

    y

    m ll ?

    - Su

    u giua

    y

    m

    all va li

    ary

    all:

    - T

    lay rs

    a U

    I

    system:

    - Li

    e m st U

    I

    implementati ns, Linux is mp sed

    three main

    dies

    de:

    Standard Utilities Programs

    Standard Li

    rary

    Kernel- Standard Utilities Programs perform individual speciali ed managementtasks

    Shell ! The U"

    I#

    systems have aGraphical User Interface!Linux uses

    KDE, G"

    O$

    E%

    ,%

    Commandsforthe managementoffilesand directories

    Filters

    Compilers

    Editors

    Commandsfortheadministration ofthesystem

    U&

    I'

    Utility Programs:

  • 8/9/2019 Implementing a System Call on Linux 2.6 for i386

    13/22

    - TheStandard Li(

    rary

    1)9

    The Standard Library

    A system call is the method that the user process uses to ask for anaction from the O.S.

    The programs perform the system calls by mean oft 0 ap.

    trap instruction:

    changes from user mode to kernel mode

    controls the correctness of the call parameters execution done on behalf of the operating system

    returns to user mode

    Since it is impossible to write a trap in C, it is provided a standard librarywith a procedure for each system call. These procedures are written inassembler and are called from C. For example a C program forperforming the system call read, it calls the procedure read ,of thestandard library.

    So, the standard library defines a standard set of functions throughwhich applications interact with the kernel, and which implement muchof the operating-system functionality that does not need the fullprivileges of kernel code.

    POSIX establishes which are the procedures of the library that thesystem has to provide, their parameters and tasks.

  • 8/9/2019 Implementing a System Call on Linux 2.6 for i386

    14/22

    1.10

    TheKer el

    The ker1 el i2

    responsi3

    le for4

    5int

    5ining the i

    4

    port5

    nt5

    3

    str5 6

    tions of theoper

    5ting system .

    It provi7

    es the main f8

    nctions of the abstract machine (system calls andInterr

    8

    pt and traps).

    9pproximate str

    8

    ct8

    re of generic UNI@

    Aernel

    1.11

    The er el

    The Linux kernel uses a monolithic model. It does

    not take the new client-server model (i.e., micro-

    kernel). The main reason for this choice is the

    improvement of the performances .

    The kernel code is executed in kernel mode with fullaccess to all the physical resources of the computer.

    ll kernel code and data are contained in a u nique

    address space.

    lthough the kernel runs as a single process with a

    single address space, Linux kernel uses the

    modularity.

  • 8/9/2019 Implementing a System Call on Linux 2.6 for i386

    15/22

    1.14

    Some irectories found in UNIX systems

    /bin Binaries which are absolutely essential to run Linux.

    /boot ll the files required for booting Linux on a system.

    /dev All the devices have their corresponding files here.

    /etc All the configuration files for the various software are

    stored here. Don't play with this directory.

    /home All users will have their 'My Documents' under this

    directory. If your id is rossi, your 'My Documents' (called

    home-directory) is /home/rossi.

    /lib The libraries required by system-applications. (Just like

    DLLs in Windows.)

    /lost+found When a disk-check finds files which are

    damaged or which are not linked to any directory, they are

    recovered to this directory. uch damages are almost

    always due to incorrect shutdown.

    1.15

    So edirectories found in IX systems

    /mnt The directory where peripherals and other file-

    systems are mounted.

    /opt The directory where optional software are installed.

    /proc proc houses a pseudo-file system. Its contents really

    do not exist anywhere on the disk, and are made available

    only when you cd to this directory and look at some file.

    /root The home-directory for the super-user: root.

    /sbin The system-administration binaries exist here.

    /tmp The directory where temporary files are created and

    stored. All users can save files here.

    /usr Everything related to users

    /var iles whose contents vary frequently are in this

    directory.

  • 8/9/2019 Implementing a System Call on Linux 2.6 for i386

    16/22

    1.16

    Somedirectories found in IX systems

    /usr Everything related to users

    /usr/bin houses critical binaries of the users

    /usr/include The header-files required by programs for compilation .

    /usr/lib The libraries required by user-applications .

    /usr/localB

    iles peculiar to this particular machine.

    /usr/sbin User-administration binaries.

    /usr/share Information that can be shared by most users.

    /usr/src The source-code for the Linux kernel.

    /usr/X11R6 Files needed by the X Window system.

    /var Files whose contents vary frequently are in this

    directory.

    /var/log The log-files of the system.

    /var/spool Directories for mail, news, printing and other queued

    work.

    18.Introducing LKM programming

    - There are several kernel architectures, but the two most important are:

    Monolithic

    Micro-kernel

    - Monolithicn kernel

    The monolithic term means that the kernel is implemented as an only one

    process, with an only address space. It is like when you create a single .cfile, and it is executed as a single process. People that are in favour of this

    model, cite the simplicity as the main goal. With a monolithic kernel,

    communication is simple, and it is possible to call a defined function from

    wherever in the kernel. Most of the UNIX kernels are monolithic (Hurd is

    an exception)

    - Micro-kernel

    The approach for micro-kernel design is simple: Let the kernel perform only

    the essential operations. Everything else that can be performed in user

  • 8/9/2019 Implementing a System Call on Linux 2.6 for i386

    17/22

    space should be done there. In a micro-kernel scenario, the kernel must

    communicate with the other operating system parts. Typically, the memory

    management, file systems and IPC communications are not inside the

    kernel. This model can take advantage of memory protection featuresprovided by modern processors. The drawback is the extra communication

    caused by this distributed schema where every subsystem has it's own

    address space.

    - Linux kernel is Monolithic, but it is also modular, i.e. the kernel can dynamically

    load parts of the kernel code. This is a really nice feature since in this way, it is

    possible to extend the kernel capabilities without modifying the rest of the code.

    With traditionalUNIX kernels, it was necessary to recompile the kernel to add anew feature. Now, it is possible to insert the module while the kernel is running.

    This doesn't produce any problem. Modern UNIX kernels support modules

    loading.

    - Linux kernel module:

    a kernel module is a part of the kernel code. In fact, if you have ever

    compiled your kernel, surely you know this: when we set preferences for our

    customized kernel, we can choose a feature to be compiled as a module or to

    be integrated in the kernel code.

    Almost everything in kernel code can be implemented as a module.However, it is common to implement file systems, drivers or some programs

    that need kernel mode (e.g. performance analysers like vtune).

    if your program needs to work in kernel mode, the best you can do is to

    implement it as a module instead of modifying the rest of the kernel.

    - structure of a kernel module

  • 8/9/2019 Implementing a System Call on Linux 2.6 for i386

    18/22

    The first thing we need to write a module is to include the proper headers.

    These headers are separated from normal headers. The kernel headers are

    in the linux subdirectory in /usr/include.

    The essential headers are:

    #include /* Weare workinginkernelmode*/

    #include /* Specificallyamodule*/

    These two files provide basic definitions to start working with modules.

    - Now we need to indicate some information about our module and ourselves. This

    is not strictly necessary but it is a good practice after all. To do this, we use the

    following macros:

    MODULE_AUTHOR

    MODULE_LICENSE

    MODULE_DESCRIPTION These macros take a string as argument. We continue writing our module:

    MODULE_AUTOR("FernandoApesteguia")

    MODULE_LICENSE("GPL")

    MODULE_DESCRIPTION("Dumbmodule")

    - Now, we need to declare the functions that will perform the module entry and

    exit points respectively.

    intinit_module(void)

    voidcleanup_module(void)

    - Vi du don gian:

  • 8/9/2019 Implementing a System Call on Linux 2.6 for i386

    19/22

    - Basics rule:

    The kernel is a special part of you operating system. Due to this, it is not

    surprising that the rules under the kernel is written are different from the

    normal programming. In fact, if you remember my previous article you

    already know this: remember that we used the printk function instead of

    printf function. And the reason is because printf is a function from the

    standard C library... Let's see the special rules that we must know:

    No libraries support: The modules that we write are linked only

    against the kernel.C

    n the contrary, when we write a normal program

    we are linking to the C library and probably against other libraries like

    theD

    NC

    ME ones. The reason for this feature is complex.C

    ne of the

    reasons is because it could be not secure to let user space libraries to

    execute in privileged mode (from inside the kernel). Moreover, since

    printf calls to write system call, if the write system call calls again to

    printf we could have an infinite loop. Fixed stack size

    When programming in user-space, we have a really big stack size (it

    can grow up to MB's), but in kernel mode we have a fixed size. This size

    depends on the architecture. This fixed size implies various

    restrictions:

  • 8/9/2019 Implementing a System Call on Linux 2.6 for i386

    20/22

    Not to implement deep recursive functions

    Not to define large arrays inside functions. Try to allocate them

    dynamicallyE

    ne of the benefits of this limitation is that the search for thetask_struct of a process can be done with few assembler instructions,

    just applying some bit masks.

    No memory protection

    When we are executing user-mode programs, the kernel cares for not

    corrupt memory. If a user program tries to access to a protected

    memory address, then the kernel returns an error to the process and

    kills it. But the kernel is supervised by nobody, so a memory corruption

    will cause a system crash.

    No Floating PointThe kernel uses integer (fixed) arithmetic. The context for the FPU

    (Float Point Unit) is not automatically saved. You can do this by hand,

    but it is a better idea not to use FPU inside the kernel.

    No MMX

    Because the same reason above showed. The MMX registers are not

    automatically saved.

    - Focusing on system calls: The Syscalls (system calls) are functions inside the

    kernel that allow normal processes to do something. There are 294 syscalls

    defined in a 2.6 linux kernel (#define NR_syscalls 294). You can see the list atunistd.h file. Most of them are self-explanatory like read, write and several

    others. These functions perform the real work that processes need to properly

    work. For example, when a process want to write some data to a file, is the

    kernel trough the write system call who writes data to disk. They are the entry

    point to work in kernel mode.

    - How to deal with syscalls

    There is a method to call syscall routines from user programs. This is done

    by means of and < unistd.h> includes. Using them, it is possible to call a

    syscall service routine with the syntax that follows: calls system callsdirectly.

    syscall(the_syscall,parameter,parameter...)

  • 8/9/2019 Implementing a System Call on Linux 2.6 for i386

    21/22

    19.System calls: mechanism

  • 8/9/2019 Implementing a System Call on Linux 2.6 for i386

    22/22

    - &X^XYJRHFQQNXNRUQJRJSYJIG^FEEXTKY\FWJNSYJWWZUYYMFY

    YWFSXKJWXHTSYWTQYTPJWSJQHTIJNS1NSZ]NYMNXNXEE NSYJWWZUY

    ]9MJXUJHNKNHX^XYJRHFQQGJNSLNS[TPJINXXYTWJINSYMJ EAX

    WJLNXYJWFGINYXFWLZRJSYXFWJMJQINSYMJTYMJWUWTHJXXTWWJLNXYJWX

    .STZWJ]FRUQJYMJSZRGJWFXXTHNFYJIYTWJFINX__NR_readIJKNSJI

    NS

    - 9NRNSL*]JHZYNTS

    In order to measure time lapses we can use the ``timestamp counter''

    processor register. The counter, available on all kinds of Pentium processors

    is a 64 bit register that gets incremented at each clock tick.

    To read the counter a program can invoke the rdtsc assembly instruction.

    After including , (named after "machine specific registers"), C

    code can call readtsc(low,high) to retrieve the 64 bit counter into two 32

    bit variables, orreadtscl(low) to retrieve only the lower half of the

    counter.We'll use the latter form, as we'll just need subtract two values, anoperation immune to 32-bit overflow if the measured difference is less than

    32 bits in size.

    -

    20.


Recommended