linux驱动开发3系统调用.docx
- 文档编号:27958935
- 上传时间:2023-07-06
- 格式:DOCX
- 页数:13
- 大小:531.72KB
linux驱动开发3系统调用.docx
《linux驱动开发3系统调用.docx》由会员分享,可在线阅读,更多相关《linux驱动开发3系统调用.docx(13页珍藏版)》请在冰豆网上搜索。
linux驱动开发3系统调用
一、linux驱动开发--系统调用
1、系统调用原理
用户实现系统调用是通过SWI指令来实现的,SWI指令是使ARM从用户模式切换到管理模式。
内核运行在管理模式,用户模式运行在用户模式。
SWI指令格式如下:
SWI{cond}immed_24
immed_24为24位立即数也就是最终要用的中断号
如执行swi0x900004这条指令就会产生异常,使系统进入到系统管理模式,在异常向量表中的bswi指令,最终会跳转到arch/arm/kernel/entry-common.S这个文件中的vector_swi标号处,
代码如下,做了精简就是程序执行时运行的代码:
.typesys_call_table,#object//定义sys_call_table
ENTRY(sys_call_table)
#include"calls.S"//sys_call_table标号后面直接跟系统调用表,在calls.S中,各个系统调用函数的函数名即函数地址被按顺序存储。
ENTRY(vector_swi)
/*xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
tstr8,#PSR_T_BIT
movner10,#0@nothumbOABIemulation
ldreqr10,[lr,#-4]@getSWIinstruction
//取得SWI指令本身的机器码
/*xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
/*xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
ldrip,__cr_alignment
ldrip,[ip]
mcrp15,0,ip,c1,c0@updatecontrolregister
#endif
enable_irq
get_thread_infotsk
adrtbl,sys_call_table@loadsyscalltablepointer
/*xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
bicsr10,r10,#0xff000000
//__NR_OABI_SYSCALL_BASE实际为0x900000
所以SWI输入中断号的时候,后面是0x900000加中断号
eornescno,r10,#__NR_OABI_SYSCALL_BASE
sys_oabi_call_table与sys_call_table等价
ldrnetbl,=sys_oabi_call_table
1.//所以对于上面示例中swi0x900004系统调用号scno=0x900004
2.//eor scno,scno,#0x900000
/*xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
/*xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
ldrr10,[tsk,#TI_FLAGS]@checkforsyscalltracing
stmdbsp!
{r4,r5}@pushfifthandsixthargs
/*xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
/*xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
tstr10,#_TIF_SYSCALL_WORK@arewetracingsyscalls?
bne__sys_trace
cmpscno,#NR_syscalls@checkuppersyscalllimit
adrlr,BSYM(ret_fast_syscall)@returnaddress
ldrccpc,[tbl,scno,lsl#2]@callsys_*routine//找到要调用的函数,开始执行
/*xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
总之,系统调用就是使用SWI+中断号使系统运行到管理模式,然后再跳转到vector_swi就算出相应的中断号,然后再通过查询sys_call_tabl表,跳转到相应的系统调用函数。
arch/arm/include/asm/unistd.h中定义的都是系统调用号,由用户进程进行系统调用的时候会用到。
2、添加系统调用
1>在 arch/arm/kernel/calls.S中添加自己要添加的系统调用函数如:
asmlinkageintsys_my_add(inta,intb)
{
returna+b;
}
2>在arch/arm/include/asm/unistd.h中最后一行添加,中断号要最后一个中断号加1
#define__NR_my_ade (__NR_SYSCALL_BASE+378)
3>arch/arm/kernel/calls.S最后一行添加
CALL(sys_my_add)
4>在用户空间进行系统调用
#include
#include
#include
intmain(intargc,char*argv[])
{
intsum;
sum=syscall(378,1,2);
printf("sum=%d\n",sum);
return0;
}
3、LR寄存器
ARM异常中断处理、lr寄存器、工作模式栈设计、中断服务程序ISR
中断和异常处理
中断是异常的一种。
每种异常都有各自的异常处理(exceptionhandler),handler存放在异常向量表(vectortable)中,由于向量表比较小,handler里通常通过一句跳转语句跳转到实际的异常服务程序中去。
异常会引起处理器工作模式的变化,异常和工作模式的关系为:
当发生异常时,处理器会自动将:
1.当前模式的cpsr存放至异常模式的spsr
2.pc存放至异常模式的lr
3.改变cpsr的工作模式域
4.将pc设置成exceptionhandler的地址
向量表里面存放着handler,handler里面通常是一句跳转语句:
之所以是跳转语句,是因为这几种异常handler的间隔只有4个字节的地址差,即存放一条32位指令,异常服务程序一条指令处理不完吧,所以放一条跳转语句在那里,通过跳转语句跳转到实际的异常服务程序。
注意B和LDR使用的区别。
然而由于FIQ是向量表里面的最后异常,如果向量表后面没有其他内容的话,FIR的handler可以不用跳转,将FIQ服务程序直接放在地址0x0000001C的开始。
----------------------------
七种异常
reset:
初始化内存、缓存、中断源、每种工作模式下的栈指针。
dataabort:
访问了无效内存地址,譬如某些内存地址上并没有挂载实际的物理器件。
另外,可能访问了没有权限的内存。
IRQ:
外设将IRQ引脚设为低电平时触发。
FIQ:
外设将FIQ引脚设为低电平时触发,FIQ优先级比IRQ高,有更多的独立模式寄存器。
prefetchabort:
取指令时造成内存错误时触发。
SWI:
通过执行SWI指令触发。
undefinedinstruction:
遇到了非法指令。
----------------------------
异常返回
lr寄存器保存着异常返回地址。
几种常用的处理lr的方式
----------------------------
中断
中断处理步骤:
步骤2里面的都是处理器自动完成的,与其他异常有点不太一样的是它还会将中断掩码设为1,即屏蔽中断。
手动使能中断的方法
中断栈设计
中断时需要保护现场,即将当前工作模式下的数据压入栈。
另外,在reset异常中,需要设置栈指针。
为了避免栈溢出,可以每次都调用栈检查函数(见汇编篇),还可以采用内存保护机制。
典型的栈分布为:
B分布比A分布好的原因是,即使栈溢出了,不会损坏向量表。
譬如要设计以上的一个栈分布时,代码如下,不同工作模式下的栈指针应在reset异常下完成:
一开始设置SVC模式的栈,然后IRQ的,然后user的。
通过MSR改变cpsr。
USR_Stack,Usr32md等都是宏定义,通过EQU来定义:
顺便说下DCD指令,DCD就是分配一个地址并初始化为指定的表达式,如:
DCD 0x8000;就是分配一个32位的地址,其内容是0x8000
如果用上标号label,那么这个label相当于一个变量,如:
label DCD 0X8000;这样引用label就是使用了0x8000这个数值。
----------------------------
简单的非递归的interrupthandler
中断服务程序ISR完成步骤的3和4,在步骤3中通过读取芯片内的中断状态寄存器,可以知道哪个中断源发生了中断,并调用相应的处理程序,所以ISR也像一个表一样的东西。
可以用C编写。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- linux 驱动 开发 系统 调用