.long sys_restart_syscall /* 0 - old "setup()M system call, used for restarting */

.long sys_exit

.long sys_fork

.long sys_read

.long sys_write

.long sys_close

.long sys_utimensat /* 320 */ .long sys_signalfd .long sys_timerfd .long sys_eventfd .long sys_fallocate

The purpose of the .long statements is to align the table entries in memory.

The tables defined in this way have the properties of a C array and can therefore be processed using pointer arithmetic. sys_call_table is the base pointer and points to the start of the array, that is, to the zero entry in C terms. If a userspace program invokes the open system call, the number passed is 5. The dispatcher routine adds this number to the sys_call_table base and arrives at the fifth entry that holds the address of sys_open — this is the processor-independent handler function. Once the parameter values still held in registers have been copied onto the stack, the kernel calls the handler routine and switches to the processor-independent part of system call handling.

Because the kernel mode and user mode use two different stacks, as described in Chapter 3, system call parameters cannot be passed on the stack as would normally be the case. Switching between the stacks is performed either in architecture-specific assembly language code that is called when kernel mode is entered, or is carried out automatically by the processor when the protection level is switched from user to kernel mode.

Continue reading here: Return to User Mode

Was this article helpful?

0 0