鸿蒙LiteOs读源码教程+向LiteOS中添加一个系统调用
本文分为2个部分:第1部分简要介绍如何读鸿蒙Liteos源码,第2部分是实验向LiteOS中添加一个系统调用的完整过程。
前置资料:
imx6ull开发板使用方式详解 + 源码下载 +编译运行简单程序 + Ubuntu虚拟机使用鸿蒙LiteOs操作系统常见错误汇总
一、鸿蒙Liteos读源码教程
鸿蒙的源码是放在openharmony文件夹下,openharmony下的kernel文件夹存放操作系统内核的相关代码和实现。
内核是操作系统的核心部分,所以像负责:资源管理、任务调度、内存管理、设备驱动、进程通信的源码都可以在kernel文件夹里看到。
进入到kernel文件夹下后会看到liteos_a和liteos_m,我们只需要知道liteos_a是针对嵌入式设备的,所以像我们实验用的开发板就是看liteos_a下的代码,而liteos_m是针对物联网设备设计的,所以我们暂时先不去看这个。
友情提示:ubuntu虚拟机是有可视化界面的,只需要在桌面上点击进入Files即可看到系统中的文件:

进入liteos_a后真正的核心代码同样是存储在kernel下的:

主要介绍3个比较重要的:
base:该文件夹包含操作系统内核的基础部分,如调度器,同步机制,内存管理等基础功能的实现。
include:该文件夹包含内核需要的所有头文件。
user:该文件夹包含一些用户级别的功能,如用户任务,用户接口等。
所以如果想查看有关内核的代码就进入base文件夹,想查看或者修改头文件就进入include文件夹。
假设我们现在进入到base文件夹:

接下来我逐一向大家简要介绍:
core:包含了内核的核心代码,比如初始化代码,启动代码等。
include:包含了base部分所有的头文件。
ipc:是inter-process communication的缩写,和进程相关,包含了实现进程间通信的代码。
mem:是内存缩写,包含了实现内存管理的代码,如内存分配、内存释放等。
misc:包含杂项代码,如工具函数,调试功能。
mp:包含多处理器相关的代码,如多核心调度,同步等。
om:包含LiteOS的运维相关代码。
sched:是调度缩写,包含了LiteOS的任务调度代码,包括任务的创建,删除,切换等。
vm:是虚拟内存的缩写,包含了实现虚拟内存管理的代码,如页表管理,地址转换等。
二、向LiteOS中添加一个系统调用
实验要求:
该实验需要分别在用户态和内核态完成两部分内容:
内容1:在用户态下要为新添加的系统调用增加相应的库函数作为接口。
内容2:在内核态下要添加与接口函数对应的系统调用。
编写一个应用程序,该应用程序通过调用第一步中添加的库函数接口,进而触发新添加的系统调用,从而验证新添加系统调用的正确性。
参考资料:
OpenHarmony LiteOS-A内核文档之学习--系统调用-开源基础软件社区-51CTO.COM
第1步:在内核态添加系统调用号:
打开/home/book/openharmony/prebuits/lite/sysroot/usr/include/arm-liteos/bits/syscall.h文件,添加如下代码:

#define __NR_hxsyscall (__NR_OHOS_BEGIN +21)
在同文件里的末尾添加如下代码:

#define SYS_hxsyscall (__NR_OHOS_BEGIN + 21)
解释:定义一个名为__NR_hxsyscall和SYS_hxsyscall的宏,其值为(__NR_OHOS_BEGIN + 21),自定义了系统调用的系统调用号。这样定义了宏之后,可以在代码中使用__NR_hxsyscall或SYS_hxsyscall来代表自定义的系统调用号,以方便后续在代码中调用该系统调用。
两个宏实际上是等价的,只是提供了不同的命名选项。开发者可以根据需要选择使用SYS_hxsyscall或者__NR_hxsyscall。
如果是在用户空间(用户态)代码中,可能会使用没有前缀的版本,而在内核(内核态)代码中则可能会使用有前缀的版本,但这完全取决于项目的具体代码风格和约定。
第2步:在用户态添加系统调用号:
在/openharmony/third_party/musl/kernel/obj/include/bits/syscall.h文件,添加如下代码:

#define __NR_hxsyscall (__NR_OHOS_BEGIN + 21)
解释: /openharmony/third_party/musl/kernel/obj/include/bits/syscall.h文件是位于 musl libc 库的内核代码中,运行在用户态。
/home/book/openharmony/prebuits/lite/sysroot/usr/include/arm-liteos/bits/syscall.h文件是位于 OhOS Lite 操作系统的系统头文件中,运行在内核态。
所以第1步是在内核态添加系统调用号,第2步是在用户态添加系统调用号。
第3步:添加函数定义和实现
进入home/book/openharmony/kernel/liteos_a/syscall/los_syscall.h,新增系统调用函数的声明:

syscall同级目录添加.c文件,用于写入系统调用函数内容:

实现系统调用函数:

第4步:实现调用号和调用函数间的映射关系
打开/home/book/openharmony/kernel/liteos_a/syscall/syscall_lookup.h文件,新增系统调用号和系统调用函数之间的映射关系:

将用户态的系统调用宏__NR_hxsyscall和系统调用函数HxSyscall进行映射,相当于就是关联。
第5步:编写测试函数
在/home/book/doc_and_source_for_openharmony/apps下创建hxsyscall文件夹,再创建Makefile和hxsyscall.c文件(可以直接拷贝hello的内容进行修改):

修改hxsyscall.c内容,调用用户态的系统调用宏,传入参数:

说明:因为前面已经将SYS_hxsyscall这个宏与HxSyscall这个系统调用函数关联,所以“wake up”会作为一个参数传入下图的HxSyscall函数中,最终能够输出Hx call you to wake up!

然后修改Makefile的内容:

在同级目录下打开终端,输入make进行编译:

第6步:重新编译内核
这一步很关键,因为新增了一个系统调用号,必须要重新编译内核才能使调用号生效,并与系统调用函数进行关联。
首先删掉/openharmony/kernel/liteos_a/out/imx6ull的下面几个文件:

进入/openharmony/kernel/liteos_a然后进入命令栏,先输入下两行代码,确保操作万无一失:
cd /home/book/openharmony/kernel/liteos_a
cp tools/build/config/debug/imx6ull_clang.config .config
再输入make clean:

然后输入make -j 8:

再输入make rootfs,编译根文件系统:

将out/imx6ull下的rootfs.img改名为rootfs.jffs2:

cp out/imx6ull/rootfs.img out/imx6ull/rootfs.jffs2
第7步:开发板运行
把apps下的hxsyscall下的hysyscall文件手动复制到home/openharmony/kernel/liteos_a/out/imx6ull/rootfs/bin目录下重新制作rootfs.jfss2

openharmony/kernel/liteos_a/out/imx6ull下打开终端,输入mkfs.jffs2 -s 0x10000 -e 0x10000 -d rootfs -o rootfs.jffs2

回到电脑,先删掉/doc_and_source_for_openharmony_imx6ull/IMX6ULL/开发板配套资料/软件/烧写工具/100ask_files_imx6ull烧写工具/file文件夹下已有的liteos.bin和rootfs.jffs2文件。
然后把新的liteos.bin和rootfs.jffs2复制该文件夹下:

先连接上开发板,然后打开MobaXterm连接上串口,然后点击下载到内存并启动。
按照第一次试验启动开发板,出现81000000,输入cd ./bin,再输入ls,可以看到文件和虚拟机里的文件一致:

输入./hxsyscall输出显示Hx call you to wake up!

相关文章:
鸿蒙LiteOs读源码教程+向LiteOS中添加一个系统调用
本文分为2个部分:第1部分简要介绍如何读鸿蒙Liteos源码,第2部分是实验向LiteOS中添加一个系统调用的完整过程。 前置资料: imx6ull开发板使用方式详解 源码下载 编译运行简单程序 Ubuntu虚拟机使用鸿蒙LiteOs操作系统常见错误汇总 一、鸿…...
美国站群服务器IP如何设置分配?
在配置美国站群服务器时,IP的分配是一个重要的步骤。下面将介绍一些关于美国站群服务器IP分配的相关知识。 独享IP和虚拟IP 在租用美国站群服务器之前,我们需要了解提供的IP是独享的还是虚拟的。独享IP指每个网站都有独立的IP地址,而虚…...
R语言——taxize(第二部分)
taxize(第二部分) 3. taxize 文档中译3.10. classification(根据类群ID检索分类阶元层级)示例1:传递单个ID值示例2:传递多个ID值示例3:传递单个名称示例4:传递多个名称示例5…...
Postman+Newman+Jenkins实现接口测试持续集成
近期在复习Postman的基础知识,在小破站上跟着百里老师系统复习了一遍,也做了一些笔记,希望可以给大家一点点启发。 1.新建一个项目 2.设置自定义工作空间 3.执行windows的批处理命令 4.执行系统的Groovy脚本 5.生成的HTML的报告集成到Jenkin…...
C#WPF中的实现读取和写入文件的几种方式
说明:C#中实现读取和写入的类根据需要来选择。 1、File类 File类是用于操作文件的工具类,提供了对文件进行创建、复制、删除、移动和打开单一文件的静态方法。但需要注意的是,WPF中使用File的类,需要先引用System.IO下的命名空间。…...
如何利用自动发现将现网的进程纳入到监控系统中?
进程监控是一项关键任务,旨在监测系统中运行的进程的性能和状态。通过有效的进程监控,可以实时了解进程的运行情况,及时发现问题并采取措施,确保系统的稳定性和性能。 本期EasyOps产品使用最佳实践,我们将为您揭晓&am…...
英语学习(过去篇)
一、询问别人一周的情况 1.日常活动词汇 1)I watched TV 我看了电视 2)I ate breakfast 我吃了早餐 3)I left the house 我离开了家 4)I did the dishes 我洗了碗 5)I washed my clothes …...
excel中通过ROW函数返回引用的行号
例如,想引用B3的行号(行号应该是3): 鼠标点在想输入函数的单元格: 插入-》函数: 选择ROW函数: 点击“继续”,然后点击红框圈出来的按钮: 鼠标点击B3单元格&…...
spring学习笔记-IOC,AOP,事务管理
目录 概述 什么是spring 侵入式的概念 spring的核心 spring的优势 注意 IOC控制反转 概述 核心 容器 DI,dependency injection依赖注入 概念 注入方式 循环依赖 spring如何解决循环依赖 spring生成Bean的方式 Bean属性注入(Bean属性赋值…...
MYSQL中的触发器TRIGGER
1.概念 触发器是一个特殊的存储过程,当触发器保护的数据发生变更时就会触发。 2.特性 1.触发器与表息息相关,一般我们一个表创建六个触发器。 2.六个触发器其实是三种类六个 insert 类型 before | after insertupdate 类型 before | af…...
用人话讲解深度学习中CUDA,cudatookit,cudnn和pytorch的关系
参考链接 本人学习使用,侵权删谢谢。用人话讲解深度学习中CUDA,cudatookit,cudnn和pytorch的关系 CUDA CUDA是显卡厂商NVIDIA推出的运算平台。 CUDA™是一种由NVIDIA推出的通用并行计算架构,是一种并行计算平台和编程模型&…...
【JavaEE】Servlet API 详解(HttpServletRequest类)
一、HttpServletRequest Tomcat 通过 Socket API 读取 HTTP 请求(字符串), 并且按照 HTTP 协议的格式把字符串解析成 HttpServletRequest 对象(内容和HTTP请求报文一样) 1.1 HttpServletRequest核心方法 1.2 方法演示 WebServlet("/showRequest&…...
HTML页面的全屏显示及退出全屏案例
进入全屏 requestFullscreen 接收一个参数 options(可选), options 是一个对象, 但是只有一个字段 navigationUI, 用于控制是否在元素处于全屏模式时显示导航条. 可选值为 auto, hide, show, 默认值为 auto;当元素不在文档内时, 调用requestFullScreen回失败。 退出…...
layui弹出层点回车键无限弹出解决
$(document).keydown(function (event) {if (event.keyCode 13) {$("*").blur();//去掉焦点if ($(".layui-layer-btn0").length > 0)layer.closeAll();}});...
抖音测试付费短视频:从短剧领域拓展到知识、娱乐全品类
11月16日,抖音开始测试短视频内容付费,即用户在观看创作者的内容时,部分内容需要付费解锁才能全部观看,涉及范围不仅包括此前已经进行付费试水的短剧领域,还拓展至知识、娱乐等几乎全品类内容,用户可按单条…...
代码随想录算法训练营第五十五天 | LeetCode 583. 两个字符串的删除操作、72. 编辑距离、编辑距离总结
代码随想录算法训练营第五十五天 | LeetCode 583. 两个字符串的删除操作、72. 编辑距离、编辑距离总结 文章链接:两个字符串的删除操作、编辑距离、编辑距离总结 视频链接:两个字符串的删除操作、编辑距离 1. LeetCode 583. 两个字符串的删除操作 1.1 思…...
Excel vlookup 如何使用
Excel vlookup 如何使用 打开WX, 搜索 “程序员奇点” Excel vlookup可以说是利器,非常好用的工具,用来查询 Excel 或者进行数据匹配,十分方便。 VLookuP 如何使用,不常用的同学经常容易忘记,这次做个记录ÿ…...
Latex常用特殊字符汇总
本文汇总了博主在使用Latex写文档过程中遇到的所有常用疑难字符、表达式等等及对应的Latex形式 持续更新... 目录 常用字符波浪号1. 文本模式:~2. 数学模式: ∼ \sim ∼3. 字母上方的波浪号: a ˜ \~a a˜ 字母上方角标 (数学模式强调符)箭头…...
Day1跟李沐学AI-深度学习课程00-04【预告、课程安排、深度学习介绍、安装、数据操作+数据预处理】
00 预告 《动手学深度学习》https://github.com/d2l-ai/d2l-zh 01 课程安排 02 深度学习介绍 03 安装 本地安装 使用conda/miniconda环境 conda env remove d2l-zh conda create -n -y d2l-zh python3.8 pip conda activate d2l-zh 安装需要的包 pip install -y jupyter …...
借助拧紧曲线高效管理螺栓装配防错——SunTorque智能扭矩系统
拧紧曲线作为拧紧质量的“晴雨表”,在拧紧过程中,能够实时探知到拧紧状态是否存在异常,并根据曲线特质推测出拧紧过程中遇到了什么样的问题,今天SunTorque智能扭矩系统带您了解拧紧曲线在螺栓装配防错管理中如何发挥作用。 合格的…...
[特殊字符] 智能合约中的数据是如何在区块链中保持一致的?
🧠 智能合约中的数据是如何在区块链中保持一致的? 为什么所有区块链节点都能得出相同结果?合约调用这么复杂,状态真能保持一致吗?本篇带你从底层视角理解“状态一致性”的真相。 一、智能合约的数据存储在哪里…...
AI-调查研究-01-正念冥想有用吗?对健康的影响及科学指南
点一下关注吧!!!非常感谢!!持续更新!!! 🚀 AI篇持续更新中!(长期更新) 目前2025年06月05日更新到: AI炼丹日志-28 - Aud…...
XCTF-web-easyupload
试了试php,php7,pht,phtml等,都没有用 尝试.user.ini 抓包修改将.user.ini修改为jpg图片 在上传一个123.jpg 用蚁剑连接,得到flag...
微信小程序之bind和catch
这两个呢,都是绑定事件用的,具体使用有些小区别。 官方文档: 事件冒泡处理不同 bind:绑定的事件会向上冒泡,即触发当前组件的事件后,还会继续触发父组件的相同事件。例如,有一个子视图绑定了b…...
3.3.1_1 检错编码(奇偶校验码)
从这节课开始,我们会探讨数据链路层的差错控制功能,差错控制功能的主要目标是要发现并且解决一个帧内部的位错误,我们需要使用特殊的编码技术去发现帧内部的位错误,当我们发现位错误之后,通常来说有两种解决方案。第一…...
服务器硬防的应用场景都有哪些?
服务器硬防是指一种通过硬件设备层面的安全措施来防御服务器系统受到网络攻击的方式,避免服务器受到各种恶意攻击和网络威胁,那么,服务器硬防通常都会应用在哪些场景当中呢? 硬防服务器中一般会配备入侵检测系统和预防系统&#x…...
微信小程序 - 手机震动
一、界面 <button type"primary" bindtap"shortVibrate">短震动</button> <button type"primary" bindtap"longVibrate">长震动</button> 二、js逻辑代码 注:文档 https://developers.weixin.qq…...
C++中string流知识详解和示例
一、概览与类体系 C 提供三种基于内存字符串的流,定义在 <sstream> 中: std::istringstream:输入流,从已有字符串中读取并解析。std::ostringstream:输出流,向内部缓冲区写入内容,最终取…...
【HTTP三个基础问题】
面试官您好!HTTP是超文本传输协议,是互联网上客户端和服务器之间传输超文本数据(比如文字、图片、音频、视频等)的核心协议,当前互联网应用最广泛的版本是HTTP1.1,它基于经典的C/S模型,也就是客…...
实现弹窗随键盘上移居中
实现弹窗随键盘上移的核心思路 在Android中,可以通过监听键盘的显示和隐藏事件,动态调整弹窗的位置。关键点在于获取键盘高度,并计算剩余屏幕空间以重新定位弹窗。 // 在Activity或Fragment中设置键盘监听 val rootView findViewById<V…...
