以write系统调用函数为例向串口终端输出字符串:
printf("hello,world\n");或者write(1, "hello,world\n", 12);
1.某个进程调用write系统调用函数
2.首先跑到C库的write函数的定义(实现)
3.C库write函数的定义将做两件事
(1)保存write函数对应的系统调用号到r7寄存器
系统调用号:linux内核给每一个系统调用函数都分配一个唯一的数字编号,这个编号称之为系统调用号(系统调用函数的身份证号),定义在内核源码的:arch/arm/include/asm/unistd.h。
write函数的系统调用号(__NR_系统调用函数名): #define __NR_write 4
(2)调用svc指令触发软中断异常、老ARM版本使用swi指令、 新ARM版本使用svc指令
4.一旦C库的write函数触发软中断异常,接下来要做:
ARM核硬件做:
(1)备份CPSR
(2)设置CPSR
(3)lr=pc-4
(4)pc=软中断的处理入口地址0x08
跳转到内核事先准备好的异常向量表的软中断处理入口地址0x08,继续执行,开启了软件处理异常的流程;至此:CPU由USER模式切换SVC管理模式
5.一旦跳转到软中断异常的处理入口地址以后,将做以下事情:
保护现场(压栈)
处理做两件事:
(1).从r7寄存器中取出之前保存的系统调用号4
(2).再以系统调用号为下标,在内核实现准备好的系统调用表(数组)中找到对应的函数sys_write;找到以后,调用此函数,此函数执行完毕,返回即可
“系统调用表”:本质上就是一个数组,数组的每一个元素保存的是一个函数指针,函数名命名sys_系统调用函数名,这些代码统统由内核已经实现好(定义在内核源码的arch/arm/arch/arm/kernel/calls.S)
恢复现场(出栈),也就代表着应用程序调用write函数的返回