View
228
Download
0
Category
Preview:
Citation preview
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