Movatterモバイル変換


[0]ホーム

URL:


TheHyperNewsLinux KHGDiscussion Pages

How System Calls Work on Linux/i86

This section covers first the mechanisms provided by the 386for handling system calls, and then shows how Linux uses thosemechanisms. This is not a reference to the individual systemcalls: There are very many of them, new ones are addedoccasionally, and they are documented in man pages that shouldbe on your Linux system.

What Does the 386 Provide?

The 386 recognizes two event classes: exceptions andinterrupts. Both cause a forced context switch to new aprocedure or task. Interrupts can occur at unexpected timesduring the execution of a program and are used to respond tosignals from hardware. Exceptions are caused by the executionof instructions.

Two sources of interrupts are recognized by the 386:Maskable interrupts and Nonmaskable interrupts. Two sources ofexceptions are recognized by the 386: Processor detectedexceptions and programmed exceptions.

Each interrupt or exception has a number, which is referredto by the 386 literature as the vector. The NMI interrupt andthe processor detected exceptions have been assigned vectors inthe range 0 through 31, inclusive. The vectors for maskableinterrupts are determined by the hardware. External interruptcontrollers put the vector on the bus during theinterrupt-acknowledge cycle. Any vector in the range 32through 255, inclusive, can be used for maskable interrupts orprogrammed exceptions. Here is a listing of all the possibleinterrupts and exceptions:

0divide error
1debug exception
2NMI interrupt
3Breakpoint
4INTO-detected Overflow
5BOUND range exceeded
6Invalid opcode
7coprocessor not available
8double fault
9coprocessor segment overrun
10invalid task state segment
11segment not present
12stack fault
13general protection
14page fault
15reserved
16coprocessor error
17-31reserved
32-255maskable interrupts

The priority of simultaneous interrupts and exceptions is:

HIGHESTFaults except debug faults
.Trap instructions INTO, INT n, INT 3
.Debug traps for this instruction
.Debug traps for next instruction
.NMI interrupt
LOWESTINTR interrupt

How Linux Uses Interrupts and Exceptions

Under Linux the execution of a system call is invoked by amaskable interrupt orexception class transfer, causedby the instructionint 0x80. We use vector 0x80 totransfer control to the kernel. This interrupt vector isinitialized during system startup, along with other importantvectors like the system clock vector.

iBCS2 requries anlcall 0,7 instruction, whichLinux can send to the iBCS2 compatibility module appropriate ifan iBCS2-compliant binary is being executed. In fact, Linuxwill assume that an iBCS2-compliant binary is being executed ifanlcall 0,7 call is executed, and will automaticallyswitch modes.

As of version 0.99.2 of Linux, there are 116 system calls.Documentation for these can be found in the man (2) pages. Whena user invokes a system call, execution flow is as follows:

How Linux Initializes the system call vectors

Thestartup_32() code found in/usr/src/linux/boot/head.S starts everything off by callingsetup_idt(). This routine sets up an IDT (InterruptDescriptor Table) with 256 entries. No interrupt entry pointsare actually loaded by this routine, as that is done only afterpaging has been enabled and the kernel has been moved to0xC0000000. An IDT has 256 entries, each 4 bytes long, for atotal of 1024 bytes.Whenstart_kernel() (found in /usr/src/linux/init/main.c) iscalled it invokestrap_init() (found in/usr/src/linux/kernel/traps.c).trap_init() sets up the IDT viathe macroset_trap_gate() (found in /usr/include/asm/system.h).trap_init() initializes the interrupt descriptor table as shownhere:

0divide_error
1debug
2nmi
3int3
4overflow
5bounds
6invalid_op
7device_not_available
8double_fault
9coprocessor_segment_overrun
10invalid_TSS
11segment_not_present
12stack_segment
13general_protection
14page_fault
15reserved
16coprocessor_error
17alignment_check
18-48reserved
At this point the interrupt vector for the system calls is notset up. It is initialized bysched_init() (found in/usr/src/linux/kernel/sched.c). A call toset_system_gate(0x80, &system_call) sets interrupt 0x80 to be a vector tothesystem_call() entry point.

How to Add Your Own System Calls

  1. Create a directory under the /usr/src/linux/ directory to holdyour code.
  2. Put any include files in /usr/include/sys/ and /usr/include/linux/.
  3. Add the relocatable module produced by the link of your newkernel code to theARCHIVES and the subdirectory totheSUBDIRS lines of the top level Makefile. Seefs/Makefile, target fs.o for an example.
  4. Add a#define __NR_xx to unistd.h to assigna call number for your system call, wherexx,the index, is something descriptive relating to your systemcall. It will be used to set up the vector throughsys_call_table to invoke you code.
  5. Add an entry point for your system call to thesys_call_table in sys.h. It should match the index(xx) that you assigned in the previous step.TheNR_syscalls variable will be recalculatedautomatically.
  6. Modify any kernel code in kernel/fs/mm/, etc. to take intoaccount the environment needed to support your new code.
  7. Run make from the top level to produce the new kernelincorporating your new code.
At this point, you will have to either add a syscall to yourlibraries, or use the proper_syscalln() macroin your user program for your programs to access the new systemcall.The386DX Microprocessor Programmer's Reference Manual is ahelpful reference, as is James Turley'sAdvanced 80386Programming Techniques. See theAnnotated Bibliography.

Copyright (C) 1993, 1996 Michael K. Johnson, johnsonm@redhat.com.
Copyright (C) 1993 Stanley Scalsky


Messages

4.Note:wrong file for system_call code by Tim Bird
3.Note:would be nice to explain syscall macros by Tim Bird
2.Note:wrong file for syscallX() macro by Tim Bird
1.Feedback:the directory /usr/src/libc/syscall/ byvijay gupta
1.Note:...no longer exists. byMichael K. Johnson
->Feedback:the solution to the problem by Vijay Gupta




[8]ページ先頭

©2009-2025 Movatter.jp