提交 69cd227f 编写于 作者: 鸿蒙内核源码分析's avatar 鸿蒙内核源码分析

您知道工作台是如何创建的码? 添加 VFS部分shell命令代码的注释

鸿蒙内核源码分析系列 【 CSDN | OSCHINA | WIKI 】
鸿蒙内核源码注释中文版 【 CSDN仓 | Gitee仓 | Github仓 | Coding仓 】四大仓库每日同步更新
项目给鸿蒙内核源码逐行加上中文注解,详细阐述框架和代码细节, 精读 HarmonyOS 内核源码, 将迅速拔高对计算机整体理解,从此高屋建瓴看问题.
上级 78b01f7d
......@@ -2,16 +2,14 @@
[鸿蒙源码分析系列篇 【 CSDN ](https://blog.csdn.net/kuangyufei/article/details/108727970) [| OSCHINA ](https://my.oschina.net/u/3751245/blog/4626852) [| WIKI 】](https://gitee.com/weharmony/kernel_liteos_a_note/wikis/pages) 从 HarmonyOS 架构层视角整理成文, 并首创用生活场景讲故事的方式试图去解构内核,一窥究竟。
---
# **[kernel\_liteos\_a_note](https://gitee.com/weharmony/kernel_liteos_a_note): 鸿蒙内核源码注释中文版**
# ![](https://oscimg.oschina.net/oscnet/up-c1f5f5e88b38fcb25f274a2062384b0c61e.png)
[![star](https://gitee.com/weharmony/kernel_liteos_a_note/badge/star.svg?theme=dark)](https://gitee.com/weharmony/kernel_liteos_a_note)[![fork](https://gitee.com/weharmony/kernel_liteos_a_note/badge/fork.svg?theme=dark)](https://gitee.com/weharmony/kernel_liteos_a_note)
每个码农,职业生涯,都应精读一遍内核源码. 鸿蒙内核源码就是很好的精读项目.一旦熟悉内核代码级实现,将迅速拔高对计算机整体理解,从此高屋建瓴看问题.
# ![](https://oscimg.oschina.net/oscnet/up-c1f5f5e88b38fcb25f274a2062384b0c61e.png)
每个码农,职业生涯,都应精读一遍内核源码. 鸿蒙内核源码就是很好的精读项目.一旦熟悉内核代码级实现,将迅速拔高对计算机整体理解,从此高屋建瓴看问题.
## **做了些什么呢**
......
......@@ -55,8 +55,8 @@ struct file_table_s {
struct fd_table_s {//fd表结构体
unsigned int max_fds;
struct file_table_s *ft_fds; /* process fd array associate with system fd *///进程的FD数组,与系统fd相关联
fd_set *open_fds;
fd_set *proc_fds;
fd_set *open_fds; //打开的fds 默认打开了 0,1,2 (stdin,stdout,stderr)
fd_set *proc_fds; //处理的fds 默认打开了 0,1,2 (stdin,stdout,stderr)
sem_t ft_sem; /* manage access to the file table */ //管理对文件表的访问
};
//files_struct 一般用于进程 process->files
......@@ -72,19 +72,19 @@ struct files_struct {//进程文件表结构体
};
typedef struct ProcessCB LosProcessCB;
//以下函数见于 ..\third_party\NuttX\fs\inode\fs_files.c
void files_refer(int fd);
struct files_struct *dup_fd(struct files_struct *oldf);
struct files_struct *alloc_files(void);
struct files_struct *alloc_files(void);//返回分配好的files_struct,其中包含fd总数,stdin,stdout,stderr等信息 stdin也是一个文件
void delete_files(LosProcessCB *processCB, struct files_struct *files);
void delete_files(LosProcessCB *processCB, struct files_struct *files);//删除进程的文件管理器
struct files_struct *create_files_snapshot(const struct files_struct *oldf);
struct files_struct *create_files_snapshot(const struct files_struct *oldf);//创建文件管理器快照,所谓快照就是一份拷贝
void delete_files_snapshot(struct files_struct *files);
void delete_files_snapshot(struct files_struct *files);//删除文件管理器快照
int alloc_fd(int minfd);
int alloc_fd(int minfd);//分配一个fd,当然是从files_struct->fdt 数组中拿一个未被使用(分配)的fd,默认都是 -1
#endif
......@@ -56,7 +56,7 @@ FAR int fscheck(FAR const char *path)
char *fullpath = NULL;
char *fullpath_bak = NULL;
ret = vfs_normalize_path((const char *)NULL, path, &fullpath);
ret = vfs_normalize_path((const char *)NULL, path, &fullpath);//检查path的规范性
if (ret < 0) {
ret = -ret;
goto errout;
......
......@@ -35,10 +35,10 @@
#include "fs/file.h"
#include "fs/fs.h"
static void FileTableLock(struct fd_table_s *fdt)
static void FileTableLock(struct fd_table_s *fdt)//对文件表操作前先拿锁
{
/* Take the semaphore (perhaps waiting) */
while (sem_wait(&fdt->ft_sem) != 0) {
while (sem_wait(&fdt->ft_sem) != 0) { //拿信号量,没有信号量就处于等待状态
/*
* The only case that an error should occur here is if the wait was
* awakened by a signal.
......@@ -46,16 +46,16 @@ static void FileTableLock(struct fd_table_s *fdt)
LOS_ASSERT(get_errno() == EINTR);
}
}
static void FileTableUnLock(struct fd_table_s *fdt)
//
static void FileTableUnLock(struct fd_table_s *fdt)//对文件表操作完后解锁
{
int ret = sem_post(&fdt->ft_sem);
int ret = sem_post(&fdt->ft_sem);//发送信号
if (ret == -1) {
PRINTK("sem_post error, errno %d \n", get_errno());
}
}
static int AssignProcessFd(const struct fd_table_s *fdt, int minFd)
static int AssignProcessFd(const struct fd_table_s *fdt, int minFd)//分配进程fd
{
if (fdt == NULL) {
return VFS_ERROR;
......@@ -63,7 +63,7 @@ static int AssignProcessFd(const struct fd_table_s *fdt, int minFd)
/* search unused fd from table */
for (int i = minFd; i < fdt->max_fds; i++) {
if (!FD_ISSET(i, fdt->proc_fds)) {
if (!FD_ISSET(i, fdt->proc_fds)) {//i尚未被设置,则返回i
return i;
}
}
......@@ -87,7 +87,7 @@ static struct fd_table_s *GetFdTable(void)
return fdt;
}
//是否为一个有效的进程fd
static bool IsValidProcessFd(struct fd_table_s *fdt, int procFd)
{
if (fdt == NULL) {
......@@ -98,12 +98,12 @@ static bool IsValidProcessFd(struct fd_table_s *fdt, int procFd)
}
return true;
}
//分配系统fd
void AssociateSystemFd(int procFd, int sysFd)
{
struct fd_table_s *fdt = GetFdTable();
if (!IsValidProcessFd(fdt, procFd)) {
if (!IsValidProcessFd(fdt, procFd)) {//先检查进程fd的有效性
return;
}
......@@ -111,7 +111,7 @@ void AssociateSystemFd(int procFd, int sysFd)
return;
}
FileTableLock(fdt);
FileTableLock(fdt);//操作临界区,先拿锁
fdt->ft_fds[procFd].sysFd = sysFd;
FileTableUnLock(fdt);
}
......@@ -215,26 +215,26 @@ int DisassociateProcessFd(int procFd)
return sysFd;
}
//分配一个进程fd
int AllocProcessFd(void)
{
return AllocLowestProcessFd(MIN_START_FD);
return AllocLowestProcessFd(MIN_START_FD);//0,1,2已经分配给控制台了,所以从3开始
}
int AllocLowestProcessFd(int minFd)
{
struct fd_table_s *fdt = GetFdTable();
struct fd_table_s *fdt = GetFdTable();//获取当前进程的文件管理器
if (fdt == NULL) {
return VFS_ERROR;
}
//minFd应该是一个正数,0,1,2已经被分配到stdin,stdout,stderr
/* minFd should be a positive number,and 0,1,2 had be distributed to stdin,stdout,stderr */
if (minFd < MIN_START_FD) {
if (minFd < MIN_START_FD) {//如果小于3,就改成3
minFd = MIN_START_FD;
}
FileTableLock(fdt);
FileTableLock(fdt);//操作临界区,必须上锁
int procFd = AssignProcessFd(fdt, minFd);
if (procFd == VFS_ERROR) {
......@@ -244,7 +244,7 @@ int AllocLowestProcessFd(int minFd)
// occupy the fd set
FD_SET(procFd, fdt->proc_fds);
FileTableUnLock(fdt);
FileTableUnLock(fdt);//释放锁
return procFd;
}
......
......@@ -56,15 +56,15 @@
#include <ctype.h>
typedef enum
{
RM_RECURSIVER,
RM_FILE,
RM_DIR,
CP_FILE,
CP_COUNT
{
RM_RECURSIVER, //递归删除
RM_FILE, //删除文件
RM_DIR, //删除目录
CP_FILE, //拷贝文件
CP_COUNT //拷贝数量
} wildcard_type;
#define ERROR_OUT_IF(condition, message_function, handler) \
#define ERROR_OUT_IF(condition, message_function, handler) \ //这种写法挺妙的
do \
{ \
if (condition) \
......@@ -132,13 +132,30 @@ int osShellCmdDoChdir(const char *path)
return 0;
}
/*******************************************************
命令功能
ls命令用来显示当前目录的内容。
命令格式
ls [path]
path为空时,显示当前目录的内容。
path为无效文件名时,显示失败,提示:
ls error: No such directory。
path为有效目录路径时,会显示对应目录下的内容。
使用指南
ls命令显示当前目录的内容。
ls可以显示文件的大小。
proc下ls无法统计文件大小,显示为0。
*******************************************************/
int osShellCmdLs(int argc, const char **argv)
{
char *fullpath = NULL;
const char *filename = NULL;
int ret;
char *shell_working_directory = OsShellGetWorkingDirtectory();
char *shell_working_directory = OsShellGetWorkingDirtectory();//获取当前工作目录
if (shell_working_directory == NULL)
{
return -1;
......@@ -146,31 +163,46 @@ int osShellCmdLs(int argc, const char **argv)
ERROR_OUT_IF(argc > 1, PRINTK("ls or ls [DIRECTORY]\n"), return -1);
if (argc == 0)
if (argc == 0)//木有参数时 -> #ls
{
ls(shell_working_directory);
ls(shell_working_directory);//执行ls 当前工作目录
return 0;
}
filename = argv[0];
ret = vfs_normalize_path(shell_working_directory, filename, &fullpath);
ERROR_OUT_IF(ret < 0, set_err(-ret, "ls error"), return -1);
filename = argv[0];//有参数时 -> #ls ../harmony or #ls /no such file or directory
ret = vfs_normalize_path(shell_working_directory, filename, &fullpath);//获取全路径,注意这里带出来fullpath,而fullpath已经在内核空间
ERROR_OUT_IF(ret < 0, set_err(-ret, "ls error"), return -1);//
ls(fullpath);
free(fullpath);
ls(fullpath);//执行 ls 全路径
free(fullpath);//释放全路径,为啥要释放,因为fullpath已经由内核空间分配
return 0;
}
/*******************************************************
命令功能
cd命令用来改变当前目录。
命令格式
cd [path]
未指定目录参数时,会跳转至根目录。
cd后加路径名时,跳转至该路径。
路径名以 /(斜杠)开头时,表示根目录。
.(点)表示当前目录。
..(点点)表示父目录。
cd ..
*******************************************************/
int osShellCmdCd(int argc, const char **argv)
{
if (argc == 0)
if (argc == 0)//没有参数时 #cd
{
(void)osShellCmdDoChdir("/");
return 0;
}
(void)osShellCmdDoChdir(argv[0]);
(void)osShellCmdDoChdir(argv[0]);//#cd .. 带参数情况
return 0;
}
......@@ -179,7 +211,18 @@ int osShellCmdCd(int argc, const char **argv)
#define CAT_TASK_PRIORITY 10
#define CAT_TASK_STACK_SIZE 0x3000
pthread_mutex_t g_mutex_cat = PTHREAD_MUTEX_INITIALIZER;
/*******************************************************
cat用于显示文本文件的内容。
命令格式
cat [pathname]
使用指南
cat用于显示文本文件的内容。
使用实例
举例:cat harmony.txt
*******************************************************/
int osShellCmdDoCatShow(UINTPTR arg)
{
char buf[CAT_BUF_SIZE];
......@@ -1002,7 +1045,7 @@ static int os_wildcard_match(const char *src, const char *filename)
}
/* To determine whether a wildcard character exists in a path */
//确定路径中是否存在通配符
static int os_is_containers_wildcard(const char *filename)
{
while (*filename != '\0')
......@@ -1017,20 +1060,20 @@ static int os_is_containers_wildcard(const char *filename)
}
/* Delete a matching file or directory */
//删除匹配的文件或目录
static int os_wildcard_delete_file_or_dir(const char *fullpath, wildcard_type mark)
{
int ret;
switch (mark)
{
case RM_RECURSIVER:
ret = os_shell_cmd_do_rmdir(fullpath);
case RM_RECURSIVER://递归删除
ret = os_shell_cmd_do_rmdir(fullpath);//删除目录,其中递归调用 rmdir
break;
case RM_FILE:
case RM_FILE://删除文件
ret = unlink(fullpath);
break;
case RM_DIR:
case RM_DIR://删除目录
ret = rmdir(fullpath);
break;
default:
......@@ -1048,7 +1091,7 @@ static int os_wildcard_delete_file_or_dir(const char *fullpath, wildcard_type ma
}
/* Split the path with wildcard characters */
//使用通配符拆分路径
static char* os_wildcard_split_path(char *fullpath, char **handle, char **wait)
{
int n = 0;
......@@ -1084,7 +1127,7 @@ static char* os_wildcard_split_path(char *fullpath, char **handle, char **wait)
}
/* Handling entry of the path with wildcard characters */
//处理具有通配符的目录
static int os_wildcard_extract_directory(char *fullpath, void *dst, wildcard_type mark)
{
char separator[] = "/";
......@@ -1213,7 +1256,29 @@ closedir_out:
(void)closedir(d);
return VFS_ERROR;
}
/*****************************************************************
命令功能
拷贝文件,创建一份副本。
命令格式
cp [SOURCEFILE] [DESTFILE]
SOURCEFILE - 源文件路径。- 目前只支持文件,不支持目录。
DESTFILE - 目的文件路径。 - 支持目录以及文件。
使用指南
同一路径下,源文件与目的文件不能重名。
源文件必须存在,且不为目录。
源文件路径支持“*”和“?”通配符,“*”代表任意多个字符,“?”代表任意单个字符。目的路径不支持通配符。当源路径可匹配多个文件时,目的路径必须为目录。
目的路径为目录时,该目录必须存在。此时目的文件以源文件命名。
目的路径为文件时,所在目录必须存在。此时拷贝文件的同时为副本重命名。
目前不支持多文件拷贝。参数大于2个时,只对前2个参数进行操作。
目的文件不存在时创建新文件,已存在则覆盖。
拷贝系统重要资源时,会对系统造成死机等重大未知影响,如用于拷贝/dev/uartdev-0 文件时,会产生系统卡死现象。
使用实例
举例:cp harmony.txt ./tmp/
*****************************************************************/
int osShellCmdCp(int argc, const char **argv)
{
int ret;
......@@ -1223,20 +1288,20 @@ int osShellCmdCp(int argc, const char **argv)
char *dst_fullpath = NULL;
struct stat stat_buf;
int count = 0;
char *shell_working_directory = OsShellGetWorkingDirtectory();
char *shell_working_directory = OsShellGetWorkingDirtectory();//获取进程当前工作目录
if (shell_working_directory == NULL)
{
return -1;
}
ERROR_OUT_IF(argc < 2, PRINTK("cp [SOURCEFILE] [DESTFILE]\n"), return -1);
ERROR_OUT_IF(argc < 2, PRINTK("cp [SOURCEFILE] [DESTFILE]\n"), return -1);//参数必须要两个
src = argv[0];
dst = argv[1];
/* Get source fullpath. */
ret = vfs_normalize_path(shell_working_directory, src, &src_fullpath);
ret = vfs_normalize_path(shell_working_directory, src, &src_fullpath);//获取源路径的全路径
if (ret < 0)
{
set_errno(-ret);
......@@ -1244,7 +1309,7 @@ int osShellCmdCp(int argc, const char **argv)
return -1;
}
if (src[strlen(src) - 1] == '/')
if (src[strlen(src) - 1] == '/')//如果src最后一个字符是 '/'说明是个目录,src必须是个文件,目前只支持文件,不支持目录
{
PRINTK("cp %s error: Source file can't be a directory.\n", src);
goto errout_with_srcpath;
......@@ -1252,7 +1317,7 @@ int osShellCmdCp(int argc, const char **argv)
/* Get dest fullpath. */
ret = vfs_normalize_path(shell_working_directory, dst, &dst_fullpath);
ret = vfs_normalize_path(shell_working_directory, dst, &dst_fullpath);//获取目标路径的全路径
if (ret < 0)
{
set_errno(-ret);
......@@ -1262,27 +1327,27 @@ int osShellCmdCp(int argc, const char **argv)
/* Is dest path exist? */
ret = stat(dst_fullpath, &stat_buf);
if (ret < 0)
ret = stat(dst_fullpath, &stat_buf);//判断目标路径存不存在
if (ret < 0)//不存在的情况
{
/* Is dest path a directory? */
/* Is dest path a directory? */ //目标路径是个目录吗?
if (dst[strlen(dst) - 1] == '/')
if (dst[strlen(dst) - 1] == '/') //是个不存在的目录
{
PRINTK("cp error: %s, %s.\n", dst_fullpath, strerror(errno));
PRINTK("cp error: %s, %s.\n", dst_fullpath, strerror(errno));//打印错误信息
goto errout_with_path;
}
}
else
{
if (S_ISREG(stat_buf.st_mode) && dst[strlen(dst) - 1] == '/')
if (S_ISREG(stat_buf.st_mode) && dst[strlen(dst) - 1] == '/')//是普通文件但最后一个字符是'/'
{
PRINTK("cp error: %s is not a directory.\n", dst_fullpath);
goto errout_with_path;
}
}
if (os_is_containers_wildcard(src_fullpath))
if (os_is_containers_wildcard(src_fullpath))//是否包含通配符
{
if (ret < 0 || S_ISREG(stat_buf.st_mode))
{
......@@ -1292,7 +1357,7 @@ int osShellCmdCp(int argc, const char **argv)
PRINTK("cp error : Out of memory.\n");
goto errout_with_path;
}
(void)os_wildcard_extract_directory(src_copy, &count, CP_COUNT);
(void)os_wildcard_extract_directory(src_copy, &count, CP_COUNT);//处理具有通配符的目录
free(src_copy);
if (count > 1)
{
......@@ -1302,11 +1367,11 @@ int osShellCmdCp(int argc, const char **argv)
}
ret = os_wildcard_extract_directory(src_fullpath, dst_fullpath, CP_FILE);
}
else
else//不包含通配符的情况
{
ret = os_shell_cmd_do_cp(src_fullpath, dst_fullpath);
ret = os_shell_cmd_do_cp(src_fullpath, dst_fullpath);//执行拷贝操作
}
free(dst_fullpath);
free(dst_fullpath); //这两个路径都由内核分配了内存,所以要释放
free(src_fullpath);
return ret;
......@@ -1415,7 +1480,23 @@ int osShellCmdRmdir(int argc, const char **argv)
return 0;
}
/*****************************************************************
命令功能
sync命令用于同步缓存数据(文件系统的数据)到sd卡。
命令格式
sync
参数说明
无。
使用指南
sync命令用来刷新缓存,当没有sd卡插入时不进行操作。
有sd卡插入时缓存信息会同步到sd卡,成功返回时无显示。
使用实例
举例:输入sync,有sd卡时同步到sd卡,无sd卡时不操作。
*****************************************************************/
int osShellCmdSync(int argc, const char **argv)
{
ERROR_OUT_IF(argc > 0, PRINTK("\nUsage: sync\n"), return -1);
......@@ -1423,6 +1504,19 @@ int osShellCmdSync(int argc, const char **argv)
sync();
return 0;
}
/*****************************************************************
命令功能
lsfd命令用来显示当前已经打开的文件描述符及对应的文件名。
命令格式
lsfd
使用指南
lsfd命令显示当前已经打开文件的fd号以及文件的名字。
使用实例
举例:输入lsfd
*****************************************************************/
int osShellCmdLsfd(int argc, const char **argv)
{
......
......@@ -851,7 +851,7 @@ STATIC UINT32 OsProcessCreateInit(LosProcessCB *processCB, UINT32 flags, const C
#endif
#ifdef LOSCFG_FS_VFS
processCB->files = alloc_files();
processCB->files = alloc_files();//分配进程的文件的管理器
if (processCB->files == NULL) {
ret = LOS_ENOMEM;
goto EXIT;
......
......@@ -1159,7 +1159,7 @@ STATIC VOID ConsoleCirBufDelete(CirBufSendCB *cirBufSendCB)
(VOID)LOS_EventDestroy(&cirBufSendCB->sendEvent);
(VOID)LOS_MemFree(m_aucSysMem0, cirBufSendCB);
}
//控制台缓存初始化,创建一个 发送任务
STATIC UINT32 OsConsoleBufInit(CONSOLE_CB *consoleCB)
{
UINT32 ret;
......@@ -1200,18 +1200,18 @@ STATIC VOID OsConsoleBufDeinit(CONSOLE_CB *consoleCB)
consoleCB->cirBufSendCB = NULL;
(VOID)LOS_EventWrite(&cirBufSendCB->sendEvent, CONSOLE_SEND_TASK_EXIT);
}
//控制台描述符初始化
STATIC CONSOLE_CB *OsConsoleCBInit(UINT32 consoleID)
{
CONSOLE_CB *consoleCB = (CONSOLE_CB *)LOS_MemAlloc((VOID *)m_aucSysMem0, sizeof(CONSOLE_CB));
CONSOLE_CB *consoleCB = (CONSOLE_CB *)LOS_MemAlloc((VOID *)m_aucSysMem0, sizeof(CONSOLE_CB));//内核空间分配控制台描述符
if (consoleCB == NULL) {
return NULL;
}
(VOID)memset_s(consoleCB, sizeof(CONSOLE_CB), 0, sizeof(CONSOLE_CB));
(VOID)memset_s(consoleCB, sizeof(CONSOLE_CB), 0, sizeof(CONSOLE_CB));//清0
consoleCB->consoleID = consoleID;
consoleCB->shellEntryId = SHELL_ENTRYID_INVALID; /* initialize shellEntryId to an invalid value */
consoleCB->name = LOS_MemAlloc((VOID *)m_aucSysMem0, CONSOLE_NAMELEN);
consoleCB->consoleID = consoleID;//记录控制台ID
consoleCB->shellEntryId = SHELL_ENTRYID_INVALID; /* initialize shellEntryId to an invalid value *///将shellEntryId初始化为无效值
consoleCB->name = LOS_MemAlloc((VOID *)m_aucSysMem0, CONSOLE_NAMELEN);//控制台名称 不能多于16个字符
if (consoleCB->name == NULL) {
PRINT_ERR("consoleCB->name malloc failed\n");
(VOID)LOS_MemFree((VOID *)m_aucSysMem0, consoleCB);
......@@ -1219,52 +1219,52 @@ STATIC CONSOLE_CB *OsConsoleCBInit(UINT32 consoleID)
}
return consoleCB;
}
//释放控制台描述符初始化时所占用的内核空间
STATIC VOID OsConsoleCBDeinit(CONSOLE_CB *consoleCB)
{
(VOID)LOS_MemFree((VOID *)m_aucSysMem0, consoleCB->name);
(VOID)LOS_MemFree((VOID *)m_aucSysMem0, consoleCB->name);//释放控制台名称占用的内核内存
consoleCB->name = NULL;
(VOID)LOS_MemFree((VOID *)m_aucSysMem0, consoleCB);
(VOID)LOS_MemFree((VOID *)m_aucSysMem0, consoleCB);//释放控制台描述符所占用的内核内存
}
//创建一个控制台
STATIC CONSOLE_CB *OsConsoleCreate(UINT32 consoleID, const CHAR *deviceName)
{
INT32 ret;
CONSOLE_CB *consoleCB = OsConsoleCBInit(consoleID);//
CONSOLE_CB *consoleCB = OsConsoleCBInit(consoleID);//初始化控制台
if (consoleCB == NULL) {
PRINT_ERR("console malloc error.\n");
return NULL;
}
ret = snprintf_s(consoleCB->name, CONSOLE_NAMELEN, CONSOLE_NAMELEN - 1,
"%s%u", CONSOLE, consoleCB->consoleID);
"%s%u", CONSOLE, consoleCB->consoleID);//通过printf方式得到name
if (ret == -1) {
PRINT_ERR("consoleCB->name snprintf_s failed\n");
goto ERR_WITH_NAME;
}
ret = (INT32)OsConsoleBufInit(consoleCB);
ret = (INT32)OsConsoleBufInit(consoleCB);//控制台buf初始化
if (ret != LOS_OK) {
goto ERR_WITH_NAME;
}
ret = (INT32)LOS_SemCreate(1, &consoleCB->consoleSem);
ret = (INT32)LOS_SemCreate(1, &consoleCB->consoleSem);//创建控制台信号量
if (ret != LOS_OK) {
PRINT_ERR("creat sem for uart failed\n");
goto ERR_WITH_BUF;
}
ret = OsConsoleDevInit(consoleCB, deviceName);
ret = OsConsoleDevInit(consoleCB, deviceName);//控制台设备初始化
if (ret != LOS_OK) {
goto ERR_WITH_SEM;
}
ret = OsConsoleFileInit(consoleCB);
ret = OsConsoleFileInit(consoleCB);//控制台文件初始化
if (ret != LOS_OK) {
goto ERR_WITH_DEV;
}
OsConsoleTermiosInit(consoleCB, deviceName);
OsConsoleTermiosInit(consoleCB, deviceName);//控制台条款初始化
return consoleCB;
ERR_WITH_DEV:
......@@ -1298,7 +1298,7 @@ STATIC UINT32 OsConsoleDelete(CONSOLE_CB *consoleCB)
return ret;
}
//初始化系统控制台并返回stdinfd stdoutfd stderrfd
//初始化系统控制台并返回 stdinfd stdoutfd stderrfd
/* Initialized system console and return stdinfd stdoutfd stderrfd */
INT32 system_console_init(const CHAR *deviceName)//deviceName: /dev/serial /dev/telnet
{
......@@ -1315,7 +1315,7 @@ INT32 system_console_init(const CHAR *deviceName)//deviceName: /dev/serial /dev/
return VFS_ERROR;
}
consoleCB = OsConsoleCreate((UINT32)consoleID, deviceName);//创建一个控制台CB
consoleCB = OsConsoleCreate((UINT32)consoleID, deviceName);//创建一个控制台控制块
if (consoleCB == NULL) {
PRINT_ERR("%s, %d\n", __FUNCTION__, __LINE__);
return VFS_ERROR;
......@@ -1328,7 +1328,7 @@ INT32 system_console_init(const CHAR *deviceName)//deviceName: /dev/serial /dev/
}
LOS_SpinUnlockRestore(&g_consoleSpin, intSave);
#ifdef LOSCFG_SHELL
#ifdef LOSCFG_SHELL //shell支持
ret = OsShellInit(consoleID);//通过控制台初始化shell
if (ret != LOS_OK) {
PRINT_ERR("%s, %d\n", __FUNCTION__, __LINE__);
......@@ -1530,22 +1530,22 @@ INT32 ConsoleUpdateFd(VOID)
return g_console[consoleID - 1]->fd;
}
//获取参数控制台ID 获取对应的控制台控制块(描述符)
CONSOLE_CB *OsGetConsoleByID(INT32 consoleID)
{
if (consoleID != CONSOLE_TELNET) {
if (consoleID != CONSOLE_TELNET) {//只允许 1,2存在,> 3 时统统变成1
consoleID = CONSOLE_SERIAL;
}
return g_console[consoleID - 1];
}
//获取参数任务的控制台控制块(描述符)
CONSOLE_CB *OsGetConsoleByTaskID(UINT32 taskID)
{
INT32 consoleID = g_taskConsoleIDArray[taskID];
return OsGetConsoleByID(consoleID);
}
//设置控制台ID
VOID OsSetConsoleID(UINT32 newTaskID, UINT32 curTaskID)
{
if ((newTaskID >= LOSCFG_BASE_CORE_TSK_LIMIT) || (curTaskID >= LOSCFG_BASE_CORE_TSK_LIMIT)) {
......@@ -1579,7 +1579,7 @@ ERROUT:
set_errno(ret);
return VFS_ERROR;
}
//控制台发送任务
STATIC UINT32 ConsoleSendTask(UINTPTR param)
{
CONSOLE_CB *consoleCB = (CONSOLE_CB *)param;
......
......@@ -130,7 +130,7 @@ extern "C" {
#endif /* __cplusplus */
extern UINT32 OsSystemInit(VOID);
extern VOID SystemInit(VOID);
extern VOID SystemInit(VOID);//见于..\vendor\hi3516dv300\module_init\src\system_init.c
//注册 HZ , tick
LITE_OS_SEC_TEXT_INIT VOID osRegister(VOID)
{
......@@ -187,21 +187,21 @@ LITE_OS_SEC_TEXT_INIT STATIC UINT32 OsIpcInit(VOID)
return LOS_OK;
}
#ifdef LOSCFG_KERNEL_PIPE
#ifdef LOSCFG_KERNEL_PIPE//管道支持
LITE_OS_SEC_TEXT_INIT STATIC VOID OsDriverPipeInit(VOID)
{
(VOID)pipe_init();
(VOID)pipe_init();//管道初始化
}
#endif
#ifdef LOSCFG_DRIVERS_HIEVENT
#ifdef LOSCFG_DRIVERS_HIEVENT //hievent支持
LITE_OS_SEC_TEXT_INIT STATIC VOID OsDriverHiEventInit(VOID)
{
(VOID)HieventInit();
}
#endif
#ifdef LOSCFG_COMPAT_BSD
#ifdef LOSCFG_COMPAT_BSD //是否兼容BSD
extern void configure (void);
LITE_OS_SEC_TEXT_INIT STATIC INT32 OsBsdInit(VOID)
{
......@@ -288,7 +288,7 @@ LITE_OS_SEC_TEXT_INIT INT32 OsMain(VOID)
* 2. OsCpupInit
* 3. other inits have task creation
*/
#ifdef LOSCFG_KERNEL_CPUP
#ifdef LOSCFG_KERNEL_CPUP //cpu统计是否支持
ret = OsCpupInit();// shell cpup命令用于查询系统CPU的占用率 命令格式cpup [mode] [taskID]
if (ret != LOS_OK) {
PRINT_ERR("OsCpupInit error\n");
......@@ -387,38 +387,38 @@ STATIC UINT32 OsSystemInitTaskCreate(VOID)
TSK_INIT_PARAM_S sysTask;
(VOID)memset_s(&sysTask, sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S));
sysTask.pfnTaskEntry = (TSK_ENTRY_FUNC)SystemInit;//外部函数,
sysTask.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE;
sysTask.pcName = "SystemInit";
sysTask.usTaskPrio = LOSCFG_BASE_CORE_TSK_DEFAULT_PRIO;// 10
sysTask.pfnTaskEntry = (TSK_ENTRY_FUNC)SystemInit;//任务的入口函数,这个任务由外部提供 比如..\vendor\hi3516dv300\module_init\src\system_init.c
sysTask.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE;//16K
sysTask.pcName = "SystemInit";//任务的名称
sysTask.usTaskPrio = LOSCFG_BASE_CORE_TSK_DEFAULT_PRIO;// 内核默认优先级为10
sysTask.uwResved = LOS_TASK_STATUS_DETACHED;//任务分离模式
#if (LOSCFG_KERNEL_SMP == YES)
sysTask.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid());
#endif
return LOS_TaskCreate(&taskID, &sysTask);//创建任务
return LOS_TaskCreate(&taskID, &sysTask);//创建任务并加入就绪队列,并立即参与调度
}
#ifdef LOSCFG_MEM_RECORDINFO
STATIC UINT32 OsMemShowTaskCreate(VOID)
#ifdef LOSCFG_MEM_RECORDINFO //记录内存信息功能
STATIC UINT32 OsMemShowTaskCreate(VOID)//创建一个显示内存使用信息的任务
{
UINT32 taskID;
TSK_INIT_PARAM_S appTask;
(VOID)memset_s(&appTask, sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S));
appTask.pfnTaskEntry = (TSK_ENTRY_FUNC)OsMemRecordShowTask;
appTask.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE;
appTask.pcName = "memshow_Task";
appTask.usTaskPrio = LOSCFG_BASE_CORE_TSK_DEFAULT_PRIO;
appTask.uwResved = LOS_TASK_STATUS_DETACHED;
return LOS_TaskCreate(&taskID, &appTask);
appTask.pfnTaskEntry = (TSK_ENTRY_FUNC)OsMemRecordShowTask; //任务的入口函数
appTask.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE;//16K
appTask.pcName = "memshow_Task";//任务名称
appTask.usTaskPrio = LOSCFG_BASE_CORE_TSK_DEFAULT_PRIO; //优先级为10
appTask.uwResved = LOS_TASK_STATUS_DETACHED;//分离模式
return LOS_TaskCreate(&taskID, &appTask);//创建任务并加入就绪队列,并立即参与调度
}
#endif
UINT32 OsSystemInit(VOID)
{
UINT32 ret;
#ifdef LOSCFG_FS_VFS
los_vfs_init(); //虚拟文件初始化
#ifdef LOSCFG_FS_VFS //虚拟文件系统支持
los_vfs_init(); //虚拟文件系统初始化
#endif
#ifdef LOSCFG_COMPAT_LINUXKPI
g_pstSystemWq = create_workqueue("system_wq");
......@@ -435,8 +435,8 @@ UINT32 OsSystemInit(VOID)
}
PRINTK("create memshow_Task ok\n");
#endif
#ifdef LOSCFG_KERNEL_TICKLESS
LOS_TicklessEnable();
#ifdef LOSCFG_KERNEL_TICKLESS //低功耗模式
LOS_TicklessEnable();//使能低功耗模式
#endif
return 0;
......
......@@ -335,13 +335,13 @@ STATIC INT32 TelnetPoll(struct file *file, poll_table *table)
return 0;
}
STATIC const struct file_operations_vfs g_telnetOps = {
TelnetOpen,
TelnetClose,
TelnetRead,
TelnetWrite,
STATIC const struct file_operations_vfs g_telnetOps = {//远程登录操作
TelnetOpen, //打开
TelnetClose, //关闭
TelnetRead, //读取数据
TelnetWrite, //写入数据
NULL,
TelnetIoctl,
TelnetIoctl, //远程控制
NULL,
#ifndef CONFIG_DISABLE_POLL
TelnetPoll,
......@@ -376,7 +376,7 @@ INT32 TelnetedRegister(VOID)
}
/* When a telnet client connection established, update the output console for tasks. */
INT32 TelnetDevInit(INT32 clientFd)
INT32 TelnetDevInit(INT32 clientFd)//建立telnet客户机连接后,更新任务的输出控制台。
{
INT32 ret;
......@@ -384,25 +384,25 @@ INT32 TelnetDevInit(INT32 clientFd)
PRINT_ERR("Invalid telnet clientFd.\n");
return -1;
}
ret = system_console_init(TELNET);
ret = system_console_init(TELNET);//初始化系统控制台
if (ret != 0) {
PRINT_ERR("Telnet console init error.\n");
PRINT_ERR("Telnet console init error.\n");//打印初始化失败
return ret;
}
ret = ioctl(STDIN_FILENO, CFG_TELNET_SET_FD, clientFd);
ret = ioctl(STDIN_FILENO, CFG_TELNET_SET_FD, clientFd);//ioctl:控制I/O设备, 提供了一种获得设备信息和向设备发送控制参数的手段
if (ret != 0) {
PRINT_ERR("Telnet device ioctl error.\n");
(VOID)system_console_deinit(TELNET);
(VOID)system_console_deinit(TELNET);//错误情况下删除初始化
}
return ret;
}
/* When closing the telnet client connection, reset the output console for tasks. */
INT32 TelnetDevDeinit(VOID)
INT32 TelnetDevDeinit(VOID)//关闭telnet客户端连接时,重置任务的输出控制台。
{
INT32 ret;
ret = system_console_deinit(TELNET);
ret = system_console_deinit(TELNET);//删除初始化
if (ret != 0) {
PRINT_ERR("Telnet console deinit error.\n");
}
......
......@@ -158,10 +158,10 @@ INT32 OsShellDeinit(INT32 consoleId)
return 0;
}
//获取进程当前工作目录
CHAR *OsShellGetWorkingDirtectory(VOID)
{
CONSOLE_CB *consoleCB = OsGetConsoleByTaskID(OsCurrTaskGet()->taskID);
CONSOLE_CB *consoleCB = OsGetConsoleByTaskID(OsCurrTaskGet()->taskID);//获取当前任务的控制台
ShellCB *shellCB = NULL;
if (consoleCB == NULL) {
......
......@@ -262,7 +262,7 @@ ssize_t SysWrite(int fd, const void *buf, size_t nbytes)
}
return ret;
}
//系统调用之 打开一个文件
int SysOpen(const char *path, int oflags, ...)
{
int ret;
......@@ -271,20 +271,20 @@ int SysOpen(const char *path, int oflags, ...)
int procFd = -1;
if (path != NULL) {
ret = UserPathCopy(path, &pathRet);
ret = UserPathCopy(path, &pathRet);//先将path从用户空间拷贝到内核空间
if (ret != 0) {
goto OUT;
}
}
procFd = AllocProcessFd();
procFd = AllocProcessFd();//分配一个进程fd
if (procFd < 0) {
ret = -EMFILE;
goto OUT;
}
if ((unsigned int)oflags & O_DIRECTORY) {
ret = do_opendir(pathRet, oflags);
if ((unsigned int)oflags & O_DIRECTORY) {//如果是个目录
ret = do_opendir(pathRet, oflags);//打开目录
if (ret < 0) {
ret = -get_errno();
}
......
git add -A
git commit -m '开始对VFS模块代码注释,从进程文件管理器切入 process->files
git commit -m '您知道工作台是如何创建的码? 添加 VFS部分shell命令代码的注释
鸿蒙内核源码分析系列 【 CSDN | OSCHINA | WIKI 】
鸿蒙内核源码注释中文版 【 CSDN仓 | Gitee仓 | Github仓 | Coding仓 】四大仓库每日同步更新代码和wiki
鸿蒙内核源码注释中文版 【 CSDN仓 | Gitee仓 | Github仓 | Coding仓 】四大仓库每日同步更新
项目给鸿蒙内核源码逐行加上中文注解,详细阐述框架和代码细节, 精读 HarmonyOS 内核源码, 将迅速拔高对计算机整体理解,从此高屋建瓴看问题.'
git push origin
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册