• 首页
  • 关于我们
  • 产品中心
  • 新闻资讯
  • 在线招聘
  • 联系我们
  • 新闻资讯

    你的位置:开云(中国)Kaiyun·官方网站 > 新闻资讯 > 开云(中国)Kaiyun·官方网站 鸿蒙轻内核M核源码分析系列之Musl LibC

    开云(中国)Kaiyun·官方网站 鸿蒙轻内核M核源码分析系列之Musl LibC

    发布日期:2023-12-09 12:53    点击次数:100

    开云(中国)Kaiyun·官方网站

    念念了解更多内容,请造访:

    51CTO和华为官方合营共建的鸿蒙时代社区

    https://harmonyos.51cto.com

    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的区别是,央求到手后开云(中国)Kaiyun·官方网站,对央求的内存区域置0。函数realloc用于从头央求一块内存区域。

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