当前位置: 首页 > news >正文

鸿蒙轻内核M核源码分析系列二十 Newlib C

LiteOS-M内核LibC实现有2种,可以根据需求进行二选一,分别是musl libC和newlibc。本文先学习下Newlib C的实现代码。文中所涉及的源码,均可以在开源站点https://gitee.com/openharmony/kernel_liteos_m 获取。

使用Musl C库的时候,内核提供了基于LOS_XXX适配实现pthread、mqeue、fs、semaphore、time等模块的posix接口(//kernel/liteos_m/kal/posix)。内核提供的posix接口与musl中的标准C库接口共同组成LiteOS-M的LibC。编译时使用arm-none-eabi-gcc,但只使用其工具链的编译功能,通过加上-nostdinc与-nostdlib强制使用我们自己改造后的musl-C。

社区及三方厂商开发多使用公版工具链arm-none-eabi-gcc加上私有定制优化进行编译,LiteOS-M内核也支持公版arm-none-eabi-gcc C库编译内核运行。newlib是小型C库,针对posix接口涉及系统调用的部分,newlib提供一些需要系统适配的钩子函数,例如_exit(),_open(),_close(),_gettimeofday()等,操作系统适配这些钩子,就可以使用公版newlib工具链编译运行程序。


1、Newlib C文件系统

在使用Newlib C并且使能支持POSIX FS API时(可以在kernel\liteos-m\目录下,执行make meuconfig弹出配置界面,路径为Compat-Choose libc implementation),如下图所示。可以使用文件kal\libc\newlib\porting\src\fs.c中定义的文件系统操作接口。这些是标准的POSIX接口,如果想了解POSIX用法,可以在linux平台输入 man -a 函数名称,比如man -a opendir来打开函数的手册。

1.1 函数mount、umount和umount2

这些函数的用法,函数实现和musl c部分一致。

int mount(const char *source, const char *target,const char *filesystemtype, unsigned long mountflags,const void *data)
{return LOS_FsMount(source, target, filesystemtype, mountflags, data);
}int umount(const char *target)
{return LOS_FsUmount(target);
}int umount2(const char *target, int flag)
{return LOS_FsUmount2(target, flag);
}

1.2 文件操作接口

以下划线开头的函数实现是newlib c的钩子函数实现。有关newlib的钩子函数调用过程下文专门分析下。

int _open(const char *path, int oflag, ...)
{va_list vaList;va_start(vaList, oflag);int ret;ret = LOS_Open(path, oflag);va_end(vaList);return ret;
}int _close(int fd)
{return LOS_Close(fd);
}ssize_t _read(int fd, void *buf, size_t nbyte)
{return LOS_Read(fd, buf, nbyte);
}ssize_t _write(int fd, const void *buf, size_t nbyte)
{return LOS_Write(fd, buf, nbyte);
}off_t _lseek(int fd, off_t offset, int whence)
{return LOS_Lseek(fd, offset, whence);
}int _unlink(const char *path)
{return LOS_Unlink(path);
}int _fstat(int fd, struct stat *buf)
{return LOS_Fstat(fd, buf);
}int _stat(const char *path, struct stat *buf)
{return LOS_Stat(path, buf);
}int fsync(int fd)
{return LOS_Fsync(fd);
}int mkdir(const char *path, mode_t mode)
{return LOS_Mkdir(path, mode);
}DIR *opendir(const char *dirName)
{return LOS_Opendir(dirName);
}struct dirent *readdir(DIR *dir)
{return LOS_Readdir(dir);
}int closedir(DIR *dir)
{return LOS_Closedir(dir);
}int rmdir(const char *path)
{return LOS_Unlink(path);
}int rename(const char *oldName, const char *newName)
{return LOS_Rename(oldName, newName);
}int statfs(const char *path, struct statfs *buf)
{return LOS_Statfs(path, buf);
}int ftruncate(int fd, off_t length)
{return LOS_Ftruncate(fd, length);
}

在newlib没有使能使能支持POSIX FS API时时,需要提供这些钩子函数的空的实现,返回-1错误码即可。

int _open(const char *path, int oflag, ...)
{return -1;
}int _close(int fd)
{return -1;
}ssize_t _read(int fd, void *buf, size_t nbyte)
{return -1;
}ssize_t _write(int fd, const void *buf, size_t nbyte)
{return -1;
}off_t _lseek(int fd, off_t offset, int whence)
{return -1;
}int _unlink(const char *path)
{return -1;
}int _fstat(int fd, struct stat *buf)
{return -1;
}int _stat(const char *path, struct stat *buf)
{return -1;
}

2、Newlib C内存分配释放

newlibc 的malloc适配参考The Red Hat newlib C Library-malloc。实现malloc适配有以下两种方法:

  • 实现 _sbrk_r 函数。这种方法中,内存分配函数使用newlib中的。

  • 实现 _malloc_r, _realloc_r, _free_r, _memalign_r, _malloc_usable_size_r等。这种方法中,内存分配函数可以使用内核的。

为了方便地根据业务进行内存分配算法调优和问题定位,推荐选择后者。内核的内存函数定义在文件kal\libc\newlib\porting\src\malloc.c中。源码片段如下,代码实现比较简单,不再分析源码。

......
void __wrap__free_r(struct _reent *reent, void *aptr)
{if (aptr == NULL) {return;}LOS_MemFree(OS_SYS_MEM_ADDR, aptr);
}size_t __wrap__malloc_usable_size_r(struct _reent *reent, void *aptr)
{return 0;
}void *__wrap__malloc_r(struct _reent *reent, size_t nbytes)
{if (nbytes == 0) {return NULL;}return LOS_MemAlloc(OS_SYS_MEM_ADDR, nbytes);
}void *__wrap__memalign_r(struct _reent *reent, size_t align, size_t nbytes)
{if (nbytes == 0) {return NULL;}return LOS_MemAllocAlign(OS_SYS_MEM_ADDR, nbytes, align);
}
......

可能已经注意到函数命名由__wrap_加上钩子函数名称两部分组成。这是因为newlib中已经存在这些函数的符号,因此需要用到gcc的wrap的链接选项替换这些函数符号为内核的实现,在设备开发板的配置文件中,比如//device/board/fnlink/v200zr/liteos_m/config.gni,新增这些函数的wrap链接选项,示例如下:

board_ld_flags += ["-Wl,--wrap=_malloc_r","-Wl,--wrap=_realloc_r","-Wl,--wrap=_free_r","-Wl,--wrap=_memalign_r","-Wl,--wrap=_malloc_usable_size_r",
]

3、Newlib钩子函数介绍

以open函数的钩子函数_open为例来介绍newlib的钩子函数的调用过程。open()函数实现在newlib-cygwin\newlib\libc\syscalls\sysopen.c中,该函数会进一步调用函数_open_r,这是个可重入函数Reentrant Function,支持在多线程中运行。

int
open (const char *file,int flags, ...)
{va_list ap;int ret;va_start (ap, flags);ret = _open_r (_REENT, file, flags, va_arg (ap, int));va_end (ap);return ret;
}

所有的可重入函数定义在文件夹newlib-cygwin\newlib\libc\reent,函数_open_r定义在该文件夹的文件newlib-cygwin\newlib\libc\reent\openr.c里。函数代码如下:

int
_open_r (struct _reent *ptr,const char *file,int flags,int mode)
{int ret;errno = 0;if ((ret = _open (file, flags, mode)) == -1 && errno != 0)ptr->_errno = errno;return ret;
}

函数_open_r如上述代码所示,会进一步调用函数_open,该函数,以arm硬件平台为例,实现在newlib-cygwin\libgloss\arm\syscalls.c文件里。newlib目录是和硬件平台无关的痛殴他那个功能实现,libloss目录是底层的驱动实现,以各个硬件平台为文件夹进行组织。在特定硬件平台的目录下的syscalls.c文件里面实现了newlib需要的各个桩函数:

/* Forward prototypes.  */
int	_system		(const char *);
int	_rename		(const char *, const char *);
int	_isatty		(int);
clock_t _times		(struct tms *);
int	_gettimeofday	(struct timeval *, void *);
int	_unlink		(const char *);
int	_link		(const char *, const char *);
int	_stat		(const char *, struct stat *);
int	_fstat		(int, struct stat *);
int	_swistat	(int fd, struct stat * st);
void *	_sbrk		(ptrdiff_t);
pid_t	_getpid		(void);
int	_close		(int);
clock_t	_clock		(void);
int	_swiclose	(int);
int	_open		(const char *, int, ...);
int	_swiopen	(const char *, int);
int	_write		(int, const void *, size_t);
int	_swiwrite	(int, const void *, size_t);
_off_t	_lseek		(int, _off_t, int);
_off_t	_swilseek	(int, _off_t, int);
int	_read		(int, void *, size_t);
int	_swiread	(int, void *, size_t);
void	initialise_monitor_handles (void);

对于上文提到的函数_open,源码如下。后续不再继续分析了,LiteOS-M内核会提供这些钩子函数的实现。

int
_open (const char * path, int flags, ...)
{return _swiopen (path, flags);
}

小结

本文学习了LiteOS-M内核Newlib C的实现,特别是文件系统和内存分配释放部分,最后介绍了Newlib钩子函数。

如果大家想更加深入的学习 OpenHarmony 开发的内容,不妨可以参考以下相关学习文档进行学习,助你快速提升自己:

OpenHarmony 开发环境搭建:https://qr18.cn/CgxrRy

《OpenHarmony源码解析》:https://qr18.cn/CgxrRy

  • 搭建开发环境
  • Windows 开发环境的搭建
  • Ubuntu 开发环境搭建
  • Linux 与 Windows 之间的文件共享
  • ……

系统架构分析:https://qr18.cn/CgxrRy

  • 构建子系统
  • 启动流程
  • 子系统
  • 分布式任务调度子系统
  • 分布式通信子系统
  • 驱动子系统
  • ……

OpenHarmony 设备开发学习手册:https://qr18.cn/CgxrRy

在这里插入图片描述

OpenHarmony面试题(内含参考答案):https://qr18.cn/CgxrRy

相关文章:

鸿蒙轻内核M核源码分析系列二十 Newlib C

LiteOS-M内核LibC实现有2种,可以根据需求进行二选一,分别是musl libC和newlibc。本文先学习下Newlib C的实现代码。文中所涉及的源码,均可以在开源站点https://gitee.com/openharmony/kernel_liteos_m 获取。 使用Musl C库的时候&#xff0c…...

力扣1818.绝对差值和

力扣1818.绝对差值和 把nums1拷贝复制一份 去重排序 对于每个nums2都找到差距最小的那个数(二分) 作差求最大可优化差值去重排序可以直接用set 自动去重排序了 const int N 1e97;class Solution {public:int minAbsoluteSumDiff(vector<int>& nums1, vector<i…...

矩阵练习2

48.旋转图像 规律&#xff1a; 对于矩阵中第 i行的第 j 个元素&#xff0c;在旋转后&#xff0c;它出现在倒数第i 列的第 j 个位置。 matrix[col][n−row−1]matrix[row][col] 可以使用辅助数组&#xff0c;如果不想使用额外的内存&#xff0c;可以用一个临时变量 。 还可以通…...

2024海南省大数据教师培训-Hadoop集群部署

前言 本文将详细介绍Hadoop分布式计算框架的来源&#xff0c;架构和应用场景&#xff0c;并附上最详细的集群搭建教程&#xff0c;能更好的帮助各位老师和同学们迅速了解和部署Hadoop框架来进行生产力和学习方面的应用。 一、Hadoop介绍 Hadoop是一个开源的分布式计算框架&…...

力扣算法题:将数字变为0的操作次数--多语言实现

无意间看到&#xff0c;力扣存算法代码居然还得升级vip。。。好吧&#xff0c;我自己存吧 golang&#xff1a; func numberOfSteps(num int) int {steps : 0for num > 0 {if num%2 0 {num / 2} else {num - 1}steps}return steps } javascript: /*** param {number} num…...

vue前段处理时间格式,设置开始时间为00:00:00,设置结束时间为23:59:59

在Vue开发中&#xff0c;要在前端控制日期时间选择器的时间范围&#xff0c;可以通过以下方式实现&#xff1a; 使用beforeDestroy生命周期钩子函数来处理时间范围&#xff1a; 在Vue组件中&#xff0c;可以监听日期时间选择器的变化&#xff0c;在选择开始日期时&#xff0c;自…...

Java 8 新特性全面解读

Java 8&#xff0c;作为一次重大更新&#xff0c;于2014年引入了多项创新特性&#xff0c;极大地改善了Java的编程体验和性能。此版本不仅加入了对函数式编程的支持&#xff0c;还增强了接口的功能&#xff0c;引入了新的API&#xff0c;并优化了语言的整体效率。接下来&#x…...

JavaScript知识之函数

javascript函数 在JavaScript基础之上提供了部分函数,同时也可以自定义函数,JavaScript基础详见之前的文章javascript基础知识 自定义函数 //关键字 函数名 参数列表 函数体 function test(a,b,c){alert(a":"b":"c) }function test1(a,b){return a;//不…...

【Pepper机器人开发与应用】一、Pepper SDK for LabVIEW下载与安装教程

‍‍&#x1f3e1;博客主页&#xff1a; virobotics(仪酷智能)&#xff1a;LabVIEW深度学习、人工智能博主 &#x1f4d1;上期文章&#xff1a;『一文汇总对比英伟达、AMD、英特尔显卡GPU』 &#x1f37b;本文由virobotics(仪酷智能)原创 &#x1f973;欢迎大家关注✌点赞&…...

HCIP-AI EI 认证课程大纲

该阶段详细介绍计算机视觉、注意力机制与Transformer、自然语言处理、语音处理等 AI 核心领域技术&#xff0c;并重点介绍华为云 EI 服务使用。 共计48 课时。第一节&#xff1a;计算机视觉技术概述与图像处理基础 - &#xff08;3 课时&#xff09; - 什么是计算机视觉&#x…...

@Test注解方法,方法无法执行

1.背景 写了一个测试方法,执行后如图 2.原因是 该项目是springbootgradle...构建的项目 在build.gradle配置文件中关闭了单元测试: test {useJUnitPlatform()// 是否启用单元测试enabled false } 3.处理方式 开启单元测试 test {useJUnitPlatform()// 是否启用单元测试ena…...

golang函数

【1】函数&#xff1a; 对特定的功能进行提取&#xff0c;形成一个代码片段&#xff0c;这个代码片段就是我们所说的函数 【2】函数的作用&#xff1a;提高代码的复用性 【3】函数和函数是并列的关系&#xff0c;所以我们定义的函数不能写到main函数中 【4】基本语法 func 函…...

ubuntu上存在多个版本python,根据需要选择你想使用的python版本

文章目录 前言一、二、使用步骤总结 前言 参考1 一、 sudo update-alternatives --install /usr/bin/python python /usr/bin/python3.6 1二、使用步骤 总结...

idea 常用插件推荐

文章目录 1、Lombok2、Convert YAML and Properties File3、Grep Console4、MyBatisX5、Free MyBatis Tool6、MyBatis Log EasyPlus &#xff08;SQL拼接&#xff09;7、MyBatisPlus8、Eclipse theme9、Eclipse Plus Theme10、Rainbow Brackets Lite - Free and OpenSource&…...

训练大模型自动在RAG和记忆间选择

现如今&#xff0c;检索增强生成(Retrieval-augmented generation&#xff0c;RAG)管道已经能够使得大语言模型(Large Language Models&#xff0c;LLM)在其响应环节中&#xff0c;充分利用外部的信息源了。不过&#xff0c;由于RAG应用会针对发送给LLM的每个请求&#xff0c;都…...

抖店没人做了?不是项目不行了,而是商家们都换思路去玩了

我是王路飞。 有没有发现现在很多抖店新手都在吐槽&#xff0c;抖店不好做了&#xff0c;做不起来&#xff0c;没人做了&#xff0c;太内卷了...... 对这种做不起来还在怪项目本身的&#xff0c;一定要离他远一点&#xff0c;省得被他的负能量给影响到自己的状态。 任何项目…...

Qt5.15.2+VS2019新加类出现无法解析的外部符号

Qt5.15.2VS2019新加类出现无法解析的外部符号&#xff1a; 原因&#xff1a;没有生成对应的moc文件&#xff0c;导致没生成对应的元对象。 解决方案&#xff1a;记事本打开工程vcxproj&#xff0c;把报错的文件ClInclude&#xff0c;改为QtMoc&#xff0c;解决问题 未修改前&…...

启动mysql 3.5时出现 MySql 服务正在启动 . MySql 服务无法启动。

有可能是端口冲突 netstat -ano | findstr :3306运行这段代码出现类似&#xff1a; 可以看到端口 3306 已经被进程 ID 为 6284 的进程占用。为了启动新的 MySQL 服务&#xff0c;我们需要停止这个进程或更改新服务的端口&#xff1a; 1、终止进程 taskkill /PID 6284 /F2、确…...

并发编程理论基础——可见性、原子性和有序性问题(一)

核心问题&#xff1a;分工&#xff0c;同步&#xff0c;互斥 分工&#xff1a;如何高效地拆解任务并分配给线程 生产者-消费者模式、Thread-Per-Message模式、Worker-Thread模式、ComplateableFuture和CompletionServiceJava SDK 并发包里的 Executor、Fork/Join、Future 本质上…...

心理咨询系统源码|心理咨询系统开发|心理咨询系统

心理咨询系统&#xff0c;作为一种集现代化科技与专业心理服务于一体的工具&#xff0c;正逐渐渗透到我们生活的各个角落。它不仅为个人提供了便捷的心理支持&#xff0c;还为企业和组织带来了全新的管理方式。下面&#xff0c;我们将深入探讨心理咨询系统的可应用范围及其带来…...

Chapter03-Authentication vulnerabilities

文章目录 1. 身份验证简介1.1 What is authentication1.2 difference between authentication and authorization1.3 身份验证机制失效的原因1.4 身份验证机制失效的影响 2. 基于登录功能的漏洞2.1 密码爆破2.2 用户名枚举2.3 有缺陷的暴力破解防护2.3.1 如果用户登录尝试失败次…...

Cesium1.95中高性能加载1500个点

一、基本方式&#xff1a; 图标使用.png比.svg性能要好 <template><div id"cesiumContainer"></div><div class"toolbar"><button id"resetButton">重新生成点</button><span id"countDisplay&qu…...

UDP(Echoserver)

网络命令 Ping 命令 检测网络是否连通 使用方法: ping -c 次数 网址ping -c 3 www.baidu.comnetstat 命令 netstat 是一个用来查看网络状态的重要工具. 语法&#xff1a;netstat [选项] 功能&#xff1a;查看网络状态 常用选项&#xff1a; n 拒绝显示别名&#…...

基于当前项目通过npm包形式暴露公共组件

1.package.sjon文件配置 其中xh-flowable就是暴露出去的npm包名 2.创建tpyes文件夹&#xff0c;并新增内容 3.创建package文件夹...

智能在线客服平台:数字化时代企业连接用户的 AI 中枢

随着互联网技术的飞速发展&#xff0c;消费者期望能够随时随地与企业进行交流。在线客服平台作为连接企业与客户的重要桥梁&#xff0c;不仅优化了客户体验&#xff0c;还提升了企业的服务效率和市场竞争力。本文将探讨在线客服平台的重要性、技术进展、实际应用&#xff0c;并…...

【HTML-16】深入理解HTML中的块元素与行内元素

HTML元素根据其显示特性可以分为两大类&#xff1a;块元素(Block-level Elements)和行内元素(Inline Elements)。理解这两者的区别对于构建良好的网页布局至关重要。本文将全面解析这两种元素的特性、区别以及实际应用场景。 1. 块元素(Block-level Elements) 1.1 基本特性 …...

安卓基础(aar)

重新设置java21的环境&#xff0c;临时设置 $env:JAVA_HOME "D:\Android Studio\jbr" 查看当前环境变量 JAVA_HOME 的值 echo $env:JAVA_HOME 构建ARR文件 ./gradlew :private-lib:assembleRelease 目录是这样的&#xff1a; MyApp/ ├── app/ …...

算法:模拟

1.替换所有的问号 1576. 替换所有的问号 - 力扣&#xff08;LeetCode&#xff09; ​遍历字符串​&#xff1a;通过外层循环逐一检查每个字符。​遇到 ? 时处理​&#xff1a; 内层循环遍历小写字母&#xff08;a 到 z&#xff09;。对每个字母检查是否满足&#xff1a; ​与…...

vulnyx Blogger writeup

信息收集 arp-scan nmap 获取userFlag 上web看看 一个默认的页面&#xff0c;gobuster扫一下目录 可以看到扫出的目录中得到了一个有价值的目录/wordpress&#xff0c;说明目标所使用的cms是wordpress&#xff0c;访问http://192.168.43.213/wordpress/然后查看源码能看到 这…...

Razor编程中@Html的方法使用大全

文章目录 1. 基础HTML辅助方法1.1 Html.ActionLink()1.2 Html.RouteLink()1.3 Html.Display() / Html.DisplayFor()1.4 Html.Editor() / Html.EditorFor()1.5 Html.Label() / Html.LabelFor()1.6 Html.TextBox() / Html.TextBoxFor() 2. 表单相关辅助方法2.1 Html.BeginForm() …...