Linux Kernel:
Linux Kernel is a small and special code within the core of
the Linux Operating System and directly interacts with the hardware. It
involves process management, process scheduling, system calls, interrupt
handling, bottom halves, kernel synchronization and its techniques, memory
management and process address space.
A process is the program being executed on the processor.
Threads are the objects of activity within the process. Kernel schedules
individual threads. Linux does not differentiate between thread and process. A
multi-threaded program can have multiple processes. A process is created using
the fork call. Fork call will return in the child process and in the parent
process. At the time of the fork, all the resources are copied from the parent
to the child. When the exec call is called, the new address space is loaded for
the process. Linux kernel maintains a
doubly linked list of task structures pertaining to the processes and refers to
them with process descriptors which are used to keep information regarding the
processes. The size of the process structure depends on the architecture of the
machine. For 32-bit machines, it is about 1.7KB. Task structure gets stored in
memory using kernel stack for each process.
A process kernel stack has a low memory address and a high memory
address. The stack grows from the high memory address to the low memory address
and its front can be found with the stack pointer. The thread_struct and the
task_struct are stored on this process address space towards the low memory
address. PID helps to identify the process from one of thousands. The
thread_info_struct is used to conserve memory because storing1.7KB in a 4KB
process space uses up a lot. It has pointers to the task_struct structures. The
pointer is a redirection to the actual data structure and uses up a very tiny
space. The maximum number of processes in linux can be set in the configuration
at pid_max in the nested directories of proc, sys and kernel. A current macro
points to the currently executing task_struct structure. The processes can be
in different process states. The first state to enter when the process is
forked is the ready state. When the scheduler dispatches the task to run, it
enters the running state and when the task exits, it is terminated. A task can
switch between running and ready many times by going through an intermediary state
called the waiting state or the interruptible state. In this state, the task
sleeps on the waiting queue for a specific event. When an event occurs, and a
task is woken up and placed back on the queue. This state is visible in the
task_struct structure of every process. To manipulate the current process
stack, there is an API to set_task_state. The process context is the context in
which the kernel executes on behalf of the process. It is triggered by a system
call. Current macro is not valid in the interrupt context. Init process is the
first process that gets created which then forks other user space processes.
The etc tab entries and init tab entries keep track of all the processes and
daemons to create. A process tree helps
organize the processes. A copy on write is a technique which makes a copy of
the address space when a child edits it. Until that time, all reading child
processes can continue to use only one instance. The set of resources such as
virtual memory, file system, and signals that can be shared are determined by
the clone system call which is invoked as part of the fork system call. If the
page tables need to be copied, then a vfork system call is called instead of
fork. Kernel threads only run within the kernel and do not have an associated
process space. Flush is an example of kernel thread. The ps -ef command lists
all the kernel threads. All the tasks that were undertaken at the time of fork
are reversed at the time of the process exit. The process descriptor will be removed
when all the references to it are removed. A zombie process is not in the
running process. A zombie process is one that is not in the running state, but
its process descriptor still lingers. A process that exists before the child is
a case where the child becomes parentless. The kernel provides the child with new
parents.
No comments:
Post a Comment