色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

LiteOS-A內核中的procfs文件系統分析

OpenAtom OpenHarmony ? 來源:未知 ? 2022-12-02 21:10 ? 次閱讀

點擊藍字 ╳ 關注我們


開源項目 OpenHarmony
是每個人的 OpenHarmony

蔣衛峰

深圳開鴻數字產業發展有限公司

OS內核開發工程師


一、 procfs介紹

procfs是類UNIX操作系統中進程文件系統(process file system)的縮寫,主要用于通過內核訪問進程信息和系統信息,以及可以修改內核參數改變系統行為。需要注意的是,procfs文件系統是一個虛擬文件系統,不存在硬盤當中,而是系統啟動時動態生成的文件系統,儲存在內存中。procfs文件系統通常掛載在/proc目錄下。
LiteOS-A是OpenAtom OpenHarmony(以下簡稱“OpenHarmony”)系統中使用的輕量系統內核,實現了procfs文件系統。本文主要對LiteOS-A內核中的procfs文件系統的設計、實現和使用進行介紹和分析。
procfs文件系統是LiteOS-A內核文件系統的一個案例,通過了解procfs文件系統,能夠熟悉LiteOS-A的文件系統框架,并很好地將內核信息通過文件系統反饋給使用者。

1. Linux系統中的procfs文件系統包含的內容
Ubuntu 20.04中的/proc文件信息如下:

圖1:Ubuntu proc目錄信息

2. OS-A系統的命令以及procfs文件系統的內容
LiteOS-A的命令集:

LiteOS-A的proc目錄信息如下:

圖2:liteOS-A proc目錄信息

二、 procfs文件系統的設計

LiteOS-A中使用VFS作為各個文件系統的粘合層,而VFS在OpenHarmony內核中采用樹結構實現,樹中的每一個節點都是Vnode結構體。VFS提供統一的抽象接口用于屏蔽文件系統之間的差異,其提供三大操作接口用于統一不同文件系統調用不同接口的現狀。
VFS提供的三大操作接口:
? VnodeOps
? MountOps
? file_operations_vfs
VnodeOps用于控制Vnode節點,MountOps控制掛載點,file_operations_vfs提供常用的文件接口。
文件系統各自需要實現VFS提供的這三大接口,即實現系統本身需要的接口方法,讓VFS能夠調用這些接口即可。procfs文件系統雖作為一個偽文件系統pseudo-file system,但其仍舊需要實現上述接口。
1. VFS提供的重要接口
(1) Vnode 結構體:
struct Vnode {
enum VnodeType type; /* Vnode節點類型 */
int useCount; /* 節點鏈接數 */
uint32_t hash; /* 哈希值 */
uint uid; /* 文件擁有者的user id */
uint gid; /* 文件群組id */
mode_t mode; /* 文件讀寫執行權限 */
LIST_HEAD parentPathCaches; /* 指向父節點的路徑緩存 */
LIST_HEAD childPathCaches; /* 指向兒子節點的路徑緩存 */
struct Vnode *parent; /* vnode父節點 */
struct VnodeOps *vop; /* vnode操作接口 */
struct file_operations_vfs *fop; /* 文件操作接口,即指定文件系統 */
void *data; /* 數據,指向內部數據的指針 */
uint32_t flag; /* 節點標簽 */
LIST_ENTRY hashEntry; /* 掛入v_vnodeHashEntry[i]中 */
LIST_ENTRY actFreeEntry; /* 通過本節點掛載到空閑和使用鏈表中 */
struct Mount *originMount; /* 所在文件系統掛載信息 */
struct Mount *newMount; /* 其他掛載在這個節點中的文件系統信息 */
char *filePath; /* Vnode的路徑信息 */
struct page_mapping mapping; /* page mapping of the vnode */
};
圖3:Vnode structure

Vnode功能接口定義:
struct VnodeOps {
int (*Create)(struct Vnode *parent, const char *name, int mode, struct Vnode **vnode);// 創建節點
int (*Lookup)(struct Vnode *parent, const char *name, int len, struct Vnode **vnode);// 查詢節點
int (*Open)(struct Vnode *vnode, int fd, int mode, int flags);// 打開節點
ssize_t (*ReadPage)(struct Vnode *vnode, char *buffer, off_t pos);
ssize_t (*WritePage)(struct Vnode *vnode, char *buffer, off_t pos, size_t buflen);
int (*Close)(struct Vnode *vnode);// 關閉節點
int (*Reclaim)(struct Vnode *vnode);// 回收節點
int (*Unlink)(struct Vnode *parent, struct Vnode *vnode, const char *fileName);// 取消硬鏈接
int (*Rmdir)(struct Vnode *parent, struct Vnode *vnode, const char *dirName);// 刪除目錄節點
int (*Mkdir)(struct Vnode *parent, const char *dirName, mode_t mode, struct Vnode **vnode);// 創建目錄節點
int (*Readdir)(struct Vnode *vnode, struct fs_dirent_s *dir);// 讀目錄節點信息
int (*Opendir)(struct Vnode *vnode, struct fs_dirent_s *dir);// 打開目錄節點
int (*Rewinddir)(struct Vnode *vnode, struct fs_dirent_s *dir);// 定位目錄節點
int (*Closedir)(struct Vnode *vnode, struct fs_dirent_s *dir);// 關閉目錄節點
int (*Getattr)(struct Vnode *vnode, struct stat *st);// 獲取節點屬性
int (*Setattr)(struct Vnode *vnode, struct stat *st);// 設置節點屬性
int (*Chattr)(struct Vnode *vnode, struct IATTR *attr);// 改變節點屬性
int (*Rename)(struct Vnode *src, struct Vnode *dstParent, const char *srcName, const char *dstName);
int (*Truncate)(struct Vnode *vnode, off_t len);// 縮小或擴大
int (*Truncate64)(struct Vnode *vnode, off64_t len);
int (*Fscheck)(struct Vnode *vnode, struct fs_dirent_s *dir);
int (*Link)(struct Vnode *src, struct Vnode *dstParent, struct Vnode **dst, const char *dstName);
int (*Symlink)(struct Vnode *parentVnode, struct Vnode **newVnode, const char *path, const char *target);
ssize_t (*Readlink)(struct Vnode *vnode, char *buffer, size_t bufLen);
};

Vnode根節點的初始化操作:
將全局Vnode表進行初始化,開始節點指向根目錄/,全局節點g_rootVnode。
int VnodesInit(void)
{
int retval = LOS_MuxInit(&g_vnodeMux, NULL);
if (retval != LOS_OK) {
PRINT_ERR("Create mutex for vnode fail, status: %d", retval);
return retval;
}


LOS_ListInit(&g_vnodeFreeList);
LOS_ListInit(&g_vnodeVirtualList);
LOS_ListInit(&g_vnodeActiveList);
retval = VnodeAlloc(NULL, &g_rootVnode);
if (retval != LOS_OK) {
PRINT_ERR("VnodeInit failed error %d ", retval);
return retval;
}
g_rootVnode->mode = S_IRWXU | S_IRWXG | S_IRWXO | S_IFDIR;
g_rootVnode->type = VNODE_TYPE_DIR;
g_rootVnode->filePath = "/";


return LOS_OK;
}

(2) Mount結構體:
struct Mount {
LIST_ENTRY mountList; /* 全局Mount鏈表 */
const struct MountOps *ops; /* Mount的功能函數 */
struct Vnode *vnodeBeCovered; /* 要被掛載的節點 */
struct Vnode *vnodeCovered; /* 要掛載的節點 */
struct Vnode *vnodeDev; /* 設備vnode */
LIST_HEAD vnodeList; /* Vnode表的表頭 */
int vnodeSize; /* Vnode表的節點數量 */
LIST_HEAD activeVnodeList; /* 激活的節點鏈表 */
int activeVnodeSize; /* 激活的節點數量 */
void *data; /* 數據,指向內部數據的指針 */
uint32_t hashseed; /* Random seed for vfshash */
unsigned long mountFlags; /* 掛載標簽 */
char pathName[PATH_MAX]; /* 掛載點路徑 */
char devName[PATH_MAX]; /* 設備名稱 /dev/sdb-1 */
};
圖4:Mount structure

掛載點的接口定義:
struct MountOps {
int (*Mount)(struct Mount *mount, struct Vnode *vnode, const void *data);
int (*Unmount)(struct Mount *mount, struct Vnode **blkdriver);
int (*Statfs)(struct Mount *mount, struct statfs *sbp);//統計文件系統的信息,類型、大小等
int (*Sync)(struct Mount *mount);
};

(3)文件結構定義:
struct file
{
unsigned int f_magicnum; /* file magic number. -- to be deleted */
int f_oflags; /* Open mode flags */
struct Vnode *f_vnode; /* Driver interface */
loff_t f_pos; /* File position */
unsigned long f_refcount; /* reference count */
char *f_path; /* File fullpath */
void *f_priv; /* Per file driver private data */
const char *f_relpath; /* realpath. -- to be deleted */
struct page_mapping *f_mapping; /* mapping file to memory */
void *f_dir; /* DIR struct for iterate the directory if open a directory */
const struct file_operations_vfs *ops;
int fd;
};

文件接口功能定義:
struct file_operations_vfs
{
/* The device driver open method differs from the mountpoint open method */


int (*open)(struct file *filep);
int (*close)(struct file *filep);
ssize_t (*read)(struct file *filep, char *buffer, size_t buflen);
ssize_t (*write)(struct file *filep, const char *buffer, size_t buflen);
off_t (*seek)(struct file *filep, off_t offset, int whence);
int (*ioctl)(struct file *filep, int cmd, unsigned long arg);
int (*mmap)(struct file* filep, struct VmMapRegion *region);
/* The two structures need not be common after this point */


int (*poll)(struct file *filep, poll_table *fds);
int (*stat)(struct file *filep, struct stat* st);
int (*fallocate)(struct file* filep, int mode, off_t offset, off_t len);
int (*fallocate64)(struct file *filep, int mode, off64_t offset, off64_t len);
int (*fsync)(struct file *filep);
ssize_t (*readpage)(struct file *filep, char *buffer, size_t buflen);
int (*unlink)(struct Vnode *vnode);
};

2.文件系統的重要接口設計
procfs文件系統中每個目錄或文件都是一個Vnode,也可以理解為一個entry。ProcDirEntry中的subdir指向的目錄中的一個子項,其本質是一個單向鏈表的形式,并且采用頭插法的形式進行節點的插入。
圖5:DirEntry

圖6:ProcFile

圖7:ProcData

圖8: ProcFileOperations

三、 procfs文件系統的實現

1.Procfs的注冊過程
(1)向系統注冊文件系統入口函數:
LOS_MODULE_INIT(ProcFsInit, LOS_INIT_LEVEL_KMOD_EXTENDED);

(2)向VFS文件系統表注冊系統名以及實現的接口等:
const struct MountOps procfs_operations = {
.Mount = VfsProcfsMount,
.Unmount = NULL,
.Statfs = VfsProcfsStatfs,
};


static struct VnodeOps g_procfsVops = {
.Lookup = VfsProcfsLookup,
.Getattr = VfsProcfsStat,
.Readdir = VfsProcfsReaddir,
.Opendir = VfsProcfsOpendir,
.Closedir = VfsProcfsClosedir,
.Truncate = VfsProcfsTruncate
};


static struct file_operations_vfs g_procfsFops = {
.read = VfsProcfsRead,
.write = VfsProcfsWrite,
.open = VfsProcfsOpen,
.close = VfsProcfsClose
};


// 注冊文件系統名字以及實現的接口方法等
FSMAP_ENTRY(procfs_fsmap,"procfs",procfs_operations,FALSE,FALSE);

2.Procfs的初始化
初始化需要做的工作主要包括向OS注冊procfs文件系統,生成procfs文件目錄中的文件初始項,在liteOS-A具體包含目錄power、mounts等。
procfs文件系統的初始化流程大致如下:
// 系統的入口函數
main(VOID)
|-> OsMain() // ./liteos/kernel/liteos_a/kernel/common/main.c
| // 進行系統的相關初始化工作
| -> EarliestInit()
| -> ...
|
| -> KModInit()
|-> ...
|
|-> OsInitCall(LOS_INIT_LEVEL_KMOD_EXTENDED) // 生成procfs文件系統并掛載到/proc目錄
|-> InitLevelCall(level)//根據不同的級別進行相關初始化工作,procfs的級別是8,其級別是文件系統向OS注冊的
| // ./liteos/kernel/liteos_a/fs/proc/os_adapt/proc_init.c
|
|-> ProcFsInit() // 進行procfs文件系統的具體初始化工作
| |-> mkdir(PROCFS_MOUNT_POINT, PROCFS_DEFAULT_MODE) // 先生成/proc目錄,之后需要將procfs文件系統掛載到該目錄下
| |-> mount(NULL, PROCFS_MOUNT_POINT, "procfs", 0, NULL)
| | // 生成mount文件,包括分配Vnode和掛載Vnode
| |
| |-> ProcMountsInit()
| | | // procfs具體項的初始化都寫在一個獨立的文件中,例如mounts在./liteos/kernel/liteos_a/fs/proc/os_adapt/mounts_proc.c
| | |
| | |-> ProcMountsInit(void)
| | | // 創建mounts節點并掛載到該目錄下,NULL位parent為父節點,若parent為NULL,則默認父節點為/proc
| | |
| | |-> CreateProcEntry("mounts", 0, NULL)
| | | // 先判斷節點是文件屬性還是目錄屬性,后選擇具體的節點創建函數,在這選擇File節點
| | |
| | |-> ProcCreateFile(parent, name, NULL, mode)
| | |-> struct ProcDirEntry *pn = NULL
| | |-> ProcAllocNode(&parent, name, S_IFREG | mode) // 具體的分配節點
| | |-> struct ProcDirEntry *pn = NULL;
| | | // 首先對節點的合法性進行相關檢查,例如parent是否NULL,name是否NULL等
| | |
| | |-> pn = (struct ProcDirEntry *)malloc(sizeof(struct ProcDirEntry));//分配一個struct ProcDirEntry內存地址
| | | // 對生成的節點賦予一些屬性,例如節點名字長度,權限,名字等,每個ProcDirEntry都需要指定一個ProcFile成員,里面含有具體信息
| | |
| | |-> pn->nameLen = strlen(lastName);
| | |-> pn->mode = mode;
| | |-> ret = memcpy_s(pn->name, sizeof(pn->name), lastName, strlen(lastName) + 1);
| | |-> pn->pf = (struct ProcFile *)malloc(sizeof(struct ProcFile));
| | |-> pn->pf->pPDE = pn;// ProcFile的parent是生成的pn節點
| | | // 生成對應的節點,對節點指定相應的函數接口后,需要掛載的父節點中
| | |
| | |-> ProcAddNode(parent, pn)
| | | // 先判斷parent是否為NULL以及pn是否已經有parent,即判斷是否已掛載
| | |
| | | // 在這里可知一個目錄下的子目錄以及文件都是以一個單鏈表的形式存儲的,且采用的是頭插法,即最先生成的在最后面
| | |-> pn->parent = parent;
| | |-> pn->next = parent->subdir;
| | |-> parent->subdir = pn;
| |->...
| |
| |->ProcPmInit() // 目錄初始化工作
| | | // power目錄下含有子目錄,但是目錄生成的過程都一樣,在這以power文件夾為例
| | |-> struct ProcDirEntry *power = CreateProcEntry("power", S_IFDIR | S_IRWXU | S_IRWXG | S_IROTH, NULL);
| | | |-> CreateProcEntry("power", S_IFDIR | S_IRWXU | S_IRWXG | S_IROTH, NULL)
| | | | |-> // 先判斷節點是文件屬性還是目錄屬性,后選擇具體的節點創建函數,在這選擇目錄節點
| | | | |
| | | | |-> ProcCreateDir(parent, name, NULL, mode)
| | | | | | // 這里節點創建和掛載和上述文件節點創建一樣,不再贅述
| | | | | |
| | | | | |-> ProcAllocNode(&parent, name, S_IFREG | mode) // 具體的分配節點
| | | | | |-> ProcAddNode(parent, pn)
| | | | |
| | | |
| | |-> ...
| |
|...

四、procfs業務分析

1.procfs掛載過程分析
在procfs文件系統的掛載過程中,若使用qemu進行調試,則掛載的命令大致如下: mount -R -t procfs [Dir_Path]
mount的系統調用間接調用procfs的mount接口。
用戶輸入掛載命令后,引發系統調用SysMount開始逐層調用:
-> ... 
-> SysMount(const char *source, const char *target, const char *filesystemtype, unsigned long mountflags,const void *data)
|--|-> 將路徑,文件系統等轉化之后調用mount
| |-> mount(sourceRet, targetRet, (filesystemtype ? fstypeRet : NULL), mountflags, dataRet)
| | |-> //找到指定的文件系統
| | |-> fsmap = mount_findfs(filesystemtype)
| | |-> mops = fsmap->fs_mops // 為mount節點指定mount的接口函數
| | |-> //找到掛載目錄對應的Vnode并且設置文件系統相關信息
| | |-> VnodeLookup(target, &mountpt_vnode, 0)
| | | |->VnodeLookupAt(path, vnode, flags, NULL)
| | | | |-> //對目錄變成絕對路徑并且從全局Vnode鏈表中開始找
| | | | |-> PreProcess(path, &startVnode, &normalizedPath)
| | | | | |-> vfs_normalize_path(NULL, originPath, &absolutePath)
| | |-> mnt = MountAlloc(mountpt_vnode, (struct MountOps*)mops)
| | |-> mops->Mount(mnt, device, data)//進入具體的procfs文件系統的mount函數
| | | |-> VfsProcfsMount(struct Mount *mnt, struct Vnode *device, const void *data)
| | | | |-> VnodeAlloc(&g_procfsVops, &vp);//生成一個Vnode用于掛載mount節點和procfs文件系統的root節點
| | | | |-> root = GetProcRootEntry(); //獲取procfs文件系統的根節點
| | | | |-> vp->data = root; //
| | | | |-> vp->originMount = mnt;// 將vp掛載在掛載目錄所對應的mount節點上
| | | | |-> mnt->data = NULL;
| | | | |-> mnt->vnodeCovered = vp;// mount節點掛載的Vnode是該文件系統,方便后續在mount鏈表中找掛載點
| | | | |-> vp->type = root->type;
|||...

2.節點的增加過程分析
關鍵代碼如下:
   temp = ProcFindNode(parent, pn->name);
if (temp != NULL) {
PRINT_ERR("Error!ProcDirEntry '%s/%s' already registered ", parent->name, pn->name);
spin_unlock(&procfsLock);
return -EEXIST;
}
pn->parent = parent;
pn->next = parent->subdir;
parent->subdir=pn;
為了更好地說明,假設目前已經在系統中生成了proc/和mounts節點,proc/節點就是該文件系統的根節點,此時兩者的關系可以用下圖表示:

圖9:層級目錄的關系

此時若需要在兩者在插入一個power節點,則首先需要先生成一個power節點如下,再改變相應的指向即可,具體可以參考圖10,給出三者之間的關系,最終的節點效果如圖11。
圖10:生成一個新節點

圖11:重新組合

3、writeproc shell命令的創建
liteOS-A中含有一個叫writeproc的shell命令,使用格式如下:
writeproc value >> path

shell命令的創建方式主要有兩種,分靜態注冊和動態注冊,writeproc命令使用靜態注冊方式進行注冊,在本文中也主要介紹靜態注冊。
shell開發的流程如下:
①定義一個新增命令所要調用的執行函數xxx;
② 使用SHELLCMD_ENTRY函數添加新增命令項;
③ 在鏈接選項liteos_tables_ldflags.mk中添加鏈接該新增命令項參數;
④ 重新編譯代碼后運行。
writeproc的注冊如下:
// 定義一個具體的執行函數 
int OsShellCmdWriteProc(int argc, char **argv);
// 新增命令項
SHELLCMD_ENTRY(writeproc_shellcmd,CMD_TYPE_EX,"writeproc",XARGS,(CmdCallBackFunc)OsShellCmdWriteProc);
writeproc的具體流程分析:
①首先由用戶按照命令格式進行輸入;
②OsShellCmdWriteProc函數對輸入的命令進行分析,并采取相關的動作。
-> ... 
-> // 使用shell命令喚起writeproc注冊函數
-> writeproc value >> path
|-> // 進行初始化工作,主要用于判斷輸入路徑是否合法,節點是否存在
|-> struct ProcDirEntry *handle = NULL;
|-> const char *rootProcDir = "/proc/";
|-> handle = OpenProcFile(realPath, O_TRUNC) // 若路徑合法則找到對應的Vnode
| |-> pn = ProcFindEntry(fileName)
| | |-> int leveltotal = 0;// leveltotal用于判定文件所對應的層級,一個/表示一層
| | | // 遍歷Vnode找到對應的Vnode并返回
| |-> pn->flags = (unsigned int)(pn->flags) | (unsigned int)flags// 設置節點相應的權限
| |-> ...
| WriteProcFile(handle, value, len) // 找到文件句柄之后開始寫入數據
| | // 使用Vnode的文件接口對ProcFile數據成員進行寫入
| |-> result = pde->procFileOps->write(pde->pf, (const char *)buf, len, &(pde->pf->fPos))
|...
根據文件名查找Vnode的關鍵代碼:
pn = &g_procRootDirEntry; 
while ((pn != NULL) && (levelcount < leveltotal)) {
levelcount++;
isfoundsub = 0;
while (pn != NULL) {
next = strchr(path, '/');
if (next == NULL) {
while (pn != NULL) {
if (strcmp(path, pn->name) == 0) {
spin_unlock(&procfsLock);
return pn;
}
pn = pn->next;
}
pn = NULL;
spin_unlock(&procfsLock);
return pn;
}

len = next - path;
if (pn == &g_procRootDirEntry) {
if (levelcount == leveltotal) {
spin_unlock(&procfsLock);
return pn;
}
len = g_procRootDirEntry.nameLen;
}
if (ProcMatch(len, path, pn)) {
isfoundsub = 1;
path += len + 1;
break;
}

pn = pn->next;
}
}

五、總結

本文介紹了LiteOS-A內核下proc相關目錄信息,并且對LiteOS-A內核中procfs文件系統的原理和實現,結合源碼進行了分析。同時,通過writeproc shell命令介紹了procfs的使用。希望讀者可以掌握LiteOS-A文件系統的基本知識,更好地運用于基于LiteOS-A內核的系統移植工作。
關于OpenHarmony內核的內容,之前我還介紹了LiteOS-A內核之基礎硬件——中斷控制器、GIC400內核對象隊列的算法、OpenHarmony LiteOS-M內核事件的運作機制,以及內核IPC機制數據結構、OpenHarmony Liteos-A內核之iperf3移植方法,感興趣的讀者可以點擊閱讀:《淺談OpenHarmony LiteOS-A內核之基礎硬件——中斷控制器GIC400》、《OpenHarmony——內核對象隊列之算法詳解(上)》、《OpenHarmony——內核對象隊列之算法詳解(下)》、《OpenHarmony——內核對象事件之源碼詳解》、《OpenHarmony——內核IPC機制數據結構解析》、《OpenHarmony Liteos_A內核之iperf3移植心得》。


原文標題:LiteOS-A內核中的procfs文件系統分析

文章出處:【微信公眾號:OpenAtom OpenHarmony】歡迎添加關注!文章轉載請注明出處。

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 鴻蒙
    +關注

    關注

    57

    文章

    2339

    瀏覽量

    42811
  • OpenHarmony
    +關注

    關注

    25

    文章

    3713

    瀏覽量

    16256

原文標題:LiteOS-A內核中的procfs文件系統分析

文章出處:【微信號:gh_e4f28cfa3159,微信公眾號:OpenAtom OpenHarmony】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    Jtti:Linux虛擬文件系統和容器化的關系

    在Linux,虛擬文件系統(VFS)和容器化技術之間有密切的關系。容器化是指通過使用容器來運行應用程序,而容器本質上是在宿主機上運行的獨立進程,它們通常共享宿主機的操作系統內核和部分
    的頭像 發表于 11-27 15:38 ?143次閱讀

    一文讀懂MSA(測量系統分析)

    一文讀懂MSA(測量系統分析)
    的頭像 發表于 11-01 11:08 ?867次閱讀
    一文讀懂MSA(測量<b class='flag-5'>系統分析</b>)

    測量系統分析

    電子發燒友網站提供《測量系統分析.doc》資料免費下載
    發表于 10-10 11:46 ?0次下載

    電路原理 電力系統分析電力電子電磁學

    電路原理 模電數電電力電子電磁學 PLC電力系統 電力系統分析
    發表于 10-07 16:21

    Linux根文件系統的掛載過程

    Linux根文件系統(rootfs)是Linux系統中所有其他文件系統和目錄的起點,它是內核啟動時掛載的第一個文件系統。
    的頭像 發表于 10-05 16:50 ?405次閱讀

    時鐘噪聲對DAC性能影響系統分析

    電子發燒友網站提供《時鐘噪聲對DAC性能影響系統分析.pdf》資料免費下載
    發表于 09-26 09:14 ?0次下載
    時鐘噪聲對DAC性能影響<b class='flag-5'>系統分析</b>

    想提高開發效率,不要忘記文件系統

    ?同學們都知道,開發過程中文件系統的重要性,同樣的,4G-Cat.1模組的文件系統也非常重要,它通常與數據傳輸速度、存儲效率,以及數據安全性等有非常重要的關系,在應用開發也非常重要。
    的頭像 發表于 09-21 08:18 ?232次閱讀
    想提高開發效率,不要忘記<b class='flag-5'>文件系統</b>

    如何修改buildroot和debian文件系統

    本文檔主要介紹在沒有編譯環境的情況下,如何修改buildroot和debian文件系統方法,如在buildroot文件系統添加文件、修改目錄等文件
    的頭像 發表于 07-22 17:46 ?458次閱讀
    如何修改buildroot和debian<b class='flag-5'>文件系統</b>

    linux--sysfs文件系統

    sysfs文件系統 sysfs,全稱為System Filesystem,是一個由Linux內核實現的虛擬文件系統。它扮演著一個橋梁的角色,將內核
    的頭像 發表于 07-08 11:37 ?844次閱讀
    linux--sysfs<b class='flag-5'>文件系統</b>

    服務器數據恢復—CX4-480存儲XFS文件系統分區丟失的數據恢復案例

    重裝操作系統后,未知原因導致服務器操作系統層面的磁盤分區改變,一個XFS文件系統分區丟失,無法訪問,該分區存放大量重要業務信息。
    的頭像 發表于 06-03 14:51 ?318次閱讀
    服務器數據恢復—CX4-480存儲<b class='flag-5'>中</b>XFS<b class='flag-5'>文件系統分</b>區丟失的數據恢復案例

    【鴻蒙】小型系統LiteOS-A內核

    對該芯片架構的支持,這個工作較為復雜,不在這篇文章范圍內。 基礎適配 LiteOS-A 提供系統運行所需的系統初始化流程和定制化配置選項。移植過程,需要關注初始化流程中跟硬件配置相關
    的頭像 發表于 02-29 16:16 ?1169次閱讀
    【鴻蒙】小型<b class='flag-5'>系統</b><b class='flag-5'>LiteOS-A</b><b class='flag-5'>內核</b>

    淺談現場總線的智能照明系統分析與應用研究

    淺談現場總線的智能照明系統分析與應用研究 張穎姣 安科瑞電氣股份有限公司 上海嘉定 201801 【摘要】:科學技術的發展使得照明控制的方法不斷發生改變,近年來照明控制系統大多在現場總線的基礎上實現
    的頭像 發表于 02-26 09:29 ?515次閱讀
    淺談現場總線的智能照明<b class='flag-5'>系統分析</b>與應用研究

    Linux系統如何擴展文件系統

    當數據盤沒有創建分區,只在設備上創建了文件系統?;蛘吒袷交擞脖P,就直接mount上系統使用。
    的頭像 發表于 02-21 09:53 ?834次閱讀

    鴻蒙輕內核源碼分析:虛擬文件系統 VFS

    接口不統一,若系統中有多個文件系統類型,訪問不同的文件系統就需要使用不同的非標準接口。而通過在系統添加 VFS 層,提供統一的抽象接口,屏
    的頭像 發表于 02-18 14:50 ?806次閱讀

    單端口網絡S參數測量系統分析

    單端口網絡S參數測量系統分析
    的頭像 發表于 01-05 09:22 ?672次閱讀
    單端口網絡S參數測量<b class='flag-5'>系統分析</b>
    主站蜘蛛池模板: 野花韩国中文版免费观看| 俄罗斯美女啪啪| 交换娇妻呻吟声不停中文字幕| 欧美黄色第一页| 曰产无码久久久久久精品| 国产精品人妻99一区二| 欧美精品XXXXBBBB| 诱受H嗯啊巨肉各种play| 国产人A片在线乱码视频| 日本高清免费一本在线观看| 13一18TV处流血TV| 黑人巨摘花破女处| 午夜久久影院| 大胆国模一区二区三区伊人 | 久久精品国产亚洲AV忘忧草蜜臀| 三级黄色在线视频| H厨房灌草莓| 两性午夜色视频免费网站| 亚洲一级毛片免费在线观看| 国产精品免费大片| 色偷偷男人天堂| xxxxhd17欧美老师| 男人免费网站| 1313久久国产午夜精品理论片| 精品亚洲大全| 亚洲乱妇88网| 国产亚洲精品精华液| 偷拍亚洲色自拍| 国产99RE在线观看69热| 日本漂亮妈妈7观整有限中| 99热这里只有是精品| 免费看黄色小说| 18日本人XXXXXX18| 快播可乐网| 中文字幕一区二区三区在线观看| 精品无码日本蜜桃麻豆| 亚洲精品理论电影在线观看| 国产无遮挡无码视频在线观看不卡 | 蜜芽在线播放免费人成日韩视频| 伊人久久大香线蕉综合网站| 娇小亚裔被两个黑人|