导航:首页 > 源码编译 > make源码剖析

make源码剖析

发布时间:2022-05-02 19:10:10

❶ 怎么使用,手上有一本linux内核2.4版源代码分析大全

一般在Linux系统中的/usr/src/linux*.*.*(*.*.*代表的是内核版本,如2.4.23)目录下就是内核源代码(如果没有类似目录,是因为还没安装内核代码)。另外还可从互连网上下载。注意,不要总到去下载,最好使用它的镜像站点下载。请在mirrors/里找一个合适的下载点,再到pub/linux/kernel/v2.6/目录下去下载2.4.23内核。
代码目录结构
在阅读源码之前,还应知道Linux内核源码的整体分布情况。现代的操作系统一般由进程管理、内存管理、文件系统、驱动程序和网络等组成。Linux内核源码的各个目录大致与此相对应,其组成如下(假设相对于Linux-2.4.23目录):
1.arch目录包括了所有和体系结构相关的核心代码。它下面的每一个子目录都代表一种Linux支持的体系结构,例如i386就是Intel CPU及与之相兼容体系结构的子目录。PC机一般都基于此目录。
2.include目录包括编译核心所需要的大部分头文件,例如与平台无关的头文件在include/linux子目录下。
3.init目录包含核心的初始化代码(不是系统的引导代码),有main.c和Version.c两个文件。这是研究核心如何工作的好起点。
4.mm目录包含了所有的内存管理代码。与具体硬件体系结构相关的内存管理代码位于arch/*/mm目录下。
5.drivers目录中是系统中所有的设备驱动程序。它又进一步划分成几类设备驱动,每一种有对应的子目录,如声卡的驱动对应于drivers/sound。
6.ipc目录包含了核心进程间的通信代码。
7.moles目录存放了已建好的、可动态加载的模块。
8.fs目录存放Linux支持的文件系统代码。不同的文件系统有不同的子目录对应,如ext3文件系统对应的就是ext3子目录。
Kernel内核管理的核心代码放在这里。同时与处理器结构相关代码都放在arch/*/kernel目录下。
9.net目录里是核心的网络部分代码,其每个子目录对应于网络的一个方面。
10.lib目录包含了核心的库代码,不过与处理器结构相关的库代码被放在arch/*/lib/目录下。
11.scripts目录包含用于配置核心的脚本文件。
12.documentation目录下是一些文档,是对每个目录作用的具体说明。
一般在每个目录下都有一个.depend文件和一个Makefile文件。这两个文件都是编译时使用的辅助文件。仔细阅读这两个文件对弄清各个文件之间的联系和依托关系很有帮助。另外有的目录下还有Readme文件,它是对该目录下文件的一些说明,同样有利于对内核源码的理解。
在阅读方法或顺序上,有纵向与横向之分。所谓纵向就是顺着程序的执行顺序逐步进行;所谓横向,就是按模块进行。它们经常结合在一起进行。对于Linux启动的代码可顺着Linux的启动顺序一步步来阅读;对于像内存管理部分,可以单独拿出来进行阅读分析。实际上这是一个反复的过程,不可能读一遍就理解。

❷ 有关计算机的好书介绍一下

编程珠玑》(推荐,思维方法很好)
《c专家编程》(强烈推荐,虽然绝版,而且上面有些不符合现在标准的内容,不过看完后,C的功力还是会大增)
《c++ primer plus》(强烈推荐,C++入门级书本,内容相当详细)
《effective c++》(强烈推荐,看完C++功力绝对大涨)
《more effective c++》(同上,一个作者写的)
《c++标准程序库》(推荐STL入门读物,可当工具书)
《STL源码剖析》(推荐,可以先通过该书了解STL的实作,结合现在的代码,足以让人领略STL的伟大之处……)
《深入浅出MFC》(说实话,没看完,不过用来了解MFC的体系还是很不错的,不推荐初学者看)

《linux c编程》(前半部分讲make file很详细,后半部分就一般般了……)
《UINX环境高级编程(second edition)》(强烈推荐,大师之作,怎能不看?这本英文容易看懂,看英文就可以了)
《linux内核完全剖析》(看得不多,感觉暂时还不大懂-,-)
《windows系统编程》(Johnson M.Hart)(学习windows api的入门书,不是GUI的API)
《Windows程序设计》(Charles Petzold)(强烈推荐,这本用来学习windows GUI就相当合适了)

java how to program》(推荐,java入门书,内容很不错)
《java编程思想》(没读过英文的,不过中文的读着很累,对java剖析地很深)

《IBM-PC 汇编语言程序设计》(推荐,学汇编的好书……)

《数据结构与算法分析——c语言描述》(Mark Allen Weiss)(推荐,内容丰富,不过基本上是伪代码描述)
《数据结构与程序设计——c语言(第二版)》(Robert L.Kruse)(个人学这本入门,觉得很不错=。=)
《计算机算法(c++版)》(后半部分过难还没看,前半部分还是很不错的)
《算法艺术与信息学竞赛》(题目无数,提及了相当多的算法,适合做OI/ICPC导向性读物。)
《算法导论(second edition)》(强烈推荐,没听过的话太让人失望了……)
《C语言名题精选百则技巧篇》(推荐,都是一些很经典的东西,代码风格不错)

《operating system concepts》(强烈推荐,名着啊)
《modern operating systems》(推荐,英文没上面那本好懂,不过作者有相同的人)
《artificial intelligence --- a modern approach》(看了一点,学习人工智能绝对的好书)
《compilers: principles, techniques, and tools》(强烈推荐,学习编译原理必备)

我很认真的上网搜的,希望可以帮到你,呵呵

❸ 作为一个新手,我该如何看懂UBOOT的源代码,我看了几天,还是分析不出那些函数的作用

拿到代码都是先从整体再到局部的
先看框架 任何symbian复杂的代码都是从UI生产view,view创建container的
很大一部分代码都会和container打交道的,因为它是控件的容器嘛。
不要太去专注人家的算法 先没必要浪费那时间 知道这个类是干什么的 都有什么方法 基本就可以了 还有类与类之间的关系呢 也要搞明白 这个呢 通常调试跟一下 会有所明白吧
代码里肯定会有你不认识不了解陌生的API 你英语好的话 查SDK 英语不好的话 google一下 或多或少都有些答案的
以上是我看代码的一个基本流程吧 当然拿到一分陌生又复杂的代码头很大 但还是有规律可循的 抓住主干UI-

❹ 根据提供的Linux操作系统源码中的Makefile结构,分析在工程多级目录中存在多个makefile文件时编译的顺序如

书上56页有讲
make的递归过程指的是:在Makefile中使用“make”作为一个命令来执行本身或者其它makefile文件的过程。递归调用在一个存在有多级子目录的项目中非常有用。例如,当前目录下存在一个“subdir”子目录,在这个子目录中有描述此目录编译规则的makefile文件,在执行make时需要从上层目录(当前目录)开始并完成它所有子目录的编译。那么在当前目录下可以使用这样一个规则来实现对这个子目录的编译:
subsystem:
cd subdir && $(MAKE)

其等价于规则:

subsystem:
$(MAKE) -C subdir

❺ 求一段Linux操作系统源代码分析

Linux内核的配置系统由三个部分组成,分别是:
Makefile:分布在 Linux 内核源代码中的 Makefile,定义 Linux 内核的编译规则;
配置文件(config.in):给用户提供配置选择的功能;
配置工具:包括配置命令解释器(对配置脚本中使用的配置命令进行解释)和配置用户界面(提供基于字符界面、基于 Ncurses 图形界面以及基于 Xwindows 图形界面的用户配置界面,各自对应于 Make config、Make menuconfig 和 make xconfig)。
这些配置工具都是使用脚本语言,如 Tcl/TK、Perl 编写的(也包含一些用 C 编写的代码)。本文并不是对配置系统本身进行分析,而是介绍如何使用配置系统。所以,除非是配置系统的维护者,一般的内核开发者无须了解它们的原理,只需要知道如何编写 Makefile 和配置文件就可以。所以,在本文中,我们只对 Makefile 和配置文件进行讨论。另外,凡是涉及到与具体 CPU 体系结构相关的内容,我们都以 ARM 为例,这样不仅可以将讨论的问题明确化,而且对内容本身不产生影响。
2. Makefile
2.1 Makefile 概述
Makefile 的作用是根据配置的情况,构造出需要编译的源文件列表,然后分别编译,并把目标代码链接到一起,最终形成 Linux 内核二进制文件。
由于 Linux 内核源代码是按照树形结构组织的,所以 Makefile 也被分布在目录树中。Linux 内核中的 Makefile 以及与 Makefile 直接相关的文件有:

Makefile:顶层 Makefile,是整个内核配置、编译的总体控制文件。
.config:内核配置文件,包含由用户选择的配置选项,用来存放内核配置后的结果(如 make config)。
arch/*/Makefile:位于各种 CPU 体系目录下的 Makefile,如 arch/arm/Makefile,是针对特定平台的 Makefile。
各个子目录下的 Makefile:比如 drivers/Makefile,负责所在子目录下源代码的管理。
Rules.make:规则文件,被所有的 Makefile 使用。
用户通过 make config 配置后,产生了 .config。顶层 Makefile 读入 .config 中的配置选择。顶层 Makefile 有两个主要的任务:产生 vmlinux 文件和内核模块(mole)。为了达到此目的,顶层 Makefile 递归的进入到内核的各个子目录中,分别调用位于这些子目录中的 Makefile。至于到底进入哪些子目录,取决于内核的配置。在顶层 Makefile 中,有一句:include arch/$(ARCH)/Makefile,包含了特定 CPU 体系结构下的 Makefile,这个 Makefile 中包含了平台相关的信息。
位于各个子目录下的 Makefile 同样也根据 .config 给出的配置信息,构造出当前配置下需要的源文件列表,并在文件的最后有 include $(TOPDIR)/Rules.make。
Rules.make 文件起着非常重要的作用,它定义了所有 Makefile 共用的编译规则。比如,如果需要将本目录下所有的 c 程序编译成汇编代码,需要在 Makefile 中有以下的编译规则:
%.s: %.c
$(CC) $(CFLAGS) -S $< -o $@

有很多子目录下都有同样的要求,就需要在各自的 Makefile 中包含此编译规则,这会比较麻烦。而 Linux 内核中则把此类的编译规则统一放置到 Rules.make 中,并在各自的 Makefile 中包含进了 Rules.make(include Rules.make),这样就避免了在多个 Makefile 中重复同样的规则。对于上面的例子,在 Rules.make 中对应的规则为:
%.s: %.c
$(CC) $(CFLAGS) $(EXTRA_CFLAGS) $(CFLAGS_$(*F)) $(CFLAGS_$@) -S $< -o $@

2.2 Makefile 中的变量
顶层 Makefile 定义并向环境中输出了许多变量,为各个子目录下的 Makefile 传递一些信息。有些变量,比如 SUBDIRS,不仅在顶层 Makefile 中定义并且赋初值,而且在 arch/*/Makefile 还作了扩充。
常用的变量有以下几类:
1) 版本信息
版本信息有:VERSION,PATCHLEVEL, SUBLEVEL, EXTRAVERSION,KERNELRELEASE。版本信息定义了当前内核的版本,比如 VERSION=2,PATCHLEVEL=4,SUBLEVEL=18,EXATAVERSION=-rmk7,它们共同构成内核的发行版本KERNELRELEASE:2.4.18-rmk7
2) CPU 体系结构:ARCH
在顶层 Makefile 的开头,用 ARCH 定义目标 CPU 的体系结构,比如 ARCH:=arm 等。许多子目录的 Makefile 中,要根据 ARCH 的定义选择编译源文件的列表。
3) 路径信息:TOPDIR, SUBDIRS
TOPDIR 定义了 Linux 内核源代码所在的根目录。例如,各个子目录下的 Makefile 通过 $(TOPDIR)/Rules.make 就可以找到 Rules.make 的位置。
SUBDIRS 定义了一个目录列表,在编译内核或模块时,顶层 Makefile 就是根据 SUBDIRS 来决定进入哪些子目录。SUBDIRS 的值取决于内核的配置,在顶层 Makefile 中 SUBDIRS 赋值为 kernel drivers mm fs net ipc lib;根据内核的配置情况,在 arch/*/Makefile 中扩充了 SUBDIRS 的值,参见4)中的例子。
4) 内核组成信息:HEAD, CORE_FILES, NETWORKS, DRIVERS, LIBS
Linux 内核文件 vmlinux 是由以下规则产生的:
vmlinux: $(CONFIGURATION) init/main.o init/version.o linuxsubdirs
$(LD) $(LINKFLAGS) $(HEAD) init/main.o init/version.o
--start-group
$(CORE_FILES)
$(DRIVERS)
$(NETWORKS)
$(LIBS)
--end-group
-o vmlinux
可以看出,vmlinux 是由 HEAD、main.o、version.o、CORE_FILES、DRIVERS、NETWORKS 和 LIBS 组成的。这些变量(如 HEAD)都是用来定义连接生成 vmlinux 的目标文件和库文件列表。其中,HEAD在arch/*/Makefile 中定义,用来确定被最先链接进 vmlinux 的文件列表。比如,对于 ARM 系列的 CPU,HEAD 定义为:
HEAD := arch/arm/kernel/head-$(PROCESSOR).o
arch/arm/kernel/init_task.o
表明 head-$(PROCESSOR).o 和 init_task.o 需要最先被链接到 vmlinux 中。PROCESSOR 为 armv 或 armo,取决于目标 CPU。 CORE_FILES,NETWORK,DRIVERS 和 LIBS 在顶层 Makefile 中定义,并且由 arch/*/Makefile 根据需要进行扩充。 CORE_FILES 对应着内核的核心文件,有 kernel/kernel.o,mm/mm.o,fs/fs.o,ipc/ipc.o,可以看出,这些是组成内核最为重要的文件。同时,arch/arm/Makefile 对 CORE_FILES 进行了扩充:
# arch/arm/Makefile
# If we have a machine-specific directory, then include it in the build.
MACHDIR := arch/arm/mach-$(MACHINE)
ifeq ($(MACHDIR),$(wildcard $(MACHDIR)))
SUBDIRS += $(MACHDIR)
CORE_FILES := $(MACHDIR)/$(MACHINE).o $(CORE_FILES)
endif
HEAD := arch/arm/kernel/head-$(PROCESSOR).o
arch/arm/kernel/init_task.o
SUBDIRS += arch/arm/kernel arch/arm/mm arch/arm/lib arch/arm/nwfpe
CORE_FILES := arch/arm/kernel/kernel.o arch/arm/mm/mm.o $(CORE_FILES)
LIBS := arch/arm/lib/lib.a $(LIBS)

5) 编译信息:CPP, CC, AS, LD, AR,CFLAGS,LINKFLAGS
在 Rules.make 中定义的是编译的通用规则,具体到特定的场合,需要明确给出编译环境,编译环境就是在以上的变量中定义的。针对交叉编译的要求,定义了 CROSS_COMPILE。比如:
CROSS_COMPILE = arm-linux-
CC = $(CROSS_COMPILE)gcc
LD = $(CROSS_COMPILE)ld
......
CROSS_COMPILE 定义了交叉编译器前缀 arm-linux-,表明所有的交叉编译工具都是以 arm-linux- 开头的,所以在各个交叉编译器工具之前,都加入了 $(CROSS_COMPILE),以组成一个完整的交叉编译工具文件名,比如 arm-linux-gcc。
CFLAGS 定义了传递给 C 编译器的参数。
LINKFLAGS 是链接生成 vmlinux 时,由链接器使用的参数。LINKFLAGS 在 arm/*/Makefile 中定义,比如:
# arch/arm/Makefile
LINKFLAGS :=-p -X -T arch/arm/vmlinux.lds

6) 配置变量CONFIG_*
.config 文件中有许多的配置变量等式,用来说明用户配置的结果。例如 CONFIG_MODULES=y 表明用户选择了 Linux 内核的模块功能。
.config 被顶层 Makefile 包含后,就形成许多的配置变量,每个配置变量具有确定的值:y 表示本编译选项对应的内核代码被静态编译进 Linux 内核;m 表示本编译选项对应的内核代码被编译成模块;n 表示不选择此编译选项;如果根本就没有选择,那么配置变量的值为空。
2.3 Rules.make 变量
前面讲过,Rules.make 是编译规则文件,所有的 Makefile 中都会包括 Rules.make。Rules.make 文件定义了许多变量,最为重要是那些编译、链接列表变量。
O_OBJS,L_OBJS,OX_OBJS,LX_OBJS:本目录下需要编译进 Linux 内核 vmlinux 的目标文件列表,其中 OX_OBJS 和 LX_OBJS 中的 "X" 表明目标文件使用了 EXPORT_SYMBOL 输出符号。
M_OBJS,MX_OBJS:本目录下需要被编译成可装载模块的目标文件列表。同样,MX_OBJS 中的 "X" 表明目标文件使用了 EXPORT_SYMBOL 输出符号。
O_TARGET,L_TARGET:每个子目录下都有一个 O_TARGET 或 L_TARGET,Rules.make 首先从源代码编译生成 O_OBJS 和 OX_OBJS 中所有的目标文件,然后使用 $(LD) -r 把它们链接成一个 O_TARGET 或 L_TARGET。O_TARGET 以 .o 结尾,而 L_TARGET 以 .a 结尾。

❻ 根据提供的Linux 操作系统源码中Makefile 结构,分析在工程中多级目录中存在着多个makefile 时,编译的顺

多级目录的编译顺序也是有Makefile控制的, 如下这个例子(3个子目录, 一个Makefile), 子目录的编译顺序由这个Makefile控制.
sub_a sub_b sub_c Makefile

❼ 推荐一些学C++的书

这是某个网友的工作总结,很适合你的。

掐指一算工作也已经十个月了,再过两个月就算是我合理度过工作一年的门槛,这一年学到了什么,错过了什么,很值得在新的一年开始的时候反思及总结一下,不然未来可能会更加盲目。。。。
回想起2008年刚刚出来找工作的时候,仅仅是学了《C++ Primer》一书,并且看过《Programming With MFC》的前面大部分章节,竟然找工作很顺利:)因为好像大部分纯粹是从学校出来的毕业生,哪怕是科班出生的,因为教材即教育方式的限制,甚至都还不知道什么叫标准库-_-!我没有夸张,这是我工作后了解到的现实,也是与一些后来在读大学生交流后才知道的。所以,虽然我当时感觉自己知道的并不多,但是实际上公司却发现我似乎懂得很多:)

刚开始的计划:作为电子通信专业出来,但是最后走向纯粹软件行业的我,知道自己的不足,对于基础知识的掌握太过薄弱,可能会限制自己将来的发展,我一开始工作就知道的。我并不认为起步阶段,在我们公司,更熟悉得一些C++语法能够是一辈子的优势,这些在工作一年以后都会成为泡沫。。。。所以这刚开始的时候,其实我给自己定下了一些目标:
1. 首先当然是继续学习好C++,争取把找工作前读了一半的《Effective C++》读完,另外应该再接再厉将《More Effective C++》和《Effective STL》读完。
2. 数据结构及算法部分我一直认为是自己最最欠缺的,因为毕竟大学学的“软件技术基础”课程和真正的计算机专业相差太远,所以我一直以来认为自己起码在开始的一年中补上,定的计划是学习完Weiss《数据结构与算法分析 C++描述》和《算法导论》一书。
3. 当时刚开始进公司,是分配到网络游戏服务器小组的,一开始自己就对服务器方面能开发网络程序抱有兴趣,学习网络方面的知识自然也在计划之中,当时的设想是在Windows方面学习《Win32多线程编程》,Linux方面学习《Unix环境高级编程》,《TCP/IP详解》第一卷,《Unix网络编程》第一卷的。
以上就是我为自己一年工作后应该学习的东西。。。。。。。。到现在回头看看,感慨颇多,因为虽然一年期限只剩下2个月了,其实还有太多太多事情没有做。

计划的未完成:第1步的书我仅仅只看完了《Effective C++》。。。。因为当时买的都是原版书,所以看完《Effective C++》都是硬着头皮上的,后来好像总感觉精力不足,没有勇气看下去了,或者是自己感觉有更多更重要的事情需要去做,所以就没有继续了。
第2步我一直认为很重要,中途的确也开始学习过,就在前段时间,我不仅仅是看Weiss《数据结构与算法分析 C++描述》一书,并且还附带同步阅读侯捷的《STL源码剖析》一书,最最绝的是,因为刚学完好几种语言,我当时是尝试用各种语言去实现书上的算法和数据结构的。但是学习完了二叉树部分以后,我的工作转到了反外挂上面,因为的确比较喜欢这样底层的工作,所以大部分工作后的时间(本来就不多)都自己去弄汇编去了,数据结构的学习也就中断了。
第3步,除了《Win32多线程编程》一书我的确是从头到尾看过了,《Unix环境高级编程》当时是安排在公司利用吃饭的间隙和下午休息时间看的,但是仅仅是看了个开头,然后我的工作从服务器组换到了客户端去了,公司此时服务器紧张,唯一的一台Linux服务器也分配给了网络方面去做数据库去了,我在公司甚至一台可以登陆的Linux服务器都没有,所以作罢,当书从公司带到家里来后,因为当时家里也有别的学习计划,所以中断了。《TCP/IP详解》第一卷一书TCP,UDP部分因为刚开始做服务器时,在总监的指导下(其实就是给我用工作时间来看),大概看过了,《Unix网络编程》第一卷也是出于同样的原因我看过了利用套接字编写简单的TCP,UDP程序部分,其他的后来都没有看。
总而言之,从计划的完成角度上来看,我这一年是及其失败的,因为似乎该看的都没有看。。。该学的都没有学。但是回过头来看,其实计划一开始指定的时候是我刚刚开始工作,懂得并不多的时候,很多时候我的学习并没有怠慢,仅仅是因为工作中碰到感觉自己更感兴趣,或者是觉得更有作用的知识,所以学习方向有所偏差了。

计划不如变化:的确后来发生的事情是计划不如变化了-_-!因为第一个实际的工作并不是和网络有关的,所以刚开始工作时网络知识的学习中断了,看过我以前的总结的人就会知道,我来公司做的第一个事情就是一个“未控制异常Dump系统”我也不知道该怎么描述这个工作,也许用英文更能表达,“Error Dump”。在做这个工作的时候总监为了让我理解SEH,所以拿出他的《Windows核心编程》给我看,看完此章节后,我如获至宝,感觉此书非读不可,好书就是好书,哪怕我仅仅是突然读了12章节,都会觉得欲罢不能,所以,最后我从网上购得此书,完全学过!受益良多!在此推荐一下此书^^

在看此书的这个时候我的第2个工作内容也正如火如荼的进行,基本上那时候在公司我就看《Windows核心编程》在家我就看《Effective C++》,我的第2个工作(不是换公司哦,仅仅是换了内容)是做一个文件系统,一个这么大的东西给我一直当时刚参加工作不到一个月的家伙,说明公司的确还看的起我,我一直这么认为:)其实这个文件系统的修补及优化一直是贯穿与我这一年的工作的-_-!直到最近还有个莫名奇妙的非必出Bug还没有解决-_-!

就是在这个工作中我第一次写概要设计,详细设计等设计文档,并开始自己设计并编码完成一个独立的模块,对于这些知识的重要,在现在看来,怎么评价都不过分,这是我非常非常感谢公司的地方,能够在一开始就给了我这样重要的机会,当时还趁着公司的需要,学习了一下软件工程方面(当时甚至不理解什么叫需求-_-!)的和UML方面的知识。这些我也是感觉受益良多。对于这么一个比较大的系统,我自己对怎么编码才能够在后期能够很好的改动维护也慢慢的有了一些想法,特别是对于OO思想的领悟感觉上了一个台阶。毕竟我刚开始工作的时候,还谈不上任何成型的思想的,仅仅是懂C++语法而已。
接下来的工作很有意思,我得将我在Windows下写的文件系统移植到Linux下面去,这期间我开始在工作中真正的接触Linux(以前读书的时候仅仅是玩Linux,其实牵涉到编程的很少),这期间虽然工作中因为原有的框架很成型,并没有太多的需要我学习的地方,但是我还是学习了一下Makefile的编写,g++的使用,并且再一次的用上了Vim,呵呵,当时那样用Putty登上服务器编写的模式,除了Vim我似乎没有别的选择。但是此时我还是勉强的适应Vim而已。此时也大概的了解了一下哪些函数可能是MS扩充的,哪些是ISO的,哪些是POSIX的,起码对于这些概念都有了了解,以后也不至于编写可移植程序还使用Win32 API的错误:)
最最有意思的是,在客户端弄了这么久,服务器已经暂时不需要我了,于是我继续在客户端方面工作,包括一个游戏TrayIcon功能,外置聊天窗口,这是对于GameUI方面的知识有所了解。然后是为游戏引擎分析并选择一个最佳的XML解析器,再然后是为游戏底层类创建,添加了一个工厂模式。其实那时也还没有理解XML到底是什么用的,为什么我们游戏需要那么麻烦速度又不快的配置,那时候也不明白优化的过程中其实使用的是重构的思想,也不明白工厂模式这样的设计模式到底有什么功能,仅仅是参考CEGUI的实现硬生生的照搬了一套。但是说实话,不是这次的经历,在第二次再碰到设计模式相关的知识需要时,我也不会下定决心,最后读完了一整本原版GOF的《设计模式》一书。。。。
再后来的工作就更有意思了,客户端总监叫我好好的看看Lua方面的知识,方便为客户端添加一套脚本系统。这时真是变化太快,这些知识完全脱离了计划,因为公司能够让我用整天整天的工作时间来看书,我无论是上班还是下班都在看书,整整学习完了一本《Programming in LUA》,对于脚本语言的特性理解受益匪浅,对于LUA这样的为嵌入式而生的脚本语言更加是了解了更多。此时虽然因为公司考虑到因为游戏已经快要完成,此时添加这样的脚本系统不再合适,所以使用Lua的工作中断,但是我对脚本语言的兴趣并没有中断,我接下来不仅没有放弃LUA的学习,甚至想起来接着学完以前学过又中断的python,看完了《Python核心编程》一书。学完Python后对于脚本语言的兴趣更加是无法收拾了,对于Python语法的优美感叹不已,库的丰富更加是五体投地。这也是后来我能够教女朋友去学Python的原因:)这和当年教她学习C简直就是两种体验-_-!

Python学习告一段落后,也一直没有使用机会,然后处于对Linux的兴趣,我开始独自摸索,我通过看完一本《Bash高级编程》学习了Bash,这是我学习的第3个脚本语言,但是说实话,感觉Bash是3个里面最难的,-_-!但是就是对Bash的学习,让我感觉Linux不再是繁复的操作系统,一切通过Bash来完成,很多时候能够比图形界面更加快,更加有效,这是实实在在的进步,因为以前在命令行中老是重复的敲代码,快烦透了,学了Bash以后我也开始知道什么叫“懒惰的程序员”了,那就是能够自动化操作的绝不自己一步一步操作:)再加上学习Lua,Python,Bash时都能统一用到的Vim编辑器,我对Vim的使用已经从勉强没有办法的适应到了没有Vim没有办法生存的地步。对于这么一个刚开始复杂到吐血,到用熟了极大的享受的工具,也让我慢慢有了一些思想,能够节省我时间的工具,我总是愿意去花时间学习,因为无论其多复杂,学习曲线再长,学会了还是受益无穷的!这对于我后来提高工作效率,愿意花时间去学习任何看起来能够对我有帮助的工具起到了决定性的作用!要知道,很久以前的我是语言至上,工具仅仅是工具,没有什么技术含量,谁不能学的思想!这个时候我才慢慢领悟到总监所说“工欲善其事必先利其器”的思想!于是我愿意花时间去学习Total Command提高我平时管理文件,操作文件的效率,去学习Visual Assist去提高我编码的效率,去学习AQTime以提高我profile的效率,学习DevPartner以提高开发后Test的效率,学习SoftIce, OllyDbg, IDA Pro去提高我反汇编的效率,这些都和我使用Vim从勉强到离不开的经历有关!
再到了后来我写了一个日志服务器,用以记录游戏运行时候的数据,虽然用到了MySQL C API,但是我竟然一直没有想过好好地去重新学习SQL和MySQL的使用,这是我工作以来的第一次-_-!工作中碰到,然后自己没有去好好深入学习的东西可能就是数据库了,包括后来我再次用到了SQL Sever时,我还是没有深入去学习。
然后开始完成工作中最大规模的系统,游戏服务器的监控系统,对于一个这样包含了监视,控制等操作的大型系统,设计来管理公司将来所有运行的服务器,而此系统几乎我是一人独立设计编码完成的!初期的概要设计阶段,由我设计监控点端,由一同事设计监控中心,到了后来,除了监控的前段界面不是我做的,我一人全部包揽其他所有部分的设计及编码工作。
此工作让我对于一个系统整体的理解,设计,以编码实现的思想提高,怎么评价也不过分。其中最有意思的一个插曲是在监控点一端我用到了状态机模式,也就是这样,老总推荐了我一本书去看GOF的《设计模式》,虽然他仅仅是叫我去看看状态机模式,并完成工作,但是按照本人的工作惯性,最后还是将整本《设计模式》23个设计模式完全看完,呵呵,只可惜,从那以后好像一直没有再开发一个系统的工作可以做了,所以学到的东西都还在肚子里面没有办法发挥。
再后来通过做一个内存管理模块,对于号称C/C++最大的缺陷,内存管理部分有了一定的了解,但是这个工作由于比较仓促,说实话,最后的了解实在有限。但是对于我后来去看《STL源码剖析》最最前面的内存分配器方面的内容帮助不小,对于此号称很难的部分理解起来几乎全无困难。
再到后来,我开始做工具-_-!这是最无聊的工作,虽然是优化,但是我几乎重做,这里我需要反思,因为我无规模概念的将本来可以短时间内完成的工作用了很长时间才完成,但是我在此时对于优化C++代码的一些问题慢慢在脑海中形成。并且在这段时间中我按照原有计划,开始学习数据结构的知识。
再接下来,我更进一步的去优化了原有的文件系统,使得其速度得到了很大的提升,这时候我爱上了AQTime这样一个工具,就是它使得优化工作从以前的不停插入GetTime代码,到后来的编码完成,运行,看数据这样享受的过程!
再后来,开始做反外挂工作,现在也还在做,但是慢慢的发现老总的想法和自己有所偏差,我一直希望尽量高强度的去预防,而老总却常常觉得到一定规模就够了,因为毕竟我们不是专家,花太多时间并不值得。这段时间我将我全部的精力都用在了反汇编上面,看了不少C++的反汇编代码,结合前段时间看的《Inside C++ Object》一书,理解透了不少东西。正好也学习了一下C/C++中调用汇编代码和汇编代码中调用C/C++函数的方法,这些在将来做汇编优化的时候肯定有用。说实话,我很高兴我能在工作的初期阶段就能进行类似这样的工作,去了解壳,PE文件结构等知识,这些工作的受益可以是影响一辈子的!和数据结构的知识相比也毫不逊色!我当时的想法我趁此时投入全部精力好好的学习Win32 汇编,但是看起来现在是没有太多时间了。此事中间有个插曲,为了防止太容易的被人反汇编,我们在整个反外挂系统中加入了一些Python元素,这部分的工作因为我以前学过Python自然的交到了我头上,而我在额外熟悉了Python C API接口的基础上,肯定是很快的完成了任务:)这点倒真是戏剧性,工作外的学习,最后也对工作有了帮助。
接下来的目标:第一年就学习的我这么杂的程序员估计不多了,的确太杂了,所以我还是好好的按照原有计划来,将网络部分好好精通吧,不然感觉和一事无成也差不太远,虽然就算上述所有的杂项知识都用不上,其实对于我对于一些新API的掌握也比刚开始的速度要快多了,毕竟学的多了:)
网络,这是我剩下两个月中最最重要的目标。我要在工作满一年之际,发现我已经可以编写一般的网络程序,甚至小型高效的网络框架!

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/vagrxie/archive/2009/02/09/3868743.aspx

❽ 黑马程序员的Python培训内容有什么

黑马程序员

链接: https://pan..com/s/1DLZapQQYaVhzQCC5Ek9jDA

提取码: a9tz 复制这段内容后打开网络网盘手机App,操作更方便哦

若资源有问题欢迎追问~

❾ linux初学者问一个glibc的源代码。

应该是宏定义吧,因为它不是一个语句,而是直接一行代码。。另外,你可以阅读一下。。

sysdeps/unix/make-syscalls.sh
sysdeps/unix/syscalls.list(sysdeps/unix/inet/syscalls.list)
sysdeps/unix/syscall-template.S
syscall-template.S顾名思义是个定义的模板,每个生成的系统调用都要参考这个模板,但是怎么用模板来“刻画”每一个系统调用呢?于是就有了syscalls.list,而make-syscalls.sh就是用模板和那个列表来构建生成系统调用定义的makefile,该makefile最终生成最后的定义。有兴趣的朋友应该仔细看看这几个文件。
现在再想想,这么做其实是有道理的,在Linux下,系统调用的真正定义有很多相似的地方,确实可以通过“模板”来生成对应的汇编,但是否真值得花时间去构建那么抽象的一个模板和框架?我说不清楚,本着“懒惰”的原则确实应该如此,不过看看模板本身似乎原因不仅仅是“懒惰”。
从这里我们也可以看出glibc的代码难读啊,比起Linux内核来,不仅仅是风格的问题,还有就是使用了太多的tricks,导致的结果也很显而易见,参与glibc开发的和参与linux内核开发的人明显不是一个数量级的。

另外读glibc 建议 参考 c函数库 源码剖析 (一本电子书 网上找一下) 有具体的实现。。

❿ 如何打包安卓手机Zip升级包如何签名不换Recovery,用官方Recovery

通过分析update.zip包在具体android系统升级的过程,来理解Android系统中Recovery模式服务的工作原理。
我们先从update.zip包的制作开始,然后是Android系统的启动模式分析,Recovery工作原理,如何从我们上层开始选择system update到重启到Recovery服务,以及在Recovery服务中具体怎样处理update.zip包升级的,我们的安装脚本updater-script怎样被解析并执行的等一系列问题。分析过程中所用的Android源码是gingerbread0919(tcc88xx开发板标配的),测试开发板是tcc88xx。
一、 update.zip包的目录结构
|----boot.img
|----system/
|----recovery/
`|----recovery-from-boot.p
`|----etc/
`|----install-recovery.sh
|---META-INF/
`|CERT.RSA
`|CERT.SF
`|MANIFEST.MF
`|----com/
`|----google/
`|----android/
`|----update-binary
`|----updater-script
`|----android/
`|----metadata
二、 update.zip包目录结构详解
以上是我们用命令make otapackage 制作的update.zip包的标准目录结构。
1、boot.img是更新boot分区所需要的文件。这个boot.img主要包括kernel+ramdisk。
2、system/目录的内容在升级后会放在系统的system分区。主要用来更新系统的一些应用或则应用会用到的一些库等等。可以将Android源码编译out/target/proct/tcc8800/system/中的所有文件拷贝到这个目录来代替。
3、recovery/目录中的recovery-from-boot.p是boot.img和recovery.img的补丁(patch),主要用来更新recovery分区,其中etc/目录下的install-recovery.sh是更新脚本。
4、update-binary是一个二进制文件,相当于一个脚本解释器,能够识别updater-script中描述的操作。该文件在Android源码编译后out/target/proct/tcc8800/system bin/updater生成,可将updater重命名为update-binary得到。
该文件在具体的更新包中的名字由源码中bootable/recovery/install.c中的宏ASSUMED_UPDATE_BINARY_NAME的值而定。
5、updater-script:此文件是一个脚本文件,具体描述了更新过程。我们可以根据具体情况编写该脚本来适应我们的具体需求。该文件的命名由源码中bootable/recovery/updater/updater.c文件中的宏SCRIPT_NAME的值而定。
6、 metadata文件是描述设备信息及环境变量的元数据。主要包括一些编译选项,签名公钥,时间戳以及设备型号等。
7、我们还可以在包中添加userdata目录,来更新系统中的用户数据部分。这部分内容在更新后会存放在系统的/data目录下。
8、update.zip包的签名:update.zip更新包在制作完成后需要对其签名,否则在升级时会出现认证失败的错误提示。而且签名要使用和目标板一致的加密公钥。加密公钥及加密需要的三个文件在Android源码编译后生成的具体路径为:
out/host/linux-x86/framework/signapk.jar
build/target/proct/security/testkey.x509.pem
build/target/proct/security/testkey.pk8 。
我们用命令make otapackage制作生成的update.zip包是已签过名的,如果自己做update.zip包时必须手动对其签名。
具体的加密方法:$ java –jar gingerbread/out/host/linux/framework/signapk.jar –w gingerbread/build/target/proct/security/testkey.x509.pem gingerbread/build/target/proct/security/testkey.pk8 update.zip update_signed.zip
以上命令在update.zip包所在的路径下执行,其中signapk.jar testkey.x509.pem以及testkey.pk8文件的引用使用绝对路径。update.zip 是我们已经打好的包,update_signed.zip包是命令执行完生成的已经签过名的包。
9、MANIFEST.MF:这个manifest文件定义了与包的组成结构相关的数据。类似Android应用的mainfest.xml文件。
10、CERT.RSA:与签名文件相关联的签名程序块文件,它存储了用于签名JAR文件的公共签名。
11、CERT.SF:这是JAR文件的签名文件,其中前缀CERT代表签名者。
另外,在具体升级时,对update.zip包检查时大致会分三步:①检验SF文件与RSA文件是否匹配。②检验MANIFEST.MF与签名文件中的digest是否一致。③检验包中的文件与MANIFEST中所描述的是否一致。
三、 Android升级包update.zip的生成过程分析
1) 对于update.zip包的制作有两种方式,即手动制作和命令生成。
第一种手动制作:即按照update.zip的目录结构手动创建我们需要的目录。然后将对应的文件拷贝到相应的目录下,比如我们向系统中新加一个应用程序。可以将新增的应用拷贝到我们新建的update/system/app/下(system目录是事先拷贝编译源码后生成的system目录),打包并签名后,拷贝到SD卡就可以使用了。这种方式在实际的tcc8800开发板中未测试成功。签名部分未通过,可能与具体的开发板相关。
第二种制作方式:命令制作。Android源码系统中为我们提供了制作update.zip刷机包的命令,即make otapackage。该命令在编译源码完成后并在源码根目录下执行。 具体操作方式:在源码根目录下执行
①$ . build/envsetup.sh。
②$ lunch 然后选择你需要的配置(如17)。
③$ make otapackage。
在编译完源码后最好再执行一遍上面的①、②步防止执行③时出现未找到对应规则的错误提示。命令执行完成后生成的升级包所在位置在out/target/proct/full_tcc8800_evm_target_files-eng.mumu.20120309.111059.zip将这个包重新命名为update.zip,并拷贝到SD卡中即可使用。
这种方式(即完全升级)在tcc8800开发板中已测试成功。
2) 使用make otapackage命令生成update.zip的过程分析。
在源码根目录下执行make otapackage命令生成update.zip包主要分为两步,第一步是根据Makefile执行编译生成一个update原包(zip格式)。第二步是运行一个python脚本,并以上一步准备的zip包作为输入,最终生成我们需要的升级包。下面进一步分析这两个过程。
第一步:编译Makefile。对应的Makefile文件所在位置:build/core/Makefile。从该文件的884行(tcc8800,gingerbread0919)开始会生成一个zip包,这个包最后会用来制作OTA package 或者filesystem image。先将这部分的对应的Makefile贴出来如下:

[python] view plainprint?
# -----------------------------------------------------------------
# A zip of the directories that map to the target filesystem.
# This zip can be used to create an OTA package or filesystem image
# as a post-build step.
#
根据上面的Makefile可以分析这个包的生成过程:
首先创建一个root_zip根目录,并依次在此目录下创建所需要的如下其他目录
①创建RECOVERY目录,并填充该目录的内容,包括kernel的镜像和recovery根文件系统的镜像。此目录最终用于生成recovery.img。
②创建并填充BOOT目录。包含kernel和cmdline以及pagesize大小等,该目录最终用来生成boot.img。
③向SYSTEM目录填充system image。
④向DATA填充data image。
⑤用于生成OTA package包所需要的额外的内容。主要包括一些bin命令。
⑥创建META目录并向该目录下添加一些文本文件,如apkcerts.txt(描述apk文件用到的认证证书),misc_info.txt(描述Flash内存的块大小以及boot、recovery、system、userdata等分区的大小信息)。
⑦使用保留连接选项压缩我们在上面获得的root_zip目录。
⑧使用fs_config(build/tools/fs_config)配置上面的zip包内所有的系统文件(system/下各目录、文件)的权限属主等信息。fs_config包含了一个头文件#include“private/android_filesystem_config.h”。在这个头文件中以硬编码的方式设定了system目录下各文件的权限、属主。执行完配置后会将配置后的信息以文本方式输出 到META/filesystem_config.txt中。并再一次zip压缩成我们最终需要的原始包。
第二步:上面的zip包只是一个编译过程中生成的原始包。这个原始zip包在实际的编译过程中有两个作用,一是用来生成OTA update升级包,二是用来生成系统镜像。在编译过程中若生成OTA update升级包时会调用(具体位置在Makefile的1037行到1058行)一个名为ota_from_target_files的python脚本,位置在/build/tools/releasetools/ota_from_target_files。这个脚本的作用是以第一步生成的zip原始包作为输入,最终生成可用的OTA升级zip包。
二 下面我们分析ota_from_target_files这个python脚本是怎样生成最终zip包的。先讲这个脚本的代码贴出来如下:
[python] view plainprint?
import sys
if sys.hexversion < 0x02040000:
print >> sys.stderr, "Python 2.4 or newer is required."
sys.exit(1)
主函数main是python的入口函数,我们从main函数开始看,大概看一下main函数(脚本最后)里的流程就能知道脚本的执行过程了。
① 在main函数的开头,首先将用户设定的option选项存入OPTIONS变量中,它是一个python中的类。紧接着判断有没有额外的脚本,如果有就读入到OPTIONS变量中。
解压缩输入的zip包,即我们在上文生成的原始zip包。然后判断是否用到device-specific extensions(设备扩展)如果用到,随即读入到OPTIONS变量中。
③ 判断是否签名,然后判断是否有新内容的增量源,有的话就解压该增量源包放入一个临时变量中(source_zip)。自此,所有的准备工作已完毕,随即会调用该 脚本中最主要的函数WriteFullOTAPackage(input_zip,output_zip)
④ WriteFullOTAPackage函数的处理过程是先获得脚本的生成器。默认格式是edify。然后获得metadata元数据,此数据来至于Android的一些环境变量。然后获得设备配置参数比如api函数的版本。然后判断是否忽略时间戳。
⑤ WriteFullOTAPackage函数做完准备工作后就开始生成升级用的脚本文件(updater-script)了。生成脚本文件后将上一步获得的metadata元数据写入到输出包out_zip。
⑥至此一个完整的update.zip升级包就生成了。生成位置在:out/target/proct/tcc8800/full_tcc8800_evm-ota-eng.mumu.20120315.155326.zip。将升级包拷贝到SD卡中就可以用来升级了。
四、 Android OTA增量包update.zip的生成
在上面的过程中生成的update.zip升级包是全部系统的升级包。大小有80M多。这对手机用户来说,用来升级的流量是很大的。而且在实际升级中,我们只希望能够升级我们改变的那部分内容。这就需要使用增量包来升级。生成增量包的过程也需要上文中提到的ota_from_target_files.py的参与。
下面是制作update.zip增量包的过程。
① 在源码根目录下依次执行下列命令
$ . build/envsetup.sh
$ lunch 选择17
$ make
$ make otapackage
执行上面的命令后会在out/target/proct/tcc8800/下生成我们第一个系统升级包。我们先将其命名为A.zip
② 在源码中修改我们需要改变的部分,比如修改内核配置,增加新的驱动等等。修改后再一次执行上面的命令。就会生成第二个我们修改后生成的update.zip升级包。将 其命名为B.zip。
③ 在上文中我们看了ota_from_target_files.py脚本的使用帮助,其中选项-i就是用来生成差分增量包的。使用方法是以上面的A.zip 和B.zip包作为输入,以update.zip包作 为输出。生成的update.zip就是我们最后需要的增量包。
具体使用方式是:将上述两个包拷贝到源码根目录下,然后执行下面的命令。
$ ./build/tools/releasetools/ota_from_target_files -i A.zip B.zip update.zip。
在执行上述命令时会出现未找到recovery_api_version的错误。原因是在执行上面的脚本时如果使用选项i则会调用WriteIncrementalOTAPackage会从A包和B包中的META目录下搜索misc_info.txt来读取recovery_api_version的值。但是在执行make otapackage命令时生成的update.zip包中没有这个目录更没有这个文档。
此时我们就需要使用执行make otapackage生成的原始的zip包。这个包的位置在out/target/proct/tcc8800/obj/PACKAGING/target_files_intermediates/目录下,它是在用命令make otapackage之后的中间生产物,是最原始的升级包。我们将两次编译的生成的包分别重命名为A.zip和B.zip,并拷贝到SD卡根目录下重复执行上面的命令:
$ ./build/tools/releasetools/ota_form_target_files -i A.zip B.zip update.zip。
在上述命令即将执行完毕时,在device/telechips/common/releasetools.py会调用IncrementalOTA_InstallEnd,在这个函数中读取包中的RADIO/bootloader.img。
而包中是没有这个目录和bootloader.img的。所以执行失败,未能生成对应的update.zip。可能与我们未修改bootloader(升级firmware)有关。此问题在下一篇博客已经解决。
制作增量包失败的原因,以及解决方案。

Android系统Recovery工作原理之使用update.zip升级过程分析(二)---update.zip差分包问题的解决
在上一篇末尾提到的生成差分包时出现的问题,现已解决,由于最近比较忙,相隔的时间也比较长,所以单列一个篇幅提示大家。这个问题居然是源码中的问题,可能你已经制作成功了,不过我的这个问题确实是源码中的一个问题,不知道是不是一个bug,下文会具体分析!
一、生成OTA增量包失败的解决方案
在上一篇中末尾使用ota_from_target_files脚本制作update.zip增量包时失败,我们先将出现的错误贴出来。
在执行这个脚本的最后读取input_zip中RADIO/bootloader.img时出现错误,显示DeviceSpecifiParams这个对象中没有input_zip属性。
我们先从脚本中出现错误的调用函数中开始查找。出现错误的调用地方是在函WriteIncrementalOTAPackage(443行)中的device_specific.IncrementalOTA_InstallEnd(),其位于WriteIncrementalOTAPackage()中的末尾。进一步跟踪源码发现,这是一个回调函数,他的具体执行方法位于源码中/device/telechips/common/releasetools.py脚本中的IncrementalOTA_InstallEnd()函数。下面就分析这个函数的作用。
releasetools.py脚本中的两个函数FullOTA_InstallEnd()和IncrementalOTA_InstallEnd()的作用都是从输入包中读取RADIO/下的bootloader.img文件写到输出包中,同时生成安装bootloader.img时执行脚本的那部分命令。只不过一个是直接将输入包中的bootloader.img镜像写到输出包中,一个是先比较target_zip和source_zip中的bootloader.img是否不同(使用选项-i生成差分包时),然后将新的镜像写入输出包中。下面先将这个函数(位于/device/telechips/common/releasetools.py)的具体实现贴出来:
我们的实际情况是,在用命令make otapackage时生成的包中是没有这个RADIO目录下的bootloader.img镜像文件(因为这部分更新已被屏蔽掉了)。但是这个函数中对于从包中未读取到bootloader.img文件的情况是有错误处理的,即返回。所以我们要从 出现的实际错误中寻找问题的原由。
真正出现错误的地方是:
target_bootloader=info.input_zip.read(“RADIO/bootloader.img”)。
出现错误的原因是:AttributeError:‘DeviceSpecificParams’object has no attribute ‘input_zip’,提示我们DeviceSpecificParams对象没有input_zip这个属性。
二、updater-script脚本执行流程分析:
先看一下在测试过程中用命令make otapackage生成的升级脚本如下:
[python] view plainprint?
assert(!less_than_int(1331176658, getprop("ro.build.date.utc")));
assert(getprop("ro.proct.device") == "tcc8800" ||
下面分析下这个脚本的执行过程:
①比较时间戳:如果升级包较旧则终止脚本的执行。
②匹配设备信息:如果和当前的设备信息不一致,则停止脚本的执行。
③显示进度条:如果以上两步匹配则开始显示升级进度条。
④格式化system分区并挂载。
⑤提取包中的recovery以及system目录下的内容到系统的/system下。
⑥为/system/bin/下的命令文件建立符号连接。
⑦设置/system/下目录以及文件的属性。
⑧将包中的boot.img提取到/tmp/boot.img。
⑨将/tmp/boot.img镜像文件写入到boot分区。
⑩完成后卸载/system。
三、总结
以上的九篇着重分析了Android系统中Recovery模式中的一种,即我们做好的update.zip包在系统更新时所走过的流程。其核心部分就是Recovery服务的工作原理。其他两种FACTORY RESET、ENCRYPTED FILE SYSTEM ENABLE/DISABLE与OTA INSTALL是相通的。重点是要理解Recovery服务的工作原理。另外详细分析其升级过程,对于我们在实际升级时,可以根据我们的需要做出相应的修改。

阅读全文

与make源码剖析相关的资料

热点内容
喷油螺杆制冷压缩机 浏览:577
python员工信息登记表 浏览:375
高中美术pdf 浏览:158
java实现排列 浏览:511
javavector的用法 浏览:979
osi实现加密的三层 浏览:230
大众宝来原厂中控如何安装app 浏览:911
linux内核根文件系统 浏览:240
3d的命令面板不见了 浏览:521
武汉理工大学服务器ip地址 浏览:144
亚马逊云服务器登录 浏览:521
安卓手机如何进行文件处理 浏览:70
mysql执行系统命令 浏览:926
php支持curlhttps 浏览:142
新预算法责任 浏览:443
服务器如何处理5万人同时在线 浏览:247
哈夫曼编码数据压缩 浏览:424
锁定服务器是什么意思 浏览:383
场景检测算法 浏览:616
解压手机软件触屏 浏览:348