1 之前自己写过一篇介绍shell的文章hi3518 openharmony shell命令代码修改,并没有全面介绍shell,最近又参考了两篇鸿蒙内核源码shell解析和鸿蒙系统的shell 。liteos-a中shell相关代码是有两处,但是这两处有什么区别和联系,第一篇没有去介绍,第二篇介绍了但是没有更深入细致的说明二者的关系,所以本文中着重介绍一下。 2 liteos-a中的两个shell地方,我们可以把它俩叫做app_shell和full_shell,一个是用户空间程序,会生成单独的shell文件,放到了跟文件系统的bin目录下,代码位置如下: 另一个地方运行在内核空间,和内核固件放到了一起,代码位置如下: 我们在串口操作命令,不管是系统命令还是运行二进制文件,都会走到如下函数,在如下函数会判断两种情况,调用不同的系统调用,从而由用户态切换到内核态。 运行效果如下: 其中execve和syscall(__NR_shellexec, cmdName, cmdline)分别执行二机制文件和系统命令,关于系统调用简单说就是通过软中断方式由用户态进入到内核态,内核态会有对应的处理函数,此文不着重介绍,这两个判断函数所在文件如下所示: 3 先说系统命令的调用流程,从用户态进入内核态之后,进入到的函数名称如下,从函数位置名字和里边的copyfromuser可以看出这就是一个系统调用处理函数,还有从用户空间往内核空间拷贝命令的操作。 在这个函数里最终调用的函数为 OsCmdExec,注意内核代码中有两个这个函数的实现不要弄混,用户程序的shell代码中的这个函数是不对的,代码中也有注释说明。 在这个函数中最终在全局变量中找到命令匹配的执行函数,完成了命令你的调用。 4 然后说一下二进制文件调用的流程 execve最终的系统调用执行函数是SysExecve 然后直接调用 在这个函数里,最终调用到了运行加载运行elf二进制文件的操作 5 app_shell和full_shell的这两部分代码,有好多函数名都一样,代码逻辑也类似,很很容易让人疑惑,操作系统接受命令时,默认会初始化串口shell控制台,,还有一个功能时telnet服务器在启动时会初始化telnet控制台,串口是启动时调用,telnet是自己运行命令调用,后续我们在单独介绍telnet shell相关代码,敬请期待。
https://ost.51cto.com/#bkwz
::: hljs-center
:::