当前位置: 首页 > news >正文

网站设计配色方案wordpress 轻云

网站设计配色方案,wordpress 轻云,建设工程施工合同名词解释,品牌营销策划网站十天学Linux内核之第七天---电源开和关时都发生了什么 原文:十天学Linux内核之第七天---电源开和关时都发生了什么说实话感觉自己快写不下去了#xff0c;其一是有些勉强跟不上来#xff0c;其二是感觉自己越写越差#xff0c;刚开始可能是新鲜感以及很多读者的鼓励#xf… 十天学Linux内核之第七天---电源开和关时都发生了什么 原文:十天学Linux内核之第七天---电源开和关时都发生了什么  说实话感觉自己快写不下去了其一是有些勉强跟不上来其二是感觉自己越写越差刚开始可能是新鲜感以及很多读者的鼓励现在就是想快点完成自己制定的任务不过总有几个读者给自己鼓励很欣慰的事情不多感慨了加紧时间多多去探索吧今天要去描述的是电源开和关时都发生了什么一起去看看吧~~   bootloader引导装入程序将内核映像加载到内存并处理控制权传送到内核后在内核引导时每个子系统都必须要初始化我们根据实际执行的线性顺序跟踪内核的初始化过程下图说明了从系统加电到断电这一过程中所有事情发生的顺序这个图不多加解释了看图就知道其线性执行顺序中间过程也是很简单的步骤啦。   我们首先讨论的是BIOS和Open和Fireware它们分别是x86和PPC系统加电后在只读内存的某一地址(一般是Flash ROM)最先运行的代码这些代码负责激活系统中相应的部分以便处理内核的加载对于x86而言这就是系统的驻留之处基本的输入输出是一块引导系统并与硬件相关的系统初始化代码这里不多说了对于PowerPC而言初始化代码的类型与PowerPC体系结构的出现时间有关详情就参见Open Fireware 的主页www.openfireware.org   引导装入程序Bootloaders大家应该早就有所了解了Boot Loaders是驻留在计算机引导设备的程序第一个引导设备往往是系统中的第一个硬盘完成足够的系统初始化工作后BIOS或固件调用引导装入程序一旦成功加载进来内核就初始化并配置操作系统对x86系统而言BIOS允许用户为其系统设置引导设备的顺序这里提一下GRUBGrand Unified Bootloader 是基于x86的引导装入程序用来加载Linux。GRUB2在设计之初就考虑了移植到PPC系统的问题哎具体的就www.gnu.org/software/grub上有丰富的文档并且百度上也有相关的例程之类的我觉得这里我就不再阐释了。   Linux装入程序即LILO这个我还是得说说和GRUB相类似但是LILO仅仅使用配置文件并且没有命令行接口。LILO运行时的第一阶段步骤如下 第一阶段 开始执行并且显示“L.检测磁盘几何信息并且显示“I.;加载第二阶段的代码。第二阶段 开始执行并且显示“L.;确定引导数据和操作系统的位置并且显示”O.确定启动哪个操作系统并且跳转到该操作系统LILO配置文件中的一段代码如下(代码在etc/lilo.conf上可以查看): 1 image /boot/bzimage-2.6.7-mytestkernel  //image指明内核所在地 2 label Kernel 2.6.7, my test kernel  //label描述配置的字符串 3 root /dev/hda6          //root指明根文件系统驻留的分区 4 read-only              //表明根分区在引导时候不可被修改   GRUB和LILO的主要区别 LILO将配置信息存储在主引导记录中若有任何改动必须运行/sbin/lilo来更新主引导记录LILO没有交互式的命令行接口LILO不能读取不同的文件系统  最后说一下Yabootyaboot是另一个引导程序比如说grub和lilo是比较出名的引导程序用于Macintosh。主页http://yaboot.ozlabs.org/ Yaboot引导时的步骤如下 OF调用Yaboot找到引导设备和引导路径并打开引导分区打开/etc/yaboot.conf或命令解释器加载映像或内核以及initrd执行映像这里需要在Ubuntu上自己操作当然对Ubuntu的基本命令操作是首先要了解的然后才能根据步骤一步一步执行下去。     x86和PowerPC体系结构的硬件初始化由于内存管理的初始化与硬件息息相关要理解其初始化过程就必须了解硬件的规格那么都只能去看看资料才能了解了这里我多讲不了。现在的PowerPC和x86的代码都集中在init/main.c的start_kernel()中该例程位于体系结构无关的代码段它调用特定体系结构的例程来完成内存初始化。下面我们来探究一下start_kernel()函数。   跳转到start_kernel()时候执行进程0也就是平时说的超级用户进程进程0孕育了进程1也就是init进程然后进程0就变成CPU的空闲进程调/sbin/init时仅有这两个进程在运行 1 asmlinkage void __init start_kernel(void) 2 { 3 char * command_line; 4 extern struct kernel_param __start___param[], __stop___param[]; 5 //来设置smp process id当然目前看到的代码里面这里是空的 6 smp_setup_processor_id(); 7 //lockdep是linux内核的一个调试模块用来检查内核互斥机制尤其是自旋锁潜在的死锁问题。 8 //自旋锁由于是查询方式等待不释放处理器比一般的互斥机制更容易死锁 9 //故引入lockdep检查以下几种情况可能的死锁lockdep将有专门的文章详细介绍在此只是简单列举 10 // 11 //·同一个进程递归地加锁同一把锁 12 // 13 //·一把锁既在中断或中断下半部使能的情况下执行过加锁操作 14 // 又在中断或中断下半部里执行过加锁操作。这样该锁有可能在锁定时由于中断发生又试图在同一处理器上加锁 15 // 16 //·加锁后导致依赖图产生成闭环这是典型的死锁现象。 17 lockdep_init(); 18 debug_objects_early_init(); 19 //初始化stack_canary栈3 20 //stack_canary的是带防止栈溢出攻击保护的堆栈。 21 // 当user space的程序通过int 0x80进入内核空间的时候CPU自动完成一次堆栈切换 22 //从user space的stack切换到kernel space的stack。 23 // 在这个进程exit之前所发生的所有系统调用所使用的kernel stack都是同一个。 24 //kernel stack的大小一般为4096/8192 25 //内核堆栈示意图帮助大家理解 26 // 27 // 内存低址 内存高址 28 // | |-----------------------------esp| 29 // -----------------------------------4096------------------------------- 30 // | 72 | 4 | x 4016 | 4 | 31 // -------------------------------------------------------------------- 32 // |thread_info | | STACK_END_MAGIC | var/call chain |stack_canary | 33 // -------------------------------------------------------------------- 34 // | 28 | 44 | | | 35 // V | | 36 // restart_block V 37 // 38 //esp0x0 0x40 39 // --------------------------------------------------------------------------- 40 // |ebx|ecx|edx|esi|edi|ebp|eax|ds|es|fs|gs|orig_eax|eip|cs|eflags|oldesp|oldss| 41 // --------------------------------------------------------------------------- 42 // | kernel完成 | cpu自动完成 | 43 boot_init_stack_canary(); 44 // cgroup: 它的全称为control group.即一组进程的行为控制. 45 // 比如,我们限制进程/bin/sh的CPU使用为20%.我们就可以建一个cpu占用为20%的cgroup. 46 // 然后将/bin/sh进程添加到这个cgroup中.当然,一个cgroup可以有多个进程. 47 48 cgroup_init_early(); 49 //更新kernel中的所有的立即数值但是包括哪些需要再看 50 core_imv_update(); 51 //关闭当前CUP中断 52 local_irq_disable(); 53 //修改标记early_boot_irqs_enabled; 54 //通过一个静态全局变量 early_boot_irqs_enabled来帮助我们调试代码 55 //通过这个标记可以帮助我们知道是否在”early bootup code”也可以通过这个标志警告是有无效的终端打开 56 early_boot_irqs_off(); 57 //每一个中断都有一个IRQ描述符struct irq_desc来进行描述。 58 //这个函数的主要作用是设置所有的 IRQ描述符struct irq_desc的锁是统一的锁 59 //还是每一个IRQ描述符struct irq_desc都有一个小锁。 60 early_init_irq_lock_class(); 61 62 // 大内核锁BKL--Big Kernel Lock 63 //大内核锁本质上也是自旋锁但是它又不同于自旋锁自旋锁是不可以递归获得锁的因为那样会导致死锁。 64 //但大内核锁可以递归获得锁。大内核锁用于保护整个内核而自旋锁用于保护非常特定的某一共享资源。 65 //进程保持大内核锁时可以发生调度具体实现是 66 //在执行schedule时schedule将检查进程是否拥有大内核锁如果有它将被释放以致于其它的进程能够获得该锁 67 //而当轮到该进程运行时再让它重新获得大内核锁。注意在保持自旋锁期间是不运行发生调度的。 68 //需要特别指出整个内核只有一个大内核锁其实不难理解内核只有一个而大内核锁是保护整个内核的当然有且只有一个就足够了。 69 //还需要特别指出的是大内核锁是历史遗留内核中用的非常少一般保持该锁的时间较长因此不提倡使用它。 70 //从2.6.11内核起大内核锁可以通过配置内核使其变得可抢占自旋锁是不可抢占的这时它实质上是一个互斥锁使用信号量实现。 71 //大内核锁的API包括 72 // 73 //void lock_kernel(void); 74 // 75 //该函数用于得到大内核锁。它可以递归调用而不会导致死锁。 76 // 77 //void unlock_kernel(void); 78 // 79 //该函数用于释放大内核锁。当然必须与lock_kernel配对使用调用了多少次lock_kernel就需要调用多少次unlock_kernel。 80 //大内核锁的API使用非常简单按照以下方式使用就可以了 81 //lock_kernel(); //对被保护的共享资源的访问 … unlock_kernel() 82 lock_kernel(); 83 //初始化time ticket时钟 84 tick_init(); 85 //函数 tick_init() 很简单调用 clockevents_register_notifier 函数向 clockevents_chain 通知链注册元素 86 // tick_notifier。这个元素的回调函数指明了当时钟事件设备信息发生变化例如新加入一个时钟事件设备等等时 87 //应该执行的操作该回调函数为 tick_notify 88 boot_cpu_init(); 89 //初始化页地址当然对于arm这里是个空函数 90 page_address_init(); 91 printk(KERN_NOTICE %s, linux_banner); 92 //系结构相关的内核初始化过程 93 setup_arch(command_line); 94 //初始化内存管理 95 mm_init_owner(init_mm, init_task); 96 //处理启动命令这里就是设置的cmd_line 97 setup_command_line(command_line); 98 //这个在定义了SMP的时候有作用现在这里为空函数对于smp的使用后面在看。。。 99 setup_nr_cpu_ids(); 100 //如果没有定义CONFIG_SMP宏则这个函数为空函数。 101 //如果定义了CONFIG_SMP宏则这个setup_per_cpu_areas()函数给每个CPU分配内存 102 //并拷贝.data.percpu段的数据。为系统中的每个CPU的per_cpu变量申请空间。 103 setup_per_cpu_areas(); 104 //定义在include/asm-x86/smp.h。 105 //如果是SMP环境则设置boot CPU的一些数据。在引导过程中使用的CPU称为boot CPU 106 smp_prepare_boot_cpu(); /* arch-specific boot-cpu hooks */ 107 //设置node 和 zone 数据结构 108 //内存管理的讲解 109 build_all_zonelists(NULL); 110 //初始化page allocation相关结构 111 page_alloc_init(); 112 printk(KERN_NOTICE Kernel command line: %s/n, boot_command_line); 113 //解析内核参数 114 parse_early_param(); 115 parse_args(Booting kernel, static_command_line, __start___param, 116 __stop___param - __start___param, 117 unknown_bootoption); 118 119 //初始化hash表以便于从进程的PID获得对应的进程描述指针按照实际的物理内存初始化pid hash表 120 //这里涉及到进程管理 121 pidhash_init(); 122 //初始化VFS的两个重要数据结构dcache和inode的缓存。 123 vfs_caches_init_early(); 124 //把编译期间kbuild设置的异常表也就是__start___ex_table和__stop___ex_table之中的所有元素进行排序 125 sort_main_extable(); 126 //初始化中断向量表 127 trap_init(); 128 //memory map初始化 129 mm_init(); 130 //核心进程调度器初始化调度器的初始化的优先级要高于任何中断的建立 131 //并且初始化进程0即idle进程但是并没有设置idle进程的NEED_RESCHED标志 132 //所以还会继续完成内核初始化剩下的事情。 133 //这里仅仅为进程调度程序的执行做准备。 134 //它所做的具体工作是调用init_bh函数(kernel/softirq.c)把timer,tqueue,immediate三个人物队列加入下半部分的数组 135 sched_init(); 136 //抢占计数器加1 137 preempt_disable(); 138 //检查中断是否打开 139 if (!irqs_disabled()) { 140 printk(KERN_WARNING start_kernel(): bug: interrupts were 141 enabled *very* early, fixing it/n); 142 local_irq_disable(); 143 } 144 //Read-Copy-Update的初始化 145 //RCU机制是Linux2.6之后提供的一种数据一致性访问的机制 146 //从RCUread-copy-update的名称上看我们就能对他的实现机制有一个大概的了解 147 //在修改数据的时候首先需要读取数据然后生成一个副本对副本进行修改 148 //修改完成之后再将老数据update成新的数据此所谓RCU。 149 rcu_init(); 150 //定义在lib/radix-tree.c。 151 //Linux使用radix树来管理位于文件系统缓冲区中的磁盘块 152 //radix树是trie树的一种 153 radix_tree_init(); 154 /* init some links before init_ISA_irqs() */ 155 //early_irq_init 则对数组中每个成员结构进行初始化, 156 //例如, 初始每个中断源的中断号.其他的函数基本为空. 157 early_irq_init(); 158 //初始化IRQ中断和终端描述符。 159 //初始化系统中支持的最大可能的中断描述结构struct irqdesc变量数组irq_desc[NR_IRQS], 160 //把每个结构变量irq_desc[n]都初始化为预先定义好的坏中断描述结构变量bad_irq_desc, 161 //并初始化该中断的链表表头成员结构变量pend 162 init_IRQ(); 163 //prio-tree是一棵查找树管理的是什么 164 //http://blog.csdn.net/dog250/archive/2010/06/28/5700317.aspx 165 prio_tree_init(); 166 //初始化定时器Timer相关的数据结构 167 init_timers(); 168 //对高精度时钟进行初始化 169 hrtimers_init(); 170 //软中断初始化 171 softirq_init(); 172 //初始化时钟源 173 timekeeping_init(); 174 //初始化系统时间 175 //检查系统定时器描述结构struct sys_timer全局变量system_timer是否为空 176 //如果为空将其指向dummy_gettimeoffset()函数。 177 time_init(); 178 //profile只是内核的一个调试性能的工具 179 //这个可以通过menuconfig中的Instrumentation Support-profile打开。 180 profile_init(); 181 if (!irqs_disabled()) 182 printk(KERN_CRIT start_kernel(): bug: interrupts were 183 enabled early/n); 184 //与开始的early_boot_irqs_off相对应 185 early_boot_irqs_on(); 186 //与local_irq_disbale相对应开中断 187 local_irq_enable(); 188 gfp_allowed_mask __GFP_BITS_MASK; 189 //memory cache的初始化 190 kmem_cache_init_late(); 191 //初始化控制台以显示printk的内容在此之前调用的printk只是把数据存到缓冲区里 192 //只有在这个函数调用后才会在控制台打印出内容 193 //该函数执行后可调用printk()函数将log_buf中符合打印级别要求的系统信息打印到控制台上。 194 console_init(); 195 if (panic_later) 196 panic(panic_later, panic_param); 197 //如果定义了CONFIG_LOCKDEP宏那么就打印锁依赖信息否则什么也不做 198 lockdep_info(); 199 200 //如果定义CONFIG_DEBUG_LOCKING_API_SELFTESTS宏 201 //则locking_selftest()是一个空函数否则执行锁自测 202 locking_selftest(); 203 #ifdef CONFIG_BLK_DEV_INITRD 204 if (initrd_start !initrd_below_start_ok 205 page_to_pfn(virt_to_page((void *)initrd_start)) min_low_pfn) { 206 printk(KERN_CRIT initrd overwritten (0x%08lx 0x%08lx) - 207 disabling it./n, 208 page_to_pfn(virt_to_page((void *)initrd_start)), 209 min_low_pfn); 210 initrd_start 0; 211 } 212 #endif 213 //页面初始化可以参考上面的cgroup机制 214 page_cgroup_init(); 215 //页面分配debug启用 216 enable_debug_pagealloc(); 217 //此处函数为空 218 kmemtrace_init(); 219 //memory lead侦测初始化如何侦测 220 kmemleak_init(); 221 222 //在kmem_caches之后表示建立一个高速缓冲池建立起SLAB_DEBUG_OBJECTS标志。 223 debug_objects_mem_init(); 224 //idr在linux内核中指的就是整数ID管理机制 225 //从本质上来说这就是一种将整数ID号和特定指针关联在一起的机制 226 //idr机制适用在那些需要把某个整数和特定指针关联在一起的地方。 227 idr_init_cache(); 228 //是否是对SMP的支持单核是否需要这个要分析 229 setup_per_cpu_pageset(); 230 //NUMA (Non Uniform Memory Access) policy 231 //具体是什么不懂 232 numa_policy_init(); 233 if (late_time_init) 234 late_time_init(); 235 //初始化调度时钟 236 sched_clock_init(); 237 //calibrate_delay函数可以计算出cpu在一秒钟内执行了多少次一个极短的循环 238 //计算出来的值经过处理后得到BogoMIPS 值 239 //Bogo是Bogus(伪)的意思MIPS是millions of instructions per second(百万条指令每秒)的缩写。 240 //这样我们就知道了其实这个函数是linux内核中一个cpu性能测试函数。 241 calibrate_delay(); 242 //PID是process id的缩写 243 pidmap_init(); 244 //来自mm/rmap.c 245 //分配一个anon_vma_cachep作为anon_vma的slab缓存。 246 //这个技术是PFRA页框回收算法技术中的组成部分。 247 //这个技术为定位而生——快速的定位指向同一页框的所有页表项。 248 anon_vma_init(); 249 #ifdef CONFIG_X86 250 if (efi_enabled) 251 efi_enter_virtual_mode(); 252 #endif 253 //创建thread_info缓存 254 thread_info_cache_init(); 255 //申请了一个slab来存放credentials??????如何理解 256 cred_init(); 257 //根据物理内存大小计算允许创建进程的数量 258 fork_init(totalram_pages); 259 //给进程的各种资源管理结构分配了相应的对象缓存区 260 proc_caches_init(); 261 //创建 buffer_head SLAB 缓存 262 buffer_init(); 263 //初始化key的management stuff 264 key_init(); 265 //关于系统安全的初始化主要是访问控制 266 security_init(); 267 //与debug kernel相关 268 dbg_late_init(); 269 //调用kmem_cache_create()函数来为VFS创建各种SLAB分配器缓存 270 //包括names_cachep、filp_cachep、dquot_cachep和bh_cachep等四个SLAB分配器缓存 271 vfs_caches_init(totalram_pages); 272 //创建信号队列 273 signals_init(); 274 //回写相关的初始化 275 page_writeback_init(); 276 #ifdef CONFIG_PROC_FS 277 proc_root_init(); 278 #endif 279 //它将剩余的subsys初始化.然后将init_css_set添加进哈希数组css_set_table[ ]中. 280 //在上面的代码中css_set_hash()是css_set_table的哈希函数. 281 //它是css_set-subsys为哈希键值,到css_set_table[ ]中找到对应项.然后调用hlist_add_head()将init_css_set添加到冲突项中. 282 //然后,注册了cgroup文件系统.这个文件系统也是我们在用户空间使用cgroup时必须挂载的. 283 //最后,在proc的根目录下创建了一个名为cgroups的文件.用来从用户空间观察cgroup的状态. 284 cgroup_init(); 285 cpuset_init(); 286 ////进程状态初始化实际上就是分配了一个存储线程状态的高速缓存 287 taskstats_init_early(); 288 delayacct_init(); 289 //此处为一空函数 290 imv_init_complete(); 291 //测试CPU的各种缺陷记录检测到的缺陷以便于内核的其他部分以后可以使用他们工作。 292 check_bugs(); 293 //电源相关的初始化 294 acpi_early_init(); /* before LAPIC and SMP init */ 295 // 296 sfi_init_late(); 297 ftrace_init(); 298 //创建1号进程详细分析之 299 rest_init(); 300 } 下面将一些内核引导的函数归类以后查询就可以使这个样子的这些都是我百度到的总结的如下如果想了解每个函数的含义可以参考一个文档我把链接附在下面http://wenku.baidu.com/link?urlBW4g5AS9KHtvkHorS90lbFOAac2HZFgErLaqeiQr-fejBuRWu8bF28LxKKKxGwGuaQI0ALSUsJeY_dj6m_jgkxX9ozZiE17U0i__sZk_YYa CPU初始化 smp_setup_processor_id() boot_cpu_init() setup_arch(command_line); setup_nr_cpu_ids() setup_per_cpu_areas() smp_prepare_boot_cpu() setup_per_cpu_pageset();  calibrate_delay(); cpuset_init(); 内存管理初始化 boot_init_stack_canary() page_address_init(); mm_init_owner(); page_alloc_init();  mm_init(); rcu_init(); kmem_cache_init_late(); page_cgroup_init();  kmemleak_init();  numa_policy_init(); anon_vma_init(); page_writeback_init(); 进程管理 pidhash_init(); sched_init();  sched_clock_init() pidmap_init(); fork_init(totalram_pages);  taskstats_init_early(); 文件系统 vfs_caches_init_early();  thread_info_cache_init(); vfs_caches_init(totalram_pages); 中断 early_irq_init(); init_IRQ();  softirq_init(); 同步互斥 lockdep_init(); lockdep_info(); locking_selftest();  时钟 tick_init();  init_timers();  hrtimers_init(); timekeeping_init(); time_init(); 调试 debug_objects_early_init(); console_init(); enable_debug_pagealloc();  debug_objects_mem_init(); dbg_late_init(); 其他 sort_main_extable(); trap_init();  efi_enter_virtual_mode(); cred_init();  proc_caches_init();  buffer_init(); key_init();  security_init(); signals_init(); proc_root_init(); delayacct_init(); check_bugs(); acpi_early_init(); sfi_init_late();  未知 cgroup_init_early(); build_all_zonelists(NULL); preempt_disable(); radix_tree_init(); prio_tree_init(); profile_init(); idr_init_cache(); cgroup_init(); ftrace_init();最后来总结一下Linux内核的初始化过程 启动和锁住内核为Linux的内存管理初始化页高速缓存和页面地址为多CPU做好准备显示内核标志初始化Linux调度程序分析传到Linux内核的参数初始化中断处理程序定时器处理程序和信号处理程序挂载初始文件系统完成系统的初始化并且将控制权从init交回系统   小结   今天主要是描述了系统加电和断电时候的内核引导期间发生了什么事情先讨论了BIOS和Firmware以及它们是如何与内核引导装入程序交互的也讨论了装入程序LILOGRUB和Yaboot最后着重分析了start_kernel()函数的代码这个是我看网上代码的主要是别人分析的太好了所以借鉴了一下只要能懂就行最后列出了一系列的函数只要看了链接上的 都能懂的我也努力在看共同进步吧大家~     版权所有转载请注明转载地址http://www.cnblogs.com/lihuidashen/p/4250095.html posted on 2015-01-27 09:11 NET未来之路 阅读(...) 评论(...) 编辑 收藏 转载于:https://www.cnblogs.com/lonelyxmas/p/4251897.html
http://www.zqtcl.cn/news/210361/

相关文章:

  • 网站建设与维护案列网站作品怎么做
  • 茂名放心营销网站开发seo收费
  • 旅游网站品牌建设本地使用宝塔安装wordpress
  • 专门做外链的网站制作论坛类网站模板免费下载
  • 靖江建设行业协会网站投资做网站
  • 做网站视频背景潍坊网站制作建设
  • 深圳市官网网站建设哪家好百度抓取网站登录
  • 免费做cpa单页网站友情链接买卖代理
  • 免费网站建站排名中国最大的软件公司
  • 码云pages做静态网站广西建设培训网
  • 建设网站需要花钱吗网站seo方案策划书
  • 德阳网站怎么做seo陈木胜个人资料
  • 电子规划书商务网站建设wordpress主机推荐
  • wordpress设置多站点html5开发手机app
  • 移动互联和网站开发哪个好做推广便宜的网站有哪些
  • 极速网站建设定制价格微信公众号运营助手
  • .net制作网站开发教程在线修图编辑器
  • 哪些网站可以做详情页聊城高新区建设局网站
  • 湖南网站优化代运营山东建设厅证件查询网址
  • 以百度云做网站空间浙江外贸网站建设
  • 南通网站建设推广专家wordpress 信息流 主题
  • 网站培训机构有哪些大学生做企业网站
  • 网站培训班有哪些课程做的好的大学生旅行有哪些网站好
  • 昌江县住房和城乡建设局网站佛山建设网站制作
  • 做网站 图片 文件夹 放哪儿北京模板网站建设
  • 网站制作公司哪家正规注册工程公司名称大全
  • 佛山微信网站建设哪家好做电商讲师课程的网站
  • 泰州城乡建设网站深圳logo设计公司哪家好
  • 东阳网站建设yw81wordpress登录注册页面梅花
  • 网站备案 厦门福州企业网站开发