From 18ea5d1857eb86dbdeb0e5e4224839ac3efcb7f8 Mon Sep 17 00:00:00 2001 From: kuangyufei Date: Tue, 22 Dec 2020 16:23:47 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=87=E4=BB=B6=E6=98=AF=E5=A6=82=E4=BD=95?= =?UTF-8?q?=E6=98=A0=E5=B0=84=E5=88=B0=E5=86=85=E5=AD=98=E7=9A=84=EF=BC=9F?= =?UTF-8?q?=E7=90=86=E8=A7=A3=E9=A1=B5=E9=AB=98=E9=80=9F=E7=BC=93=E5=AD=98?= =?UTF-8?q?(page=20cache)=E6=98=AF=E5=85=B3=E9=94=AE=20=E6=90=9C=E7=B4=A2?= =?UTF-8?q?=20@note=5Fpic=20=E5=8F=AF=E4=BB=A5=E6=9F=A5=E7=9C=8B=E5=85=A8?= =?UTF-8?q?=E9=83=A8=E5=AD=97=E7=AC=A6=E5=9B=BE=20=E6=90=9C=E7=B4=A2=20@no?= =?UTF-8?q?te=5Fwhy=20=E6=98=AF=E6=B3=A8=E8=80=85=E5=B0=9A=E6=9C=AA?= =?UTF-8?q?=E7=9C=8B=E6=98=8E=E7=99=BD=E7=9A=84=E5=9C=B0=E6=96=B9=EF=BC=8C?= =?UTF-8?q?=E5=A6=82=E6=9E=9C=E6=82=A8=E7=9C=8B=E6=98=8E=E7=99=BD=E4=BA=86?= =?UTF-8?q?=EF=BC=8C=E8=AF=B7=E5=91=8A=E8=AF=89=E6=B3=A8=E8=80=85=E5=AE=8C?= =?UTF-8?q?=E5=96=84=20=E6=90=9C=E7=B4=A2=20@note=5Fthinking=20=E6=98=AF?= =?UTF-8?q?=E6=B3=A8=E8=80=85=E7=9A=84=E6=80=9D=E8=80=83=E5=92=8C=E5=90=90?= =?UTF-8?q?=E6=A7=BD=E7=9A=84=E5=9C=B0=E6=96=B9=20=E6=90=9C=E7=B4=A2=20@no?= =?UTF-8?q?te=5F#if0=20=E6=98=AF=E7=94=B1=E7=AC=AC=E4=B8=89=E6=96=B9?= =?UTF-8?q?=E9=A1=B9=E7=9B=AE=E6=8F=90=E4=BE=9B=E4=B8=8D=E7=94=B1=E5=86=85?= =?UTF-8?q?=E6=A0=B8=E6=BA=90=E7=A0=81=E4=B8=AD=E5=AE=9A=E4=B9=89=E7=9A=84?= =?UTF-8?q?=E6=9E=81=E4=B8=BA=E9=87=8D=E8=A6=81=E7=9A=84=E7=BB=93=E6=9E=84?= =?UTF-8?q?=E4=BD=93=EF=BC=8C=E4=B8=BA=E6=96=B9=E4=BE=BF=E7=90=86=E8=A7=A3?= =?UTF-8?q?=E8=80=8C=E6=B7=BB=E5=8A=A0=E7=9A=84=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 6 +- fs/vfs/operation/fs_file_mapping.c | 91 ++++++++++-------- fs/vfs/operation/fs_init.c | 2 +- kernel/base/include/los_vm_filemap.h | 35 +++++++ kernel/base/include/los_vm_map.h | 6 +- kernel/base/include/los_vm_phys.h | 2 +- kernel/base/vm/los_vm_filemap.c | 43 +++++---- kernel/base/vm/los_vm_map.c | 6 +- kernel/base/vm/los_vm_phys.c | 2 +- kernel/base/vm/los_vm_scan.c | 16 +-- zzz/doc/note_ipc.h | 3 +- zzz/git/push.sh | 3 +- ...5\347\272\247\347\273\210\347\253\257.png" | Bin zzz/pic/{ => ppt}/10.HPM.png | Bin zzz/pic/{ => ppt}/11.POSIX.png | Bin .../pic/ppt/12.\345\244\232\346\240\270.png" | Bin ....\345\244\232\350\277\233\347\250\213.png" | Bin ...3\347\250\213\351\200\232\344\277\241.png" | Bin ...0\346\200\201\351\223\276\346\216\245.png" | Bin ...0\347\275\262\347\255\226\347\225\245.png" | Bin ...0\345\217\221\346\214\221\346\210\230.png" | Bin ...1\345\261\225\350\266\213\345\212\277.png" | Bin ...0\344\270\216\344\272\244\346\265\201.png" | Bin ...6\346\236\204\347\256\200\344\273\213.png" | Bin ...0\346\215\256\347\256\241\347\220\206.png" | Bin ...2\347\241\200\345\271\263\345\217\260.png" | Bin ...0\350\265\240\345\255\265\345\214\226.png" | Bin ...1\346\241\210\347\216\260\347\212\266.png" | Bin ...0\345\217\221\346\255\245\351\252\244.png" | Bin ...3\351\252\214\345\217\230\345\214\226.png" | Bin ...6\350\256\241\347\233\256\346\240\207.png" | Bin ...6\346\236\204\346\200\273\344\275\223.png" | Bin ...6\350\256\241\347\233\256\346\240\207.png" | Bin ...7\344\273\266\346\214\221\346\210\230.png" | Bin ...3\351\231\220\347\256\241\347\220\206.png" | Bin ...3\345\274\217\350\260\203\347\224\250.png" | Bin ...1\347\220\206\344\270\255\345\277\203.png" | Bin ...45\244\207\345\274\200\345\217\221IDE.png" | Bin ...0\345\217\221\345\267\245\345\205\267.png" | Bin ...1\350\200\205\345\256\230\347\275\221.png" | Bin ...1\350\200\205\345\271\263\345\217\260.png" | Bin ....\346\221\204\345\203\217\345\244\264.png" | Bin ...6\345\275\225\347\273\223\346\236\204.png" | Bin ...7\344\273\266\347\263\273\347\273\237.png" | Bin ...3\347\273\237\350\260\203\347\224\250.png" | Bin ...2\346\213\237\345\206\205\345\255\230.png" | Bin ...7\350\275\257\346\200\273\347\272\277.png" | Bin ...3\347\273\237\351\203\250\347\275\262.png" | Bin ...6\350\231\232\346\213\237\345\214\226.png" | Bin .../pic/ppt/42\347\244\272\344\276\213.png" | Bin .../pic/ppt/43.\347\244\272\344\276\2132.png" | Bin ...0\346\215\256\347\256\241\347\220\206.png" | Bin ...6\350\231\232\346\213\237\345\214\226.png" | Bin ...3\345\217\260\346\241\206\346\236\266.png" | Bin ...4\347\224\250\346\241\206\346\236\266.png" | Bin ...4\344\270\255\344\275\215\347\275\256.png" | Bin zzz/pic/{ => turing}/elf info.jpg | Bin ...e\345\205\263\347\263\273\345\233\276.png" | Bin 0 -> 31913 bytes 58 files changed, 135 insertions(+), 80 deletions(-) rename "zzz/pic/1.\350\266\205\347\272\247\347\273\210\347\253\257.png" => "zzz/pic/ppt/1.\350\266\205\347\272\247\347\273\210\347\253\257.png" (100%) rename zzz/pic/{ => ppt}/10.HPM.png (100%) rename zzz/pic/{ => ppt}/11.POSIX.png (100%) rename "zzz/pic/12.\345\244\232\346\240\270.png" => "zzz/pic/ppt/12.\345\244\232\346\240\270.png" (100%) rename "zzz/pic/13.\345\244\232\350\277\233\347\250\213.png" => "zzz/pic/ppt/13.\345\244\232\350\277\233\347\250\213.png" (100%) rename "zzz/pic/14.\350\277\233\347\250\213\351\200\232\344\277\241.png" => "zzz/pic/ppt/14.\350\277\233\347\250\213\351\200\232\344\277\241.png" (100%) rename "zzz/pic/15.\345\212\250\346\200\201\351\223\276\346\216\245.png" => "zzz/pic/ppt/15.\345\212\250\346\200\201\351\223\276\346\216\245.png" (100%) rename "zzz/pic/16.\345\274\271\346\200\247\351\203\250\347\275\262\347\255\226\347\225\245.png" => "zzz/pic/ppt/16.\345\274\271\346\200\247\351\203\250\347\275\262\347\255\226\347\225\245.png" (100%) rename "zzz/pic/17.\345\244\232\350\256\276\345\244\207\345\272\224\347\224\250\345\274\200\345\217\221\346\214\221\346\210\230.png" => "zzz/pic/ppt/17.\345\244\232\350\256\276\345\244\207\345\272\224\347\224\250\345\274\200\345\217\221\346\214\221\346\210\230.png" (100%) rename "zzz/pic/18.\345\217\221\345\261\225\350\266\213\345\212\277.png" => "zzz/pic/ppt/18.\345\217\221\345\261\225\350\266\213\345\212\277.png" (100%) rename "zzz/pic/19.\345\217\215\351\246\210\344\270\216\344\272\244\346\265\201.png" => "zzz/pic/ppt/19.\345\217\215\351\246\210\344\270\216\344\272\244\346\265\201.png" (100%) rename "zzz/pic/2.HarmonyOs\346\236\266\346\236\204\347\256\200\344\273\213.png" => "zzz/pic/ppt/2.HarmonyOs\346\236\266\346\236\204\347\256\200\344\273\213.png" (100%) rename "zzz/pic/20.\345\210\206\345\270\203\345\274\217\346\225\260\346\215\256\347\256\241\347\220\206.png" => "zzz/pic/ppt/20.\345\210\206\345\270\203\345\274\217\346\225\260\346\215\256\347\256\241\347\220\206.png" (100%) rename "zzz/pic/21.\345\205\261\345\273\272\345\237\272\347\241\200\345\271\263\345\217\260.png" => "zzz/pic/ppt/21.\345\205\261\345\273\272\345\237\272\347\241\200\345\271\263\345\217\260.png" (100%) rename "zzz/pic/22.\346\215\220\350\265\240\345\255\265\345\214\226.png" => "zzz/pic/ppt/22.\346\215\220\350\265\240\345\255\265\345\214\226.png" (100%) rename "zzz/pic/22.\350\247\243\345\206\263\346\226\271\346\241\210\347\216\260\347\212\266.png" => "zzz/pic/ppt/22.\350\247\243\345\206\263\346\226\271\346\241\210\347\216\260\347\212\266.png" (100%) rename "zzz/pic/23.\345\274\200\345\217\221\346\255\245\351\252\244.png" => "zzz/pic/ppt/23.\345\274\200\345\217\221\346\255\245\351\252\244.png" (100%) rename "zzz/pic/24\345\274\200\345\217\221\350\200\205\344\275\223\351\252\214\345\217\230\345\214\226.png" => "zzz/pic/ppt/24\345\274\200\345\217\221\350\200\205\344\275\223\351\252\214\345\217\230\345\214\226.png" (100%) rename "zzz/pic/25.\345\206\205\346\240\270\350\256\276\350\256\241\347\233\256\346\240\207.png" => "zzz/pic/ppt/25.\345\206\205\346\240\270\350\256\276\350\256\241\347\233\256\346\240\207.png" (100%) rename "zzz/pic/26.\351\251\261\345\212\250\345\271\263\345\217\260\346\236\266\346\236\204\346\200\273\344\275\223.png" => "zzz/pic/ppt/26.\351\251\261\345\212\250\345\271\263\345\217\260\346\236\266\346\236\204\346\200\273\344\275\223.png" (100%) rename "zzz/pic/27.\351\251\261\345\212\250\350\275\257\344\273\266\350\256\276\350\256\241\347\233\256\346\240\207.png" => "zzz/pic/ppt/27.\351\251\261\345\212\250\350\275\257\344\273\266\350\256\276\350\256\241\347\233\256\346\240\207.png" (100%) rename "zzz/pic/28.\351\251\261\345\212\250\350\275\257\344\273\266\346\214\221\346\210\230.png" => "zzz/pic/ppt/28.\351\251\261\345\212\250\350\275\257\344\273\266\346\214\221\346\210\230.png" (100%) rename "zzz/pic/29.\346\235\203\351\231\220\347\256\241\347\220\206.png" => "zzz/pic/ppt/29.\346\235\203\351\231\220\347\256\241\347\220\206.png" (100%) rename "zzz/pic/3.\345\210\206\345\270\203\345\274\217\350\260\203\347\224\250.png" => "zzz/pic/ppt/3.\345\210\206\345\270\203\345\274\217\350\260\203\347\224\250.png" (100%) rename "zzz/pic/30.\350\256\276\345\244\207\347\256\241\347\220\206\344\270\255\345\277\203.png" => "zzz/pic/ppt/30.\350\256\276\345\244\207\347\256\241\347\220\206\344\270\255\345\277\203.png" (100%) rename "zzz/pic/31.\350\256\276\345\244\207\345\274\200\345\217\221IDE.png" => "zzz/pic/ppt/31.\350\256\276\345\244\207\345\274\200\345\217\221IDE.png" (100%) rename "zzz/pic/32.\350\256\276\345\244\207\345\274\200\345\217\221\345\267\245\345\205\267.png" => "zzz/pic/ppt/32.\350\256\276\345\244\207\345\274\200\345\217\221\345\267\245\345\205\267.png" (100%) rename "zzz/pic/33.\350\256\276\345\244\207\345\274\200\345\217\221\350\200\205\345\256\230\347\275\221.png" => "zzz/pic/ppt/33.\350\256\276\345\244\207\345\274\200\345\217\221\350\200\205\345\256\230\347\275\221.png" (100%) rename "zzz/pic/34\350\256\276\345\244\207\345\274\200\345\217\221\350\200\205\345\271\263\345\217\260.png" => "zzz/pic/ppt/34\350\256\276\345\244\207\345\274\200\345\217\221\350\200\205\345\271\263\345\217\260.png" (100%) rename "zzz/pic/35.\346\221\204\345\203\217\345\244\264.png" => "zzz/pic/ppt/35.\346\221\204\345\203\217\345\244\264.png" (100%) rename "zzz/pic/36.\347\273\237\344\270\200\351\251\261\345\212\250\345\271\263\345\217\260\347\233\256\345\275\225\347\273\223\346\236\204.png" => "zzz/pic/ppt/36.\347\273\237\344\270\200\351\251\261\345\212\250\345\271\263\345\217\260\347\233\256\345\275\225\347\273\223\346\236\204.png" (100%) rename "zzz/pic/37.\346\226\207\344\273\266\347\263\273\347\273\237.png" => "zzz/pic/ppt/37.\346\226\207\344\273\266\347\263\273\347\273\237.png" (100%) rename "zzz/pic/38.\347\263\273\347\273\237\350\260\203\347\224\250.png" => "zzz/pic/ppt/38.\347\263\273\347\273\237\350\260\203\347\224\250.png" (100%) rename "zzz/pic/39.\350\231\232\346\213\237\345\206\205\345\255\230.png" => "zzz/pic/ppt/39.\350\231\232\346\213\237\345\206\205\345\255\230.png" (100%) rename "zzz/pic/4.\345\210\206\345\270\203\345\274\217\350\275\257\346\200\273\347\272\277.png" => "zzz/pic/ppt/4.\345\210\206\345\270\203\345\274\217\350\275\257\346\200\273\347\272\277.png" (100%) rename "zzz/pic/40.\344\270\200\346\254\241\345\274\200\345\217\221\345\244\232\347\263\273\347\273\237\351\203\250\347\275\262.png" => "zzz/pic/ppt/40.\344\270\200\346\254\241\345\274\200\345\217\221\345\244\232\347\263\273\347\273\237\351\203\250\347\275\262.png" (100%) rename "zzz/pic/41.\347\241\254\344\273\266\350\231\232\346\213\237\345\214\226.png" => "zzz/pic/ppt/41.\347\241\254\344\273\266\350\231\232\346\213\237\345\214\226.png" (100%) rename "zzz/pic/42\347\244\272\344\276\213.png" => "zzz/pic/ppt/42\347\244\272\344\276\213.png" (100%) rename "zzz/pic/43.\347\244\272\344\276\2132.png" => "zzz/pic/ppt/43.\347\244\272\344\276\2132.png" (100%) rename "zzz/pic/5.\345\210\206\345\270\203\345\274\217\346\225\260\346\215\256\347\256\241\347\220\206.png" => "zzz/pic/ppt/5.\345\210\206\345\270\203\345\274\217\346\225\260\346\215\256\347\256\241\347\220\206.png" (100%) rename "zzz/pic/6.\347\241\254\344\273\266\350\231\232\346\213\237\345\214\226.png" => "zzz/pic/ppt/6.\347\241\254\344\273\266\350\231\232\346\213\237\345\214\226.png" (100%) rename "zzz/pic/7.\345\275\222\344\270\200\345\214\226\347\232\204\351\251\261\345\212\250\345\271\263\345\217\260\346\241\206\346\236\266.png" => "zzz/pic/ppt/7.\345\275\222\344\270\200\345\214\226\347\232\204\351\251\261\345\212\250\345\271\263\345\217\260\346\241\206\346\236\266.png" (100%) rename "zzz/pic/8.IOT\345\234\272\346\231\257\346\236\201\350\275\273\351\207\217\345\272\224\347\224\250\346\241\206\346\236\266.png" => "zzz/pic/ppt/8.IOT\345\234\272\346\231\257\346\236\201\350\275\273\351\207\217\345\272\224\347\224\250\346\241\206\346\236\266.png" (100%) rename "zzz/pic/9.HarmonyOS\346\236\266\346\236\204\344\270\255\344\275\215\347\275\256.png" => "zzz/pic/ppt/9.HarmonyOS\346\236\266\346\236\204\344\270\255\344\275\215\347\275\256.png" (100%) rename zzz/pic/{ => turing}/elf info.jpg (100%) create mode 100644 "zzz/pic/turing/\350\277\233\347\250\213FD_\347\263\273\347\273\237FD_inode\345\205\263\347\263\273\345\233\276.png" diff --git a/README.md b/README.md index 3d6df749..b77b57d3 100644 --- a/README.md +++ b/README.md @@ -25,9 +25,11 @@ 搜索 **[@note_pic]()** 可查看绘制的全部字符图 - 搜索 **[@note_why]()** 是注者尚未看明白的地方,如果您看明白了,请告诉注者完善 + 搜索 **[@note_why]()** 是注者尚未看明白的地方,如果您看明白了,请Pull Request告诉注者完善 - 搜索 **[@note_thinking]()** 是注者的思考和吐槽鸿蒙源码的地方 + 搜索 **[@note_thinking]()** 是注者的思考和建议 + + 搜索 **[@note_#if0]()** 是由第三方项目提供不由内核源码中定义的极为重要的结构体,为方便理解而添加的。 - ### **理解内核的三个层级** diff --git a/fs/vfs/operation/fs_file_mapping.c b/fs/vfs/operation/fs_file_mapping.c index 9a7effa7..17c9773f 100644 --- a/fs/vfs/operation/fs_file_mapping.c +++ b/fs/vfs/operation/fs_file_mapping.c @@ -37,17 +37,18 @@ #include "los_list.h" #include "los_atomic.h" #include "los_vm_filemap.h" -/****************************************************************** + +#if 0 //@note_#if0 定义见于 ..\third_party\NuttX\include\nuttx\fs\fs.h typedef volatile INT32 Atomic; struct page_mapping { - LOS_DL_LIST page_list; /* all pages * / - SPIN_LOCK_S list_lock; /* lock protecting it * / + LOS_DL_LIST page_list; /* all pages */ + SPIN_LOCK_S list_lock; /* lock protecting it */ LosMux mux_lock; /* mutex lock * / - unsigned long nrpages; /* number of total pages * / + unsigned long nrpages; /* number of total pages */ unsigned long flags; - Atomic ref; /* reference counting * / - struct file *host; /* owner of this mapping * / + Atomic ref; /* reference counting */ + struct file *host; /* owner of this mapping */ }; /* map: full_path(owner) <-> mapping * / @@ -60,26 +61,32 @@ struct file_map { struct file { - unsigned int f_magicnum; /* file magic number * / - int f_oflags; /* Open mode flags * / - FAR struct inode *f_inode; /* 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 * / - struct page_mapping *f_mapping; /* mapping file to memory * / - void *f_dir; /* DIR struct for iterate the directory if open a directory * / + unsigned int f_magicnum; /* file magic number */ + int f_oflags; /* Open mode flags */ + FAR struct inode *f_inode; /* 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 */ + struct page_mapping *f_mapping; /* mapping file to memory */ + void *f_dir; /* DIR struct for iterate the directory if open a directory */ }; +#endif -******************************************************************/ static struct file_map g_file_mapping = {0}; -//初始化文件映射 + +/************************************************************************************************** + 初始化文件映射模块, + file_map: 每个需映射到内存的文件必须创建一个 file_map,都挂到全部g_file_mapping链表上 + page_mapping: 记录的是<文件,文件页>的关系,一个文件在操作过程中被映射成了多少个页, + file:是文件系统管理层面的概念 +**************************************************************************************************/ uint init_file_mapping() { uint ret; - LOS_ListInit(&g_file_mapping.head);//初始化文件映射的链表 + LOS_ListInit(&g_file_mapping.head);//初始化全局文件映射节点,所有文件的映射都将g_file_mapping.head挂在链表上 ret = LOS_MuxInit(&g_file_mapping.lock, NULL);//初始化文件映射互斥锁 if (ret != LOS_OK) { @@ -88,20 +95,24 @@ uint init_file_mapping() return ret; } -//通过文件名查找文件映射,不用锁的方式 +//以无锁的方式通过文件名查找文件映射并返回 static struct page_mapping *find_mapping_nolock(const char *fullpath) { struct file_map *fmap = NULL; LOS_DL_LIST_FOR_EACH_ENTRY(fmap, &g_file_mapping.head, struct file_map, head) {//遍历文件映射链表 - if (!strcmp(fmap->owner, fullpath)) {//对比文件路径 + if (!strcmp(fmap->owner, fullpath)) {//用整个文件路径来标识文件的唯一性 return &fmap->mapping; } } return NULL; } -//添加一个文件映射 +/************************************************************************************************** + 增加一个文件映射,这个函数被do_open()函数调用,每打开一次文件就会调用一次 + 注意不同的进程打开同一个文件,拿到的file是不一样的。 + https://blog.csdn.net/cywosp/article/details/38965239 +**************************************************************************************************/ void add_mapping(struct file *filep, const char *fullpath) { void *tmp = NULL; @@ -118,7 +129,7 @@ void add_mapping(struct file *filep, const char *fullpath) (VOID)LOS_MuxLock(&g_file_mapping.lock, LOS_WAIT_FOREVER);//操作临界区,先拿锁 path_len = strlen(fullpath) + 1; - mapping = find_mapping_nolock(fullpath);//先看有米有映射过 + mapping = find_mapping_nolock(fullpath);//是否已有文件映射 if (mapping) {//有映射过的情况 LOS_AtomicInc(&mapping->ref);//引用自增 filep->f_mapping = mapping;//赋值 @@ -131,9 +142,9 @@ void add_mapping(struct file *filep, const char *fullpath) fmap = (struct file_map *)LOS_MemAlloc(m_aucSysMem0, fmap_len);//分配一个file_map - /* page-cache as a optimization feature, just return when out of memory *///页面缓存作为一个优化功能,当内存不足时返回 + /* page-cache as a optimization feature, just return when out of memory */ - if (!fmap) { + if (!fmap) {//页面缓存作为一个优化功能,当内存不足时返回 PRINT_WARN("%s-%d: Mem alloc failed. fmap length(%d)\n", __FUNCTION__, __LINE__, fmap_len); return; @@ -150,9 +161,9 @@ void add_mapping(struct file *filep, const char *fullpath) } (void)memset_s(fmap, fmap_len, 0, fmap_len);//清0 - fmap->owner = tmp;//赋值,此时owner指向内核区 + fmap->owner = tmp;//赋值,此时owner指向内核区,但要记得释放掉 LOS_AtomicSet(&fmap->mapping.ref, 1);//引用设为1 - (void)strcpy_s(fmap->owner, path_len, fullpath);//从用户区 拷贝到内核区 + (void)strcpy_s(fmap->owner, path_len, fullpath);//将参数fullpath由用户区拷贝到内核区 @note_thinking 鸿蒙提供了专门的拷贝函数 arch_copy_from_user 为啥不用? LOS_ListInit(&fmap->mapping.page_list);//初始化文件映射的页表链表,上面将会挂这个文件映射的所有虚拟内存页 LOS_SpinInit(&fmap->mapping.list_lock);//初始化文件映射的自旋锁 @@ -160,16 +171,16 @@ void add_mapping(struct file *filep, const char *fullpath) if (retval != LOS_OK) { PRINT_ERR("%s %d, Create mutex for mapping.mux_lock failed, status: %d\n", __FUNCTION__, __LINE__, retval); } - (VOID)LOS_MuxLock(&g_file_mapping.lock, LOS_WAIT_FOREVER);//先拿全局变量g_file_mapping的互斥锁 - LOS_ListTailInsert(&g_file_mapping.head, &fmap->head);//因为要将本次文件挂上去 + (VOID)LOS_MuxLock(&g_file_mapping.lock, LOS_WAIT_FOREVER);//拿锁操作g_file_mapping + LOS_ListTailInsert(&g_file_mapping.head, &fmap->head);//将文件映射结点挂入全局链表 (VOID)LOS_MuxUnlock(&g_file_mapping.lock);//释放锁 - filep->f_mapping = &fmap->mapping;//映射互绑操作,都是自己人了, - filep->f_mapping->host = filep;//文件互绑操作,亲上加亲了。 + filep->f_mapping = &fmap->mapping;//之间互绑 + filep->f_mapping->host = filep;//之间互绑,从此相亲相爱一家人 return; } -//查找文件映射 +//通过参数路径查找文件映射并返回 struct page_mapping *find_mapping(const char *fullpath) { struct page_mapping *mapping = NULL; @@ -180,7 +191,7 @@ struct page_mapping *find_mapping(const char *fullpath) (VOID)LOS_MuxLock(&g_file_mapping.lock, LOS_WAIT_FOREVER); - mapping = find_mapping_nolock(fullpath);//找去 + mapping = find_mapping_nolock(fullpath);//找啊找!外面加锁了,就无需再锁了 if (mapping) {//找到 LOS_AtomicInc(&mapping->ref);//引用自增 } @@ -189,7 +200,7 @@ struct page_mapping *find_mapping(const char *fullpath) return mapping; } -//引用递减 +//引用递减,删除或关闭文件时 由 files_close_internal调用 void dec_mapping(struct page_mapping *mapping) { if (mapping == NULL) { @@ -202,17 +213,17 @@ void dec_mapping(struct page_mapping *mapping) } (VOID)LOS_MuxUnlock(&g_file_mapping.lock); } -//清除文件映射,无锁方式 +//以无锁方式清除文件映射 void clear_file_mapping_nolock(const struct page_mapping *mapping) { unsigned int i = 3; /* file start fd */ struct file *filp = NULL; - while (i < CONFIG_NFILE_DESCRIPTORS) {//循环遍历查找 + while (i < CONFIG_NFILE_DESCRIPTORS) {//循环遍历查找,0,1,2已经固定分配了,固从3始 filp = &tg_filelist.fl_files[i];//一个个来 - if (filp->f_mapping == mapping) {//发现一样 - filp->f_mapping = NULL;//直接NULL,注意这里并没有break,而是继续撸到最后,这里如果break了会怎样? @note_thinking - } + if (filp->f_mapping == mapping) {//找到了 + filp->f_mapping = NULL;//直接NULL,注意这里并没有break,而是继续撸到最后,因为 file:mapping 是 N:1的关系 + }//仔细想想:多个进程会使用同一个page_mapping,因为page_mapping的创建是由fullPath来唯一标识的 i++; } } @@ -295,7 +306,7 @@ int remove_mapping(const char *fullpath, const struct file *ex_filp) (void)sem_post(&f_list->fl_sem);//发出信号量 return OK; } - +//重命名文件映射, void rename_mapping(const char *src_path, const char *dst_path) { int ret; diff --git a/fs/vfs/operation/fs_init.c b/fs/vfs/operation/fs_init.c index f1a0db7a..f3325f93 100644 --- a/fs/vfs/operation/fs_init.c +++ b/fs/vfs/operation/fs_init.c @@ -97,7 +97,7 @@ void los_vfs_init(void)//系统调用了los_vfs_init()后,会将"/"作为root_ } dev->i_mode |= S_IFDIR | S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH; - retval = init_file_mapping();//初始化文件映射 + retval = init_file_mapping();//初始化文件映射模块 if (retval != LOS_OK) { PRINT_ERR("Page cache file map init failed\n"); return; diff --git a/kernel/base/include/los_vm_filemap.h b/kernel/base/include/los_vm_filemap.h index 12ff41c0..740c39a2 100644 --- a/kernel/base/include/los_vm_filemap.h +++ b/kernel/base/include/los_vm_filemap.h @@ -48,6 +48,41 @@ extern "C" { #endif /* __cplusplus */ #endif /* __cplusplus */ + +/************************************************************************************************** + 磁盘高速缓存是一种软件机制,它允许系统把通常存放在磁盘上的一些数据保留在 RAM 中,以便对那些数据的 + 进一步访问不用再访问磁盘而能尽快得到满足。 + 页高速缓存中的信息单位是一个完整的页。 + 一个页包含的磁盘块在物理上不一定相邻,所以不能用设备号和块号标识,而是通过页的所有者和所有者数据中的索引来识别。 + 页高速缓存可以缓存以下内容 + A.普通文件数据 + B.含有目录的页 + C.直接从快设备读取的页 + D.用户进程数据的页 + E.特殊文件系统的文件页 +**************************************************************************************************/ +#if 0 //@note_#if0 +//page_mapping描述的是一个文件在内存中被映射了多少页,<文件,文件页的关系> +/* file mapped in VMM pages */ +struct page_mapping { + LOS_DL_LIST page_list; /* all pages */ //文件映射的所有页链表,这些页的内容都来源同一个文件 + SPIN_LOCK_S list_lock; /* lock protecting it */ + LosMux mux_lock; /* mutex lock */ // + unsigned long nrpages; /* number of total pages */ + unsigned long flags; + Atomic ref; /* reference counting */ + struct file *host; /* owner of this mapping *///属于哪个文件的映射 +}; + +/* map: full_path(owner) <-> mapping */ +struct file_map { + LOS_DL_LIST head; + LosMux lock; /* lock to protect this mapping */ + struct page_mapping mapping; + char *owner; /* owner: full path of file */ +}; +#endif + //文件页结构体 typedef struct FilePage { LOS_DL_LIST node; //节点 diff --git a/kernel/base/include/los_vm_map.h b/kernel/base/include/los_vm_map.h index df18c914..829dbe5c 100644 --- a/kernel/base/include/los_vm_map.h +++ b/kernel/base/include/los_vm_map.h @@ -89,9 +89,9 @@ struct VmSpace; typedef struct VmSpace LosVmSpace; //缺页结构信息体 typedef struct VmFault { - UINT32 flags; /* FAULT_FLAG_xxx flags */ - unsigned long pgoff; /* Logical page offset based on region */ - VADDR_T vaddr; /* Faulting virtual address */ + UINT32 flags; /* FAULT_FLAG_xxx flags */ //缺页标识 + unsigned long pgoff; /* Logical page offset based on region */ //基于线性区的逻辑页偏移量 + VADDR_T vaddr; /* Faulting virtual address */ //产生缺页的虚拟地址 VADDR_T *pageKVaddr; /* KVaddr of pagefault's vm page's paddr */ //pageKVaddr为缺页的vm页面物理地址对应的内核虚拟地址,这里要说明下啥意思,缺页的意思是此进程的虚拟空间中没有这个虚拟地址的映射, //但并不代表物理页框没有被别的进程虚拟空间所映射.一定要理解这里! diff --git a/kernel/base/include/los_vm_phys.h b/kernel/base/include/los_vm_phys.h index 58de4424..25f1d17b 100644 --- a/kernel/base/include/los_vm_phys.h +++ b/kernel/base/include/los_vm_phys.h @@ -60,7 +60,7 @@ struct VmFreeList { UINT32 listCnt; //双循环链表节点总数 }; //针对匿名页和文件页各拆分成一个活跃,一个不活跃的链表。 -enum OsLruList { +enum OsLruList {//Lru全称是Least Recently Used,即最近最久未使用的意思 VM_LRU_INACTIVE_ANON = 0, //非活动匿名页 LRU 链表(swap) VM_LRU_ACTIVE_ANON, //活动匿名页 LRU 链表(swap) VM_LRU_INACTIVE_FILE, //非活动文件页 LRU 链表(磁盘) diff --git a/kernel/base/vm/los_vm_filemap.c b/kernel/base/vm/los_vm_filemap.c index 1ff43f97..ecf1f27f 100644 --- a/kernel/base/vm/los_vm_filemap.c +++ b/kernel/base/vm/los_vm_filemap.c @@ -48,32 +48,32 @@ extern "C" { #endif /* __cplusplus */ #endif /* __cplusplus */ - +//增加页到页高速缓存 STATIC VOID OsPageCacheAdd(LosFilePage *page, struct page_mapping *mapping, VM_OFFSET_T pgoff) { LosFilePage *fpage = NULL; - LOS_DL_LIST_FOR_EACH_ENTRY(fpage, &mapping->page_list, LosFilePage, node) { + LOS_DL_LIST_FOR_EACH_ENTRY(fpage, &mapping->page_list, LosFilePage, node) {//遍历page_list链表 if (fpage->pgoff > pgoff) { - LOS_ListTailInsert(&fpage->node, &page->node); + LOS_ListTailInsert(&fpage->node, &page->node);//挂到链表上 goto done_add; } } - LOS_ListTailInsert(&mapping->page_list, &page->node); + LOS_ListTailInsert(&mapping->page_list, &page->node);//挂到链表上 - OsSetPageLRU(page->vmPage); //将页面加入LRU表 + OsSetPageLRU(page->vmPage); //给页面贴上LRU标签 done_add: mapping->nrpages++; } - +//将页面加到活动文件页LRU链表上 VOID OsAddToPageacheLru(LosFilePage *page, struct page_mapping *mapping, VM_OFFSET_T pgoff) { OsPageCacheAdd(page, mapping, pgoff); OsLruCacheAdd(page, VM_LRU_ACTIVE_FILE); } - +//从页高速缓存上删除页 VOID OsPageCacheDel(LosFilePage *fpage) { /* delete from file cache list */ @@ -492,7 +492,11 @@ VOID OsDelMapInfo(LosVmMapRegion *region, LosVmPgFault *vmf, BOOL cleanDirty) } LOS_SpinUnlockRestore(®ion->unTypeData.rf.file->f_mapping->list_lock, intSave); } -//文件缺页时的处理,先读入磁盘数据,再重新读页数据 +/************************************************************************************************** +文件缺页时的处理,先读入磁盘数据,再重新读页数据 + + +**************************************************************************************************/ INT32 OsVmmFileFault(LosVmMapRegion *region, LosVmPgFault *vmf) { INT32 ret; @@ -505,7 +509,7 @@ INT32 OsVmmFileFault(LosVmMapRegion *region, LosVmPgFault *vmf) struct page_mapping *mapping = NULL; LosFilePage *fpage = NULL; - if (!LOS_IsRegionFileValid(region) || (region->unTypeData.rf.file->f_mapping == NULL) || (vmf == NULL)) { + if (!LOS_IsRegionFileValid(region) || (region->unTypeData.rf.file->f_mapping == NULL) || (vmf == NULL)) {//文件是否映射到了内存 VM_ERR("Input param is NULL"); return LOS_NOK; } @@ -518,7 +522,7 @@ INT32 OsVmmFileFault(LosVmMapRegion *region, LosVmPgFault *vmf) if (fpage != NULL) { OsPageRefIncLocked(fpage); } else { - fpage = OsPageCacheAlloc(mapping, vmf->pgoff);//其中分配一个vmpage(物理页框) + fpage + fpage = OsPageCacheAlloc(mapping, vmf->pgoff);//分配一个vmpage(物理页框) + fpage if (fpage == NULL) { VM_ERR("Failed to alloc a page frame"); LOS_SpinUnlockRestore(&mapping->list_lock, intSave); @@ -535,7 +539,7 @@ INT32 OsVmmFileFault(LosVmMapRegion *region, LosVmPgFault *vmf) oldPos = file_seek(file, 0, SEEK_CUR);//相对当前位置偏移,记录偏移后的位置 NUTTX file_seek(file, fpage->pgoff << PAGE_SHIFT, SEEK_SET);// 相对开始位置偏移 if (file->f_inode && file->f_inode->u.i_mops->readpage) {//见于 NUTTX fat_operations.readpage = NULL - ret = file->f_inode->u.i_mops->readpage(file, (char *)kvaddr, PAGE_SIZE); + ret = file->f_inode->u.i_mops->readpage(file, (char *)kvaddr, PAGE_SIZE);//从文件中读取一页数据到kvaddr } else { ret = file_read(file, kvaddr, PAGE_SIZE);//将4K数据读到虚拟地址,磁盘数据进入物理页框 fpage->pgoff << PAGE_SHIFT 处 } @@ -630,7 +634,7 @@ VOID OsFileCacheRemove(struct page_mapping *mapping) LosVmFileOps g_commVmOps = {// .open = NULL, .close = NULL, - .fault = OsVmmFileFault, //缺页处理 + .fault = OsVmmFileFault, //缺页中断处理 .remove = OsVmmFileRemove,//删除页 }; @@ -692,8 +696,11 @@ LosFilePage *OsFindGetEntry(struct page_mapping *mapping, VM_OFFSET_T pgoff) } /* need mutex & change memory to dma zone. */ -//Direct Memory Access(存储器直接访问)指一种高速的数据传输操作,允许在外部设备和存储器之间直接读写数据。 -//整个数据传输操作在一个称为"DMA控制器"的控制下进行的。CPU只需在数据传输开始和结束时做一点处理(开始和结束时候要做中断处理) +/************************************************************************************************** +以页高速缓存方式分配一个文件页 LosFilePage + Direct Memory Access(存储器直接访问)指一种高速的数据传输操作,允许在外部设备和存储器之间直接读写数据。 + 整个数据传输操作在一个称为"DMA控制器"的控制下进行的。CPU只需在数据传输开始和结束时做一点处理(开始和结束时候要做中断处理) +**************************************************************************************************/ LosFilePage *OsPageCacheAlloc(struct page_mapping *mapping, VM_OFFSET_T pgoff) { VOID *kvaddr = NULL; @@ -701,13 +708,13 @@ LosFilePage *OsPageCacheAlloc(struct page_mapping *mapping, VM_OFFSET_T pgoff) LosVmPage *vmPage = NULL; LosFilePage *fpage = NULL; - vmPage = LOS_PhysPageAlloc(); //分配一个物理页 + vmPage = LOS_PhysPageAlloc(); //先分配一个物理页 if (vmPage == NULL) { VM_ERR("alloc vm page failed"); return NULL; } physSeg = OsVmPhysSegGet(vmPage);//通过页获取所在seg - kvaddr = OsVmPageToVaddr(vmPage);//获取内核空间的虚拟地址,具体点进去看函数说明,这里一定要理解透彻 + kvaddr = OsVmPageToVaddr(vmPage);//获取内核空间的虚拟地址,具体点进去看函数说明,这里一定要理解透彻! if ((physSeg == NULL) || (kvaddr == NULL)) { LOS_PhysPageFree(vmPage); //异常情况要释放vmPage VM_ERR("alloc vm page failed!"); @@ -731,9 +738,9 @@ LosFilePage *OsPageCacheAlloc(struct page_mapping *mapping, VM_OFFSET_T pgoff) fpage->dirtyEnd = 0; //脏页结束位置 fpage->physSeg = physSeg; //页框所属段.其中包含了 LRU LIST == fpage->vmPage = vmPage; //物理页框 - fpage->mapping = mapping; //page_mapping 见于 NUTTX + fpage->mapping = mapping; //记录所有文件页映射 fpage->pgoff = pgoff; //偏移 - (VOID)memset_s(kvaddr, PAGE_SIZE, 0, PAGE_SIZE);//4K地址清0 + (VOID)memset_s(kvaddr, PAGE_SIZE, 0, PAGE_SIZE);//页内数据清0 return fpage; } diff --git a/kernel/base/vm/los_vm_map.c b/kernel/base/vm/los_vm_map.c index e2640b43..c5587b93 100644 --- a/kernel/base/vm/los_vm_map.c +++ b/kernel/base/vm/los_vm_map.c @@ -418,14 +418,14 @@ VADDR_T OsAllocSpecificRange(LosVmSpace *vmSpace, VADDR_T vaddr, size_t len) return vaddr; } - +//映射类型为文件的线性区是否有效 BOOL LOS_IsRegionFileValid(LosVmMapRegion *region) { struct file *filep = NULL; if ((region != NULL) && (LOS_IsRegionTypeFile(region)) && - (region->unTypeData.rf.file != NULL)) { + (region->unTypeData.rf.file != NULL)) {//满足文件映射的条件 filep = region->unTypeData.rf.file; - if (region->unTypeData.rf.fileMagic == filep->f_magicnum) { + if (region->unTypeData.rf.fileMagic == filep->f_magicnum) {//魔法数字未被改变 return TRUE; } } diff --git a/kernel/base/vm/los_vm_phys.c b/kernel/base/vm/los_vm_phys.c index 50e405dc..b35db5f4 100644 --- a/kernel/base/vm/los_vm_phys.c +++ b/kernel/base/vm/los_vm_phys.c @@ -261,7 +261,7 @@ VOID *OsVmPageToVaddr(LosVmPage *page)// VADDR_T vaddr; vaddr = KERNEL_ASPACE_BASE + page->physAddr - SYS_MEM_BASE;//page->physAddr - SYS_MEM_BASE 得到物理地址上的偏移量 //因在整个虚拟内存中内核空间和用户空间是通过地址隔离的,如此很巧妙的就把该物理页映射到了内核空间 - //内核空间的vmPage是不会被置换的,所以是常驻内存,内核空间初始化mmu时就映射好了L1表 + //内核空间的vmPage是不会被置换的,因为是常驻内存,内核空间初始化mmu时就映射好了L1表 return (VOID *)(UINTPTR)vaddr; } //通过虚拟地址找映射的物理页框 diff --git a/kernel/base/vm/los_vm_scan.c b/kernel/base/vm/los_vm_scan.c index bb44c513..ad3d2123 100644 --- a/kernel/base/vm/los_vm_scan.c +++ b/kernel/base/vm/los_vm_scan.c @@ -35,8 +35,8 @@ #include "fs/file.h" #include "los_vm_filemap.h" -/* unmap a lru page by map record info caller need lru lock *///通过映射记录信息调用者需要lru锁来取消一个映射lru页面 -VOID OsUnmapPageLocked(LosFilePage *page, LosMapInfo *info) +/* unmap a lru page by map record info caller need lru lock */ +VOID OsUnmapPageLocked(LosFilePage *page, LosMapInfo *info)//通过映射记录信息调用者需要lru锁来取消一个映射lru页面 { if (page == NULL || info == NULL) { VM_ERR("UnmapPage error input null!"); @@ -60,8 +60,8 @@ VOID OsUnmapAllLocked(LosFilePage *page) } } -/* add a new lru node to lru list, lruType can be file or anon *///在lru列表中添加一个新的lru节点,lruType可以是文件或匿名 -VOID OsLruCacheAdd(LosFilePage *fpage, enum OsLruList lruType) +/* add a new lru node to lru list, lruType can be file or anon */ +VOID OsLruCacheAdd(LosFilePage *fpage, enum OsLruList lruType)//在lru列表中添加一个新的lru节点,lruType可以是文件或匿名 { UINT32 intSave; LosVmPhysSeg *physSeg = fpage->physSeg; //得到页面对应段 @@ -76,8 +76,8 @@ VOID OsLruCacheAdd(LosFilePage *fpage, enum OsLruList lruType) LOS_SpinUnlockRestore(&physSeg->lruLock, intSave);//解锁 } -/* dellete a lru node, caller need hold lru_lock *///删除lru节点,调用者需要拿到lru锁 -VOID OsLruCacheDel(LosFilePage *fpage) +/* dellete a lru node, caller need hold lru_lock */ +VOID OsLruCacheDel(LosFilePage *fpage)//删除lru节点,调用者需要拿到lru锁 { LosVmPhysSeg *physSeg = fpage->physSeg; //得到页面对应段 int type = OsIsPageActive(fpage->vmPage) ? VM_LRU_ACTIVE_FILE : VM_LRU_INACTIVE_FILE;//得到页面LRU类型 @@ -92,8 +92,8 @@ BOOL OsInactiveListIsLow(LosVmPhysSeg *physSeg) physSeg->lruSize[VM_LRU_INACTIVE_FILE]) ? TRUE : FALSE;//直接对比size,效率杠杠的 } -/* move a page from inactive list to active list head *///将页面从非活动列表移动到活动列表 -STATIC INLINE VOID OsMoveToActiveList(LosFilePage *fpage) +/* move a page from inactive list to active list head */ +STATIC INLINE VOID OsMoveToActiveList(LosFilePage *fpage)//将页面从非活动列表移动到活动列表 { LosVmPhysSeg *physSeg = fpage->physSeg; //得到页面对应段 diff --git a/zzz/doc/note_ipc.h b/zzz/doc/note_ipc.h index 65c6e89d..62810599 100644 --- a/zzz/doc/note_ipc.h +++ b/zzz/doc/note_ipc.h @@ -26,8 +26,7 @@ /* */ /************************************************************************************************** - * - * + **************************************************************************************************/ diff --git a/zzz/git/push.sh b/zzz/git/push.sh index 28513fda..3245ea62 100644 --- a/zzz/git/push.sh +++ b/zzz/git/push.sh @@ -1,8 +1,9 @@ git add -A -git commit -m '理解线性区是理解虚拟内存的关键,丰富对线性区的注解 +git commit -m '文件是如何映射到内存的?理解页高速缓存(page cache)是关键 搜索 @note_pic 可以查看全部字符图 搜索 @note_why 是注者尚未看明白的地方,如果您看明白了,请告诉注者完善 搜索 @note_thinking 是注者的思考和吐槽的地方 +搜索 @note_#if0 是由第三方项目提供不由内核源码中定义的极为重要的结构体,为方便理解而添加的。 ' git push origin master diff --git "a/zzz/pic/1.\350\266\205\347\272\247\347\273\210\347\253\257.png" "b/zzz/pic/ppt/1.\350\266\205\347\272\247\347\273\210\347\253\257.png" similarity index 100% rename from "zzz/pic/1.\350\266\205\347\272\247\347\273\210\347\253\257.png" rename to "zzz/pic/ppt/1.\350\266\205\347\272\247\347\273\210\347\253\257.png" diff --git a/zzz/pic/10.HPM.png b/zzz/pic/ppt/10.HPM.png similarity index 100% rename from zzz/pic/10.HPM.png rename to zzz/pic/ppt/10.HPM.png diff --git a/zzz/pic/11.POSIX.png b/zzz/pic/ppt/11.POSIX.png similarity index 100% rename from zzz/pic/11.POSIX.png rename to zzz/pic/ppt/11.POSIX.png diff --git "a/zzz/pic/12.\345\244\232\346\240\270.png" "b/zzz/pic/ppt/12.\345\244\232\346\240\270.png" similarity index 100% rename from "zzz/pic/12.\345\244\232\346\240\270.png" rename to "zzz/pic/ppt/12.\345\244\232\346\240\270.png" diff --git "a/zzz/pic/13.\345\244\232\350\277\233\347\250\213.png" "b/zzz/pic/ppt/13.\345\244\232\350\277\233\347\250\213.png" similarity index 100% rename from "zzz/pic/13.\345\244\232\350\277\233\347\250\213.png" rename to "zzz/pic/ppt/13.\345\244\232\350\277\233\347\250\213.png" diff --git "a/zzz/pic/14.\350\277\233\347\250\213\351\200\232\344\277\241.png" "b/zzz/pic/ppt/14.\350\277\233\347\250\213\351\200\232\344\277\241.png" similarity index 100% rename from "zzz/pic/14.\350\277\233\347\250\213\351\200\232\344\277\241.png" rename to "zzz/pic/ppt/14.\350\277\233\347\250\213\351\200\232\344\277\241.png" diff --git "a/zzz/pic/15.\345\212\250\346\200\201\351\223\276\346\216\245.png" "b/zzz/pic/ppt/15.\345\212\250\346\200\201\351\223\276\346\216\245.png" similarity index 100% rename from "zzz/pic/15.\345\212\250\346\200\201\351\223\276\346\216\245.png" rename to "zzz/pic/ppt/15.\345\212\250\346\200\201\351\223\276\346\216\245.png" diff --git "a/zzz/pic/16.\345\274\271\346\200\247\351\203\250\347\275\262\347\255\226\347\225\245.png" "b/zzz/pic/ppt/16.\345\274\271\346\200\247\351\203\250\347\275\262\347\255\226\347\225\245.png" similarity index 100% rename from "zzz/pic/16.\345\274\271\346\200\247\351\203\250\347\275\262\347\255\226\347\225\245.png" rename to "zzz/pic/ppt/16.\345\274\271\346\200\247\351\203\250\347\275\262\347\255\226\347\225\245.png" diff --git "a/zzz/pic/17.\345\244\232\350\256\276\345\244\207\345\272\224\347\224\250\345\274\200\345\217\221\346\214\221\346\210\230.png" "b/zzz/pic/ppt/17.\345\244\232\350\256\276\345\244\207\345\272\224\347\224\250\345\274\200\345\217\221\346\214\221\346\210\230.png" similarity index 100% rename from "zzz/pic/17.\345\244\232\350\256\276\345\244\207\345\272\224\347\224\250\345\274\200\345\217\221\346\214\221\346\210\230.png" rename to "zzz/pic/ppt/17.\345\244\232\350\256\276\345\244\207\345\272\224\347\224\250\345\274\200\345\217\221\346\214\221\346\210\230.png" diff --git "a/zzz/pic/18.\345\217\221\345\261\225\350\266\213\345\212\277.png" "b/zzz/pic/ppt/18.\345\217\221\345\261\225\350\266\213\345\212\277.png" similarity index 100% rename from "zzz/pic/18.\345\217\221\345\261\225\350\266\213\345\212\277.png" rename to "zzz/pic/ppt/18.\345\217\221\345\261\225\350\266\213\345\212\277.png" diff --git "a/zzz/pic/19.\345\217\215\351\246\210\344\270\216\344\272\244\346\265\201.png" "b/zzz/pic/ppt/19.\345\217\215\351\246\210\344\270\216\344\272\244\346\265\201.png" similarity index 100% rename from "zzz/pic/19.\345\217\215\351\246\210\344\270\216\344\272\244\346\265\201.png" rename to "zzz/pic/ppt/19.\345\217\215\351\246\210\344\270\216\344\272\244\346\265\201.png" diff --git "a/zzz/pic/2.HarmonyOs\346\236\266\346\236\204\347\256\200\344\273\213.png" "b/zzz/pic/ppt/2.HarmonyOs\346\236\266\346\236\204\347\256\200\344\273\213.png" similarity index 100% rename from "zzz/pic/2.HarmonyOs\346\236\266\346\236\204\347\256\200\344\273\213.png" rename to "zzz/pic/ppt/2.HarmonyOs\346\236\266\346\236\204\347\256\200\344\273\213.png" diff --git "a/zzz/pic/20.\345\210\206\345\270\203\345\274\217\346\225\260\346\215\256\347\256\241\347\220\206.png" "b/zzz/pic/ppt/20.\345\210\206\345\270\203\345\274\217\346\225\260\346\215\256\347\256\241\347\220\206.png" similarity index 100% rename from "zzz/pic/20.\345\210\206\345\270\203\345\274\217\346\225\260\346\215\256\347\256\241\347\220\206.png" rename to "zzz/pic/ppt/20.\345\210\206\345\270\203\345\274\217\346\225\260\346\215\256\347\256\241\347\220\206.png" diff --git "a/zzz/pic/21.\345\205\261\345\273\272\345\237\272\347\241\200\345\271\263\345\217\260.png" "b/zzz/pic/ppt/21.\345\205\261\345\273\272\345\237\272\347\241\200\345\271\263\345\217\260.png" similarity index 100% rename from "zzz/pic/21.\345\205\261\345\273\272\345\237\272\347\241\200\345\271\263\345\217\260.png" rename to "zzz/pic/ppt/21.\345\205\261\345\273\272\345\237\272\347\241\200\345\271\263\345\217\260.png" diff --git "a/zzz/pic/22.\346\215\220\350\265\240\345\255\265\345\214\226.png" "b/zzz/pic/ppt/22.\346\215\220\350\265\240\345\255\265\345\214\226.png" similarity index 100% rename from "zzz/pic/22.\346\215\220\350\265\240\345\255\265\345\214\226.png" rename to "zzz/pic/ppt/22.\346\215\220\350\265\240\345\255\265\345\214\226.png" diff --git "a/zzz/pic/22.\350\247\243\345\206\263\346\226\271\346\241\210\347\216\260\347\212\266.png" "b/zzz/pic/ppt/22.\350\247\243\345\206\263\346\226\271\346\241\210\347\216\260\347\212\266.png" similarity index 100% rename from "zzz/pic/22.\350\247\243\345\206\263\346\226\271\346\241\210\347\216\260\347\212\266.png" rename to "zzz/pic/ppt/22.\350\247\243\345\206\263\346\226\271\346\241\210\347\216\260\347\212\266.png" diff --git "a/zzz/pic/23.\345\274\200\345\217\221\346\255\245\351\252\244.png" "b/zzz/pic/ppt/23.\345\274\200\345\217\221\346\255\245\351\252\244.png" similarity index 100% rename from "zzz/pic/23.\345\274\200\345\217\221\346\255\245\351\252\244.png" rename to "zzz/pic/ppt/23.\345\274\200\345\217\221\346\255\245\351\252\244.png" diff --git "a/zzz/pic/24\345\274\200\345\217\221\350\200\205\344\275\223\351\252\214\345\217\230\345\214\226.png" "b/zzz/pic/ppt/24\345\274\200\345\217\221\350\200\205\344\275\223\351\252\214\345\217\230\345\214\226.png" similarity index 100% rename from "zzz/pic/24\345\274\200\345\217\221\350\200\205\344\275\223\351\252\214\345\217\230\345\214\226.png" rename to "zzz/pic/ppt/24\345\274\200\345\217\221\350\200\205\344\275\223\351\252\214\345\217\230\345\214\226.png" diff --git "a/zzz/pic/25.\345\206\205\346\240\270\350\256\276\350\256\241\347\233\256\346\240\207.png" "b/zzz/pic/ppt/25.\345\206\205\346\240\270\350\256\276\350\256\241\347\233\256\346\240\207.png" similarity index 100% rename from "zzz/pic/25.\345\206\205\346\240\270\350\256\276\350\256\241\347\233\256\346\240\207.png" rename to "zzz/pic/ppt/25.\345\206\205\346\240\270\350\256\276\350\256\241\347\233\256\346\240\207.png" diff --git "a/zzz/pic/26.\351\251\261\345\212\250\345\271\263\345\217\260\346\236\266\346\236\204\346\200\273\344\275\223.png" "b/zzz/pic/ppt/26.\351\251\261\345\212\250\345\271\263\345\217\260\346\236\266\346\236\204\346\200\273\344\275\223.png" similarity index 100% rename from "zzz/pic/26.\351\251\261\345\212\250\345\271\263\345\217\260\346\236\266\346\236\204\346\200\273\344\275\223.png" rename to "zzz/pic/ppt/26.\351\251\261\345\212\250\345\271\263\345\217\260\346\236\266\346\236\204\346\200\273\344\275\223.png" diff --git "a/zzz/pic/27.\351\251\261\345\212\250\350\275\257\344\273\266\350\256\276\350\256\241\347\233\256\346\240\207.png" "b/zzz/pic/ppt/27.\351\251\261\345\212\250\350\275\257\344\273\266\350\256\276\350\256\241\347\233\256\346\240\207.png" similarity index 100% rename from "zzz/pic/27.\351\251\261\345\212\250\350\275\257\344\273\266\350\256\276\350\256\241\347\233\256\346\240\207.png" rename to "zzz/pic/ppt/27.\351\251\261\345\212\250\350\275\257\344\273\266\350\256\276\350\256\241\347\233\256\346\240\207.png" diff --git "a/zzz/pic/28.\351\251\261\345\212\250\350\275\257\344\273\266\346\214\221\346\210\230.png" "b/zzz/pic/ppt/28.\351\251\261\345\212\250\350\275\257\344\273\266\346\214\221\346\210\230.png" similarity index 100% rename from "zzz/pic/28.\351\251\261\345\212\250\350\275\257\344\273\266\346\214\221\346\210\230.png" rename to "zzz/pic/ppt/28.\351\251\261\345\212\250\350\275\257\344\273\266\346\214\221\346\210\230.png" diff --git "a/zzz/pic/29.\346\235\203\351\231\220\347\256\241\347\220\206.png" "b/zzz/pic/ppt/29.\346\235\203\351\231\220\347\256\241\347\220\206.png" similarity index 100% rename from "zzz/pic/29.\346\235\203\351\231\220\347\256\241\347\220\206.png" rename to "zzz/pic/ppt/29.\346\235\203\351\231\220\347\256\241\347\220\206.png" diff --git "a/zzz/pic/3.\345\210\206\345\270\203\345\274\217\350\260\203\347\224\250.png" "b/zzz/pic/ppt/3.\345\210\206\345\270\203\345\274\217\350\260\203\347\224\250.png" similarity index 100% rename from "zzz/pic/3.\345\210\206\345\270\203\345\274\217\350\260\203\347\224\250.png" rename to "zzz/pic/ppt/3.\345\210\206\345\270\203\345\274\217\350\260\203\347\224\250.png" diff --git "a/zzz/pic/30.\350\256\276\345\244\207\347\256\241\347\220\206\344\270\255\345\277\203.png" "b/zzz/pic/ppt/30.\350\256\276\345\244\207\347\256\241\347\220\206\344\270\255\345\277\203.png" similarity index 100% rename from "zzz/pic/30.\350\256\276\345\244\207\347\256\241\347\220\206\344\270\255\345\277\203.png" rename to "zzz/pic/ppt/30.\350\256\276\345\244\207\347\256\241\347\220\206\344\270\255\345\277\203.png" diff --git "a/zzz/pic/31.\350\256\276\345\244\207\345\274\200\345\217\221IDE.png" "b/zzz/pic/ppt/31.\350\256\276\345\244\207\345\274\200\345\217\221IDE.png" similarity index 100% rename from "zzz/pic/31.\350\256\276\345\244\207\345\274\200\345\217\221IDE.png" rename to "zzz/pic/ppt/31.\350\256\276\345\244\207\345\274\200\345\217\221IDE.png" diff --git "a/zzz/pic/32.\350\256\276\345\244\207\345\274\200\345\217\221\345\267\245\345\205\267.png" "b/zzz/pic/ppt/32.\350\256\276\345\244\207\345\274\200\345\217\221\345\267\245\345\205\267.png" similarity index 100% rename from "zzz/pic/32.\350\256\276\345\244\207\345\274\200\345\217\221\345\267\245\345\205\267.png" rename to "zzz/pic/ppt/32.\350\256\276\345\244\207\345\274\200\345\217\221\345\267\245\345\205\267.png" diff --git "a/zzz/pic/33.\350\256\276\345\244\207\345\274\200\345\217\221\350\200\205\345\256\230\347\275\221.png" "b/zzz/pic/ppt/33.\350\256\276\345\244\207\345\274\200\345\217\221\350\200\205\345\256\230\347\275\221.png" similarity index 100% rename from "zzz/pic/33.\350\256\276\345\244\207\345\274\200\345\217\221\350\200\205\345\256\230\347\275\221.png" rename to "zzz/pic/ppt/33.\350\256\276\345\244\207\345\274\200\345\217\221\350\200\205\345\256\230\347\275\221.png" diff --git "a/zzz/pic/34\350\256\276\345\244\207\345\274\200\345\217\221\350\200\205\345\271\263\345\217\260.png" "b/zzz/pic/ppt/34\350\256\276\345\244\207\345\274\200\345\217\221\350\200\205\345\271\263\345\217\260.png" similarity index 100% rename from "zzz/pic/34\350\256\276\345\244\207\345\274\200\345\217\221\350\200\205\345\271\263\345\217\260.png" rename to "zzz/pic/ppt/34\350\256\276\345\244\207\345\274\200\345\217\221\350\200\205\345\271\263\345\217\260.png" diff --git "a/zzz/pic/35.\346\221\204\345\203\217\345\244\264.png" "b/zzz/pic/ppt/35.\346\221\204\345\203\217\345\244\264.png" similarity index 100% rename from "zzz/pic/35.\346\221\204\345\203\217\345\244\264.png" rename to "zzz/pic/ppt/35.\346\221\204\345\203\217\345\244\264.png" diff --git "a/zzz/pic/36.\347\273\237\344\270\200\351\251\261\345\212\250\345\271\263\345\217\260\347\233\256\345\275\225\347\273\223\346\236\204.png" "b/zzz/pic/ppt/36.\347\273\237\344\270\200\351\251\261\345\212\250\345\271\263\345\217\260\347\233\256\345\275\225\347\273\223\346\236\204.png" similarity index 100% rename from "zzz/pic/36.\347\273\237\344\270\200\351\251\261\345\212\250\345\271\263\345\217\260\347\233\256\345\275\225\347\273\223\346\236\204.png" rename to "zzz/pic/ppt/36.\347\273\237\344\270\200\351\251\261\345\212\250\345\271\263\345\217\260\347\233\256\345\275\225\347\273\223\346\236\204.png" diff --git "a/zzz/pic/37.\346\226\207\344\273\266\347\263\273\347\273\237.png" "b/zzz/pic/ppt/37.\346\226\207\344\273\266\347\263\273\347\273\237.png" similarity index 100% rename from "zzz/pic/37.\346\226\207\344\273\266\347\263\273\347\273\237.png" rename to "zzz/pic/ppt/37.\346\226\207\344\273\266\347\263\273\347\273\237.png" diff --git "a/zzz/pic/38.\347\263\273\347\273\237\350\260\203\347\224\250.png" "b/zzz/pic/ppt/38.\347\263\273\347\273\237\350\260\203\347\224\250.png" similarity index 100% rename from "zzz/pic/38.\347\263\273\347\273\237\350\260\203\347\224\250.png" rename to "zzz/pic/ppt/38.\347\263\273\347\273\237\350\260\203\347\224\250.png" diff --git "a/zzz/pic/39.\350\231\232\346\213\237\345\206\205\345\255\230.png" "b/zzz/pic/ppt/39.\350\231\232\346\213\237\345\206\205\345\255\230.png" similarity index 100% rename from "zzz/pic/39.\350\231\232\346\213\237\345\206\205\345\255\230.png" rename to "zzz/pic/ppt/39.\350\231\232\346\213\237\345\206\205\345\255\230.png" diff --git "a/zzz/pic/4.\345\210\206\345\270\203\345\274\217\350\275\257\346\200\273\347\272\277.png" "b/zzz/pic/ppt/4.\345\210\206\345\270\203\345\274\217\350\275\257\346\200\273\347\272\277.png" similarity index 100% rename from "zzz/pic/4.\345\210\206\345\270\203\345\274\217\350\275\257\346\200\273\347\272\277.png" rename to "zzz/pic/ppt/4.\345\210\206\345\270\203\345\274\217\350\275\257\346\200\273\347\272\277.png" diff --git "a/zzz/pic/40.\344\270\200\346\254\241\345\274\200\345\217\221\345\244\232\347\263\273\347\273\237\351\203\250\347\275\262.png" "b/zzz/pic/ppt/40.\344\270\200\346\254\241\345\274\200\345\217\221\345\244\232\347\263\273\347\273\237\351\203\250\347\275\262.png" similarity index 100% rename from "zzz/pic/40.\344\270\200\346\254\241\345\274\200\345\217\221\345\244\232\347\263\273\347\273\237\351\203\250\347\275\262.png" rename to "zzz/pic/ppt/40.\344\270\200\346\254\241\345\274\200\345\217\221\345\244\232\347\263\273\347\273\237\351\203\250\347\275\262.png" diff --git "a/zzz/pic/41.\347\241\254\344\273\266\350\231\232\346\213\237\345\214\226.png" "b/zzz/pic/ppt/41.\347\241\254\344\273\266\350\231\232\346\213\237\345\214\226.png" similarity index 100% rename from "zzz/pic/41.\347\241\254\344\273\266\350\231\232\346\213\237\345\214\226.png" rename to "zzz/pic/ppt/41.\347\241\254\344\273\266\350\231\232\346\213\237\345\214\226.png" diff --git "a/zzz/pic/42\347\244\272\344\276\213.png" "b/zzz/pic/ppt/42\347\244\272\344\276\213.png" similarity index 100% rename from "zzz/pic/42\347\244\272\344\276\213.png" rename to "zzz/pic/ppt/42\347\244\272\344\276\213.png" diff --git "a/zzz/pic/43.\347\244\272\344\276\2132.png" "b/zzz/pic/ppt/43.\347\244\272\344\276\2132.png" similarity index 100% rename from "zzz/pic/43.\347\244\272\344\276\2132.png" rename to "zzz/pic/ppt/43.\347\244\272\344\276\2132.png" diff --git "a/zzz/pic/5.\345\210\206\345\270\203\345\274\217\346\225\260\346\215\256\347\256\241\347\220\206.png" "b/zzz/pic/ppt/5.\345\210\206\345\270\203\345\274\217\346\225\260\346\215\256\347\256\241\347\220\206.png" similarity index 100% rename from "zzz/pic/5.\345\210\206\345\270\203\345\274\217\346\225\260\346\215\256\347\256\241\347\220\206.png" rename to "zzz/pic/ppt/5.\345\210\206\345\270\203\345\274\217\346\225\260\346\215\256\347\256\241\347\220\206.png" diff --git "a/zzz/pic/6.\347\241\254\344\273\266\350\231\232\346\213\237\345\214\226.png" "b/zzz/pic/ppt/6.\347\241\254\344\273\266\350\231\232\346\213\237\345\214\226.png" similarity index 100% rename from "zzz/pic/6.\347\241\254\344\273\266\350\231\232\346\213\237\345\214\226.png" rename to "zzz/pic/ppt/6.\347\241\254\344\273\266\350\231\232\346\213\237\345\214\226.png" diff --git "a/zzz/pic/7.\345\275\222\344\270\200\345\214\226\347\232\204\351\251\261\345\212\250\345\271\263\345\217\260\346\241\206\346\236\266.png" "b/zzz/pic/ppt/7.\345\275\222\344\270\200\345\214\226\347\232\204\351\251\261\345\212\250\345\271\263\345\217\260\346\241\206\346\236\266.png" similarity index 100% rename from "zzz/pic/7.\345\275\222\344\270\200\345\214\226\347\232\204\351\251\261\345\212\250\345\271\263\345\217\260\346\241\206\346\236\266.png" rename to "zzz/pic/ppt/7.\345\275\222\344\270\200\345\214\226\347\232\204\351\251\261\345\212\250\345\271\263\345\217\260\346\241\206\346\236\266.png" diff --git "a/zzz/pic/8.IOT\345\234\272\346\231\257\346\236\201\350\275\273\351\207\217\345\272\224\347\224\250\346\241\206\346\236\266.png" "b/zzz/pic/ppt/8.IOT\345\234\272\346\231\257\346\236\201\350\275\273\351\207\217\345\272\224\347\224\250\346\241\206\346\236\266.png" similarity index 100% rename from "zzz/pic/8.IOT\345\234\272\346\231\257\346\236\201\350\275\273\351\207\217\345\272\224\347\224\250\346\241\206\346\236\266.png" rename to "zzz/pic/ppt/8.IOT\345\234\272\346\231\257\346\236\201\350\275\273\351\207\217\345\272\224\347\224\250\346\241\206\346\236\266.png" diff --git "a/zzz/pic/9.HarmonyOS\346\236\266\346\236\204\344\270\255\344\275\215\347\275\256.png" "b/zzz/pic/ppt/9.HarmonyOS\346\236\266\346\236\204\344\270\255\344\275\215\347\275\256.png" similarity index 100% rename from "zzz/pic/9.HarmonyOS\346\236\266\346\236\204\344\270\255\344\275\215\347\275\256.png" rename to "zzz/pic/ppt/9.HarmonyOS\346\236\266\346\236\204\344\270\255\344\275\215\347\275\256.png" diff --git a/zzz/pic/elf info.jpg b/zzz/pic/turing/elf info.jpg similarity index 100% rename from zzz/pic/elf info.jpg rename to zzz/pic/turing/elf info.jpg diff --git "a/zzz/pic/turing/\350\277\233\347\250\213FD_\347\263\273\347\273\237FD_inode\345\205\263\347\263\273\345\233\276.png" "b/zzz/pic/turing/\350\277\233\347\250\213FD_\347\263\273\347\273\237FD_inode\345\205\263\347\263\273\345\233\276.png" new file mode 100644 index 0000000000000000000000000000000000000000..709e1b4da6b2df6ac0eb779ab25e6177542f5741 GIT binary patch literal 31913 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 literal 0 HcmV?d00001 -- GitLab