In the user/usys.S
here a fragment which is generate by the usys.pl script
.global sbrk
sbrk:
li a7, SYS_sbrk
ecall
ret
.global sleep
sleep:
li a7, SYS_sleep
ecall
ret
.global uptime
uptime:
li a7, SYS_uptime
ecall
ret
The user functions will need to call the kernel syscalls, since just the kernel have the privilege to execute the instruction needed.
So the user functions need to be write in assembly so that can use the riscv ecall
instruction that will trigger the kernel function.
How the arguments are passed to this kernel syscalls functions?
CodePudding user response:
Let's just talk about sleep
. In one of your earlier questions, you posted a link to the user.h header file.
That header file tells your C compiler what arguments the function takes and what the function returns, on this line:
int sleep(int);
After processing that line, the C compiler knows that sleep
expects a single int
argument. Therefore, when you try to call that function in a C program, the compiler will ensure that an argument is passed to the function using the standard way of passing int
arguments to functions on your platform. This is called the calling convention. For example, the calling convention might say to put the argument on the stack or to put it in a specific register. You can view the assembly generated by your C compiler to see what it does when it calls sleep
.
I don't really know the details of what ecall
does, but at some point it should trigger some code in your kernel, and that code would also know about your platform's calling convention, so it can retrieve the argument that your C compiler passed to sleep
.
For more details about the kernel side, look at the the source code of sys_sleep and see how it calls argint
to get its argument.