当前位置: 首页 > 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;我们将深入探讨心理咨询系统的可应用范围及其带来…...

Oracle RAC OCR坏了怎么办?手把手教你用ocrconfig修复与备份(附11g/12c实战命令)

Oracle RAC OCR故障应急指南&#xff1a;从诊断到修复的全链路实战 凌晨三点&#xff0c;当手机铃声划破寂静&#xff0c;作为DBA的你从睡梦中惊醒。电话那头传来运维同事急促的声音&#xff1a;"生产环境RAC集群所有节点突然离线&#xff0c;CRS服务无法启动&#xff01…...

Qwen3.5-4B-Claude-Opus部署教程:模型路径软链失效时的容错加载机制

Qwen3.5-4B-Claude-Opus部署教程&#xff1a;模型路径软链失效时的容错加载机制 1. 模型概述 Qwen3.5-4B-Claude-4.6-Opus-Reasoning-Distilled-GGUF是基于Qwen3.5-4B的推理蒸馏模型&#xff0c;特别强化了结构化分析、分步骤回答以及代码与逻辑类问题的处理能力。该版本以GG…...

CREST:如何用5分钟开启分子构象探索之旅?

CREST&#xff1a;如何用5分钟开启分子构象探索之旅&#xff1f; 【免费下载链接】crest Conformer-Rotamer Ensemble Sampling Tool based on the xtb Semiempirical Extended Tight-Binding Program Package 项目地址: https://gitcode.com/gh_mirrors/crest/crest 在…...

OpenClaw调试技巧:Qwen3-32B任务失败排查手册

OpenClaw调试技巧&#xff1a;Qwen3-32B任务失败排查手册 1. 为什么需要这份手册&#xff1f; 上周我尝试用OpenClaw自动整理项目文档时&#xff0c;遇到了一个诡异现象&#xff1a;同样的任务在白天能顺利完成&#xff0c;深夜运行时却频繁报错。经过72小时的问题追踪&#…...

Phi-4-Reasoning-Vision应用场景:法律文书配图证据链推理系统

Phi-4-Reasoning-Vision应用场景&#xff1a;法律文书配图证据链推理系统 1. 法律文书配图证据链推理系统概述 在法律实务中&#xff0c;证据链的构建往往需要处理大量图文混合材料。传统人工分析方式存在效率低下、主观性强、容易遗漏细节等问题。基于Phi-4-Reasoning-Visio…...

告别官方包:手把手教你为遗留项目编译一个“增强版”Qt5.15.17

告别官方包&#xff1a;手把手教你为遗留项目编译一个“增强版”Qt5.15.17 当官方支持终止后&#xff0c;维护基于Qt5的遗留项目就像在悬崖边行走——你需要稳定性&#xff0c;但又渴望那些关键补丁和完整功能。本文将带你深入探索如何为团队构建一个功能完备的私有Qt工具链&am…...

AI写教材大揭秘!低查重技巧让你的教材脱颖而出!

在编写教材时&#xff0c;依赖相关资料是必不可少的&#xff0c;但传统的资料整合方法已经无法满足现实需求。以往&#xff0c;我们需要从各种渠道&#xff0c;比如课标文件、学术研究以及教学案例中寻找所需的信息&#xff0c;这往往需要耗费数天的时间。即便信息搜集齐全&…...

打造手游PC级操控:QtScrcpy键鼠映射完全指南

打造手游PC级操控&#xff1a;QtScrcpy键鼠映射完全指南 【免费下载链接】QtScrcpy Android实时投屏软件&#xff0c;此应用程序提供USB(或通过TCP/IP)连接的Android设备的显示和控制。它不需要任何root访问权限 项目地址: https://gitcode.com/barry-ran/QtScrcpy 手机…...

大模型应用指南:小白程序员必收藏,轻松入门AI前沿技术!

2025年大模型技术已在IT、金融、制造等领域广泛应用&#xff0c;从智能客服到数据分析&#xff0c;助力企业转型。沙丘智库《大模型应用跟踪月报》收录504个案例&#xff0c;揭示行业分布、应用场景及发展趋势。大模型不仅是技术突破&#xff0c;更是时代标志&#xff0c;小白程…...

Obsidian Full Calendar:5步构建个人知识与时间管理一体化系统

Obsidian Full Calendar&#xff1a;5步构建个人知识与时间管理一体化系统 【免费下载链接】obsidian-full-calendar Keep events and manage your calendar alongside all your other notes in your Obsidian Vault. 项目地址: https://gitcode.com/gh_mirrors/obs/obsidian…...