鸿蒙对 /proc 的实现很有意思,/proc被称为伪文件系统,或内存文件系统

    百万汉字注解 + 百篇博客分析 => 挖透鸿蒙内核源码
    国内:https://weharmony.21cloudbox.com
    国外:https://weharmony.github.io
上级 84340a2f
......@@ -88,13 +88,13 @@ struct ProcFileOperations {
};
//proc 目录/文件项, @notethinking 直接叫 ProcEntry不香吗 ?
struct ProcDirEntry {
mode_t mode;
int flags;
const struct ProcFileOperations *procFileOps;
struct ProcFile *pf;
mode_t mode; //模式(读|写...)
int flags; //标签
const struct ProcFileOperations *procFileOps;//驱动程序
struct ProcFile *pf;//文件指针
struct ProcDirEntry *next, *parent, *subdir;//当前目录项的关系项
void *data;
atomic_t count; /* open file count */
atomic_t count; /* open file count */ //打开文件的数量
spinlock_t pdeUnloadLock;
int nameLen;
......
......@@ -41,8 +41,8 @@
#define PROCFS_DEFAULT_MODE 0555
#ifdef LOSCFG_FS_PROC
static struct VnodeOps g_procfsVops;
#ifdef LOSCFG_FS_PROC //使能 /proc 功能
static struct VnodeOps g_procfsVops; // proc 文件系统
static struct file_operations_vfs g_procfsFops;
static struct ProcDirEntry *VnodeToEntry(struct Vnode *node)
......@@ -177,7 +177,7 @@ int VfsProcfsLookup(struct Vnode *parent, const char *name, int len, struct Vnod
(*vpp)->parent = parent;
return LOS_OK;
}
//装载实现,将mount挂到vnode节点上
int VfsProcfsMount(struct Mount *mnt, struct Vnode *device, const void *data)
{
struct Vnode *vp = NULL;
......@@ -193,7 +193,7 @@ int VfsProcfsMount(struct Mount *mnt, struct Vnode *device, const void *data)
struct ProcDirEntry *root = GetProcRootEntry();
vp->data = root;
vp->originMount = mnt;
vp->originMount = mnt;//绑定mount
vp->fop = &g_procfsFops;
mnt->data = NULL;
mnt->vnodeCovered = vp;
......@@ -272,7 +272,7 @@ int VfsProcfsReaddir(struct Vnode *node, struct fs_dirent_s *dir)
return i;
}
//proc 打开目录
int VfsProcfsOpendir(struct Vnode *node, struct fs_dirent_s *dir)
{
struct ProcDirEntry *pde = VnodeToEntry(node);
......@@ -284,7 +284,7 @@ int VfsProcfsOpendir(struct Vnode *node, struct fs_dirent_s *dir)
return LOS_OK;
}
//proc 打开文件
int VfsProcfsOpen(struct file *filep)
{
if (filep == NULL) {
......@@ -323,7 +323,7 @@ int VfsProcfsClose(struct file *filep)
return result;
}
//统计信息接口,简单实现
int VfsProcfsStatfs(struct Mount *mnt, struct statfs *buf)
{
(void)memset_s(buf, sizeof(struct statfs), 0, sizeof(struct statfs));
......@@ -336,14 +336,14 @@ int VfsProcfsClosedir(struct Vnode *vp, struct fs_dirent_s *dir)
{
return LOS_OK;
}
// proc 对 MountOps 接口实现
const struct MountOps procfs_operations = {
.Mount = VfsProcfsMount,
.Mount = VfsProcfsMount,//装载
.Unmount = NULL,
.Statfs = VfsProcfsStatfs,
.Statfs = VfsProcfsStatfs,//统计信息
};
static struct VnodeOps g_procfsVops = {
// proc 对 VnodeOps 接口实现
static struct VnodeOps g_procfsVops = {
.Lookup = VfsProcfsLookup,
.Getattr = VfsProcfsStat,
.Readdir = VfsProcfsReaddir,
......@@ -351,13 +351,13 @@ static struct VnodeOps g_procfsVops = {
.Closedir = VfsProcfsClosedir,
.Truncate = VfsProcfsTruncate
};
// proc 对 file_operations_vfs 接口实现
static struct file_operations_vfs g_procfsFops = {
.read = VfsProcfsRead,
.write = VfsProcfsWrite,
.open = VfsProcfsOpen,
.close = VfsProcfsClose
.read = VfsProcfsRead, // 最终调用 ProcFileOperations -> read
.write = VfsProcfsWrite,// 最终调用 ProcFileOperations -> write
.open = VfsProcfsOpen, // 最终调用 ProcFileOperations -> open
.close = VfsProcfsClose // 最终调用 ProcFileOperations -> release
};
//文件系统注册入口
FSMAP_ENTRY(procfs_fsmap, "procfs", procfs_operations, FALSE, FALSE);
#endif
......@@ -37,7 +37,7 @@
#define MSEC_TO_NSEC 1000000
#define SEC_TO_MSEC 1000
#define DECIMAL_TO_PERCENT 100
//cat /proc/uptime 的实现函数
static int UptimeProcFill(struct SeqBuf *seqBuf, void *v)
{
struct timespec curtime = {0, 0};
......@@ -69,9 +69,9 @@ static int UptimeProcFill(struct SeqBuf *seqBuf, void *v)
#endif
return 0;
}
//替换了 read 接口的实现
static const struct ProcFileOperations UPTIME_PROC_FOPS = {
.read = UptimeProcFill,
.read = UptimeProcFill,//读取接口的实现
};
void ProcUptimeInit(void)
......
......@@ -92,7 +92,7 @@ static struct ProcDirEntry *ProcFindNode(struct ProcDirEntry *parent, const char
* return: the file of handle
* add by ll
*/
struct ProcDirEntry *ProcFindEntry(const char *path)
struct ProcDirEntry *ProcFindEntry(const char *path)//查看内容项
{
struct ProcDirEntry *pn = NULL;
int isfoundsub;
......@@ -162,7 +162,7 @@ struct ProcDirEntry *ProcFindEntry(const char *path)
spin_unlock(&procfsLock);
return NULL;
}
//检查 proc名称有效性
static int CheckProcName(const char *name, struct ProcDirEntry **parent, const char **lastName)
{
struct ProcDirEntry *pn = *parent;
......@@ -198,7 +198,7 @@ static int CheckProcName(const char *name, struct ProcDirEntry **parent, const c
return 0;
}
//分配 proc 节点
static struct ProcDirEntry *ProcAllocNode(struct ProcDirEntry **parent, const char *name, mode_t mode)
{
struct ProcDirEntry *pn = NULL;
......@@ -220,8 +220,8 @@ static struct ProcDirEntry *ProcAllocNode(struct ProcDirEntry **parent, const ch
if ((S_ISDIR((*parent)->mode) == 0) || (strchr(lastName, '/'))) {
return pn;
}
pn = (struct ProcDirEntry *)malloc(sizeof(struct ProcDirEntry));
//开始各种造初始数据
pn = (struct ProcDirEntry *)malloc(sizeof(struct ProcDirEntry));//从内核分配内存
if (pn == NULL) {
return NULL;
}
......@@ -230,7 +230,7 @@ static struct ProcDirEntry *ProcAllocNode(struct ProcDirEntry **parent, const ch
mode |= S_IRUSR | S_IRGRP | S_IROTH;
}
(void)memset_s(pn, sizeof(struct ProcDirEntry), 0, sizeof(struct ProcDirEntry));
(void)memset_s(pn, sizeof(struct ProcDirEntry), 0, sizeof(struct ProcDirEntry));//初始化内存
pn->nameLen = strlen(lastName);
pn->mode = mode;
ret = memcpy_s(pn->name, sizeof(pn->name), lastName, strlen(lastName) + 1);
......@@ -253,7 +253,7 @@ static struct ProcDirEntry *ProcAllocNode(struct ProcDirEntry **parent, const ch
return NULL;
}
atomic_set(&pn->count, 1);
atomic_set(&pn->count, 1);//默认有一个引用
spin_lock_init(&pn->pdeUnloadLock);
return pn;
}
......@@ -315,14 +315,14 @@ static void ProcDetachNode(struct ProcDirEntry *pn)
}
pn->parent = NULL;
}
//在参数 parent 下创建目录
static struct ProcDirEntry *ProcCreateDir(struct ProcDirEntry *parent, const char *name,
const struct ProcFileOperations *procFileOps, mode_t mode)
{
struct ProcDirEntry *pn = NULL;
int ret;
pn = ProcAllocNode(&parent, name, S_IFDIR | mode);
pn = ProcAllocNode(&parent, name, S_IFDIR | mode);//分配一个节点
if (pn == NULL) {
return pn;
}
......@@ -337,20 +337,20 @@ static struct ProcDirEntry *ProcCreateDir(struct ProcDirEntry *parent, const cha
return pn;
}
//创建文件项
static struct ProcDirEntry *ProcCreateFile(struct ProcDirEntry *parent, const char *name,
const struct ProcFileOperations *procFileOps, mode_t mode)
{
struct ProcDirEntry *pn = NULL;
int ret;
pn = ProcAllocNode(&parent, name, S_IFREG | mode);
pn = ProcAllocNode(&parent, name, S_IFREG | mode);//分配一个节点,S_IFREG代表是文件类型
if (pn == NULL) {
return pn;
}
pn->procFileOps = procFileOps;
pn->type = VNODE_TYPE_REG;
pn->procFileOps = procFileOps;//驱动程序
pn->type = VNODE_TYPE_REG; //文件类型
ret = ProcAddNode(parent, pn);
if (ret != 0) {
free(pn->pf);
......@@ -366,9 +366,9 @@ struct ProcDirEntry *CreateProcEntry(const char *name, mode_t mode, struct ProcD
struct ProcDirEntry *pde = NULL;
if (S_ISDIR(mode)) {//目录模式 0
pde = ProcCreateDir(parent, name, NULL, mode);
pde = ProcCreateDir(parent, name, NULL, mode);//无驱动程序
} else {
pde = ProcCreateFile(parent, name, NULL, mode);
pde = ProcCreateFile(parent, name, NULL, mode);//无驱动程序
}
return pde;
}
......@@ -440,7 +440,7 @@ struct ProcDirEntry *ProcMkdir(const char *name, struct ProcDirEntry *parent)
{
return ProcCreateDir(parent, name, NULL, 0);
}
//创建数据
struct ProcDirEntry *ProcCreateData(const char *name, mode_t mode, struct ProcDirEntry *parent,
const struct ProcFileOperations *procFileOps, void *data)
{
......@@ -499,7 +499,7 @@ static int GetNextDir(struct ProcDirEntry *pn, void *buf, size_t len)
pn->pf->fPos++;
return ENOERR;
}
//打开 pro
int ProcOpen(struct ProcFile *procFile)
{
if (procFile == NULL) {
......@@ -509,7 +509,7 @@ int ProcOpen(struct ProcFile *procFile)
return OK;
}
struct SeqBuf *buf = LosBufCreat();
struct SeqBuf *buf = LosBufCreat();//创建一个 seq buf
if (buf == NULL) {
return PROC_ERROR;
}
......@@ -597,7 +597,7 @@ int ReadProcFile(struct ProcDirEntry *pde, void *buf, size_t len)
}
return result;
}
//写 proc 文件
int WriteProcFile(struct ProcDirEntry *pde, const void *buf, size_t len)
{
int result = -EPERM;
......@@ -618,7 +618,7 @@ int WriteProcFile(struct ProcDirEntry *pde, const void *buf, size_t len)
return result;
}
// seek proc 文件
loff_t LseekProcFile(struct ProcDirEntry *pde, loff_t offset, int whence)
{
if (pde == NULL || pde->pf == NULL) {
......
......@@ -87,17 +87,17 @@ int OsShellCmdWriteProc(int argc, char **argv)
char realPath[PATH_MAX] = {'\0'};
const char *rootProcDir = "/proc/";
if (argc == WRITEPROC_ARGC) {
value = argv[0];
path = argv[2];
if (argc == WRITEPROC_ARGC) {//argv[0] = ">>"
value = argv[0];//test
path = argv[2];///proc/uptime
len = strlen(value) + 1; /* +1:add the \0 */
if (strncmp(argv[1], ">>", strlen(">>")) == 0) {
if (strncmp(argv[1], ">>", strlen(">>")) == 0) { // 第二个参数必须得是 >>
if ((realpath(path, realPath) == NULL) || (strncmp(realPath, rootProcDir, strlen(rootProcDir)) != 0)) {
PRINT_ERR("No such file or directory\n");
return PROC_ERROR;
}
handle = OpenProcFile(realPath, O_TRUNC);
handle = OpenProcFile(realPath, O_TRUNC);//打开 proc 文件
if (handle == NULL) {
PRINT_ERR("No such file or directory\n");
return PROC_ERROR;
......
......@@ -623,7 +623,7 @@ void ls(const char *pathname)
return;
}
//
char *realpath(const char *path, char *resolved_path)
{
int ret, result;
......@@ -637,7 +637,7 @@ char *realpath(const char *path, char *resolved_path)
return NULL;
}
result = stat(new_path, &buf);
result = stat(new_path, &buf);//获取统计信息,即属性信息
if (resolved_path == NULL) {
if (result != ENOERR) {
......
......@@ -241,7 +241,7 @@ static char *vfs_normalize_fullpath(const char *directory, const char *filename,
return fullpath;
}
//通过目录和文件名找(绝对)路径
//虚拟文件系统 | 标准化路径
int vfs_normalize_path(const char *directory, const char *filename, char **pathname)
{
char *fullpath = NULL;
......
......@@ -223,7 +223,7 @@ cat用于显示文本文件的内容。
使用实例
举例:cat harmony.txt
*******************************************************/
int osShellCmdDoCatShow(UINTPTR arg)
int osShellCmdDoCatShow(UINTPTR arg) //shellcmd_cat 任务实现
{
int ret = 0;
char buf[CAT_BUF_SIZE];
......@@ -233,7 +233,7 @@ int osShellCmdDoCatShow(UINTPTR arg)
FILE *ini = NULL;
(void)pthread_mutex_lock(&g_mutex_cat);
ini = fopen(fullpath, "r");
ini = fopen(fullpath, "r");//打开文件
if (ini == NULL)
{
ret = -1;
......@@ -244,7 +244,7 @@ int osShellCmdDoCatShow(UINTPTR arg)
do
{
(void)memset_s(buf, sizeof(buf), 0, CAT_BUF_SIZE);
size = fread(buf, 1, CAT_BUF_SIZE, ini);
size = fread(buf, 1, CAT_BUF_SIZE, ini); //读取文件内容
if ((int)size < 0)
{
ret = -1;
......@@ -291,7 +291,7 @@ int osShellCmdCat(int argc, const char **argv)
unsigned int ca_task;
struct Vnode *vnode = NULL;
TSK_INIT_PARAM_S init_param;
char *shell_working_directory = OsShellGetWorkingDirtectory();
char *shell_working_directory = OsShellGetWorkingDirtectory();//显示当前目录 pwd
if (shell_working_directory == NULL)
{
return -1;
......@@ -299,7 +299,7 @@ int osShellCmdCat(int argc, const char **argv)
ERROR_OUT_IF(argc != 1, PRINTK("cat [FILE]\n"), return -1);
ret = vfs_normalize_path(shell_working_directory, argv[0], &fullpath);
ret = vfs_normalize_path(shell_working_directory, argv[0], &fullpath);//由相对路径获取绝对路径
ERROR_OUT_IF(ret < 0, set_err(-ret, "cat error"), return -1);
VnodeHold();
......@@ -323,14 +323,14 @@ int osShellCmdCat(int argc, const char **argv)
VnodeDrop();
(void)memset_s(&init_param, sizeof(init_param), 0, sizeof(TSK_INIT_PARAM_S));
init_param.pfnTaskEntry = (TSK_ENTRY_FUNC)osShellCmdDoCatShow;
init_param.usTaskPrio = CAT_TASK_PRIORITY;
init_param.auwArgs[0] = (UINTPTR)fullpath;
init_param.uwStackSize = CAT_TASK_STACK_SIZE;
init_param.pcName = "shellcmd_cat";
init_param.usTaskPrio = CAT_TASK_PRIORITY; //优先级10
init_param.auwArgs[0] = (UINTPTR)fullpath; //入口参数
init_param.uwStackSize = CAT_TASK_STACK_SIZE;//内核栈大小
init_param.pcName = "shellcmd_cat"; //任务名称
init_param.uwResved = LOS_TASK_STATUS_DETACHED | OS_TASK_FLAG_SPECIFIES_PROCESS;
init_param.processID = 2; /* 2: kProcess */
init_param.processID = 2; /* 2: kProcess */ //内核任务
ret = (int)LOS_TaskCreate(&ca_task, &init_param);
ret = (int)LOS_TaskCreate(&ca_task, &init_param);//创建任务显示cat内容
if (ret != LOS_OK)
{
......
......@@ -200,13 +200,13 @@ extern SPIN_LOCK_S g_taskSpin;//任务自旋锁
*
* The task is system-level task, like idle, swtmr and etc.
*/
#define OS_TASK_FLAG_SYSTEM_TASK 0x1000U
#define OS_TASK_FLAG_SYSTEM_TASK 0x1000U //系统任务
/**
* @ingroup los_task
* Flag that indicates the task property.
*
* The task is no-delete system task, like resourceTask.
* The task is no-delete system task, like resourceTask. //该任务是不可删除的系统任务,如资源回收任务
*/
#define OS_TASK_FLAG_NO_DELETE 0x2000U
......@@ -216,7 +216,7 @@ extern SPIN_LOCK_S g_taskSpin;//任务自旋锁
*
* Kills the thread during process exit.
*/
#define OS_TASK_FLAG_EXIT_KILL 0x4000U
#define OS_TASK_FLAG_EXIT_KILL 0x4000U //在进程退出期间一同被干掉的任务
/**
* @ingroup los_task
......@@ -224,14 +224,14 @@ extern SPIN_LOCK_S g_taskSpin;//任务自旋锁
*
* Specifies the process creation task.
*/
#define OS_TASK_FLAG_SPECIFIES_PROCESS 0x0U
#define OS_TASK_FLAG_SPECIFIES_PROCESS 0x0U //创建指定任务 例如: cat weharmony.net 实现
/**
* @ingroup los_task
* Boundary on which the stack size is aligned.
*
*/
#define OS_TASK_STACK_SIZE_ALIGN 16U
#define OS_TASK_STACK_SIZE_ALIGN 16U //堆栈大小对齐的边界
/**
* @ingroup los_task
......@@ -243,7 +243,7 @@ extern SPIN_LOCK_S g_taskSpin;//任务自旋锁
/**
* @ingroup los_task
* Number of usable task priorities.
*/
*/ //可用任务优先级的数量
#define OS_TSK_PRINUM (OS_TASK_PRIORITY_LOWEST - OS_TASK_PRIORITY_HIGHEST + 1)
/**
......
......@@ -39,6 +39,9 @@
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
/*
HAL层主要功能是实现轻OpenHarmony与芯片的解耦,
*/
#ifndef LOS_HAL_TABLE_BEGIN
#define LOS_HAL_TABLE_BEGIN(label, name) \
......
......@@ -59,7 +59,7 @@ extern "C" {
*
* The task is automatically deleted.
*/
#define LOS_TASK_STATUS_DETACHED 0x0800U
#define LOS_TASK_STATUS_DETACHED 0x0800U //任务被自动删除
/**
* @ingroup los_task
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册