鸿蒙内核源码分析(Shell编辑篇) | 两个任务,三个阶段

系列篇从内核视角用一句话概括shell的底层实现为:两个任务,三个阶段。其本质是独立进程,因而划到进程管理模块。每次创建shell进程都会再创建两个任务。

  • 客户端任务(ShellEntry): 负责接受来自终端(控制台)敲入的一个个字符,字符按VT规范组装成一句句的命令。
  • 服务端任务(ShellTask): 对命令进行解析并执行,将结果输出到控制台。

而按命令生命周期可分三个阶段.

  • 编辑: 鸿蒙在这个部分实现了一个简单的编辑器功能,处理控制台输入的每个字符,主要包括了对控制字符 例如 <ESC>,\t,\b,\n,\r,四个方向键0x41 ~ 0x44 的处理。
  • 解析: 对编辑后的字符串进行解析,解析出命令项和参数项,找到对应的命令项执行函数。
  • 执行: 命令可通过静态和动态两种方式注册到内核,解析出具体命令后在注册表中找到对应函数回调。将结果输出到控制台。

编辑部分由客户端任务完成,后两个部分由服务端任务完成,命令全局注册由内核完成。

  • 本篇主要说 客户端任务 和 编辑过程
  • 服务端任务 和 解析/执行过程 已在 (Shell解析篇) 中说明,请自行翻看.

什么是 Shell

从用户视角看,shell是用户窥视和操作内核的一个窗口,内核并非铁板一块,对应用层开了两个窗口,一个是系统调用,一个就是shell,由内核提供实现函数,由用户提供参数执行。区别是 shell是由独立的任务去完成,可通过将shell命令序列化编写成独立的,简单的shell程序,所以shell也是一门脚本语言,系统调用是依附于应用程序的任务去完成,能做的有限。通过shell窗口能看到 cpu的运行情况,内存的消耗情况,网络的链接状态等等。

鸿蒙 Shell 代码在哪

shell对应的概念是kernel,在鸿蒙内核,这两部分代码是分开放的,shell代码在 查看 shell 代码 ,目录结构如下.

├─include
│      dmesg.h
│      dmesg_pri.h
│      shcmd.h
│      shcmdparse.h
│      shell.h
│      shell_lk.h
│      shell_pri.h
│      shmsg.h
│      show.h
│
└─src├─base│      shcmd.c│      shcmdparse.c│      shell_lk.c│      shmsg.c│      show.c│└─cmdsdate_shellcmd.cdmesg.chwi_shellcmd.cshell_shellcmd.cwatch_shellcmd.c

Shell 控制块

跟进程,任务一样,每个概念的背后需要一个主结构体来的支撑,shell的主结构体就是ShellCB,掌握它就可以将shell拿捏的死死的,搞不懂这个结构体就读不懂shell的内核实现.所以在上面花再多功夫也不为过.

typedef struct {UINT32   consoleID;	//控制台IDUINT32   shellTaskHandle;	//shell服务端任务IDUINT32   shellEntryHandle;	//shell客户端任务IDVOID     *cmdKeyLink;		//待处理的shell命令链表VOID     *cmdHistoryKeyLink;//已处理的历史记录链表,去重,10个VOID     *cmdMaskKeyLink;	//主要用于方向键上下遍历历史命令UINT32   shellBufOffset;	//buf偏移量UINT32   shellKeyType;	//按键类型EVENT_CB_S shellEvent;	//事件类型触发pthread_mutex_t keyMutex;	//按键互斥量pthread_mutex_t historyMutex;	//历史记录互斥量CHAR     shellBuf[SHOW_MAX_LEN];	//shell命令buf,接受键盘的输入,需要对输入字符解析.CHAR     shellWorkingDirectory[PATH_MAX];//shell的工作目录
} ShellCB;
//一个shell命令的结构体,命令有长有短,鸿蒙采用了可变数组的方式实现
typedef struct {UINT32 count;	//字符数量LOS_DL_LIST list;	//双向链表CHAR cmdString[0];	//字符串,可变数组的一种实现方式.
} CmdKeyLink;enum {STAT_NOMAL_KEY,	//普通的按键STAT_ESC_KEY,	//<ESC>键在VT控制规范中时控制的起始键STAT_MULTI_KEY	//组合键
};

解读

  • 鸿蒙支持两种方式在控制台输入Shell命令,关于控制台请自行翻看控制台篇.
    • 在串口工具中直接输入Shell命令 CONSOLE_SERIAL
    • telnet工具中输入Shell命令 CONSOLE_TELNET
  • shellTaskHandleshellEntryHandle编辑/处理shell命令的两个任务ID,本篇重点说后一个.
  • cmdKeyLink,cmdHistoryKeyLink,cmdMaskKeyLink是三个类型为CmdKeyLink的结构体,本质是双向链表,对应编辑shell命令过程中的三个功能.
    • cmdKeyLink 待执行的命令链表
    • cmdHistoryKeyLink 存储命令历史记录的,即: history命令显示的内容
    • cmdMaskKeyLink 记录按上下方向键输出的内容,这个有点难理解,自行在shell中按上下方向键自行体验
  • shellBufOffsetshellBuf是成对出现的,其中存放的就是用户敲入处理后的字符.
  • keyMutexhistoryMutex为操作链表所需的互斥锁,内核用的最多的就是这类锁.
  • shellEvent用于任务之间的通讯,比如.
    • SHELL_CMD_PARSE_EVENT:编辑完成了通知解析任务开始执行
    • CONSOLE_SHELL_KEY_EVENT:收到来自控制台的CTRL + C信号产生的事件.
  • shellKeyType 按键的类型,分三种 普通,键,组合键
  • shellWorkingDirectory 工作区就不用说了,从哪个目录进入shell

创建 Shell

//shell进程的入口函数
int main(int argc, char **argv)
{//...g_shellCB = shellCB;//全局变量,说明鸿蒙同时只支持一个shell进程return OsShellCreateTask(shellCB);//初始化两个任务
}
//创建shell任务
STATIC UINT32 OsShellCreateTask(ShellCB *shellCB)
{UINT32 ret = ShellTaskInit(shellCB);//执行shell命令的任务初始化if (ret != LOS_OK) {return ret;}return ShellEntryInit(shellCB);//通过控制台接收shell命令的任务初始化
}
//进入shell客户端任务初始化,这个任务负责编辑命令,处理命令产生的过程,例如如何处理方向键,退格键,回车键等
LITE_OS_SEC_TEXT_MINOR UINT32 ShellEntryInit(ShellCB *shellCB)
{UINT32 ret;CHAR *name = NULL;TSK_INIT_PARAM_S initParam = {0};if (shellCB->consoleID == CONSOLE_SERIAL) {name = SERIAL_ENTRY_TASK_NAME;} else if (shellCB->consoleID == CONSOLE_TELNET) {name = TELNET_ENTRY_TASK_NAME;} else {return LOS_NOK;}initParam.pfnTaskEntry = (TSK_ENTRY_FUNC)ShellEntry;//任务入口函数initParam.usTaskPrio   = 9; /* 9:shell task priority */initParam.auwArgs[0]   = (UINTPTR)shellCB;initParam.uwStackSize  = 0x1000;initParam.pcName       = name;initParam.uwResved     = LOS_TASK_STATUS_DETACHED;ret = LOS_TaskCreate(&shellCB->shellEntryHandle, &initParam);//创建任务
#ifdef LOSCFG_PLATFORM_CONSOLE(VOID)ConsoleTaskReg((INT32)shellCB->consoleID, shellCB->shellEntryHandle);//将任务注册到控制台
#endifreturn ret;
}

解读

  • mainshell进程的主任务,每个进程都会创建一个默认的线程(任务),这个任务的入口函数就是大家熟知的main函数,不清楚的自行翻看任务管理各篇有详细的说明.
  • main任务再创建两个任务,即本篇开头说的两个任务,本篇重点说其中的一个 ShellEntry,任务优先级为9,算是较高优先级.
  • 指定内核栈大小为0x1000 = 4K ,因任务只负责编辑处理控制台输入的字符,命令的执行在其他任务,所以4K的内核空间足够使用.
  • ShellEntry为入口函数,这个函数的实现为本篇的重点

ShellEntry | 编辑过程

LITE_OS_SEC_TEXT_MINOR UINT32 ShellEntry(UINTPTR param)
{CHAR ch;INT32 n = 0;ShellCB *shellCB = (ShellCB *)param;CONSOLE_CB *consoleCB = OsGetConsoleByID((INT32)shellCB->consoleID);//获取控制台if (consoleCB == NULL) {PRINT_ERR("Shell task init error!\n");return 1;}(VOID)memset_s(shellCB->shellBuf, SHOW_MAX_LEN, 0, SHOW_MAX_LEN);//重置shell命令bufwhile (1) {
#ifdef LOSCFG_PLATFORM_CONSOLEif (!IsConsoleOccupied(consoleCB)) {//控制台是否被占用
#endif/* is console ready for shell ? */n = read(consoleCB->fd, &ch, 1);//从控制台读取一个字符内容,字符一个个处理if (n == 1) {//如果能读到一个字符ShellCmdLineParse(ch, (pf_OUTPUT)dprintf, shellCB);}if (is_nonblock(consoleCB)) {//在非阻塞模式下暂停 50msLOS_Msleep(50); /* 50: 50MS for sleep */}
#ifdef LOSCFG_PLATFORM_CONSOLE}
#endif}
}
//对命令行内容解析
LITE_OS_SEC_TEXT_MINOR VOID ShellCmdLineParse(CHAR c, pf_OUTPUT outputFunc, ShellCB *shellCB)
{const CHAR ch = c;INT32 ret;//不是回车键和字符串结束,且偏移量为0if ((shellCB->shellBufOffset == 0) && (ch != '\n') && (ch != '\0')) {(VOID)memset_s(shellCB->shellBuf, SHOW_MAX_LEN, 0, SHOW_MAX_LEN);//重置buf}//遇到回车或换行if ((ch == '\r') || (ch == '\n')) {if (shellCB->shellBufOffset < (SHOW_MAX_LEN - 1)) {shellCB->shellBuf[shellCB->shellBufOffset] = '\0';//字符串结束}shellCB->shellBufOffset = 0;(VOID)pthread_mutex_lock(&shellCB->keyMutex);OsShellCmdPush(shellCB->shellBuf, shellCB->cmdKeyLink);//解析回车或换行(VOID)pthread_mutex_unlock(&shellCB->keyMutex);ShellNotify(shellCB);//通知任务解析shell命令return;} else if ((ch == '\b') || (ch == 0x7F)) { /* backspace or delete(0x7F) */ //遇到删除键if ((shellCB->shellBufOffset > 0) && (shellCB->shellBufOffset < (SHOW_MAX_LEN - 1))) {shellCB->shellBuf[shellCB->shellBufOffset - 1] = '\0';//填充`\0`shellCB->shellBufOffset--;//buf减少outputFunc("\b \b");//回调入参函数}return;} else if (ch == 0x09) { /* 0x09: tab *///遇到tab键if ((shellCB->shellBufOffset > 0) && (shellCB->shellBufOffset < (SHOW_MAX_LEN - 1))) {ret = OsTabCompletion(shellCB->shellBuf, &shellCB->shellBufOffset);//解析tab键if (ret > 1) {outputFunc("OHOS # %s", shellCB->shellBuf);//回调入参函数}}return;}/* parse the up/down/right/left key */ret = ShellCmdLineCheckUDRL(ch, shellCB);//解析上下左右键if (ret == LOS_OK) {return;}if ((ch != '\n') && (ch != '\0')) {//普通的字符的处理if (shellCB->shellBufOffset < (SHOW_MAX_LEN - 1)) {//buf范围shellCB->shellBuf[shellCB->shellBufOffset] = ch;//直接加入} else {shellCB->shellBuf[SHOW_MAX_LEN - 1] = '\0';//加入字符串结束符}shellCB->shellBufOffset++;//偏移量增加outputFunc("%c", ch);//向终端输出字符}shellCB->shellKeyType = STAT_NOMAL_KEY;//普通字符
}

解读

  • ShellEntry内部是个死循环,不断的读取控制台输入的每个字符,注意是按字符处理.
  • 处理四个方向,换行回车,tab,backspace,delete,esc 等控制键,相当于重新认识了下Ascii表.可以把shell终端理解为一个简单的编辑器.
    • 按回车键 表示完成前面的输入,进入解析执行阶段.
    • 按方向键 要显示上/下一个命令的内容,一直按就一直显示上上/下下命令.
    • tab键 是要补齐命令的内容,目前鸿蒙支持如下命令:
          arp           cat           cd            chgrp         chmod         chown         cp            cpup          date          dhclient      dmesg         dns           format        free          help          hwi           ifconfig      ipdebug       kill          log           ls            lsfd          memcheck      mkdir         mount         netstat       oom           partinfo      partition     ping          ping6         pwd           reset         rm            rmdir         sem           statfs        su            swtmr         sync          systeminfo    task          telnet        test          tftp          touch         umount        uname         watch         writeproc  

例如:当在控制台按下 ch和 tab键后会输出以下三个

        chgrp         chmod         chown

内容,这些功能对使用者而已看似再平常不过,但都需要内核一一实现.

  • shellBuf存储编辑结果,当按下回车键时,将结果保存并交付给下一个阶段使用.

鸿蒙全栈开发全新学习指南

也为了积极培养鸿蒙生态人才,让大家都能学习到鸿蒙开发最新的技术,针对一些在职人员、0基础小白、应届生/计算机专业、鸿蒙爱好者等人群,整理了一套纯血版鸿蒙(HarmonyOS Next)全栈开发技术的学习路线【包含了大厂APP实战项目开发】

本路线共分为四个阶段:

第一阶段:鸿蒙初中级开发必备技能

第二阶段:鸿蒙南北双向高工技能基础:gitee.com/MNxiaona/733GH

第三阶段:应用开发中高级就业技术

第四阶段:全网首发-工业级南向设备开发就业技术:gitee.com/MNxiaona/733GH

《鸿蒙 (Harmony OS)开发学习手册》(共计892页)

如何快速入门?

1.基本概念
2.构建第一个ArkTS应用
3.……

开发基础知识:gitee.com/MNxiaona/733GH

1.应用基础知识
2.配置文件
3.应用数据管理
4.应用安全管理
5.应用隐私保护
6.三方应用调用管控机制
7.资源分类与访问
8.学习ArkTS语言
9.……

基于ArkTS 开发

1.Ability开发
2.UI开发
3.公共事件与通知
4.窗口管理
5.媒体
6.安全
7.网络与链接
8.电话服务
9.数据管理
10.后台任务(Background Task)管理
11.设备管理
12.设备使用信息统计
13.DFX
14.国际化开发
15.折叠屏系列
16.……

鸿蒙开发面试真题(含参考答案):gitee.com/MNxiaona/733GH

鸿蒙入门教学视频:

美团APP实战开发教学:gitee.com/MNxiaona/733GH

写在最后

  • 如果你觉得这篇内容对你还蛮有帮助,我想邀请你帮我三个小忙:
  • 点赞,转发,有你们的 『点赞和评论』,才是我创造的动力。
  • 关注小编,同时可以期待后续文章ing🚀,不定期分享原创知识。
  • 想要获取更多完整鸿蒙最新学习资源,请移步前往小编:gitee.com/MNxiaona/733GH

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/836285.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C++音视频开发面试题

下面是音视频开发面试题精选&#xff1a; 1、纹理抗锯齿有哪些算法&#xff1f;各有哪些利弊&#xff1f;2、使用 OpenGL PBO 为什么能提高效率&#xff1f;3、iOS 如何使用分段转码&#xff0c;如何设置分片大小&#xff1f;4、VideoToolbox 中是不是不存在平面格式&#xff…

【图解计算机网络】http1.1,http2.0,http3.0

http1.1&#xff0c;http2.0&#xff0c;http3.0 http1.1长连接管道传输缺点 http2.0头部压缩二进制格式并发传输服务端推送缺点 http3.0无队头阻塞快速建立连接连接迁移 http1.1 长连接 在http1.0的时候&#xff0c;一次http请求就要建立一次TCP连接&#xff0c;这一次的htt…

LeetCode 654.最大二叉树

LeetCode 654.最大二叉树 1、题目 题目链接&#xff1a;654. 最大二叉树 给定一个不重复的整数数组 nums 。 最大二叉树 可以用下面的算法从 nums 递归地构建: 创建一个根节点&#xff0c;其值为 nums 中的最大值。递归地在最大值 左边 的 子数组前缀上 构建左子树。递归地…

11、关系运算符、逻辑运算符(讲解 和 的区别)、赋值表达式、三目表达式、运算符优先级(超详细版本)+结合性的分析

这里写目录标题 一、关系运算符&#xff08;比较运算符&#xff09;二、⭐逻辑运算符1、 && 和 &2、|| 或 |3、&#xff01;4、^ 三、赋值运算符四、三目运算符&#xff08;条件运算符&#xff09;五、运算符优先级 在讲之前先明确几个概念&#xff1a; 1、单目运算…

【人工智能基础】GAN与WGAN实验

一、GAN网络概述 GAN&#xff1a;生成对抗网络。GAN网络中存在两个网络&#xff1a;G&#xff08;Generator&#xff0c;生成网络&#xff09;和D&#xff08;Discriminator&#xff0c;判别网络&#xff09;。 Generator接收一个随机的噪声z&#xff0c;通过这个噪声生成图片…

阿里开源编程大模型 CodeQwen1.5:64K92编程语言,Code和SQL编程,评测接近GPT-4-Turbo

前言 阿里巴巴最近发布的CodeQwen1.5模型标志着其在编程语言模型领域的一次重大突破。这款开源模型不仅支持高达92种编程语言和64K的上下文长度&#xff0c;而且在多项性能评测中显示出接近或超过当前行业领导者GPT-4-Turbo的能力。 Huggingface模型下载&#xff1a;https://h…

Boost库的使用

1 下载与安装 1.1 下载 网址&#xff1a;Boost C Libraries 进入后选择自己需要的版本安装即可 1.2 安装 1.2.1 解压 1.2.2 编译安装 双击bootstrap.bat 这一步完成后会生成一个b2.exe文件 双击b2.exe文件运行&#xff08;此步需要花费较长的时间&#xff09; 之后再stag…

双向链表(双向带头循环)的增删查改的实现(简单易懂)

一&#xff1a;双向链表的概念 每个节点除开存有数据&#xff0c;还有一个指针指向前一个节点&#xff0c;一个指针指向后一个节点&#xff0c;尾节点和哨兵位互相指向&#xff0c;从而形成一个循环。 二&#xff1a;双向链表的实现第一点&#xff1a; 本文采用三个文件进行实…

GIS数据—1984-2020中国1km人造夜间灯光观测数据

夜间灯光观测数据&#xff08;Nighttime Light,NTL&#xff09;是评估人类活动边界的常用手段&#xff0c;目前&#xff0c;该数据已经广泛应用于城市范围、不透水面、基础设施建设等一系列过程。今天&#xff0c;小编要带来的是长时间序列中国区域边界的夜间灯光观测数据。 数…

springcloud -nacos实战

一、nacos 功能简介 1.1.什么是Nacos&#xff1f; 官方简介&#xff1a;一个更易于构建云原生应用的动态服务发现(Nacos Discovery )、服务配置(Nacos Config)和服务管理平台。 Nacos的关键特性包括&#xff1a; 服务发现和服务健康监测动态配置服务动态DNS服务服务及其元数…

VMware配置Kali linux + 物理机连接Xshell

VMware 配置 kali linux 首先需要先安装VMware Workstation 我是在Windows 安装的 VMware Workstation Pro 17 虚拟化&#xff0c;产品密钥。。这里不做多说了 下载kali linux 这里我下载的是kali-linux-2024.1 Note&#xff1a;这里选Virtual Machines&#xff0c;建议不要…

景源畅信:抖音小店的商品怎么同步到橱窗?

在数字营销的海洋中&#xff0c;抖音小店与橱窗的同步操作无疑是商家们关注的焦点。这不仅能增加商品的曝光度&#xff0c;还能提高交易的可能性。那么&#xff0c;如何将抖音小店的商品同步到橱窗呢? 一、核心步骤解析 要实现商品从抖音小店同步到橱窗&#xff0c;你需要确保…

【Linux 网络】网络编程套接字 -- 详解

⚪ 预备知识 1、理解源 IP 地址和目的 IP 地址 举例理解&#xff1a;&#xff08;唐僧西天取经&#xff09; 在 IP 数据包头部中 有两个 IP 地址&#xff0c; 分别叫做源 IP 地址 和目的 IP 地址。 如果我们的台式机或者笔记本没有 IP 地址就无法上网&#xff0c;而因为…

Unity引擎是什么?有哪些优点

大家好&#xff0c;我是咕噜土豆&#xff0c;很高兴又和大家见面了。今天我们一起来了解一下Unity引擎和它有哪些优点。 首先带大家了解什么是Unity引擎 Unity引擎是一款由Unity Technologies开发的跨平台游戏开发引擎&#xff0c;广泛用于创建2D和3D游戏以及其他交互式内容&…

C++动态内存区域划分、new、delete关键字

目录 一、C/C中程序的内存区域划分 为什么会存在内存区域划分&#xff1f; 二、new关键字 1、内置类型的new/delete使用方法&#xff1a; 2、new和delete的本质 一、C/C中程序的内存区域划分 为什么会存在内存区域划分&#xff1f; 因为不同数据有不同的存储需求&#xff0…

【SpringBoot记录】从基本使用案例入手了解SpringBoot-数据访问(1)

前言 在程序开发尤其是网页应用开发中&#xff0c;数据访问是必不可少的。通过前面的基本案例我们完成了一个简单的SpringBoot Web应用并对自动配置原理有了一定了解&#xff0c;本节在上述案例基础上&#xff0c;继续编写数据访问案例&#xff0c;将通过SpringBoot中数据访问…

音视频开发6 音视频录制原理和播放原理

音视频录制原理 音视频播放原理

# 电脑突然连接不上网络了,怎么办?

电脑突然连接不上网络了&#xff0c;怎么办&#xff1f; 一、原因分析&#xff1a; 1、IP 地址冲突 2、DNS 解析出现问题。 3、电脑网络设置是否打开了【移动热点】或【飞行模式】。 4、【WLAN AutoConfig】服务是否打开。 5、无线网卡驱动损坏。 6、检查 WIFI 开关是否…

HTML+VUE3组合式+ELEMENT的容器模板示例(含侧栏导航,表格,...)

一个简单的在html中使用Vue3及Element-plus vue-icons的整合示例&#xff1a; 一、示例截图 二、文件代码 直接复制到html文件在浏览器打开即可预览 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title&g…

CCleaner系统优化与隐私保护工具,中文绿色便携版 v6.23.11010

01 软件介绍 CCleaner 是一款高级的系统优化工具&#xff0c;其设计宗旨在于彻底清理 Windows 操作系统中积累的无用文件和冗余的注册表项。此举旨在显著提升计算机的运行效率并回收磁盘空间。该软件拥有高效的能力&#xff0c;可以清除包括临时文件、浏览器缓存及其历史记录在…