鸿蒙轻内核M核源码分析系列十九 Musl LibC

news2024/11/17 13:53:08

LiteOS-M内核LibC实现有2种,可以根据需求进行二选一,分别是musl libC和newlibc。本文先学习下Musl LibC的实现代码。文中所涉及的源码,均可以在开源站点 https://gitee.com/openharmony/kernel_liteos_m 获取。LiteOS-M内核提供了和内核相关的文件系统、内存申请释放接口,其他接口可以直接使用Musl提供的。我们分别来看下内核提供的接口部分。


1、Musl LibC文件系统

在使用Musl LibC并且使能支持POSIX FS API时,可以使用文件kal\libc\musl\fs.c中定义的文件系统操作接口。这些是标准的POSIX接口,如果想了解其用法,可以参考 Section 2: system calls 。可以在网页上搜索,也可以直接把上述网址和函数名称进行拼接,如对于mount()函数,可以直接访问 https://linux.die.net/man/2/mount 。opendir等部分函数需要在 Section 3: library functions 网页上查看。下文快速记录下各个函数的使用方法。

1.1 函数mount

函数mount会挂载source参数(通常是设备名称,也可以是目录)指定的文件系统到target参数指定的目录。文件系统类型LiteOS-M内核支持"fat"和"littlefs"两种类型。"littlefs"文件系统不需要挂载选项参数mountflags。对于fat文件类型,挂载选项参数定义在文件third_party\musl\porting\liteos_m\kernel\include\sys\mount.h中,如MS_RDONLY、MS_NOSUID、MS_REMOUNT等等。参数data由文件系统进行解析,fat文件类型不需要该参数;"littlefs"文件系统需要传入的data参数应该为 (struct lfs_config*)指针类型。

该函数会调用components\fs\vfs\los_fs.c中的函数LOS_FsMount,后文会专门讲解FS VFS。

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);
}

1.2 函数umount和umount2

函数umount, umount2用于unmount卸载文件系统。参数target指定要卸载的文件系统。函数umount2除了卸载,还可以指定flag参数来控制卸载行为。支持的参数定义在third_party\musl\porting\liteos_m\kernel\include\sys\mount.h,如MNT_FORCE、MNT_DETACH、MNT_EXPIRE和UMOUNT_NOFOLLOW。

int umount(const char *target)
{
    return LOS_FsUmount(target);
}

int umount2(const char *target, int flag)
{
    return LOS_FsUmount2(target, flag);
}

1.3 函数open、close和unlink

函数open用于打开一个文件或设备,可能会先创建文件或设备。参数path指定文件或设备的路径,参数oflag需要使用下面的访问模式O_RDONLY, O_WRONLY, O_RDWR中的一个,这几个定义在文件third_party\musl\porting\liteos_m\kernel\include\fcntl.h。third_party\musl\porting\liteos_m\kernel\include\bits\fcntl.h。另外,还有些其他文件创建标签或文件状态标签可以通过逻辑与进行指定。文件创建标签有O_CLOEXEC, O_CREAT, O_DIRECTORY, O_EXCL, O_NOCTTY, O_NOFOLLOW, O_TRUNC和O_TTY_INIT。其余的为文件状态标签,这些标签定义文件中third_party\musl\porting\liteos_m\kernel\include\bits\fcntl.h中。可以访问https://linux.die.net/man/2/open了解这些标签的详细用法。

函数open返回值为文件描述符file descriptor,会被其他函数如read, write, lseek, fcntl等使用。函数close用于关闭一个文件描述符,使fd不再引用任何文件,可被再次重用。函数unlink用于删除path路径指定的文件。

int open(const char *path, int oflag, ...)
{
    va_list vaList;
    va_start(vaList, oflag);
    int ret;
    ret = LOS_Open(path, oflag, vaList);
    va_end(vaList);
    return ret;
}

int close(int fd)
{
    return LOS_Close(fd);
}

int unlink(const char *path)
{
    return LOS_Unlink(path);
}

1.4 函数read和write

函数read尝试从fd中读取nbyte字节的数据到buf开始的缓存里,读取成功时返回读取的字节数目。函数write把buf处开始的nbyte字节数据写入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);
}

1.5 函数lseek

函数lseek用于重新定位文件读写的偏移位置。参数whence取值为SEEK_SET、SEEK_CUR或SEEK_END,定义在文件third_party\musl\porting\liteos_m\kernel\include\fcntl.h。

  • SEEK_SET
    偏移设置在offset字节处。
  • SEEK_CUR
    偏移设置在当前位置加上offset字节处。
  • SEEK_END
    偏移设置在文件大小加上offset字节处。

函数执行成功时,返回值为从文件开头的偏移字节数值。

off_t lseek(int fd, off_t offset, int whence)
{
    return LOS_Lseek(fd, offset, whence);
}}

1.6 函数fstat、stat和statfs

函数fstat和stat用于获取文件的状态state,参数参数分别是文件描述符和文件路径。参数中的struct stat结构体定义在文件third_party\musl\porting\liteos_m\kernel\include\bits\stat.h中。
函数statfs返回文件系统统计statistics数据,结构体struct statfs定义在文件third_party\musl\porting\liteos_m\kernel\include\bits\statfs.h中。

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 statfs(const char *path, struct statfs *buf)
{
    return LOS_Statfs(path, buf);
}

1.7 函数mkdir、opendir、readir、closedir和rmdrir

函数mkdir用于创建一个目录,目录名称由参数path指定。参数mode指定目录权限。创建成功返回0,否则返回-1。
函数opendir用于打开一个目录流a directory stream,目录名称由参数dirName指定,返回一个执行目录刘的指针。发生错误时,返回NULL,并设置errno。返回值类型DIR是struct __dirstream的别名,定义在文件中third_party\musl\porting\liteos_m\kernel\include\dirent.h。可以访问https://linux.die.net/man/3/opendir了解更多关于该函数的信息。
函数readdir用于读取一个目录,返回一个struct dirent结构体指针,代表目录流DIR *dir中的下一个目录条目directory entry。到达目录流尾部或错误时,返回NULL。结构体定义在文件third_party\musl\porting\liteos_m\kernel\include\bits\dirent.h中。 可以访问https://linux.die.net/man/3/readdir了解更多关于该函数的信息。
函数closedir用于关闭一个目录。函数rmdir用于删除一个目录,只有空目录才会被删除。

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);
}

1.8 函数fsync

函数mkdir用于同步内存中所有已修改的文件数据到储存设备。可以访问https://linux.die.net/man/3/fsync了解更多关于该函数的信息。

int fsync(int fd)
{
    return LOS_Fsync(fd);
}

1.9 函数rename

函数rename用于重命名一个文件。可以访问https://linux.die.net/man/3/rename了解更多关于该函数的信息。

int rename(const char *oldName, const char *newName)
{
    return LOS_Rename(oldName, newName);
}

1.10 函数ftruncate

函数ftruncate用于截断一个文件到指定的长度。可以访问https://linux.die.net/man/3/ftruncate了解更多关于该函数的信息。

int ftruncate(int fd, off_t length)
{
    return LOS_Ftruncate(fd, length);
}

2、Musl LibC内存分配释放

LiteOS-M内核提供了内存分配释放函数。这些是标准的POSIX接口,如果想了解其用法,可以参考Section 3: library functions。可以在网页上搜索,也可以直接把上述网址和函数名称进行拼接,如对于malloc()函数,可以直接访问 https://linux.die.net/man/3/malloc 。opendir等部分函数需要在网页上查看。下文快速记录下各个函数的使用方法。

1.1 函数malloc、free和memalign

函数malloc和free分别调用内核内存模块的接口来实现内存申请和释放。函数memalign可以以指定的内存对齐大小来申请内存。

void free(void *ptr)
{
    if (ptr == NULL) {
        return;
    }

    LOS_MemFree(OS_SYS_MEM_ADDR, ptr);
}

void *malloc(size_t size)
{
    if (size == 0) {
        return NULL;
    }

    return LOS_MemAlloc(OS_SYS_MEM_ADDR, size);
}
void *memalign(size_t boundary, size_t size)
{
    if (size == 0) {
        return NULL;
    }

    return LOS_MemAllocAlign(OS_SYS_MEM_ADDR, size, boundary);
}

1.2 函数malloc、free和memalign

函数calloc在内存的动态存储区中分配nitems个长度为size的连续空间,函数返回一个指向分配起始地址的指针;如果分配不成功,返回NULL。
函数zalloc和malloc的区别是,申请成功后,对申请的内存区域置0。函数realloc用于重新申请一块内存区域。

void *calloc(size_t nitems, size_t size)
{
    size_t real_size;
    void *ptr = NULL;

    if (nitems == 0 || size == 0) {
        return NULL;
    }

    real_size = (size_t)(nitems * size);
    ptr = LOS_MemAlloc(OS_SYS_MEM_ADDR, real_size);
    if (ptr != NULL) {
        (void)memset_s(ptr, real_size, 0, real_size);
    }
    return ptr;
}
void *zalloc(size_t size)
{
    void *ptr = NULL;

    if (size == 0) {
        return NULL;
    }

    ptr = LOS_MemAlloc(OS_SYS_MEM_ADDR, size);
    if (ptr != NULL) {
        (void)memset_s(ptr, size, 0, size);
    }
    return ptr;
}

void *realloc(void *ptr, size_t size)
{
    if (ptr == NULL) {
        return malloc(size);
    }

    if (size == 0) {
        free(ptr);
        return NULL;
    }

    return LOS_MemRealloc(OS_SYS_MEM_ADDR, ptr, size);
}

小结

本文学习了LiteOS-M内核Musl LibC的实现,特别是文件系统和内存分配释放部分。时间仓促和能力关系,如有失误,欢迎指正。

如果大家想更加深入的学习 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

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

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

相关文章

范闲获取到庆帝与神庙的往来信件,用AES进行破解

关注微信公众号 数据分析螺丝钉 免费领取价值万元的python/java/商业分析/数据结构与算法学习资料 在《庆余年2》中,范闲与庆帝和神庙之间的权谋斗争愈演愈烈。一次偶然的机会,范闲从庆帝的密室中获取到几封与神庙往来的密信。然而,这封信件…

jvm学习笔记(二) ----- 垃圾回收

GC 一、判定对象是否是垃圾1.引用计数法2.可达性分析算法 二、垃圾回收算法1.标记清除2.标记整理3. 复制4. 分代垃圾回收1.尝试在伊甸园分配2.大对象直接晋升至老年代3.多次存活的对象4.老年代连续空间不足,触发 Full GC 链接: jvm学习笔记(一) ----- JAVA 内存 链接…

20240607每日通信--------VUE3前端引入scoket-io,后端引入Netty-SocketIO,我成功了,希望一起交流沟通

无语 前置: VUE3 前端集成scoket-io socket.io-client Sringboot 3.0JDK17集成Netty-SocketIO Netty-SocketIO 失败原因一: 前期决定要写demo时候,单独了解了,后端引入Netty-SocketIO注意事项,详见我先头写的博客 前…

别让你的品牌失去声音,品牌策划如何成为你的王牌?

品牌策划可不仅仅是一个简单的概念,它是一门真正的艺术和科学。 它涉及到在确立品牌定位之后,进行一系列精心设计的传播和推广活动,从而塑造和管理品牌,让品牌价值达到最大化。 在这个竞争激烈的市场中,想要让你的品…

一篇文章带你搞懂C++引用(建议收藏)

引用 6.1 引用概念 引用不是新定义一个变量,而是给已存在变量取了一个别名,编译器不会为引用变量开辟内存空间,它和它引用的变量共用同一块内存空间。 比如:李逵,在家称为"铁牛",江湖上人称&quo…

30、matlab现代滤波:维纳滤波/LMS算法滤波/小波变换滤波

1、信号1和信号2的维纳滤波 实现代码 N 2000; %采样点数 Fs 2000; %采样频率 t 0:1 / Fs:1 - 1 / Fs; %时间序列 Signal1 sin(2*pi*20* t) sin(2*pi*40* t) sin(2*pi*60* t); Signal2[2*ones(1,50),zeros(1,50),-1*ones(1,100),zeros(1,50),-2*ones(1,50),zeros(1,50),1…

删除目录

自学python如何成为大佬(目录):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 删除目录可以通过使用os模块提供的rmdir()函数实现。通过rmdir()函数删除目录时,只有当要删除的目录为空时才起作用。rmdir()函数的基本语…

升级最新版openssh-9.7p1及openssl-1.1.1h详细步骤及常见问题总结

近期因为openssh相继被漏洞扫描工具扫出存在漏洞,所以考虑升级操作系统中的openssh和openssl为最新版本,来避免漏洞风险。期间的升级过程及遇到的疑难问题,特此记录下来,供有需要的人参考。 本次目标是升级 openssh 为 9.7p1 版本…

算法金 | 不愧是腾讯,问基础巨细节 。。。

大侠幸会,在下全网同名「算法金」 0 基础转 AI 上岸,多个算法赛 Top 「日更万日,让更多人享受智能乐趣」 最近,有读者参加了腾讯算法岗位的面试,面试着重考察了基础知识,并且提问非常详细。 特别是关于Ada…

Linux守护进程揭秘-无声无息运行在后台

在Linux系统中,有一些特殊的进程悄无声息地运行在后台,如同坚实的基石支撑着整个系统的运转。它们就是众所周知的守护进程(Daemon)。本文将为你揭开守护进程的神秘面纱,探讨它们的本质特征、创建过程,以及如何重定向它们的输入输出…

vue2实现将el-table表格数据导出为长图片

方法一、 el-table数据导出为长图片 将el-table数据导出为图片不是一个直接的功能,但可以通过以下步骤实现: 使用html2canvas库将表格区域转换为画布(canvas)。 使用canvas的toDataURL方法将画布导出为图片格式(例如PNG)。 创建…

人工智能时代,想转型AI产品经理?这篇文章你不应该错过

前言 在这个日新月异的智能时代,人工智能(AI)已经从未来概念转变为推动各行各业发展的核心驱动力。作为连接技术与市场的桥梁,AI产品经理的角色愈发关键,他们不仅是技术的翻译者,更是创新的推动者。如果你…

ORA-12519 TNS:no appropriate service handler found

问题描述 jdbc连接Oracle失败,报错日志如下: Listener refused the connection with the following error: ORA-12519, TNS:no appropriate service handler found The Connection descriptor used by the client was:192.9.100.217:7001:wcm 问题分…

重新学习STM32(2)NVIC

概念简介 NVIC,即嵌套向量中断控制器,控制着中断相关的功能,是内核里面的一个外设。 中断在单片机编程中的作用是使单片机能及时响应需要立即处理的事件,但是这些事件也分紧急和非紧急,因此需要优先级来区分。…

泛微开发修炼之旅--10基于Ecology实现附件上传,并将上传后的文件id存入表单附件控件中的示例及源码

文章链接:泛微开发修炼之旅--10基于Ecology实现附件上传,并将上传后的文件id存入表单附件控件中的示例及源码

Cadence Virtuoso IC617 系统内存清理

1、清空simelation和垃圾箱下的文件 2、在虚拟机磁盘路径下,例如/home下面输入后,回车,等待进程走完,虚拟机关机。 cat /dev/zero > zero.fill;sync;sleep 1;sync;rm -f zero.fill 3、在windows下winR ->cmd 找到VMware安…

代码随想录算法训练营第十五天| 110.平衡二叉树、 257. 二叉树的所有路径、404.左叶子之和

110.平衡二叉树 题目链接:110.平衡二叉树 文档讲讲:代码随想录 状态:还可以 思路:计算左右子树的深度差,递归判断左右子树是否符合平衡条件 题解: public boolean isBalanced(TreeNode root) {if (root n…

【UML用户指南】-10-对高级结构建模-高级类

目录 1、类目 2、高级类 3、可见性 4、实例范围和静态范围 5、抽象元素、叶子元素和多态性元素 6、多重性 7、属性 8、操作 9、模板类 10、标准元素 1、类目 类目 (classifier)是描述结构特征和行为特征的机制。类目包括类、关联、接口、数据类…

6月26~28日,2024北京国际消防展即将开幕!

随着社会的快速发展,消防安全日益受到广大民众的高度关注。为了进一步推动消防科技的创新与发展,提升全民消防安全意识,2024年北京消防展将于6月26日在北京国家会议中心盛大开展。目前:观众预登记已全面启动,广大市民和业界人士可…

第九篇——冗余量:《史记》和《圣经》那个信息量大?

目录 一、背景介绍二、思路&方案三、过程1.思维导图2.文章中经典的句子理解3.学习之后对于投资市场的理解4.通过这篇文章结合我知道的东西我能想到什么? 四、总结五、升华 一、背景介绍 通过信息量的对比,引出来冗余度的概念,又深入浅出…