3

My understanding of a syscall (high level) workflow is:

  1. User calls libc wrapper
  2. wrapper puts syscall number and arguments in the right place, registers or stack
  3. wrapper executes syscall or int 0x80 instruction
  4. kernel interrupt handler calls sys_xxx() service routine

If that is the case, then there should be a bunch of sys_xxx() functions in kernel source. For example, for read(), in kernel 2.6 code, I found sys_read. However, in kernel 5.4 code, I did not find such service routine code, the only sys_read I found is acting like a drop in replacement for the libc wrapper. So I am confused..

A related question - the reason that kernel puts the implementation in sys_xxx() is that kernel space can also call these functions, is that correct?

Employed Russian
  • 199,314
  • 34
  • 295
  • 362
QnA
  • 1,035
  • 10
  • 25

1 Answers1

6

The kernel does indeed define a function called sys_read that behaves as you said. It's just a little hard to find with searching, because it's defined through a helper macro using token concatenation. See fs/read_write.c line 595:

SYSCALL_DEFINE3(read, unsigned int, fd, char __user *, buf, size_t, count)
{
    return ksys_read(fd, buf, count);
}

This has the effect of:

  • declaring a function named sys_read, aliased to __se_sys_read

  • defining __se_sys_read, which apparently sign-extends any 32-bit arguments and then calls __do_sys_read

  • defining __do_sys_read whose body is as shown (i.e. calling ksys_read which does the actual work).

You can see the definition of the SYSCALL_DEFINEx macros at include/linux/syscalls.h line 206.

Nate Eldredge
  • 48,811
  • 6
  • 54
  • 82