(本节笔记的实验代码,在这里)
1. 系统调用(sys_call)的作用与介绍
系统调用并不是由C库或其他库中实现的,用户空间的应用程序用到的系统调用函数sys_call的实现来源于内核空间中。
从用户空间调用(read)时,将执行SWI指令,Linux系统从用户空间切换到内核空间,在切换前,会把read函数要执行的系统调用所对应的系统调用编号传入R7寄存器,等切换完成之后,再根据R7寄存器的值来查找对应的内核中该系统调用的实现代码。
调用SWI指令的实现函数位于内核源码\arch\arm\kernel\entry-common.S中的ENTRY(vector_swi)函数中,把R7的值传进scno参数中。(该函数并不需要修改)根据scno,在位于内核源码\arch\arm\kernel\calls.S中的sys_call_table中找出编号所对应的调用函数名。
实现新的系统调用,名称为pk,功能为打印一条信息。
1)因为所要实现的系统调用的功能是打印信息,因此把代码加入printk.c中(位于内核源码\kernel\printk.c中)
『
void sys_pk
{
printk("This is a new sys call!\n");
}
』
『
CALL(sys_pk)
』
『
#define __NR_pk (__NR_SYSCALL_BASE+363)
//每个内核的系统调用编号都不一样,不一定就是363号!
』
4)重新编译内核,编译前线make clean,然后make uImage ARCH=arm CROSS_COMPILE=arm-linux-,把编译完成的uImage复制到tftp中。
『
void pk()
{
__asm__(
"ldr r7,=363 \n"
"swi \n"
:
:
:"memory");
}
int main()
{
pk();
return 0;
}
』
采用静态方式编译syscall.c,arm-linux-gcc -static syscall.c -o syscall