xv6, line by line
user/usys.S

user/usys.S

RISC-V assembly · 112 lines · annotated 100% · user program / library

This file is generated by the build (it is not in the xv6 repository). It is shown here as the build produces it. See user/usys.pl.

About this file

The system call stubs: the code that connects a C call such as write(1, "x", 1) in a user program to the kernel. This file is generated by user/usys.pl during the build; it is not part of the xv6 repository.

Every stub has the same three instructions (see system call stub):

  1. li a7, SYS_name puts the system call number in register a7;
  2. ecall traps into the kernel, which performs the call;
  3. ret returns to the C caller, with the kernel’s result in a0.

The arguments need no code at all. The caller is ordinary compiled C, which by the calling convention has already placed them in a0, a1, … before calling the stub, and the kernel reads them from exactly those registers (system call arguments).

The whole round trip for write, as an example:

user:   write(fd, buf, n)        C call, args in a0..a2
        write: li a7, 16         this file
               ecall             ── trap ──┐
kernel: uservec                  save registers in the trapframe (trampoline.S)
        usertrap                 scause 8: system call; epc += 4 (trap.c)
        syscall                  a7 = 16 → syscalls[16] = sys_write (syscall.c)
        sys_write → filewrite    the work (sysfile.c, file.c)
        syscall                  trapframe->a0 = result
        prepare_return, userret  restore registers, sret (trap.c, trampoline.S)
user:          ret               ◄─────────┘ back in C, a0 = result

Each stub is 8 bytes of machine code: li with a small constant assembles into a 2-byte compressed instruction, ecall is 4 bytes, ret 2 bytes (see user/cat.asm).

Read before: user/usys.pl, user/user.h. Read next: kernel/trampoline.S, kernel/trap.c, kernel/syscall.c.

1# generated by usys.pl - do not edit
3.global fork
5 li a7, SYS_fork
6 ecall
7 ret
8.global exit
10 li a7, SYS_exit
11 ecall
12 ret
13.global wait
15 li a7, SYS_wait
16 ecall
17 ret
18.global pipe
20 li a7, SYS_pipe
21 ecall
22 ret
23.global read
25 li a7, SYS_read
26 ecall
27 ret
28.global write
30 li a7, SYS_write
31 ecall
32 ret
33.global close
35 li a7, SYS_close
36 ecall
37 ret
38.global kill
40 li a7, SYS_kill
41 ecall
42 ret
43.global exec
45 li a7, SYS_exec
46 ecall
47 ret
48.global open
50 li a7, SYS_open
51 ecall
52 ret
53.global mknod
55 li a7, SYS_mknod
56 ecall
57 ret
58.global unlink
60 li a7, SYS_unlink
61 ecall
62 ret
63.global fstat
65 li a7, SYS_fstat
66 ecall
67 ret
68.global link
70 li a7, SYS_link
71 ecall
72 ret
73.global mkdir
75 li a7, SYS_mkdir
76 ecall
77 ret
78.global chdir
80 li a7, SYS_chdir
81 ecall
82 ret
83.global dup
85 li a7, SYS_dup
86 ecall
87 ret
88.global getpid
90 li a7, SYS_getpid
91 ecall
92 ret
93.global sys_sbrk
95 li a7, SYS_sbrk
96 ecall
97 ret
98.global pause
100 li a7, SYS_pause
101 ecall
102 ret
103.global uptime
106 ecall
107 ret
108.global sync
110 li a7, SYS_sync
111 ecall
112 ret