《Linux内核API》 |
版本 |
作者 |
参与者 |
完成日期 |
备注 |
YanlzLinux_Kernel_V01_1.0 |
严立钻 |
|
2020.02.05 |
|
|
|
|
|
|
++++“Linux内核API”:是对“Linux系统编程”的综合探索;开发Linux环境下的应用程序时,需要使用大量的Linux函数;这些函数有的属于Linux操作系统的API;底层的驱动内核工程师是嵌入式领域的重要岗位,也是一个公司的技术核心,根据芯片具体情况把操作系统(如Linux)移植到上面;同时编写必要的驱动程序,改写相应的内核代码;
++++“Linux内核API”:定位在一个科普类知识,了解Linux环境下的应用程序开发;从基础Linux、C语言、数据结构开始,到ARM、汇编、Linux内核、驱动等!
++++【C++C铸就生存利器】分类:https://blog.csdn.net/vrunsoftyanlz/category_9325802.html
++++【人工智能AI2026】分类:https://blog.csdn.net/vrunsoftyanlz/category_9212024.html
++++【立钻哥哥CSDN空间】:https://blog.csdn.net/VRunSoftYanlz/
#第一篇:Linux从入门到放弃篇 |
#第二篇:Linux C篇 |
#第三篇:Linux系统编程篇 |
#第四篇:Linux内核API篇 |
++D1、Linux内核API概述 |
++++[不能使用浮点运算]:因为Linux内核在切换模式时不保存处理器的浮点状态;
++++[不要让内核程序进行长时间等待]:Linux操作系统本身是抢占式的,但是内核是非抢占内核,就是说用户空间的程序可以抢占运行,但是内核空间程序不可以;
++++[尽可能保持代码的整洁性]:内核调试不像调试应用程序那样方便,因此,在前期代码编写的过程中保持代码的整洁易懂,将大大方便后期的调试;
++++[Linux内核API有很多配对使用]:例如,文件引用计数有加操作,也会有相应的减操作;如果在实验中进行了“引用计数”加操作,函数执行后未进行减操作还原,那么可能会出现系统崩溃;
++++在内核模式下编程,系统内的所有资源都是由内核来统一调配的,并且数量有限,因此申请资源用完后一定要进行释放,避免出现死锁情况;
ifneq($(KERNELRELEASE)) mymodule-objs:= mymodule1.0 mymodule2.0 #依赖关系 obj-m += mymodule.o #编译、链接后将生成mymodule.o模块
else PWD := $(shell pwd) KVER := $(shell uname -r) KDIR := /lib/modules/$(KVER)/build
all: $(MAKE) -C $(KDIR) M=$(PWD) #此处将再次调用make
clean: rm -rf *.o *.mod.c *.ko *.symvers *.order *.markers *~ endif |
++++printk()函数执行时首先设法获取控制台信号量,然后将要输出的字符存储到控制台的日志缓冲区,在调用控制台驱动程序来刷新缓冲区;若printk()无法获得控制台信号量,则只能把要输出的字符存储到日志缓冲区,并依赖拥有控制台信号量的进程来刷新这个缓冲区;
++++printk()函数会将数据存储到日志缓冲区,但是为了安全考虑,在这之前需要使用日志缓冲区锁,保证并发调用printk()的安全性;
printk(记录级别 “格式化输出信息”); |
++++[KERN_EMERG]: “<0>”:这是一个最高优先输出的紧急事件消息,表示操作系统崩溃前会进行输出提示信息;
++++[KERN_ALERT]:”<1>”:输出警告消息,通知需要采取措施;
++++[KERN_CRIT]:”<2>”:这是一个临界情况,当发生严重的软件或硬件操作失败时,进行输出提示信息;
++++[KERN_ERR]:”<3>”:当系统检测到发生一个错误时,会输出信息;设备驱动程序常用“KERN_ERR”来报告硬件的错误信息;
++++[KERN_WARNING]:”<4>”:提示信息,一般用于提醒;常用在于系统安全相关的消息输出;
++++[KERN_NOTICE]:”<5>”:这是一个普通的提示,系统输出时乣注意的情况信息;
++++[KERN_INFO]:”<6>”:非正式的消息,可能无关紧要,例如驱动程序进行挂载时,一般打印硬件相关信息;
++++[KERN_DEBUG]:”<7>”:这是用于程序开发与调试的信息,完成编码后,这类信息一般都要删除;
++D2、Linux内核模块机制 |
++D2.1、__module_address() |
++++立钻哥哥:函数__module_address()主要用于根据给定的一个内存地址addr,获得该内存地址所在的模块;
++++[函数位置]:linux-2.6.30/kernel/module.c;
struct module *__module_address(unsigned long addr); |
++++[返回值说明]:如果内存地址addr在某一模块的地址空间中,则返回指向该模块的结构体指针,否则返回NULL;
++D2.2、__module_ref_addr() |
++++立钻哥哥:函数__module_ref_addr()的功能是获得模块mod的引用计数所在的内存地址单元,从而通过改变该地址单元的内容,实现对其引用计数的改变;
++++[函数位置]:linux-2.6.30/include/linux/module.h;
static inline local_t *__module_ref_addr(struct module *mod, int cpu); |
++D2.3、__module_text_address() |
++++立钻哥哥:函数__module_text_address()的功能是获得一个模块指针,但必须满足条件:addr所表示的内存地址落在该模块的代码段中;
++++[函数位置]:linux-2.6.30/kernel/module.c;
struct module *__module_text_address(unsigned long addr); |
++++D2.4、__print_symbol() |
++++立钻哥哥:函数__print_symbol()的功能与sprint_symbol()的函数功能相似,实际上,__print_symbol()函数的实现中调用了函数sprint_symbol();该函数根据一个内存中的地址address查找一个内核符号,并将该符号的基本符号(例如符号名name)、它在内核符号表中的偏移offset和大小size、所属的模块名(如果有的话)等信息以格式化串fmt的形式输出;而sprint_symbol()函数则是将这些信息放到文本缓冲区buffer中;
++++[函数位置]:linux-2.6.30/kernel/kallsys.c;
void __print_symbol(const char *fmt, unsigned long address); |
++D2.5、__symbol_get() |
++++立钻哥哥:函数__symbol_get()的功能是根据给定的内核符号名symbol,获得该符号的内存地址;
++++[函数位置]:linux-2.6.30/kernel/module.c;
void *__symbol_get(const char *symbol); |
++++[返回值说明]:返回一个void类型指针,其值代表内核符号symbol的地址;如果不存在内核符号symbol,则返回NULL;
++D2.6、__symbol_put() |
++++立钻哥哥:函数__symbol_put()的功能是根据给定的内核符号名symbol,找到其所在的内核模块,并将该模块的引用计数减1;
++++[函数位置]:linux-2.6.30/kernel/module.c;
void __symbol_put(const char *symbol); |
++D2.7、find_module() |
++++立钻哥哥:函数find_module()用来获得一个指向模块的指针;它是根据给定的模块名字查找模块链表,如果找到一个与给定的模块名字相匹配的模块,则返回该模块的指针;由于一个模块的名字是唯一的且不允许有重名的模块,因此基于模块名查找模块是可行的;
++++[函数位置]:linux-2.6.30/kernel/module.c;
struct module *find_module(const char *name); |
++++[返回值说明]:返回值是一个struct module类型的指针,如果find_module()函数查找模块成功,则返回值指向查找到的名为name的模块,如果查找不成功,则返回NULL;
//立钻哥哥:模块结构体module在内核文件linux-2.6.30/include/linux/module.h中定义; struct module{ /* 模块当前的状态,state取值有三种情况: * MODULE_STATE_LIVE, 指示模块当前正在使用 * MODULE_STATE_COMING, 指示正在加载模块 * MODULE_STATE_GONING, 指示正在退出模块 */ enum module_state state;
struct list_head list; //指向模块链表中的下一个模块
... ...
/* 向内核空间导出的符号 */ const struct kernel_symbol *syms; //指向模块的符号表,表的大小为num_syms const unsigned long *crcs; unsigned int num_syms; //模块中符号的个数
/* 内核参数 */ struct kernel_param *kp; unsigned int num_kp;
... ... }; |
++D2.8、find_symbol() |
++++立钻哥哥:函数find_symbol()通过给定的内核符号的名字name,以及bool型参数gplok,warn来查找内核符号,并返回描述该符号的结构体指针;如果内核符号存在于动态插入的模块且参数owner不为空,则指针owner指向该模块;
++++[函数位置]:linux-2.6.30/kernel/module.c;
const struct kernel_symbol *find_symbol(const char *name, struct module **owner, const unsigned long **crc, bool gplok, bool warn); |
++D2.9、module_is_live() |
++++立钻哥哥:函数module_is_live()的功能是判断模块mod是否处于活动状态;
++++[函数位置]:linux-2.6.30/include/linux/module.h;
static inline int module_is_live(struct module *mod); |
++++[参数mod]:模块结构体指针,结构体中包含模块的名称、状态、所属的模块链表等;
++++[返回值说明]:该函数返回一个整型值,如果为1表示模块处于live(not going)状态;如果为0,则模块mod处于going状态;
++D2.10、module_put() |
++++立钻哥哥:函数module_put()的功能是将一个特定模块module的引用计数减1,这样当一个模块的引用计数因为不为0而不能从内核中卸载时,可以调用此函数一次或多次,实现对模块计数的清零,从而实现模块卸载;
++++[函数位置]:linux-2.6.30/kernel/module.c;
void module_put(struct module *module); |
++++[参数module]:指向模块结构体的指针,结构体中包含模块的名称、状态、所属的模块链表等;
++D2.11、module_refcount() |
++++立钻哥哥;函数module_refcount()是用来获得模块的引用计数;每个模块的结构体描述符module中都有一个该模块被引用次数的计数次数,它或者是一个指针或者是一个local_t类型变量;
++++[函数位置]:linux-2.6.30/kernel/module.c;
unsigned int module_refcount(struct module *mod); |
++++[参数mod]:表示指向模块结构体的指针,结构体中包含模块的名称、状态、所属的模块链表等;
++++[返回值说明]:返回值是一个unsigned int的类型,它的值表示模块被引用的次数;
++D2.12、sprint_symbol() |
++++立钻哥哥:函数sprint_symbol()根据一个内存中的地址address查找一个内核符号,并将该符号的基本信息,如符号名name,它在内核符号表中的偏移offset和大小size,所属的模块名(如果有的话)等信息连接成字符串赋值给文本缓冲区buffer;其中所查找的内核符号可以是原本就存在于内核中的符号,也可以是位于动态插入的模块中的符号;
++++[函数位置]:linux-2.6.30/kernel/kallsyms.c;
int sprint_symbol(char *buffer, unsigned long address); |
++++[参数buffer]:文本缓冲区,它用来记录内核符号的信息,它是一个输出型参数;
++++[参数address]:内核符号中的某一地址,为输入型参数;
++++[返回值说明]:返回值是一个int型,它表示内核符号基本信息串的长度,也即是buffer所表示的字符串的长度;
++D2.13、symbol_put_addr() |
++++立钻哥哥:函数symbol_put_addr()的功能是根据给定的一个内存地址addr,找到该地址所在的模块后,将模块的引用计数减1;它与__symbol_put()的函数有类似的功能,但二者的参数不一致;
++++[函数位置]:linux-2.6.30/kernel/module.c;
void symbol_put_addr(void *addr); |
++++[参数addr]:内存地址,通常指某一内核符号的内存地址;
++D2.14、try_module_get() |
++++立钻哥哥:函数try_module_get()的功能是首先判断模块module是否处于活动状态,然后通过local_inc()宏操作将模块module的引用计数加1;
++++[函数位置]:linux-2.6.30/kernel/module.c;
static inline int try_module_get(struct module *module); |
++++[参数module]:指向模块结构体的指针,结构体中包含模块的名称、状态、所属的模块链表等;
++++[返回值说明]:返回值为一个整型值;如果模块module处于活动状态且对其引用计数增加1的操作成功,则函数返回1,否则返回0;
++D2.15、use_module() |
++++立钻哥哥:函数use_module()的功能是实现模块a使用模块b,同时将模块b的引用计数加1;
++++[函数位置]:linux-2.6.30/kernel/module.c;
int use_module(struct module *a, struct module *b); |
++++[参数a]:表示模块结构体指针,结构体中包含模块的名称、状态、所属的模块链表等;在该函数中指使用的模块对象;
++++[参数b]:结构定义与参数a的说明相同,在该函数中指被使用的模块对象;
++++[返回值说明]:该函数返回一个整型值,如果对模块a可以使用模块b,或者是模块b之前已经被模块a所使用,则返回1,否则返回0;
++D3、Linux进程管理内核 |
++D3.1、__task_pid_nr_ns() |
++++【Linux从入门到放弃】:https://blog.csdn.net/VRunSoftYanlz/article/details/104176967
++++【Linux C函数与算法】:https://blog.csdn.net/VRunSoftYanlz/article/details/104076473
++++【Linux系统编程】:https://blog.csdn.net/VRunSoftYanlz/article/details/104151861
++++【Linux内核API】:https://blog.csdn.net/VRunSoftYanlz/article/details/104189074
++++【Linux内核剖析】:https://blog.csdn.net/VRunSoftYanlz/article/details/104200535
++++【C++C铸就生存利器】分类:https://blog.csdn.net/vrunsoftyanlz/category_9325802.html
++++【人工智能AI2026】分类:https://blog.csdn.net/vrunsoftyanlz/category_9212024.html
++++【立钻哥哥CSDN空间】:https://blog.csdn.net/VRunSoftYanlz/
【XR游戏开发QQ群:784477094】
立钻哥哥推荐的拓展学习链接(Link_Url) |
++++立钻哥哥Unity 学习空间: http://blog.csdn.net/VRunSoftYanlz/
++++虚拟现实VR资讯: https://blog.csdn.net/VRunSoftYanlz/article/details/89165846
++++HTC_VIVE开发基础:https://blog.csdn.net/VRunSoftYanlz/article/details/81989970
++++Oculus杂谈:https://blog.csdn.net/VRunSoftYanlz/article/details/82469850
++++Oculus安装使用:https://blog.csdn.net/VRunSoftYanlz/article/details/82718982
++++Unity+SteamVR=>VR:https://blog.csdn.net/VRunSoftYanlz/article/details/88809370
++++Unity减少VR晕眩症:https://blog.csdn.net/VRunSoftYanlz/article/details/89115518
++++SteamVR简介:https://blog.csdn.net/VRunSoftYanlz/article/details/86484254
++++SteamVR脚本功能分析:https://blog.csdn.net/VRunSoftYanlz/article/details/86531480
++++SteamVR2.0开发指南:https://blog.csdn.net/VRunSoftYanlz/article/details/86618187
++++SteamVR2.2.0开发指南:https://blog.csdn.net/VRunSoftYanlz/article/details/88784527
++++SteamVR2.2.0快速入门:https://blog.csdn.net/VRunSoftYanlz/article/details/88833579
++++SteamVR2.2.0交互系统:https://blog.csdn.net/VRunSoftYanlz/article/details/89199778
++++SteamVR2.2.0传送机制:https://blog.csdn.net/VRunSoftYanlz/article/details/89390866
++++SteamVR2.2.0教程(一):https://blog.csdn.net/VRunSoftYanlz/article/details/89324067
++++SteamVR2.2.0教程(二):https://blog.csdn.net/VRunSoftYanlz/article/details/89894097
++++SteamVR_Skeleton_Poser:https://blog.csdn.net/VRunSoftYanlz/article/details/89931725
++++SteamVR实战之PMCore:https://blog.csdn.net/VRunSoftYanlz/article/details/89463658
++++SteamVR/Extras:https://blog.csdn.net/VRunSoftYanlz/article/details/86584108
++++SteamVR/Input:https://blog.csdn.net/VRunSoftYanlz/article/details/86601950
++++OpenXR简介:https://blog.csdn.net/VRunSoftYanlz/article/details/85726365
++++VRTK杂谈:https://blog.csdn.net/VRunSoftYanlz/article/details/82562993
++++VRTK快速入门(杂谈):https://blog.csdn.net/VRunSoftYanlz/article/details/82955267
++++VRTK官方示例(目录):https://blog.csdn.net/VRunSoftYanlz/article/details/82955410
++++VRTK代码结构(目录):https://blog.csdn.net/VRunSoftYanlz/article/details/82780085
++++VRTK(SceneResources):https://blog.csdn.net/VRunSoftYanlz/article/details/82795400
++++VRTK_ControllerEvents:https://blog.csdn.net/VRunSoftYanlz/article/details/83099512
++++VRTK_InteractTouch:https://blog.csdn.net/VRunSoftYanlz/article/details/83120220
++++虚拟现实行业应用:https://blog.csdn.net/VRunSoftYanlz/article/details/88360157
++++Steam平台上的VR:https://blog.csdn.net/VRunSoftYanlz/article/details/88960085
++++Steam平台热销VR:https://blog.csdn.net/VRunSoftYanlz/article/details/89007741
++++VR实验:以太网帧的构成:https://blog.csdn.net/VRunSoftYanlz/article/details/82598140
++++实验四:存储器扩展实验:https://blog.csdn.net/VRunSoftYanlz/article/details/87834434
++++FrameVR示例V0913:https://blog.csdn.net/VRunSoftYanlz/article/details/82808498
++++FrameVR示例V1003:https://blog.csdn.net/VRunSoftYanlz/article/details/83066516
++++SwitchMachineV1022:https://blog.csdn.net/VRunSoftYanlz/article/details/83280886
++++PlaySceneManagerV1022:https://blog.csdn.net/VRunSoftYanlz/article/details/83280886
++++Unity5.x用户手册:https://blog.csdn.net/VRunSoftYanlz/article/details/81712741
++++Unity面试题ABC:https://blog.csdn.net/vrunsoftyanlz/article/details/78630687
++++Unity面试题D:https://blog.csdn.net/VRunSoftYanlz/article/details/78630838
++++Unity面试题E:https://blog.csdn.net/vrunsoftyanlz/article/details/78630913
++++Unity面试题F:https://blog.csdn.net/VRunSoftYanlz/article/details/78630945
++++Cocos2dx面试题:https://blog.csdn.net/VRunSoftYanlz/article/details/78630967
++++禅道[zentao]:https://blog.csdn.net/VRunSoftYanlz/article/details/83964057
++++Lua快速入门篇(Xlua拓展):https://blog.csdn.net/VRunSoftYanlz/article/details/81173818
++++Lua快速入门篇(XLua教程):https://blog.csdn.net/VRunSoftYanlz/article/details/81141502
++++Lua快速入门篇(基础概述):https://blog.csdn.net/VRunSoftYanlz/article/details/81041359
++++框架知识点:https://blog.csdn.net/VRunSoftYanlz/article/details/80862879
++++游戏框架(UI框架夯实篇):https://blog.csdn.net/vrunsoftyanlz/article/details/80781140
++++游戏框架(初探篇):https://blog.csdn.net/VRunSoftYanlz/article/details/80630325
++++.Net框架设计:https://blog.csdn.net/VRunSoftYanlz/article/details/87401225
++++从零开始学架构:https://blog.csdn.net/VRunSoftYanlz/article/details/88095895
++++设计模式简单整理:https://blog.csdn.net/vrunsoftyanlz/article/details/79839641
++++专题:设计模式(精华篇):https://blog.csdn.net/VRunSoftYanlz/article/details/81322678
++++U3D小项目参考:https://blog.csdn.net/vrunsoftyanlz/article/details/80141811
++++Unity小游戏算法分析:https://blog.csdn.net/VRunSoftYanlz/article/details/87908365
++++Unity案例(Vehicle):https://blog.csdn.net/VRunSoftYanlz/article/details/82355876
++++UML类图:https://blog.csdn.net/vrunsoftyanlz/article/details/80289461
++++PowerDesigner简介:https://blog.csdn.net/VRunSoftYanlz/article/details/86500084
++++Unity知识点0001:https://blog.csdn.net/vrunsoftyanlz/article/details/80302012
++++Unity知识点0008:https://blog.csdn.net/VRunSoftYanlz/article/details/81153606
++++U3D_Shader编程(第一篇:快速入门篇):https://blog.csdn.net/vrunsoftyanlz/article/details/80372071
++++U3D_Shader编程(第二篇:基础夯实篇):https://blog.csdn.net/vrunsoftyanlz/article/details/80372628
++++Unity引擎基础:https://blog.csdn.net/vrunsoftyanlz/article/details/78881685
++++Unity面向组件开发:https://blog.csdn.net/vrunsoftyanlz/article/details/78881752
++++Unity物理系统:https://blog.csdn.net/vrunsoftyanlz/article/details/78881879
++++Unity2D平台开发:https://blog.csdn.net/vrunsoftyanlz/article/details/78882034
++++UGUI基础:https://blog.csdn.net/vrunsoftyanlz/article/details/78884693
++++UGUI进阶:https://blog.csdn.net/vrunsoftyanlz/article/details/78884882
++++UGUI综合:https://blog.csdn.net/vrunsoftyanlz/article/details/78885013
++++Unity动画系统基础:https://blog.csdn.net/vrunsoftyanlz/article/details/78886068
++++Unity动画系统进阶:https://blog.csdn.net/vrunsoftyanlz/article/details/78886198
++++Navigation导航系统:https://blog.csdn.net/vrunsoftyanlz/article/details/78886281
++++Unity特效渲染:https://blog.csdn.net/vrunsoftyanlz/article/details/78886403
++++Unity数据存储:https://blog.csdn.net/vrunsoftyanlz/article/details/79251273
++++Unity中Sqlite数据库:https://blog.csdn.net/vrunsoftyanlz/article/details/79254162
++++WWW类和协程:https://blog.csdn.net/vrunsoftyanlz/article/details/79254559
++++Unity网络:https://blog.csdn.net/vrunsoftyanlz/article/details/79254902
++++Unity资源加密:https://blog.csdn.net/VRunSoftYanlz/article/details/87644514
++++PhotonServer简介:https://blog.csdn.net/VRunSoftYanlz/article/details/86652770
++++编写Photon游戏服务器:https://blog.csdn.net/VRunSoftYanlz/article/details/86682935
++++C#事件:https://blog.csdn.net/vrunsoftyanlz/article/details/78631267
++++C#委托:https://blog.csdn.net/vrunsoftyanlz/article/details/78631183
++++C#集合:https://blog.csdn.net/vrunsoftyanlz/article/details/78631175
++++C#泛型:https://blog.csdn.net/vrunsoftyanlz/article/details/78631141
++++C#接口:https://blog.csdn.net/vrunsoftyanlz/article/details/78631122
++++C#静态类:https://blog.csdn.net/vrunsoftyanlz/article/details/78630979
++++C#中System.String类:https://blog.csdn.net/vrunsoftyanlz/article/details/78630945
++++C#数据类型:https://blog.csdn.net/vrunsoftyanlz/article/details/78630913
++++Unity3D默认的快捷键:https://blog.csdn.net/vrunsoftyanlz/article/details/78630838
++++游戏相关缩写:https://blog.csdn.net/vrunsoftyanlz/article/details/78630687
++++UnityAPI.Rigidbody刚体:https://blog.csdn.net/VRunSoftYanlz/article/details/81784053
++++UnityAPI.Material材质:https://blog.csdn.net/VRunSoftYanlz/article/details/81814303
++++UnityAPI.Android安卓:https://blog.csdn.net/VRunSoftYanlz/article/details/81843193
++++UnityAPI.AndroidJNI安卓JNI:https://blog.csdn.net/VRunSoftYanlz/article/details/81879345
++++UnityAPI.Transform变换:https://blog.csdn.net/VRunSoftYanlz/article/details/81916293
++++UnityAPI.WheelCollider轮碰撞器:https://blog.csdn.net/VRunSoftYanlz/article/details/82356217
++++UnityAPI.Resources资源:https://blog.csdn.net/VRunSoftYanlz/article/details/83155518
++++JSON数据结构:https://blog.csdn.net/VRunSoftYanlz/article/details/82026644
++++CocosStudio快速入门:https://blog.csdn.net/VRunSoftYanlz/article/details/82356839
++++Unity企业内训(目录):https://blog.csdn.net/VRunSoftYanlz/article/details/82634668
++++Unity企业内训(第1讲):https://blog.csdn.net/VRunSoftYanlz/article/details/82634733
++++Unity企业内训(第2讲):https://blog.csdn.net/VRunSoftYanlz/article/details/82861180
++++Unity企业内训(第3讲):https://blog.csdn.net/VRunSoftYanlz/article/details/82927699
++++Unity企业内训(第4讲):https://blog.csdn.net/VRunSoftYanlz/article/details/83479776
++++Unity企业内训(第5讲):https://blog.csdn.net/VRunSoftYanlz/article/details/83963811
++++Unity企业内训(第6讲):https://blog.csdn.net/VRunSoftYanlz/article/details/84207696
++++钻哥带您了解产品原型:https://blog.csdn.net/VRunSoftYanlz/article/details/87303828
++++插件
++++计算机组成原理(教材篇):https://blog.csdn.net/VRunSoftYanlz/article/details/82719129
++++5G接入:云计算和雾计算:https://blog.csdn.net/VRunSoftYanlz/article/details/88372718
++++云计算通俗讲义:https://blog.csdn.net/VRunSoftYanlz/article/details/88652803
++++立钻哥哥Unity 学习空间: http://blog.csdn.net/VRunSoftYanlz/
--_--VRunSoft:lovezuanzuan--_--