LINUX Notes
LINUX Notes
Q.
Ans : The Kernel is the core program that runs programs and manages hardware
devices, such as disks and printers. It execute the commands which provide by
environment. Kernel provides an interface between shell and hardware.
Q2.
Ans : 1. Multi-tasking :
Linux supports true preemptive multi-tasking. All processes run entirely
independently of each other. No process needs to be concerned with making
processor time available to other processes.
Multi-user access :
A multi-user system is a computer that is able to concurrently and independently
execute several applications belonging to two or more users.
Multi-processing :
Linux also runs on multi-processor architectures. This means that the O. S. can
distribute several applications across several processors.
Architecture independence (Portability) :
Linux runs on several hardware platforms, from the Amiga to the PC to DEC
Alpha workstations. Such hardware independence is achieved by no other
serious O. S.
Demand load executables :
Only those parts of a program actually required for execution are loaded into
memory. When a new process is created using fork(), memory is not requested
immediately, but instead the memory for the parent process is used jointly by
both processes.
Paging :
Linux provide a very important concept of paging. Despite the best efforts to use
physical memory efficiently, it can happen that the available memory is fully
taken up.
Dynamic cache for hard disk :
Linux dynamically adjusts the size of cache memory in use to suit the current
memory usage situation.
Shared Libraries :
1
Ans:
The file structure of any O. S. is includes the arrangement of files & folders.
Linux organizes files into a hierarchically connected set of directories. Each
directory may contain either files or other directories. Because of the similarities
to a tree, such a structure is often referred to as a tree structure and also called
parent-child structure.
The Linux file structure branches into several directories beginning with a root
directory, /. Within the root directory several system directories contain files and
programs that are features of the Linux system. These system directories as
follows :/ root
:
Begins the file system structure, called the root
/fs
:
The virtual file system interface in in the fs directory. The
implementations of the various file systems supported by
LINUX are
held in the respective subdirectories.
/home
:
Contains users home directories
/bin
:
Holds all the standard commands and utility programs
/usr
:
Holds those files and commands used by the system; this
directory
breaks down into several sub-directory
/usr/bin
:
Holds user-oriented commands and utility programs
/usr/sbin
:
Holds system administration commands
/usr/lib
:
Holds libraries for programming languages
/usr/doc
:
Holds Linux documentation
/usr/man
:
Holds the online manual Man files
2
/usr/spool
/sbin
:
Holds spooled files, such as those generated for printing
jobs and
network transfers
:
Holds system administration commands for booting the
system
/var
:
/dev
:
printers
/etc
:
files.
/init
:
start_kernel().
/net
:
and the
/arch
of arch/
/mm
Q2.
Ans : Most Unix kernels are monolithic : each kernel layer is integrated into the whole
kernel program and urns in Kernel Mode on behalf of the current process.
Microkernel operating systems demand a very small set of functions from the
kernel, generally including a few synchronization primitives, a simple scheduler,
and an interprocess communication mechanism. Although Microkernels oriented
O. S. are generally slower than monolithic ones, since the explicit message
passing between the different layers of the O. S. might have some theoretical
advantages over monolithic ones.
Define the process and task_structure ?
Ans : The concept of a process is fundamental to any multiprogramming operating
system. A process is usually defined as an instance of a program in execution;
thus, if 16 users are running vi at once, there are 16 separate processes
( although they can share the same executable code).
Each & every process have some unique information, which store in task_struct
type process descriptor, which is the object of task_struct.
Struct task _struct
{
volatile long state;
long counter;
long priority;
unsigned long signal;
unsigned long blocked;
unsigned long flags;
int errno;
int debugreg[8];
struct task_struct *next_task;
3
Ans : Every process occupies exactly one entry in the process table. In Linux, this is
statically organized and restricted in size to NR_TASKS. NR_TASKS denotes
the maximum number of process.
Struct task_struct *task [NR_TASKS] ;
In older versions of the Linux kernel, all the processes present could be traced
by searching the task[ ] process table for entries. In the newer versions this
information is stored in the linked lists next_task and prev_task, which can be
found in the task_struct structure. The external variable init_task points to the
start of the doubly linked linked circular list.
The entry task[0] has a special significance in Linux. Task[0] is the INIT_TASK
mentioned above, which is the first to be generated when the system is booted
and has something of a special role to play.
Q.
Ans : All enitities in Linux are trated as files. The information related to all these files
(not the contents ) is stored in an Inode Table on the disk. For each file, there is
an inode entry in the table. Inodes contain information such as the files owner
and access rights.
The inode structurestruct inode
{
dev_t idev;
unsigned long i_ino;
umode_t i_mode;
uid_t i_uid;
gid_t i_gid;
off_t i_size;
time_t i_mtime;
time_t i_atime;
time_t i_ctime;
}
The component :
i_dev is a description of the device on which the file is located.
i_ino identifies the file within the device.
5
Ans:
Q.
Ans : There is something magical about booting a Linux system. First of all LILO ( The
LInux LOader ) finds the Linux kernel and loads it into memory. It then begins at
the entry point start : as the name suggests, this is assembler code
responsible for initializing the hardware. Once the essential hardware
parameters have been established, the process is switched into Protected Mode
by setting the protected mode bit in the machine status word. Then initiates a
jump to the start address of the 32 bit code for the actual operating system
kernel and continues from startup_32: . Once initialization is complete, the first
C function start_kernal() is called.
The first saves all the data the assembler code has found about the hardware
up to that point. All areas of the kernel are then initialized. The process now
running is process 0. It now generates a kernel thread which executes the init()
function.
The init() function carries out the remaining initialization. It starts the bdflush
and kswap daemons which are responsible for synchronization of the buffer
cache contents with the file system and for swapping.
Then the system call setup is used to initialize file systems and to mount the
root file system. Then an attempt is made to execute one of the programs
/etc/init, /bin/init or /sbin/init. These usually start the background processes
running under Linux and make sure that the getty program runs on each
connected terminal - thus a user can log in to the system.
If none of the above-mentioned programs exists, an attempt is made to process
/etc/rc and subsequently start a shell so that the superuser can repair the
system.
Q
Define the system calls getpid, nice, pause, fork, execve, exit, wait.
Ans : getpid:
The getpid call is a very simple system call - it merely reads a value from the
task structure and returns it :
asmlinkage int sys_getpid(void)
{
return current->pid;
}
nice :
The system call nice is a little more complicated : nice expects as its argument a
number by which the static priority of the current process is to be modified. Only
the superuser is allowed to raise his/her own priority. Note that a large argument
for sys_nice() indicates a lower priority.
pause :
A call to pause interrupts the execution of the program until the process is
reactivated by a signal. This merely amounts to setting the status of the current
process to TASK_INTERRUPTIBLE and then calling the scheduler. This results
in another task becoming active.
fork:
The system call fork is the only way of starting a new process. This is done by
creating a identical copy of the process that has called fork. Fork is a very
demanding system call. All the data of the process have to be copied, and these
can easily run to a few megabytes.
execve :
The system call execve enables a process to change its executing program.
Linux permits a number of formats for executable files. Linux supports the
widely used executable file format COFF(Common Object File Format) and
ELF(Executable and Linkable Format).
exit :
7
Ans : ps command output which processes are running at any instant. Linux assigns a
unique number to every process running in memory. This number is called
process ID or simply PID.
PID
2269
2396
TTY
tty01
tty01
PID
TTY
TIME
Launched
COMMAND
TIME COMMAND
0:05 sh
0:00 ps
:
:
:
Process ID
Terminal Id Which The Processes Were Launched
The Time That Has Elapsed since the Processes Were
What is links ? What is the difference between Hard links & Symbolic links ?
Ans : If you might want to reference a file using different different filenames to access
it from
different directories then you create a link of that file with the help of ln
command.
$ ln original-file-name link-name
Hard links & Symbolic links :
Links within one disk & one user environment is called Hard links. A hard link
may in some situations fail when you try to link to a file on some other users
directory. A file in one file system cant be linked by a hard link to a file in
another file system. If you try to link to a file on another users directory that is
located on another file system, your hard link will fail. To overcome this
restriction, you use symbolic links. A symbolic link holds the pathname of the file
to which it is linking.
Logical Addresses :
Included in the machine language instructions to specify the address of
an operand or of an instruction. Each logical addresses consists of a
segment and an offset that denotes the distance from the start of the
segment to the actual address.
(ii)
Linear Address :
A single 32 bit unsigned integer that can be used to address upto 4 GB,
that is upto 232 memory cells. Linear addresses are usually represented
in hexa decimal notation; Their values ranges from 0x00000000 to
0xffffffff.
(iii)
Physical Address :
Physical address is used to address memory cells included in memory
chips. They correspond to the electrical signals sent along the address
:
Allocates a Page Directory and filles with 0.
:
Can be used to test whether the entry in Page
pgd_clear() :
Delete the entry in page directory.
:
Releases the page of memory allocate to page
:
user area.
(ii)
pmd_bad() :
Test whether the entry in the Page Middle directory
is valid.
(iii)
pmd_clear() :
Deletes the entries in the page middle directory is
valid.
(iv)
pmd_free() :
Releases a Page Middle Directory for memory in
user segment. (v)
pmd_offset(): Returns the address of an entry in the page middle
directory to
which the address in argument is allocated.
(vi)
pmd_none() : Tests whether the entry in the page middle directory has
been
set.
Page Table :
10
Each Page Table entries points to page frames. It is of 25 bits length. The dirty
attribute is set when the contents of the memory page has been modified. A
page table entry contains a number of flags which describe the legal access
modes to the memory page and their state :
PAGE_NONE :
entry.
PAGE_SHARE
PAGE_COPY :
PAGE_READONLY:
PAGE_KERNEL
the kernel
Following are some functions have been defined to mainpulate the page table
entries and their attributes :
(i)
mk_pte()
memory address
(ii)
(iii)
(iv)
(v)
:
:
:
:
pte_alloc()
pte_clear()
pte_dirty()
pte_free()
resources, such as the stack, can be controlled via parameters of the system cal
clone.
Virtual memory :
All Linux systems provide a useful abstraction called virtual memory. Virtual
memory acts as a logical layer between the application memory requests and
the hardware Memory management Unit (MMU). Virtual memory has many
purposes and advantages:
Several processes can be executed concurrently.
It is possible to run applications whose memory needs are larger than the
available physical memory.
Processes can execute a program whose code is only partially loaded in
memory.
Each process is allowed to access a subset of the available physical
memory.
Processes can share a single memory image of a library or program.
Programs can be relocatable, that is, they can be placed anywhere in
physical memory.
Programmers can write machine-independent code, since they do not need
to be concerned about physical memory organization.
A virtual memory area is defined by the data structure vm_area_struct. The
structure vm_operations_struct defines the possible function pointers enabling
different operations to be assigned to different areas.
System call brk :
At the start of a process the value of brk field in the process table entry point to
the end of the BSS (Bash memory segment) segment for non-statically
initialized data. By modifying thus pointer the process can allocate and release
dynamic memory.
The system call brk can be used to find the current value of the pointer or to set
it to a new value. If the argument is smaller than the pointer to the end of
process code, the current value of brk will be returned. Otherwise an attempt
will be made to set a new value.
The kernel function sys_brk() calls do_mmap() to map a private and
anonymous area between the old and new values of brk, corrected to the
nearest page boundary and returns new brk value.
The kernel segment :
A Linux system call is generally initiated by the software interrupt 0x80 being
triggered. The processor then reads the gate descriptor stored in the interrupt
descriptor table. The processor jumps to this address with the segment
descriptor in the CS register pointing to the kernel segment. The assembler
routine then sets the segment selectors in the DS and ES registers in such a
way that memory accesses will read or write to data in the kernel segment.
12
As the page tables for the kernel segment are identical for all processes, this
ensures that any process in system mode will encounter the same kernel
segment. In the kernel segment, physical addresses and virtual addresses are
the same except for the virtual memory areas mapped by vmalloc().
In an x86 processor, the next step involves loading to the segment register FS a
data segment selector pointing to the user segment. Accesses to the user
segment can then be made using the put_user() and get_user() functions
mentioned earlier. This may cause a general protection error, if the referenced
address is protected. And occur a page fault error, if page cant be access. To
avoid these problems, system routines have to call the verify_area() function
before they access the user segment. This checks whether read or write access
to the given area of the user segment is permitted, investigating all the virtual
memory areas affected by the area involved.
Q
Define the static & Dynamic memory allocation in the kernel segment ?
Ans : The update process is a Linux process which at periodic intervals calls the
system call bdflush with an appropriate parameter. All modified buffer blocks that
have not been used for acertain time are writeen back to disk, together with all
superblock and inode information. The interval used by update as a default
under Linux is five seconds.
bdflush is implemented as a kernel thread and is started during kernel
initialization. In an endless loop, it writes back the number of block buffers
marked dirty given in the bdflush parameter ( default is 500). Once this is
completed, a new loop starts immediately it the proportion of modified block
buffers to the total number of buffers to the total number of buffers in the cache
becomes
too
high.
Otherwise,
the
process
switches
to
the
TASK_INTERRUPTIBLE state.
The kernel thread can be woken up using the wakup_bdflush() function.
Q
Ans : The RAM memory in a computer has always been limited and, compared to fixed
disks, relatively expensive. Particularly in multi-tasking operating systems, the
limit of working memory is quickly reached. Thus it was not long before
someone hit on the idea of offloading temporarily unused areas of primary
storage(RAM) to secondary storage.
The traditional procedure for this used to be the so-called swapping which
involves saving entire processes from memory to a secondary medium and
reading them in again. This approach does not solve the problem of running
processes with large memory requirements in the available primary memory.
Besides this, saving and reading in whole processes is very inefficient.
When new hardware architectures (VAX) were introduced, the concept of
demand paging was developed. Under the control of a memory management
unit (MMU) the entire memory is divided up into pages, with only complete
pages of memory being read in or saved as required. As all modern processor
14
15
Ans : There are many applications in which processes need to cooperate with each
other. The Linux IPC (Inter Process communication) facility provides many
methods for multiple process to communicate with each other.
A variety of forms of inter-process communication can be used under Linux.
These support
resource sharing
synchronization
connectionless and
16
Q
How Linux implements all the forms of interprocess communication explain
briefly?
Ans : Linux implements the Interprocess communication in different forms :Communication by files :
Communication via files is in fact oldest way of exchanging data between
programs. Program A writes data to a file and program B reads the data out
again. In a multi-tasking system, however both programs could be run as
processes at least quasi-parallel to each other. Race conditions then usually
produce inconsistencies in the file data, which result from one program reading
a data area before the other has completed modifying it, or both processes
modifying the same area of memory at the same time. Avoiding the race
conditions in files different types of locking mechanisms used in Linux :Mandatory Locking : Mandatory locking blocks read and write operations throughout the entire area.
There are two methods for locking entire files.
In addition to the file to be locked there is an auxiliary file known as a Lock file is
created, which refuses access to the file when it is present. The system call
link, create, open used for this locking. link system call create the lock file if
lock file does not yet exist. create aborts with an error code if the process
which is being called does not possess the appropriate access right. In open
the lock file is opened if it does not already exist.
The drawback to all three of these is that after a failure the process must
repeat its attempt to set up a lock file. Usually, the process will call sleep()
to wait for one second and then try again.
Lock the entire file by means of fcntl system call. This functions is invoked
either
through flock() or lock() system call.
2. Advisory Locking : With advisory locking, all processes accessing the file for read or write
operations have to set the appropriate lock and release it again.
Locking file areas is usually refereed as record locking. Advisory locking of file
areas can be achieved with the system call fcntl. The prototype of fcntl() is
Int sys_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg);
fd
:
cmd :
FSETLKW
17
arg
Existing Locks
lock
Set
write
None
Possible
Possible
Possible
Not legal
Not legal
Not legal
18
Shared Memory :
The most useful IPC mechanism is shared memory, which allows two or more
processes to access some common data structures by placing them in a shared
memory segment. Each process that wants to access the data structures
included in a shared memory segment must add to its address space a new
memory region, which maps the page frames associated with the shared
memory segment. Such page frames can thus be easily handled by the kernel
through demand paging.
Shmget() function is invoked to get the IPC identifier of a shared memory
segment, optionally creating it if it does not already exist.
The drawback to shared memory is that the processes need to use additional
synchronization mechanisms to ensure that race conditions do not arise.
Q What are pipes? How FIFOs are different from pipes? What are the two types of
pipes available in Linux?
Ans: A PIPE is a one-way flow of data between processes : all the data written
by a processes to the Pipe is routed by the kernel to another process, which can
thus read it.
In UNIX shells, pipes can be created by means of | operator. For example the
following statement instructs the shell to create two processes connected by a
pipe.
$ ls | more
20
The standard output of the first process, which executes the ls program, is
redirected to the pipe; the second process, which executes the more program,
reads its input from the pipe.
Another varient of pipes consists of named pipes, also known as FIFOs. They
can be set up in a file system using the command
$ mkfifo filename
pipes are special type of files in Linux, which file type is p.
The system call pipe creates a pipe, which involves setting up a temporary
inode and allocating a page of memory. The call returns one file descriptor for
reading and one for writing.
There are 2 types of pipes:
unnamed pipes
named pipes
Unnamed pipes
The examples we seen at the shell command (third) line are unnamed. They are created,
used and destroyed within the life a set of processes. Each end of the pipe has its own file
descriptor. One end is for reading and one end is for writing. When you are done with a
pipe, it is closed like any other file.
Unnamed pipes cannot be used by process that don't have some common ancestry (eg
parent-child).
Unnamed Pipes cannot exist after the process which create the unnamed pipe exit
Unnamed is unidirectional
21
unlink() They can be used with unrelated process not just descendants of the pipe creator.
Named pipe ( is commonly known as FIFO) can be used between 2 totally unrelated
processes to communicate.
Named Pipes will still exist even after the process which create the named pipe exit
Ans : Execution Tracing is a technique that allows a program to monitor the execution
of another program. The traced program can be executed step-by-step, until a
signal is received, or until a system call is invoked. Execution tracing is widely
used by debuggers, together with other techniques like the insertion of
breakpoints in the debugged program and run-time access to its variables. In
Linux, execution tracing is performed through the ptrace() system call, which
can handle the following commands :
PTRACE_TRACEMEStart
execution
tracing
for
the
current
processPTRACE_ATTACHStart
execution
tracing
for
another
processPTRACE_DETACHTerminate execution tracingPTRACE_KILLKill the
traced processPTRACE_PEEKTEXTRead a 32 bit value from the text
segmentPTRACE_PEEKDATARead a 32 bit value from the data
segmentPTRACE_POKETEXTWrite a 32 bit value from the text
segmentPTRACE_POKEDATAWrite a 32 bit value from the data
segmentPTRACE_CONTResume execution
Several monitored events can be associated with a traced program :
22
When a monitored event occurs, the traced program is stopped and a SIGCHLD
signal is sent to its parent. When the parent wishes to resume the childs
execution, it can use one of the PTRACE_CONT.
A process can also be traced using some debugging features of the Intel
Pentium processors. For example, the parent could set the values of the dr0,
.dr7 debug registers for the child by using the PTRACE_POKEUSR
command. When a monitored event occurs, the CPU raises the Debug
exception; the exception handler can then suspend the traced process and
send the SIGCHLD signal to the parent.
23
24
Whenever a different filesystem is used, first register the filesystem. This is the
responsibility of the VFS, which call the register_filesystem(). This functions
fills the information of file_system_type structure, which store the information
about the filesystem.
Once a file system implementation has been registered with the VFS, file
system of this type can be administered.
The common file model consists of the following structure types :
Mounting
The superblock structure
The inode structure
The file structure
Mounting :
Before a file can be accessed, the file system containing the file must be
mounted. This can be done using either the system call mount or the function
mount_root(). The mount_root function takes care of mounting the first file
sytem. It is called by the system call setup after all the file system
implementations permanently included in the kernel have been registered. The
setup call itself is called just once, immediately after the init process is created
by the kernel function init().
The superblock :
All the information which is essential for managing the file system is held in the
superblock. Every mounted file system is represented by a super_block
structure. These structures are held in the static table super_block[ ]. The
superblock is initialized by the function read_super() in the Virtual File System.
The superblock contains information on the entire file system, such as block
size, access rights and time of the last change. The superblock also holds
references to the file systems root inode.
Some important possible operations on super_block structure are as follows :
write_super() : The write_super function is used to save the information of the
superblock.
put_super()
: The VFS calls this function when unmounting file systems,
when it should
also release the superblock and other information buffers.
read_inode() : The inode structure is initialized by this function like read_super()
fills
super_block structure.
25
notify_change() :
acknowledged by
notify_change().
write_inode() : This function saves the inode structure, analogous to
write_super().
The inode :
Click here
Some important possible operations on inode structure are as follows :
Create() :
Lookup() :
Link() :
Unlink():
Symlink() :
The job of the lseek function is to deal with positioning within the
This function copies count bytes from the file into the buffer buf in
the user address space.
The write function operates in an analogous manner to read()
and copies data from the user address space to the file.
This function checks whether data can be read from a file or
written to one.
The ioctl() function sets device-specific parameters.
Ans : Linux supports different filesystem so in this place explain the process file
system(proc) of system V Release 4. Each process in the system which is
currently running is assigned a directory /proc/pid, where pid is the process
identification number of the relevant process. This directory contains files
holding information on certain characteristics of the process.
26
When the Proc file system is mounted, the VFS function read_super() is called
by do_mount(), and in turn calls the function pror_read_super() for the Proc
file system in the file_system list.
iget() generate the inode for the proc root directory, which is entered in the
superblock. parse_options() function then processes the mount options data
that have been provided and sets the owner of the root inode.
Accessing the file system is always carried out by accessing the root inode of
the file system. The first access is made by calling iget(). If the inode does not
exist, this function then calles the proc_read_inode() function entered in the
proc_sops structure.
This inode describes a directory with read and execute permissions for all
processes. The proc_root_inode_operations only provides two functions: the
component readdir in the form of the proc_readroot() function and the
component lookup as the proc_lookuproot() function. Both function operate
using the table root_dir[ ], which contains the different entries for the root
directory.
The individual structures contain the inode number, the length of the filename,
and the name itself. Proc_lookuproot(), which determines the inode of a file by
reference to the inode for the directory and the name of a file contained in it.
The function proc_read_inode(), the inode for most normal files is assigned the
function vector proc_array_inode_operations. All that is implemented in this,
however, is the function array_read() in the standard file operations to read the
files.
Q
Ans : As Linux was initially developed under MINIX, it is hardly surprising that the first
LINUX file system was the MINIX file system. However, this file system restricts
partitions to a maximum of 64 MB and filenames to no more than 14 characters,
so the search for a better file system was not long in starting. The result was the
Ext file system - the first to be designed especially for LINUX. Although this
allowed partitions of up to 2 GB and filenames up to 255 characters. It included
several significant extensions but offered unsatisfactory performance. The
second Extended Filesystem (Ext2) wasintroduced in 1994 : besides including
several new features, it is quite efficient and robust and has become the most
widely used LINUX file system.
The most significant features are :
Block fragmentation :
System administrators usually choose large block sizes for accessing recent
disks. As a result, small files stored in large blocks waste a lot of disk space.
This problem can be solved by allowing several files to be stored in different
fragments of the same block.
27
29
In the context of LINUX device drivers, write short notes of the following :
Polling
Interrupt Sharing
Task Queues
Interrupt
Bottom Halves
DMA
Ans : Polling :
In polling, the driver constantly checks the hardware. The driver defines a
timeout (jiffies + waiting time), and driver continuously check the hardware until
timeout limit is not reach. Whenever a timeout limit is over the timeout error
30
handling will then give the appropriate error messages in case of printer like
printer is out of paper, offline. In polling mode results pointless wasting of
processor time; but it is sometimes the fastest way of communicating with the
hardware. The device driver for the parallel interface works by polling as the
default option.
Interrupt :
The use of interrupt, on the other hand, is only possible if these are supported
by the hardware. Here, the device informs the CPU via an interrupt channel
(IRQ) that it has finished an operation. This breaks into the current operation
and carries out an interrupt service routine (ISR). Further communication with
the device then takes place within the ISR.
In the serial mouse, every movement of which sends data to the serial port,
triggering an IRQ. The data from the serial port is read first by the handling ISR,
which passes it through to the application program.
IRQs are installed using the function :
Request_irq() in which pass different parameters like irq number, address of
handling routine, device name, device id, and irqflags.
Irqflags specifies the type of interrupt. If irqflags is off (NULL) then interrupt is
slow interrupt, if is set the value SA_INTERRUPT then interrupt is a fast
interrupt, if SA_SHIRQ then it is a sharable interrupt.
Interrupt sharing :
Various hardware is used the same irq number. If different hardware which used
same interrupt, are used in same PCI board then hardware are conflict each
other. In this case interrupt sharing provides the facility to use both device in
same PCI board. For this if one device is used the PCI buses the second device
wait for freeing that buses. If an ISR capable of interrupt sharing is installed, this
must be communicated to the request_irq() function by setting the SA_SHIRQ
flag. If another ISR also capable of interrupt sharing was already installed on
this interrupts, a chain is built.
Bottom Halves :
It frequently happens that not all the functions need to be performed
immediately after an interrupt occurs; although important actions need to be
taken care of at once, others can be handled later or would take a relatively long
time and it is preferable not to block the interrupt. A bottom half is a low-priority
function, usually related to interrupt handling, that is waiting for the kernel to find
a convenient moment to run it.
Before invoking a bottom half for the first time, it must be initialized. This is done
by invoking the init_bh() function, which inserts the routine address in the nth
entry of bh_base. bh_base table to group all bottom halves together. It is an
31
array of pointers to bottom halves and can include up to 32 entries, one for each
type of bottom half.
Some Linux Bottom Halves are as follows:
CONSOLE_BH
KEYBOARD_BH
NET_BH
SCSI_BH
SERIAL_BH
TIMER_BH
:
:
:
:
:
:
Virtual console
Keyboard
Network Interface
SCSI interface
Serial port
Timer
Task Queues :
Task queue is a dynamic extension of the concept of bottom halves. Use of
bottom halves is somewhat difficult because their number is limited to only 32,
and some tasks are already assigned to fixed numbers. Task queue allow a
number of functions to be entered in a queue and processed one after another
at a later time.
A queue element is described by the tq_struct which holds :
-
init
release
32
read
IOCTL
write
select
Ans : setup () :
The setup() function must initialize the hardware devices in the computer and
set up the environment for the execution of the kernel program. Although the
BIOS already initialized most hardware de4vices, Linux does not rely on it but
reinitializes the devices in its own manner to enhance portability and
robustness. Sometimes it is desirable to pass parameters to a device driver or to
the Linux kernel in general. These parameters will come in the form of a
command line from the Linux loader LILO. This command line will be analyzed
into its component parts by the function parse_options(). The checksetup()
function is called for each of the parameters and compares the beginning of the
paramerer with the string stored in the bootsetups[ ] field, calling the
corresponding setup( ) function whenever these match. The checksetup()
function will attempt to convert the first ten parameters into integer numbers. If
this is successful, they will be stored in a field.
Init() :
The init() function is only called during kernel initialization, but is responsible for
important tasks. This function tests for the presence of a device, generates
internal device driver structures and registers the device.
The call to the init function must be carried out in one of the following functions,
depending on the type of device driver:
For
Character devices
Block devices
SCSI devices
Network devices
:
:
:
chr_dev_init()
blk_dev_init()
scsi_dev_init()
:
net_dev_init()
Before Linux can make use of the driver, it must be registered using the
functions register_chrdrv().
The init() function is also the right place to test whether a device supported by
the driver is present at all. This applies especially for devices which cannot be
connected or changed during operation, such as hard disks.
Open ():
The open function is responsible for administering all the devices and is called
as soon as a process opens a devices file. If only one process can work with a
given device. -EBUSY should be returned if other device wants to open the
device. If a device can be used by a number of processes at the same time,
open() should set up the necessary wait queues. If no device exists it should
return -ENODEV. The open() function is also the right place to initialize the
standard settings needed by the driver.
33
Release() :
The release() function is only called when the file descriptor for the device is
released. The tasks of this function comprise cleaning-up activities global in
nature, such as clearing wait queues. For some devices it can also be usefule to
pass through to the device all the data still in the buffers.
Read() & write() :
The read() and write() functions perform a similar task, that is, copying data from
and to application code. Whenever a input device is used read() function is fired
and for output devices write() function is fired, because only read operation is
possible by input device like mouse, keyboard and only write operation is
possible by output devices like printer, monitor.
IOCTL() :
Each device has its own characteristics, which may consist in different operation
modes and certain basic settings. It may also be that device parameters such as
IRQs, I/O addresses and so on need to be set at run-time. IOCTL usually only
change variables global to the driver or global device settings.
Select () :
The select () function checks whether data can be read from the device or
written to it. If the device is free or argument wait is NULL, the device will only
be check. If it is ready for the function concerned, select() will return 1,
otherwise a 0. If wait is not NULL, the process must be held up until the device
becomes available.
34
Ans : Sockets are used to handle communication links between application over the
network. Communication between the client and the server is through the
socket. To communicate client and server programs establish a connection and
bind a socket. The socket programming interface provides for communication
via a network as well as locally on a single computer. The Client socket sends a
request for server socket, server socket receive this request and send an
acknowledgement for client, client receive this ACK and send a concluding ACK
for server. Now connection is established.
A socket is represented in the kernel by the data structure socket.
Struct socket
{
short
socket_state
Long
Struct proto_ops
Void
Struct
Struct fasync_struct
Struct file
};
type;
state;
flags;
*ops;
*data;
*inode;
*fasync_list;
*file;
type determines the type of protocol used in connection. Valid entries for type
are SOCK_STREAM, SOCK_DGRAM and SOCK_RAW. Sockets of the type
SOCK_STREAM are used for TCP connections, SOCK_DGRAM for the UDP
protocol and SOCK_RAW for sending and receiving IP packets.
In state, the current state of the socket is stored. The most important states are
SS_CONNECTED and SS_UNCONNECTED.
flags are used to store the additional value for socket like SYN_SENT when a
client send a SYN to server.
The ops pointer points to the operation vector proto_ops, where the specific
operations for this protocol are entered.
The data pointer points to the substructure of the socket corresponding to the
protocol family.
There is also an inode for each BSD socket. A reference to the corresponding
inode is stored in inode, whereas file holds a reference to the primary file
structure associated with this node.
35
If different clients want to communicate with this socket then all the client
request stored in fasync_list.
Q
Ans : There is a great variety of hardware that can be used to connect computers. The
data structure device controls an abstract network device. This structure
element describes the hardware device. The some devices used in network are
as follows :
Ethernet :
Linux supports two groups of adaptors for Ethernet. These include on the one
hand the classic Ethernet cards connected to the PC bus, and on the other
adaptors linked to the PC via the PCMCIA bus.
The network devices for Ethernet cards are named eth0,.,eth3. Whenever a
computer is started, the network card is detected. The kernel outputs a message
on the cards detected and there allocation to the network devices. Two types of
card are popular in network, WD8013 and NE2000. In case of WD8013, these
cards doesnt compatible with some hardware but NE 2000 generally supported
most of the hardware.
Every Ethernet adaptor has a completely unique address. These addresses are
6 bytes long. Ethernet card supports the various types of protocol like IP, ARP,
IPX, TCP. The type determine which types of packets are send or receive.
Q Difference between SLIP and PLIP devices?
TCP
ARP
Receipt of a packet.
Option handling.
Fragmenting the IP packet, if the IP packet is too large for the device.
37
Decrementing the ttl (which holds the no. of sending packets) field.
(5)
A route must be established by the IP for every packet that is sent. The decision
on whom the packet is sent to, and via which network device, is made by
reference to the Forwarding Information Base (FIB). In FIB use the struct
fib_zone, which are responsible for one zone each. A zone denotes all routes
that have the same route mask. Thus, all host routes are in the same zone.
Fib_node and fib_info structure hold all information for a determined route. The
information is divided into two structures because much of the information for
different routes is identical. For continuous fast access, there is yet another
hash table of the struct rtable, which holds the all routes references.
When a network device is deactivated, the transfer of packets via this device is
no longer possible. This means that routes in the table which refer to this device
are no longer operable, and they are therefore automatically deleted from the
table when a device is taken off the network.
Q
IP packet filters, a very powerful tool has been placed in the hands of network
administrators. Using these filters, they can specify very precisely which IP
packets are to be send or receive. In a big organizations, in which no. of
computers are used, administrator restrict all the user with the help of IP packet
filter for sending or receiving unnecessary data. A filter consists of a list of
packet patterns. If a packet matches a pattern in the list it will be recognized by
the corresponding filter.
The characteristics of IP packet filters are used by IP accounting and IP
firewalling. In IP accounting, the complete network is traced. The administrator
check it which data are sent or received by network. In firewalling, a firewall
machine is always located at a geteway, the checking mechanisms can be
implemented relatively easily. Call_in_firewall() and call_out_firewall() restrict
receiving and sending of IP packets, respectively.
38
The transmission Control Protocol (TCP) provides full transport layer services to
applications. TCP is a reliable stream transport port-to-port protocol. The term
stream, in this context, means connection-oriented : a connection must be
established between both ends of a transmission before either may transmit
data. By creating this connection, TCP generates a virtual circuit between
sender and receiver that is active for the duration of a transmission. Reliability is
ensured by provision for error detection and retransmission of damaged frames;
all segments must be received and acknowledged before the transmission is
considered complete and the virtual circuit is discarded.
TCP protocol to be implemented with correct timing behavior. For this purpose
reset_timer(), delete_timer(), net_timer() functions are used.
In a TCP connection, client uses the function connect() to set up a connection
to the server. The function send a SYN to the server and then goes over to the
SYN_SENT state. The process now blocked until it receives the SYN/ACK from
the server. Server receive the SYN by listen() function and send a SYN/ACK for
client. Client receive this SYN and again send a concluding ACK, and the
connection is now established.
By calling close() function client sends a FIN to server. Server receive this FIN
and release the all information related to that particular client, and send the ACK
to client, and now connection is terminated.
39
The central element in address resolution is the ARP table, which consists of a
field of pointers to structures of the type arp_table. A further facility offered by
Linux is proxy ARP. This enables subnetworks which should really be directly
interconnected by hardware to be separated.
40
Ans : Modules are components of the Linux kernel that can be loaded and attached to
it as needed. To add support for a new device, you can now simply instruct a
kernel to load its module. In some cases, you may have to recompile only that
module to provide support for your device. The use of modules has the added
advantage of reducing the size of the kernel program. The kernel can load
modules in memory only as they are needed. For example, the module for the
BLOCK devices, and FILE SYSTEM, whenever you use the device and use the
file system.
Implementation in the kernel :
Linux provides three system calls : create_module, init_module and
delete_module for implementation of Linux modules. A further system call is
used by the user process to obtain a copy of the kernels symbol table.
The administration of modules under Linux makes use of a list in which all the
modules loaded are included. This list also administers the modules symbol
tables and references.
As far as the kernel is concerned, modules are loaded in two steps
corresponding to the system calls create_module and init_modules. For the user
process, this procedure divides into four phases.
The process fetches the content of the object file into its own address space. To
get the code and data into a form in which they can actually be
executed, the actual load address must be added at various points. This
process is known as relocating.
The system call create_module is now used, firstly to obtain the final address of
the object module and secondly to reserve memory for it. To do this, a
structure module is entered for the module in the list of modules and the
memory is allocated. The return value gives us the address to which the
module will later be copied.
The load address received by create_module is used to relocate the object file.
This procedure takes place in a memory area belonging to the process-if
process is a user process then load in user area, and if kernel process
load in kernel segment.
When a module is already use in a process and other process wish to
use this then it uses the module which earlier loaded. This mechanism is
known as module stacking.
41
Once the preliminary work is complete, we can load the object module. This
uses the system call init_modules. cleanup() function is called when the
module is deinstalled.
By using the system call delete_module, a module that has been loaded
can be removed again. Two preconditions need to be met for this : there
must be no references to the modules and the modules use counter
must hold a value of zero.
Q
Ans : The kernel daemon is a process which automatically carries out loading and
removing of modules without the system user noticing it. For example :
whenever a file is accessed by floppy, so kernel daemon load the block device
module for handling the block device and load the file system modules for
particular file system. But how does the kernel daemon know that modules need
to be loaded ?
Communication between the Linux kernel and the kernel daemon is carried out
by means of IPC. The kernel daemon opens a message queue with the new flag
IPC_KERNELD. The kernel sends the messages to the kernel daemon by
kerneld_send function. Request is stored in kerneld_msg struct, which
includes different information :
mtype :
ld
:
pid
:
request.
Responsibility for loading and releasing modules lies with the functions :
request_module
:
kernel requests the loading of a module
and waits until
the operation has been carried out.
release_module
delayed_release_module
specified delay.
cancel_release_module
specified condition.
:
:
removes a module
allows a module to be removed with a
42
Ans : Debugging is the process in which find out the errors and also whenever an
error is occurred at run time, rectify that error and warn for that. Only few cases
a section of program code be free of bugs as soon as it is written. Usually the
program will need debugging, for which it will be loaded into a debugger such as
gdb and run step by step until the error has been found.
The most common debugging techinque is monitoring. When you are
debugging kernel code, you can accomplish this goal with printk.
Printk :
In printk debugger, code is checked and an error occurred create the check
points and print an appropriate alarm message. For example : whenever a
kernel segment process wish to call the data and code of user segment
process, verify_area () functions is fired, which check all area related to process
and if any error is occurred, call the printk debugger, which print the appropriate
message.
Gdb - GNU debugger :
Execution Tracing is a technique that allows a program to monitor the execution
of another program. The traced program can be executed step-by-step, until a
signal is received, or until a system call is invoked. Execution tracing is widely
used by debuggers, together with other techniques like the insertion of
breakpoints in the debugged program and run-time access to its variables. In
Linux, execution tracing is performed through the ptrace() system call. Gdb
debugger works on ptrace () system call. Check the code and data, if any error
is occurred, try to repair this error if error is repaired then relocating the control
otherwise print an appropriate message.
Chapter 10 : Multi-processing
43
Ans : Most systems are single processor systems; that is, they have only one main
CPU. But sometimes applications require more processors power. So in this
situation use the multiple processor for close communication, sharing the
computer bus, the clock, and sometimes memory and peripheral devices. The
most common multiple-processor systems now use the symmetricmultiprocessing (SMP) model, in which each processor runs an identical copy
of the operating system, and these copies communicate with one another as
needed.
Most of the currently available multi-processor main boards for PCs use i486,
Pentium or Pentium Pro processors. The Pentium already has some internal
functions which support multi-processor operation, such as cache
synchronization, inter-processor interrupt handling.
It defines a highly symmetrical architecture in terms of :
Q
Memory Symmetry :
All processors share the same main memory; in particular, all physical
addresses are the same. This means that all processors execute the same
operating system, all data and applications are visible to all processors and can
be used or executed on every processor.
I/O Symmetry :
All processors share the same I/O subsystem (including the I/O port and the
interrupt controller). I/O symmetry allows reduction of a possible I/O bottleneck.
However, some MP systems assign all interrupts to one single processor and on
the other hand use the I/O APIC (Advanced Programmable Interrupt
Controller). All CPU are connected by ICC (Interrupt Controller
Communications) bus.
One processor is chosen by the BIOS; it is called the boot processor (BSP)
and is used for system initialization. All other processors are called application
processors (AP) and are initially halted by the BIOS.
45
46
Question no. 36- What are the various steps involved in kernel recompilation?
Answer- The Linux kernel is an operating system kernel used by the Linux family of UNIX
like operating system. It is one of the most prominent examples of free and open source
software. The Linux kernel is developed under open and distributed conditions. Open
means that anyone can become involved if they are able to do so. Kernel is the central part
of most of the operating systems. The main functions of kernel include process
management, resource management etc. It is the first part of operating system that is
loaded in to the RAM when the machine is booted and it will remain in the main memory.
Recompilation means compile the kernel in more compact manner. It means to upgrade or
add or remove certain features of kernel so as of your liking. In simple terms
recompilation is done for optimization and makes it more resourceful.
We need to recompile the kernel to
Reduce its size
Add or remove support for devices
Modify system parameters
STEPS INVOVLED IN KERNEL RECOMPILATION ARE AS FOLLOWS:
Step 1- Verify and update the packages required
This step is to be performed only when one wants to upgrade the kernel version. The main
packages to be checked and upgraded are: binutils, e2fsprogs, procps, gcc and moduleinit-tools. You should take extreme care while upgrading module-init-tools. A module is a
piece of code that can be inserted into the kernel on demand. Module-init-tools provide
utilities for managing Linux kernel modules - for loading, unloading, listing and removing
modules.
The main utilities available are:
insmod
rmmod
modprobe
depmod
lsmod
Configure it.
cd module-init-tools-3.2.2
./configure --prefix=/
Rename the existing version of this utility as utility. Old
make moveold
Build and install.
make
make install
Run the script generate-modprobe.conf to convert the entries in the module configuration
file for kernel version 2.4 ( /etc/modules.conf ) to a file used by kernel version 2.6
(/etc/modprobe.conf)
47
./generate-modprobe.conf /etc/modprobe.conf
48
Copy the current kernel configuration to your new kernel source. Example[root@XXXXX ~]#pwd
/usr/src/kernels/linux-2.6.19.2
[root@XXXXX ~]#cp /boot/config-<current_kernel_version> .config
[root@XXXXX ~]#make oldconfig
make menuconfig.
[root@XXXXX ~]#make menuconfig
For writing a new driver
# make drivers is used, which will cause the drivers to be compiled.
49
50