System Calls: 1 Interrupt Descriptor Table

Download as pdf or txt
Download as pdf or txt
You are on page 1of 5

System calls

March 3, 2020

In this assignment, you are to implement a custom system call handler in


the Linux kernel. For system call handling, the OS reserves a vector in the
interrupt descriptor table (IDT). Linux 32-bit OS reserves vector 128 in the
IDT for system call handling. You have to use vector 15 (currently unused and
reserved for exception) for the custom system call handler.

1 Interrupt descriptor table


An interrupt descriptor table (IDT) is a sequential array of descriptors (max
256). The size of each descriptor is 64-bits. The first 32 descriptors are reserved
for exception handling, and the others are used for interrupts. A descriptor
corresponding to a vector x contains the virtual address of the target handler
(routine), which is called on every occurrence of interrupt vector x. Apart from
containing the virtual address of the target interrupt handler (32-bits), the rest
32-bits of the descriptor contain the cs segment selector and other flags. You
can refer to page-197, fig 6-2 of Intel manual - 3. For this assignment, we are
only interested in the address of the target interrupt handler. The other fields
can be copied from the entry corresponding to the existing system call handler
(vector 128).

2 Kernel module
The IDT can only be modified in the kernel. In this assignment, you are provided
a working kernel module. A kernel module is a piece of software that is the part
of the kernel. User program can call routines in the kernel module via ioctl
system call. The kernel folder in the assignment repository contains the code
corresponding to kernel module. When the user-program does the ioctl call
for kernel module services, device ioctl (in main.c) is called. ioctl takes an
identifier and a 32-bit argument (user-mode addresses can also be passed using
typecasting). device ioctl invokes the routine corresponding to the input
identifier. You need to implement register syscall and unregister syscall
ioctls.

1
3 klib.c
klib.c in kernel folder implements the following functionalities.
1. print kernel is the system call handler corresponding to the PRINT KERNEL SYS
system call, which can be invoked using the custom system call handler.
2. syscall handler k is the custom system call handler that is invoked by
the syscall handler in ksys.S.

3. imp copy idt allocates space for new IDT, copies the contents of the cur-
rent IDT (loaded in IDTR) to the new IDT, and returns the base and
size of the new IDT in the input struct idt desc. struct idt desc
contains the base address and size of an IDT.

4. imp load idt takes two pointers new and old of type ‘‘struct idt desc
*’’. new contains the base and size of the target IDT. imp load idt loads
the target IDT in IDTR and returns the base and size of the previous IDT
in old.
5. imp free desc takes struct idt desc corresponding to an IDT allocated
in imp copy idt and releases the corresponding memory.

4 Implementation
You need to implement the following routines.

1. syscall handler
2. register syscall
3. unregister syscall
4. syscall u

4.1 syscall handler


syscall handler in “kernel/ksys.S” is the custom system call handler. You
need to map the syscall handler routine at index 15 in the IDT. The user
passes an identifier and a buffer via registers. You need to modify syscall handler
to pass these arguments directly to syscall handler k in klib.c. the kernel
uses a fixed value (216) in the %fs register. You need to set the kernel’s %fs
register before calling syscall handler k, but make sure to restore the user’s
%fs before returning to user-mode.

2
4.2 register syscall
register syscall in “kernel/main.c” is the handler corresponding to the REGISTER SYSCALL
ioctl. This routine allocates a new IDT, modifies the index 15 in the new IDT
to point to the syscall handler routine, and loads the new IDT in IDTR.
You can use the routines in klib.c to implement this functionality. struct
idt entry in klib.h represents an IDT entry. Here, lower16 and higher16 cor-
respond to lower 16-bits and higher 16-bits address of target interrupt handler.
You need to change theses values corresponding to entry at index 15 in the new
IDT. The rest of the fields of the IDT entry can be copied from the default
system call handler (i.e., index 128).

4.3 unregister syscall


unregister syscall in “kernel/main.c” is the handler corresponding to the
UNREGISTER SYSCALL ioctl. This routine would load the original IDT in IDTR,
if the IDTR was changed earlier by register syscall.

4.4 syscall u
syscall u in “user/usys.S” is the user-mode routine that invokes the syscall handler
using int $15 instruction. syscall u takes an identifier and a buffer and pass
it to the syscall handler via registers.

You are only allowed to modify “kernel/ksys.S”, “kernel/main.c”, and “user/usys.S”


files. You are not allowed to add a new file.

5 User-program
The user folder contains the user-program. The “user/syscall.c” is the main
program that enables the custom system call handler by doing REGISTER SYSCALL
ioctl, invokes the PRINT KERNEL SYS system call through syscall u, and finally
restores the original IDT using UNREGISTER SYSCALL ioctl. If the system call is
successful, the system call handler copies the string “syscall done.” to the user’s
buffer.

6 Environment
For this assignment, you need to clone the assignment repo from https://
github.com/Systems-IIITD/syscall.
Download Linux 32-bit iso by running:
“scp aos@192.168.1.161:ubuntu-16.04.6-desktop-i386.iso .’’.
The password is aos.
You need to create a virtual machine using this iso image. For this as-
signment, we need a 32-bit Linux OS. We have tested the assignment for the

3
provided Linux distribution (iso image). You have to use the above iso image
for this assignment.

6.1 Compilation and running


To compile:
“cd kernel && make” (compiles the kernel module)
“cd user && make” (compiles the user program)

To run:
“cd kernel && sudo ./load” (loads the kernel module).
“cd user && ./syscall” (executes the user program).

The kernel equivalent of printf is printk. You can run dmesg to print the
kernel log (i.e., log generated using printk, etc.) on the terminal.
Before running the user-program, you have to load the kernel module. start module
in “main.c” is called automatically when the module is loaded. If you run dmesg
at this point, you should see “module loaded successfully”. make clean removes
the executables and temporary files.

7 Design documentation
You also have to submit design documentation along with your implementation;
otherwise, the assignment will not be graded. Answer the following questions
in your design documentation.
• Paste your code corresponding to syscall handler.
• Paste your code corresponding to u syscall.

• Paste your code corresponding to register syscall.


• Paste your code corresponding to unregister syscall.
• The output of user-program.

• How do you know the location of the original IDT in unregister syscall?
• How do you know the location of the current IDT in unregister syscall?
• If somebody calls unregister syscall twice, without calling register syscall
in between.

– Do you load the original IDT twice?


– Do you free the current IDT twice?

4
7.1 How to submit.
To be done individually. Submit a zip folder that contains four files: “user/usys.S”,
“kernel/ksys.S”, “kernel/main.c”, and design documentation (in pdf format).
Please make sure that your implementation is not printing any debug messages
before submitting the final code. The submission link is on backpack.

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy