当前位置:   article > 正文

鸿蒙系统源代码解析,鸿蒙内核源码分析(系统调用篇) | 图解系统调用全貌

鸿蒙源代码是什么

8db4bb11198ed53e0b99de6a8ef0c0b3.png

本篇说清楚系统调用

读本篇之前建议先读鸿蒙内核源码分析(总目录)工作模式篇.

本篇通过一张图和七段代码详细说明系统调用的整个过程,代码一捅到底,直到汇编层再也捅不下去. 先看图,这里的模式可以理解为空间,因为模式不同运行的栈空间就不一样.

a8e45e7f6df652b620324604a6cbc614.png

过程解读

● 在应用层main中使用系统调用mq_open(posix标准接口)

● mq_open被封装在库中,这里直接看库里的代码.

● mq_open中调用syscall,将参数传给寄出器 R7,R0~R6

● SVC 0 完成用户模式到内核模式(SVC)的切换

● _osExceptSwiHdl运行在svc模式下.

● PC寄存器直接指向_osExceptSwiHdl处取指令.

● _osExceptSwiHdl是汇编代码,先保存用户模式现场(R0~R12寄存器),并调用OsArmA32SyscallHandle完成系统调用

● OsArmA32SyscallHandle中通过系统调用号(保存在R7寄存器)查询对应的注册函数SYS_mq_open

● SYS_mq_open是本次系统调用的实现函数,完成后return回到OsArmA32SyscallHandle

● OsArmA32SyscallHandle再return回到_osExceptSwiHdl

● _osExceptSwiHdl恢复用户模式现场(R0~R12寄存器)

● 从内核模式(SVC)切回到用户模式,PC寄存器也切回用户现场.

● 由此完成整个系统调用全过程

七段追踪代码,逐个分析

1.应用程序 main

intmain(void)

{

charmqname[NAMESIZE], msgrv1[BUFFER], msgrv2[BUFFER];

const char*msgptr1 ="test message1";

const char*msgptr2 ="test message2 with differnet length";

mqd_t mqdes;

intprio1 = 1, prio2 = 2;

struct timespec ts;

struct mq_attr attr;

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("Test PASSED\n");

returnPTS_PASS;

}

2. mq_open 发起系统调用

mqd_t mq_open(constchar*name,intflags, ...)

{

mode_t mode = 0;

struct mq_attr *attr = 0;

if (*name=='/')name++;

if (flags & O_CRE

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/不正经/article/detail/245090
推荐阅读
相关标签
  

闽ICP备14008679号