diff --git a/fs/proc/include/proc_fs.h b/fs/proc/include/proc_fs.h index 3cc4ea9d549b20d2429569174b8615908c9c60f3..ad074278bc423cd4478901ec8fd383dc9c2b82c1 100644 --- a/fs/proc/include/proc_fs.h +++ b/fs/proc/include/proc_fs.h @@ -78,7 +78,7 @@ typedef unsigned short fmode_t; #define FMODE_READ ((fmode_t)0x1) struct ProcFile; - +//操作pro file的抽象接口,proc本质是个内存文件系统, struct ProcFileOperations { char *name; ssize_t (*write)(struct ProcFile *pf, const char *buf, size_t count, loff_t *ppos); @@ -86,32 +86,32 @@ struct ProcFileOperations { int (*release)(struct Vnode *vnode, struct ProcFile *pf); int (*read)(struct SeqBuf *m, void *v); }; - +//proc 目录/文件项, @notethinking 直接叫 ProcEntry不香吗 ? struct ProcDirEntry { mode_t mode; int flags; const struct ProcFileOperations *procFileOps; struct ProcFile *pf; - struct ProcDirEntry *next, *parent, *subdir; + struct ProcDirEntry *next, *parent, *subdir;//当前目录项的关系项 void *data; atomic_t count; /* open file count */ spinlock_t pdeUnloadLock; int nameLen; - struct ProcDirEntry *pdirCurrent; + struct ProcDirEntry *pdirCurrent;//当前目录 char name[NAME_MAX]; - enum VnodeType type; + enum VnodeType type; //节点类型 }; - +//Proc文件结构体,对标 FILE 结构体 struct ProcFile { - fmode_t fMode; - spinlock_t fLock; - atomic_t fCount; - struct SeqBuf *sbuf; - struct ProcDirEntry *pPDE; - unsigned long long fVersion; - loff_t fPos; - char name[NAME_MAX]; + fmode_t fMode; //操作文件的模式 + spinlock_t fLock; //自旋锁 + atomic_t fCount; //原子操作 + struct SeqBuf *sbuf;//序列号BUF + struct ProcDirEntry *pPDE;//目录项 + unsigned long long fVersion;//版本号 + loff_t fPos; //文件操作偏移位 + char name[NAME_MAX];//文件名 }; struct ProcStat { diff --git a/fs/proc/os_adapt/mounts_proc.c b/fs/proc/os_adapt/mounts_proc.c index 644a0cc19f44a2a47763e22cac48797bd91dd473..702417abc1ed6972193d88def050f1427d9afa9d 100644 --- a/fs/proc/os_adapt/mounts_proc.c +++ b/fs/proc/os_adapt/mounts_proc.c @@ -37,15 +37,15 @@ #include "fs/file.h" #include "internal.h" - +//显示文件系统类型,将被作为回调函数回调 static int ShowType(const char *mountPoint, struct statfs *statBuf, void *arg) { struct SeqBuf *seqBuf = (struct SeqBuf *)arg; char *type = NULL; char *name = NULL; - switch (statBuf->f_type) { - case PROCFS_MAGIC: + switch (statBuf->f_type) {//目前鸿蒙支持的文件系统 + case PROCFS_MAGIC: type = "proc"; name = "proc"; break; @@ -72,12 +72,12 @@ static int ShowType(const char *mountPoint, struct statfs *statBuf, void *arg) default: return 0; } - - (void)LosBufPrintf(seqBuf, "%s %s %s\n", name, mountPoint, type); + + (void)LosBufPrintf(seqBuf, "%s %s %s\n", name, mountPoint, type);//打印到 seqBuf 中,即 arg中 return 0; } - +// 读取 mount 接口实现 static int MountsProcFill(struct SeqBuf *m, void *v) { foreach_mountpoint_t handler = ShowType; @@ -85,7 +85,7 @@ static int MountsProcFill(struct SeqBuf *m, void *v) return 0; } - +//实现 操作proc file 接口,也可理解为驱动程序不同 static const struct ProcFileOperations MOUNTS_PROC_FOPS = { .read = MountsProcFill, }; diff --git a/fs/proc/os_adapt/proc_init.c b/fs/proc/os_adapt/proc_init.c index 5af830bc2898b2d823a3a1eac198a3472d6b422a..e56e2eca7d00b33f9c71a917ae0167517bc7fe00 100644 --- a/fs/proc/os_adapt/proc_init.c +++ b/fs/proc/os_adapt/proc_init.c @@ -36,31 +36,31 @@ #include "sys/stat.h" #include "los_init.h" -#ifdef LOSCFG_FS_PROC - +#ifdef LOSCFG_FS_PROC //使能 PROC 模块 +//pro file 初始化 void ProcFsInit(void) { int ret; - ret = mkdir(PROCFS_MOUNT_POINT, 0); + ret = mkdir(PROCFS_MOUNT_POINT, 0);//创建 "/proc" if (ret < 0) { PRINT_ERR("failed to mkdir %s, errno = %d\n", PROCFS_MOUNT_POINT, get_errno()); return; } - + //装载文件系统 ret = mount(NULL, PROCFS_MOUNT_POINT, "procfs", 0, NULL); if (ret) { PRINT_ERR("mount procfs err %d\n", ret); return; } - ProcMountsInit(); + ProcMountsInit();//初始化 /pro/mounts #if defined(LOSCFG_SHELL_CMD_DEBUG) && defined(LOSCFG_KERNEL_VM) - ProcVmmInit(); + ProcVmmInit();//初始化 /pro/vmm #endif - ProcProcessInit(); - ProcUptimeInit(); - ProcKernelTraceInit(); + ProcProcessInit();//初始化 /pro/process + ProcUptimeInit();//初始化 /pro/uptime + ProcKernelTraceInit();//初始化 /pro/ktrace } LOS_MODULE_INIT(ProcFsInit, LOS_INIT_LEVEL_KMOD_EXTENDED); diff --git a/fs/proc/os_adapt/process_proc.c b/fs/proc/os_adapt/process_proc.c index 65fe78bba0476893dfc7e408b24832f45ade8091..fe75e4bce668eeb2dd28dd4ac072e78e1d8867e8 100644 --- a/fs/proc/os_adapt/process_proc.c +++ b/fs/proc/os_adapt/process_proc.c @@ -33,18 +33,18 @@ #include #include "proc_fs.h" #include "los_process_pri.h" - +//这个太牛了,直接读 taskinfo,注意 SeqBuf 的第一个参数是 char* buf static int ProcessProcFill(struct SeqBuf *m, void *v) { (void)v; (void)OsShellCmdTskInfoGet(OS_ALL_TASK_MASK, m, OS_PROCESS_INFO_ALL); return 0; } - +// 对 /proc/process 各种骚操作,只能读 static const struct ProcFileOperations PROCESS_PROC_FOPS = { - .read = ProcessProcFill, + .read = ProcessProcFill,//读取操作 }; - +//创建进程相关信息 /proc/process void ProcProcessInit(void) { struct ProcDirEntry *pde = CreateProcEntry("process", 0, NULL); diff --git a/fs/proc/os_adapt/vmm_proc.c b/fs/proc/os_adapt/vmm_proc.c index b4d5239186721dabf4cec8f85e65e499447f31a0..c0c45efef287551ff1ede3d9ea1f11ee3bb17652 100644 --- a/fs/proc/os_adapt/vmm_proc.c +++ b/fs/proc/os_adapt/vmm_proc.c @@ -40,7 +40,7 @@ #include "los_process_pri.h" #ifdef LOSCFG_KERNEL_VM - +//获取虚拟内存内核相关的信息,用这个方法去窥视内核是个很好的办法,精读本函数的过程是理解虚拟内存实现的过程 STATIC VOID OsVmDumpSeqSpaces(struct SeqBuf *seqBuf) { LosVmSpace *space = NULL; @@ -89,7 +89,7 @@ STATIC VOID OsVmDumpSeqSpaces(struct SeqBuf *seqBuf) } (VOID)LOS_MuxRelease(aspaceListMux); } - +// .read 接口的现实 static int VmmProcFill(struct SeqBuf *m, void *v) { (void)v; @@ -97,21 +97,21 @@ static int VmmProcFill(struct SeqBuf *m, void *v) return 0; } - +//实现 操作proc file 接口,也可理解为驱动程序不同 static const struct ProcFileOperations VMM_PROC_FOPS = { .write = NULL, .read = VmmProcFill, }; - +//初始化 虚拟内存 内容信息 void ProcVmmInit(void) { - struct ProcDirEntry *pde = CreateProcEntry("vmm", 0, NULL); + struct ProcDirEntry *pde = CreateProcEntry("vmm", 0, NULL);//创建目录 if (pde == NULL) { PRINT_ERR("create /proc/vmm error!\n"); return; } - pde->procFileOps = &VMM_PROC_FOPS; + pde->procFileOps = &VMM_PROC_FOPS;//每个目录的驱动程序都不一样 } #endif #endif diff --git a/fs/proc/src/proc_file.c b/fs/proc/src/proc_file.c index 331be79cfae4f9e73f10342b08142e414d0f0ee7..27905008b594b84da80f0b92b25f25267cbf7924 100644 --- a/fs/proc/src/proc_file.c +++ b/fs/proc/src/proc_file.c @@ -39,25 +39,25 @@ #define MIN(a, b) ((a) < (b) ? (a) : (b)) #define PROC_ROOTDIR_NAMELEN 5 #define PROC_INUSE 2 - -DEFINE_SPINLOCK(procfsLock); -bool procfsInit = false; +//定义自旋锁,说明 procfs不支持多线程访问 +DEFINE_SPINLOCK(procfsLock);//定义profs 自旋锁 +bool procfsInit = false; //是否初始化了profs static struct ProcFile g_procPf = { .fPos = 0, }; -static struct ProcDirEntry g_procRootDirEntry = { +static struct ProcDirEntry g_procRootDirEntry = { //proc 根部 即 /proc .nameLen = 5, - .mode = S_IFDIR | S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH, + .mode = S_IFDIR | S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH,//(04555) .count = ATOMIC_INIT(1), - .procFileOps = NULL, - .parent = &g_procRootDirEntry, - .name = "/proc", - .subdir = NULL, - .next = NULL, - .pf = &g_procPf, - .type = VNODE_TYPE_DIR, + .procFileOps = NULL,//对根节点无操作需求 + .parent = &g_procRootDirEntry,//自己当爹又当儿 + .name = "/proc", + .subdir = NULL, //暂无,后续必有子 + .next = NULL, //暂无.后续必有续 + .pf = &g_procPf, //全局PRO文件 + .type = VNODE_TYPE_DIR, //是个目录 }; int ProcMatch(unsigned int len, const char *name, struct ProcDirEntry *pn) @@ -360,12 +360,12 @@ static struct ProcDirEntry *ProcCreateFile(struct ProcDirEntry *parent, const ch return pn; } - +//创建 pro (目录/文件)项 struct ProcDirEntry *CreateProcEntry(const char *name, mode_t mode, struct ProcDirEntry *parent) { struct ProcDirEntry *pde = NULL; - if (S_ISDIR(mode)) { + if (S_ISDIR(mode)) {//目录模式 0 pde = ProcCreateDir(parent, name, NULL, mode); } else { pde = ProcCreateFile(parent, name, NULL, mode); diff --git a/fs/proc/src/proc_shellcmd.c b/fs/proc/src/proc_shellcmd.c index 2ec4809ec261c374b038f3eb640ce8626c048bf6..f9a4fbf03979e4809f1372908fedf280f4eb0899 100644 --- a/fs/proc/src/proc_shellcmd.c +++ b/fs/proc/src/proc_shellcmd.c @@ -49,7 +49,33 @@ #include "proc_fs.h" #define WRITEPROC_ARGC 3 +/***************************************************************** +鸿蒙内核提供了一种通过 /proc 文件系统,在运行时访问内核内部数据结构、改变内核设置的机制。 +proc文件系统是一个伪文件系统,它只存在内存当中,而不占用外存空间。它以文件系统的方式为 +访问系统内核数据的操作提供接口。 +用户和应用程序可以通过proc得到系统的信息,并可以改变内核的某些参数。由于系统的信息, +如进程,是动态改变的,所以用户或应用程序读取proc文件时,proc文件系统是动态从系统内核读出 +所需信息并提交的。 +proc fs支持传入字符串参数,需要每个文件实现自己的写方法。 +命令格式 +writeproc >> /proc/ + +参数说明 +参数 参数说明 +data 要输入的字符串,以空格为结束符,如需输入空格,请用""包裹。 +filename data要传入的proc文件。 + +proc文件实现自身的write函数,调用writeproc命令后会将入参传入write函数。 + 注意:procfs暂不支持多线程访问 + +OHOS # writeproc test >> /proc/uptime + +[INFO]write buf is: test +test >> /proc/uptime + 说明: uptime proc文件临时实现write函数,INFO日志为实现的测试函数打印的日志。 + +*****************************************************************/ int OsShellCmdWriteProc(int argc, char **argv) { int i; diff --git a/kernel/base/misc/task_shellcmd.c b/kernel/base/misc/task_shellcmd.c index b1526f204a69af5096b74f776ec921937527211b..4d8d5ddd055a169c64ecae6fa9a555c66f19141f 100644 --- a/kernel/base/misc/task_shellcmd.c +++ b/kernel/base/misc/task_shellcmd.c @@ -95,7 +95,7 @@ STATIC UINT32 *taskWaterLine = NULL; #else #define PROCESS_INFO_SHOW(seqBuf, arg...) PRINTK(arg) #endif - + LITE_OS_SEC_TEXT_MINOR UINT8 *OsShellCmdProcessMode(UINT16 mode) { if (mode == OS_KERNEL_MODE) { @@ -109,9 +109,9 @@ LITE_OS_SEC_TEXT_MINOR UINT8 *OsShellCmdProcessMode(UINT16 mode) LITE_OS_SEC_TEXT_MINOR UINT8 *OsShellCmdSchedPolicy(UINT16 policy) { - if (policy == LOS_SCHED_RR) { + if (policy == LOS_SCHED_RR) { return (UINT8 *)"RR"; - } else if (policy == LOS_SCHED_FIFO) { + } else if (policy == LOS_SCHED_FIFO) { return (UINT8 *)"FIFO"; } else if (policy == LOS_SCHED_IDLE) { return (UINT8 *)"IDLE"; @@ -119,25 +119,25 @@ LITE_OS_SEC_TEXT_MINOR UINT8 *OsShellCmdSchedPolicy(UINT16 policy) return (UINT8 *)"ERROR"; } - + LITE_OS_SEC_TEXT_MINOR UINT8 *OsShellProcessStatus(UINT16 status) { status = status & OS_PROCESS_STATUS_MASK; - if (status & OS_PROCESS_STATUS_ZOMBIES) { + if (status & OS_PROCESS_STATUS_ZOMBIES) { return (UINT8 *)"Zombies"; - } else if (status & OS_PROCESS_STATUS_INIT) { + } else if (status & OS_PROCESS_STATUS_INIT) { return (UINT8 *)"Init"; - } else if (status & OS_PROCESS_STATUS_RUNNING) { + } else if (status & OS_PROCESS_STATUS_RUNNING) { return (UINT8 *)"Running"; - } else if (status & OS_PROCESS_STATUS_READY) { + } else if (status & OS_PROCESS_STATUS_READY) { return (UINT8 *)"Ready"; - } else if (status & OS_PROCESS_STATUS_PENDING) { + } else if (status & OS_PROCESS_STATUS_PENDING) { return (UINT8 *)"Pending"; } return (UINT8 *)"Invalid"; } - + STATIC VOID OsShellCmdProcessTitle(VOID *seqBuf, UINT16 flag) { PROCESS_INFO_SHOW(seqBuf, "\r\n PID PPID PGID UID Status "); @@ -204,14 +204,14 @@ STATIC VOID OsShellCmdAllProcessInfoShow(const LosProcessCB *pcbArray, const INT for (pid = 1; pid < g_processMaxNum; ++pid) { processCB = pcbArray + pid; - if (OsProcessIsUnused(processCB)) { + if (OsProcessIsUnused(processCB)) { continue; } OsShellCmdProcessInfoShow(processCB, group, memArray, seqBuf, flag); } } - + #ifdef LOSCFG_KERNEL_VM STATIC VOID OsProcessMemUsageGet(UINT32 *memArray) { @@ -221,7 +221,7 @@ STATIC VOID OsProcessMemUsageGet(UINT32 *memArray) for (pid = 0; pid < g_processMaxNum; ++pid) { processCB = g_processCBArray + pid; - if (OsProcessIsUnused(processCB)) { + if (OsProcessIsUnused(processCB)) { continue; } proMemUsage = &memArray[pid * PROCESS_VM_INDEX_MAX]; @@ -504,7 +504,7 @@ STATIC VOID OsShellCmdAllTaskInfoData(const LosTaskCB *allTaskArray, VOID *seqBu } } } - + STATIC VOID OsShellCmdTskInfoData(const LosTaskCB *allTaskArray, VOID *seqBuf, UINT16 flag) { OsShellCmdTskInfoTitle(seqBuf, flag); @@ -532,7 +532,7 @@ STATIC VOID OsProcessAndTaskInfoGet(LosProcessCB **pcbArray, INT32 **group, LosT SCHEDULER_UNLOCK(intSave); } } - +//获取任务相关信息 LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdTskInfoGet(UINT32 taskID, VOID *seqBuf, UINT16 flag) { UINT32 size; @@ -554,15 +554,15 @@ LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdTskInfoGet(UINT32 taskID, VOID *seqBuf, } (VOID)memset_s(pcbArray, size, 0, size); OsProcessAndTaskInfoGet(&pcbArray, &group, &tcbArray, &memArray, flag); - OsShellCmdProcessInfoData(pcbArray, group, memArray, seqBuf, flag); - OsShellCmdTskInfoData(tcbArray, seqBuf, flag); + OsShellCmdProcessInfoData(pcbArray, group, memArray, seqBuf, flag); + OsShellCmdTskInfoData(tcbArray, seqBuf, flag); (VOID)LOS_MemFree(m_aucSysMem1, pcbArray); } return LOS_OK; } - + LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdDumpTask(INT32 argc, const CHAR **argv) { UINT32 flag = 0; @@ -601,6 +601,6 @@ TASK_HELP: } #ifdef LOSCFG_SHELL -SHELLCMD_ENTRY(task_shellcmd, CMD_TYPE_EX, "task", 1, (CmdCallBackFunc)OsShellCmdDumpTask); +SHELLCMD_ENTRY(task_shellcmd, CMD_TYPE_EX, "task", 1, (CmdCallBackFunc)OsShellCmdDumpTask); #endif diff --git a/kernel/common/los_seq_buf.c b/kernel/common/los_seq_buf.c index 895d17d44d5d6fa1b7d4900f0e043019718e67b2..a2bffcbd2b4a97c120ef8ea092a7d4a163affe78 100644 --- a/kernel/common/los_seq_buf.c +++ b/kernel/common/los_seq_buf.c @@ -31,8 +31,10 @@ #include "los_seq_buf.h" #include - -static int ExpandSeqBuf(struct SeqBuf *seqBuf, size_t oldCount) +/* + Sequential buffer 顺序缓存区 实现 +*/ +static int ExpandSeqBuf(struct SeqBuf *seqBuf, size_t oldCount)//扩展buf { char *newBuf = NULL; int ret; @@ -45,21 +47,21 @@ static int ExpandSeqBuf(struct SeqBuf *seqBuf, size_t oldCount) goto EXPAND_FAILED; } - newBuf = (char*)malloc(seqBuf->size <<= 1); + newBuf = (char*)malloc(seqBuf->size <<= 1);//将现有buf扩大一倍 if (newBuf == NULL) { goto EXPAND_FAILED; } (void)memset_s(newBuf + oldCount, seqBuf->size - oldCount, 0, seqBuf->size - oldCount); - - ret = memcpy_s(newBuf, seqBuf->size, seqBuf->buf, oldCount); + //memset_s 注意 oldCount 位置,因为 newBuf头部要被旧buf覆盖,所以只set后部分 + ret = memcpy_s(newBuf, seqBuf->size, seqBuf->buf, oldCount);//拷贝旧buf数据到新buf,注意 oldCount 位置 if (ret != LOS_OK) { free(newBuf); goto EXPAND_FAILED; } - seqBuf->count = oldCount; + seqBuf->count = oldCount;//目前偏移量,可理解为seek - free(seqBuf->buf); - seqBuf->buf = newBuf; + free(seqBuf->buf);//释放原有的buf + seqBuf->buf = newBuf;//采用新的buf return LOS_OK; EXPAND_FAILED: @@ -70,7 +72,7 @@ EXPAND_FAILED: return -LOS_NOK; } - +//创建seq buf struct SeqBuf *LosBufCreat(void) { struct SeqBuf *seqBuf = NULL; @@ -84,7 +86,7 @@ struct SeqBuf *LosBufCreat(void) return seqBuf; } - +//真正写 buf 函数,调整 size/count的值,count可理解为偏移位 int LosBufVprintf(struct SeqBuf *seqBuf, const char *fmt, va_list argList) { bool needreprintf = FALSE; @@ -109,10 +111,10 @@ int LosBufVprintf(struct SeqBuf *seqBuf, const char *fmt, va_list argList) seqBuf->size - seqBuf->count - 1, fmt, argList); if (bufLen >= 0) { /* succeed write. */ - seqBuf->count += bufLen; + seqBuf->count += bufLen;//成功写入,count要增长 return 0; } - if (seqBuf->buf[seqBuf->count] == '\0') { + if (seqBuf->buf[seqBuf->count] == '\0') {//这里没看懂,为啥要有这个判断, @note_thinking free(seqBuf->buf); seqBuf->buf = NULL; break; @@ -127,19 +129,19 @@ int LosBufVprintf(struct SeqBuf *seqBuf, const char *fmt, va_list argList) return -LOS_NOK; } - +//支持可变参数 写 buf int LosBufPrintf(struct SeqBuf *seqBuf, const char *fmt, ...) { va_list argList; int ret; - va_start(argList, fmt); + va_start(argList, fmt);//可变参数的实现,有点意思. ret = LosBufVprintf(seqBuf, fmt, argList); va_end(argList); return ret; } - +//释放 seq buf int LosBufRelease(struct SeqBuf *seqBuf) { if (seqBuf == NULL) { diff --git a/kernel/common/los_seq_buf.h b/kernel/common/los_seq_buf.h index 7bf69f61418a0b9379978f2a1720e1e756cdf465..f8d305f53f2c8ff64e782889053226ff3f782cb9 100644 --- a/kernel/common/los_seq_buf.h +++ b/kernel/common/los_seq_buf.h @@ -41,13 +41,13 @@ extern "C" { #endif /* __cplusplus */ #endif /* __cplusplus */ -#define SEQBUF_PAGE_SIZE 4096 -#define SEQBUF_LIMIT_SIZE (256 * SEQBUF_PAGE_SIZE) - +#define SEQBUF_PAGE_SIZE 4096 //4K 一页 +#define SEQBUF_LIMIT_SIZE (256 * SEQBUF_PAGE_SIZE) //缓冲区最大空间为1M +//序列化BUF struct SeqBuf { - char *buf; - size_t size; - size_t count; + char *buf; //内容 + size_t size;//buf大小 + size_t count;//当前位置 void *private; }; diff --git a/zzz/git/push.sh b/zzz/git/push.sh index 716f040edb8d389632ef404cd3e290ecfd680ff4..7fdfbd6f55f8544ab86eddaa01ff765426db478f 100644 --- a/zzz/git/push.sh +++ b/zzz/git/push.sh @@ -1,7 +1,7 @@ git add -A -git commit -m '理解 进程文件描述符 和 系统文件描述 是理解FD的关键. +git commit -m '鸿蒙对 /proc 的实现很有意思,/proc被称为伪文件系统,或内存文件系统 百万汉字注解 + 百篇博客分析 => 挖透鸿蒙内核源码 - 国内:https://weharmony.gitee.io + 国内:https://weharmony.21cloudbox.com 国外:https://weharmony.github.io '