更多信息请访问:与华为官方共建的Harmonyos技术社区https://harmonyos.51cto.com在阅读本文之前,本文将系统调用解释清楚。本文通过一张图片和七段代码详细介绍了系统调用的全过程。代码一直戳到最后,直到汇编层不能再继续下去。先看图,这里的mode可以理解为空间,因为mode不一样。堆栈空间不同。流程解读●在应用层main中使用系统调用mq_open(posix标准接口)●mq_open封装在库中,这里直接看库中的代码。●调用mq_open中的syscall并将参数传递给寄存器R7、R0~R6●SVC0完成从用户模式到内核模式(SVC)的切换●_osExceptSwiHdl运行在svc模式。●PC寄存器直接指向_osExceptSwiHdl取指令。●_osExceptSwiHdl为汇编代码,保存用户优先模式地址(R0~R12寄存器),调用OsArmA32SyscallHandle完成系统调用。OsArmA32SyscallHandle通过系统调用号(保存在R7寄存器中)查询对应的注册函数SYS_mq_open。SYS_mq_open就是这个系统调用的实现函数。完成后返回OsArmA32SyscallHandleOsArmA32SyscallHandle返回_osExceptSwiHdl_osExceptSwiHdl恢复用户态站点(R0~R12寄存器)从内核态(SVC)切换到用户态,PC寄存器也切换回用户态。流程中七段跟踪代码,一一分析1.Applicationmainintmain(void){charmqname[NAMESIZE],msgrv1[BUFFER],msgrv2[BUFFER];constchar*msgptr1="testmessage1";constchar*msgptr2="testmessage2withdifferentlength";mqd_tmqdes;intprio1=1,prio2=2;structtimespects;structmq_attrattr;intunresolved=0,failure=0;sprintf(mqname,"/"FUNCTION"_"TEST"_%d",getpid());attr.mq_msgsize=BUFFER;attr.mq_maxmsg=BUFFER;mqdes=mq_open(mqname,O_CREAT|O_RDWR,S_IRUSR|S_IWUSR,&attr);if(mqdes==(mqd_t)-1){perror(ERROR_PREFIX"mq_open");unresolved=1;}if(mq_send(mqdes,msgptr1,strlen(msgptr1),prio1)!=0){perror(ERROR_PREFIX"mq_send");unresolved=1;}printf("TestPASSED\n");returnPTS_PASS;}2.mq_open发起系统调用mqd_tmq_open(constchar*name,intflags,...){mode_tmode=0;structmq_attr*attr=0;if(*name=='/')name++;if(flags&O_CREAT){va_listap;va_start(ap,flags);mode=va_arg(ap,mode_t);attr=va_arg(ap,structmq_attr*);va_end(ap);}returnsyscall(SYS_mq_open,name,flags,mode,attr);}解释SYS_mq_open是一个真正的系统调用函数,对应一个系统调用号__NR_mq_open,通过宏SYSCALL_HAND_DEF.staticUINTPTRg_syscallHandle[SYS_CALL_NUM]=将SysMqOpen注册到g_syscallHandle{0};//系统调用入口函数注册staticUINT8g_syscallNArgs[(SYS_CALL_NUM+1)/NARG_PER_BYTE]={0};//保存系统调用对应的参数个数#defineSYSCALL_HAND_DEF(id,fun,rType,nArg)\if((id)
