LPC2000 启动代码Start.s文件简要分析

发布者:会飞的笨鱼最新更新时间:2018-11-29 来源: eefocus关键字:LPC2000  启动代码  Start  s文件 手机看文章 扫描二维码
随时随地手机看文章

最近要做一个温度采集。大师兄非要上ARM7,可俺还差不多是个白板呢,只能恶补一下了,先找个启动代码看看,ARM的汇编跟x86下的就是不一样啊(再说x86下的都菜的不行,呵呵),编译器与编译器之间的差异也挺大的。本例采用的是 Keil 环境下,由Keil自动生成的启动文件。平时可能用不着去自己写,可自己总是好奇心太重了,就拿来分析一下。对以后写启动代码或Bootloader也许会有些帮助吧。


先说一下启动代码的位置,启动代码是在板子加电后首先执行的。所以非要用汇编来写才行。要完成处理器模式的初始化、设置中断向量表、设置各个模式下的堆栈、初始某些变量从而把系统带到一个合适的运行环境中开始用户程序的运行。


;-------------------------------------------------------------------------------


;


; 本段设置处理器的模式相关常量


;


;-------------------------------------------------------------------------------


; Standard definitions of Mode bits and Interrupt (I & F) flags in PSRs


; 定义常量,处理器的几种工作模式。


; ARM 有7种工作模式:


;


; User: 非特权模式,大部分任务执行在这种模式   正常程序执行的模式


; FIQ: 当一个高优先级(fast)中断产生时将会进入这种模式 高速数据传输和通道处理


; IRQ: 当一个低优先级(normal)中断产生时将会进入这种模式 通常的中断处理


; SVC: 用于操作系统的保护模式


; Abort: 当存取异常时将会进入这种模式   虚拟存储及存储保护


; Undef: 当执行未定义指令时会进入这种模式 软件仿真硬件协处理器


; System: 使用和User模式相同寄存器集的特权模式


;


; 这个值将被写到CPSR寄存器的第0,1,2,3,4,5位,以表示当前的状态。


Mode_USR        EQU     0x10


Mode_FIQ        EQU     0x11


Mode_IRQ        EQU     0x12


Mode_SVC        EQU     0x13


Mode_ABT        EQU     0x17


Mode_UND        EQU     0x1B


Mode_SYS        EQU     0x1F


; 设置IRQ和FIQ中断禁止位,这两个值将被写到CPSR寄存器的第6位(FIQ)和第7位(IRQ)。1是禁止,0是允许。


I_Bit           EQU     0x80            ; when I bit is set, IRQ is disabled


F_Bit           EQU     0x40            ; when F bit is set, FIQ is disabled


;---------------------------------------------------------------------------------------------------


; 本段将完成堆栈相关的常量,


;


;---------------------------------------------------------------------------------------------------


;


; 设置各个模式下的栈大小


;


UND_Stack_Size EQU     0x00000000


SVC_Stack_Size EQU     0x00000008


ABT_Stack_Size EQU     0x00000000


FIQ_Stack_Size EQU     0x00000000


IRQ_Stack_Size EQU     0x00000080


USR_Stack_Size EQU     0x00000400


ISR_Stack_Size EQU     (UND_Stack_Size + SVC_Stack_Size + ABT_Stack_Size + \


                         FIQ_Stack_Size + IRQ_Stack_Size)


; 初始化栈空间


; 定义一个数据段,名为STACK,NOINIT - 仅仅保留内存单元,还没有写入值,可读写,ALIGN=3 - 按字节对齐。


                AREA    STACK, NOINIT, READWRITE, ALIGN=3


; 分配内存,用户模式栈名为Stack_Mem,大小为1024字节;异常模式堆栈__initial_sp 大小为128+8字节。


Stack_Mem       SPACE   USR_Stack_Size


__initial_sp    SPACE   ISR_Stack_Size


Stack_Top


;


Heap_Size       EQU     0x00000000


;堆空间,其中__heap_base 与__heap_limit 这两个符号是给采用了MICROLIB的程序准备的。


               AREA    HEAP, NOINIT, READWRITE, ALIGN=3


__heap_base


Heap_Mem        SPACE   Heap_Size


__heap_limit


;-------------------------------------------------------------------------------------------


;


; 初始化 VPB总线的频率,Start的时候将分频因子设置为1,表示与CPU CLOCK相同


;-------------------------------------------------------------------------------------------


; VPBDIV 是VPB总线的分频因子


;


; VPBDIV definitions


VPBDIV          EQU     0xE01FC100      ; VPBDIV Address


VPBDIV_SETUP    EQU     1


VPBDIV_Val      EQU     0x00000000


;-------------------------------------------------------------------------------------------


; 定义与锁相环相关的寄存器


; Phase Locked Loop (PLL) definitions


;-------------------------------------------------------------------------------------------


; 定义 PLL相关寄存器的基地址


PLL_BASE        EQU     0xE01FC080      ; PLL Base Address


; 用偏移量的方法定义其他寄存器


PLLCON_OFS      EQU     0x00            ; PLL Control Offset ;控制寄存器,写入该寄存器的值在馈送序列执行前不起作用


PLLCFG_OFS      EQU     0x04            ; PLL Configuration Offset ;配置寄存器,属性同上


PLLSTAT_OFS     EQU     0x08            ; PLL Status Offset ;状态寄存器,读取状态


PLLFEED_OFS     EQU     0x0C            ; PLL Feed Offset ;馈送寄存器,使能装载PLL控制和配置信息


PLLCON_PLLE     EQU     (1<<0)          ; PLL Enable   ;PLL使能,写入到配置寄存器的第0位,


         ; 初始为0,表示没有激活


PLLCON_PLLC     EQU     (1<<1)          ; PLL Connect   ;PLL连接使能位 ,写入到配置寄存器的第1位,当PLLC和


        ; PLLE都为1,且在有效的PLLE馈送后,将PLLE作为时钟源接


        ; 入Core,否则Core直接使用振荡器时钟。


PLLCFG_MSEL     EQU     (0x1F<<0)       ; PLL Multiplier ;PLL 倍频因子


PLLCFG_PSEL     EQU     (0x03<<5)       ; PLL Divider   ;PLLE 分频因子


PLLSTAT_PLOCK   EQU     (1<<10)         ; PLL Lock Status ;PLL锁定状态位,应该是从PLLSTAT寄存器的第10位读取数值

       

 ; 然后与 PLLSTAT_PLOCK 相比较,相同则为PLL锁定状态。

PLL_SETUP       EQU     1


PLLCFG_Val      EQU     0x00000024 ;表示向CFG配置寄存器写入的值为0 01 00100,跟系统所需的频率有关。


     ;LPC2119的主频最高是60MHz,振荡器的主频是10MHz


     ;分频值为1,倍频值为4,所以主频为40Mhz。


;-------------------------------------------------------------------------------------


; 存储器加速模块


;


;-------------------------------------------------------------------------------------


; Memory Accelerator Module (MAM) definitions


MAM_BASE        EQU     0xE01FC000      ; MAM Base Address


MAMCR_OFS       EQU     0x00            ; MAM Control Offset


MAMTIM_OFS      EQU     0x04            ; MAM Timing Offset


MAM_SETUP       EQU     1


MAMCR_Val       EQU     0x00000002


MAMTIM_Val      EQU     0x00000004


;---------------------------------------------------------------------------


; 外部存储器扩展


;


;---------------------------------------------------------------------------


; External Memory Controller (EMC) definitions


EMC_BASE        EQU     0xFFE00000      ; EMC Base Address


BCFG0_OFS       EQU     0x00            ; BCFG0 Offset


BCFG1_OFS       EQU     0x04            ; BCFG1 Offset


BCFG2_OFS       EQU     0x08            ; BCFG2 Offset


BCFG3_OFS       EQU     0x0C            ; BCFG3 Offset


;//


EMC_SETUP       EQU     0


BCFG0_SETUP EQU         0


BCFG0_Val   EQU         0x0000FBEF


BCFG1_SETUP EQU         0


BCFG1_Val   EQU         0x0000FBEF


BCFG2_SETUP EQU         0


BCFG2_Val   EQU         0x0000FBEF


BCFG3_SETUP EQU         0


BCFG3_Val   EQU         0x0000FBEF


;//End of EMC


; External Memory Pins definitions


PINSEL2         EQU     0xE002C014      ; PINSEL2 Address

PINSEL2_Val     EQU     0x0E6149E4      ; CS0..3, OE, WE, BLS0..3,

       

                                 ; D0..31, A2..23, JTAG Pins


                PRESERVE8 ;汇编伪指令,堆栈8字节对准

               

;-------------------------------------------------------------------------------


; 前面都是对寄存器位置的声明,以下是具体代码。定义了一个代码段


;


;-------------------------------------------------------------------------------


;


; Area Definition and Entry Point


; Startup Code must be linked first at Address at which it expects to run.


;定义个名为RESET的代码段


                AREA    RESET, CODE, READONLY


                ARM


; 中断向量表的异常入口共8条语句32字节,在链接的时候保证在0地址处


Vectors         LDR     PC, Reset_Addr        ;将Reset_Addr加载到PC中,程序就跳到reset_addr所指位置。


                LDR     PC, Undef_Addr


                LDR     PC, SWI_Addr


                LDR     PC, PAbt_Addr


                LDR     PC, DAbt_Addr


                NOP                            ; Reserved Vector


;               LDR     PC, IRQ_Addr


                LDR     PC, [PC, #-0x0FF0]     ; Vector from VicVectAddr


                LDR     PC, FIQ_Addr


Reset_Addr      DCD     Reset_Handler ;分配一段字内存单元给程序段Reset_Handler


Undef_Addr      DCD     Undef_Handler


SWI_Addr        DCD     SWI_Handler


PAbt_Addr       DCD     PAbt_Handler


DAbt_Addr       DCD     DAbt_Handler


                DCD     0                      ; Reserved Address


IRQ_Addr        DCD     IRQ_Handler


FIQ_Addr        DCD     FIQ_Handler


;


Undef_Handler   B       Undef_Handler


SWI_Handler     B       SWI_Handler


PAbt_Handler    B       PAbt_Handler


DAbt_Handler    B       DAbt_Handler


IRQ_Handler     B       IRQ_Handler


FIQ_Handler     B       FIQ_Handler



;-----------------------------------------------------------------------------------


;


;


;-----------------------------------------------------------------------------------


; Reset Handler

       

         EXPORT Reset_Handler


Reset_Handler  


;设置扩展存储的引脚


; Setup External Memory Pins


                IF      :DEF:EXTERNAL_MODE ;判断 EXTERNAL_MODE 是否定义,如果定义了就设置响应的管脚。见某论坛上的一个人问,外部存储器设置了但是不能工作,就是这里的 EXTERNAL_MODE 没有被定义导致扩展 存储的引脚的代码没有被编译所以没有被初始化,EXTERNAL_MODE EQU 1,应该就可以了 ,还没测试。


                LDR     R0, =PINSEL2


                LDR     R1, =PINSEL2_Val ;前面 PINSEL2_Val 被初始化为0x0E6149E4,完成一系列管脚的初始化


                STR     R1, [R0]


                ENDIF


;设置扩展存储器的控制寄存器,分别检测几个bank是否存在,分别进行设置


; Setup External Memory Controller


                IF      EMC_SETUP <> 0


                LDR     R0, =EMC_BASE


                IF      BCFG0_SETUP <> 0


                LDR     R1, =BCFG0_Val


                STR     R1, [R0, #BCFG0_OFS]


                ENDIF


                IF      BCFG1_SETUP <> 0


                LDR     R1, =BCFG1_Val

       

         STR     R1, [R0, #BCFG1_OFS]


                ENDIF


                IF      BCFG2_SETUP <> 0


                LDR     R1, =BCFG2_Val


                STR     R1, [R0, #BCFG2_OFS]


                ENDIF


                IF      BCFG3_SETUP <> 0


                LDR     R1, =BCFG3_Val


                STR     R1, [R0, #BCFG3_OFS]


                ENDIF


                ENDIF   ; EMC_SETUP

;设置VPB总线的分频因子,这里分频因子被设置为0


; Setup VPBDIV


                IF      VPBDIV_SETUP <> 0


                LDR     R0, =VPBDIV


                LDR     R1, =VPBDIV_Val


                STR     R1, [R0]


                ENDIF


;设置锁相环


; Setup PLL


                IF      PLL_SETUP <> 0


                LDR     R0, =PLL_BASE


                MOV     R1, #0xAA


                MOV     R2, #0x55


; Configure and Enable PLL


                MOV     R3, #PLLCFG_Val  


                STR     R3, [R0, #PLLCFG_OFS]    ;PLLCFG_Val = 0x00000024


                MOV     R3, #PLLCON_PLLE   ;R3 = 1


                STR     R3, [R0, #PLLCON_OFS]   ; PLLCON = 1,PLL 使能


                STR     R1, [R0, #PLLFEED_OFS]   ; 写 馈送寄存器命令序列一次是

10101010一次01010101,0xAA,0x55。规定的。

       

         STR     R2, [R0, #PLLFEED_OFS]


;等待PLL稳定


; Wait until PLL Locked


PLL_Loop        LDR     R3, [R0, #PLLSTAT_OFS]   ;将状态寄存器装载到R3中


                ANDS    R3, R3, #PLLSTAT_PLOCK   ;PLLSTAT_OFS 与1<<10 进行与且影响 CPSR 的Z位,


                BEQ     PLL_Loop    ;Z位为1 跳到PLL_Loop


; Switch to PLL Clock


                MOV     R3, #(PLLCON_PLLE:OR:PLLCON_PLLC)


                STR     R3, [R0, #PLLCON_OFS]


                STR     R1, [R0, #PLLFEED_OFS]


                STR     R2, [R0, #PLLFEED_OFS]


                ENDIF   ; PLL_SETUP


;-----------------------------------------------------------------------------


; 存储器加速模块


; Setup MAM


                IF      MAM_SETUP <> 0


                LDR     R0, =MAM_BASE

       

         MOV     R1, #MAMTIM_Val


                STR     R1, [R0, #MAMTIM_OFS]


                MOV     R1, #MAMCR_Val


                STR     R1, [R0, #MAMCR_OFS]


                ENDIF   ; MAM_SETUP

;--------------------------------------------------------------------------


;内存映射,结构有点复杂额,总之就是根据不同的情况去设置存储器映射控制寄存器,


; 00 Boot装载,中断向量从BootBlock重新映射


; 01 用户FLASH模式,中断向量不重新映射,就在FLASH里面


; 10 用户RAM模式,中断向量从静态RAM重新映射


; 11 用户外部存储器模式,中断向量从外部存储器重新映射。


; Memory Mapping (when Interrupt Vectors are in RAM)


;----------------------------------------------------------------------------


MEMMAP          EQU     0xE01FC040      ; Memory Mapping Control ;


                IF      :DEF:REMAP


                LDR     R0, =MEMMAP


                IF      :DEF:EXTMEM_MODE ;判断是不是扩展模式 是就往R1里写3


                MOV     R1, #3


                ELIF    :DEF:RAM_MODE ;如果是RAM中,往R1里写2


                MOV     R1, #2


                ELSE


                MOV     R1, #1   ;否则R1里写1,唉汇编的编译判断真够烦的。


                ENDIF


                STR     R1, [R0] ;写到MEMMAP寄存器。


                ENDIF


; Initialise Interrupt System


; ...


;为处理器的每种处理模式初始化栈空间


; Setup Stack for each mode


                LDR     R0, =Stack_Top


; Enter Undefined Instruction Mode and set its Stack Pointer


                MSR     CPSR_c, #Mode_UND:OR:I_Bit:OR:F_Bit ;CPSR_c = 0x1B|0x80|0x40 = 意思为禁止IRQ和FIQ,ARM状态,处理


器进入了未定义模式


                MOV     SP, R0     ;栈指针指向了Stack_Top


                SUB     R0, R0, #UND_Stack_Size   ;Stack_Top = Stack_Top - ABT_Stack_Size


; Enter Abort Mode and set its Stack Pointer


                MSR     CPSR_c, #Mode_ABT:OR:I_Bit:OR:F_Bit


                MOV     SP, R0


                SUB     R0, R0, #ABT_Stack_Size


; Enter FIQ Mode and set its Stack Pointer


                MSR     CPSR_c, #Mode_FIQ:OR:I_Bit:OR:F_Bit


                MOV     SP, R0


                SUB     R0, R0, #FIQ_Stack_Size


; Enter IRQ Mode and set its Stack Pointer


                MSR     CPSR_c, #Mode_IRQ:OR:I_Bit:OR:F_Bit


                MOV     SP, R0


                SUB     R0, R0, #IRQ_Stack_Size


; Enter Supervisor Mode and set its Stack Pointer


                MSR     CPSR_c, #Mode_SVC:OR:I_Bit:OR:F_Bit


                MOV     SP, R0


                SUB     R0, R0, #SVC_Stack_Size


; 进入用户模式,并且设置栈空间指针


; Enter User Mode and set its Stack Pointer


                MSR     CPSR_c, #Mode_USR


                IF      :DEF:__MICROLIB   ;支持 MICROLIB库,如果C程序的运行库是MICROLIB 则将__initial_sp 导出


                EXPORT __initial_sp


                ELSE


                MOV     SP, R0


                SUB     SL, SP, #USR_Stack_Size


                ENDIF


;进入C代码的执行,为C代码的执行创造一个运行环境


; Enter the C code


                IMPORT __main   ;导入外部符号


                LDR     R0, =__main ;将main的地址加载到r0中


                BX      R0   ;带状态的跳到main 去执行


                IF      :DEF:__MICROLIB ;还是有关使用MICROLIB库的,如果使用了该库就要导出下面连个符号。

       

         EXPORT __heap_base


                EXPORT __heap_limit


                ELSE


; User Initial Stack & Heap


                AREA    |.text|, CODE, READONLY


                IMPORT __use_two_region_memory


                EXPORT __user_initial_stackheap

__user_initial_stackheap

       

         LDR     R0, = Heap_Mem


                LDR     R1, =(Stack_Mem + USR_Stack_Size)


                LDR     R2, = (Heap_Mem +      Heap_Size)


                LDR     R3, = Stack_Mem


                BX      LR


                ENDIF


                END

一直对底层的东西不太懂,总是朦朦胧胧的感觉,索性拿启动代码看一下吧,指望着能学一下汇编。周末的学习效率是在太低了,一个小小的启动文件竟然费了两天功夫。费了牛劲了看是看完了,还是有好多地方一头雾水。因为认识的深度有限,错误的地方肯定少不了,所以还请您校正。


关键字:LPC2000  启动代码  Start  s文件 引用地址:LPC2000 启动代码Start.s文件简要分析

上一篇:LPC-2124中断概述
下一篇:stm32在Keil5调试提示: uvision IDE已停止工作

推荐阅读最新更新时间:2024-03-16 16:18

MY2410开发板(S3C2410)INC文件1----2410addr.h
#ifndef __2410ADDR_H__ #define __2410ADDR_H__ #ifdef __cplusplus extern C { #endif #include option.h // Memory control #define rBWSCON (*(volatile unsigned *)0x48000000) //Bus width & wait status #define rBANKCON0 (*(volatile unsigned *)0x48000004) //Boot ROM control #define rBANKCON1 (*(volatile unsigned *)0
[单片机]
OK6410A 开发板 (八) 6 linux-5.11 OK6410A 详细解析 从 u-boot 的 theKernel 到 linux的 start_kernel
之前写过 linux-3.0.1 ok6410a 的启动流程, 从 arch/arm/boot/compressed/head.S 到 mm_init 完成 回忆 linux-3.0.1 ok6410a 的启动流程 这里讲述了 内存镜像的生成过程以及压缩/无压缩镜像启动的不同打印 压缩内核 会打印 Uncompressing Linux… done, booting the kernel ,再打印 Booting Linux on physical CPU 非压缩内核直接打印 Booting Linux on physical CPU 这里讲述了 压缩内核的入口(arch/arm/boot/compressed/head.
[单片机]
s3c2440头文件之2440lib.h
//=================================================================== // File Name : 2440lib.h // Function : S3C2440 // Date : February 26, 2002 // Version : 0.0 // History // 0.0 :Feb.20.2002:SOP : Programming start // 0.01:Mar.29.2002:purnnamu: For Sleep_wake_up, the START... label is added //==================
[单片机]
STM32启动文件初探之startup_stm32f10x_hd.s(Reset_Handler函数)
该文件主要实现目的: 设置初始SP 设置初始PC=Reset_Handler 设置向量表入口地址,并初始化向量表 调用SystemInit,把系统时钟配制成72M,SystemInit在库文件system_stm32f10.c定义 调转到标号_main,最终来到C程序文件 ; Reset handler Reset_Handler PROC EXPORT Reset_Handler IMPORT __main IMPORT SystemInit LDR R0, =SystemInit BLX R0
[嵌入式]
05-S3C2440学习之内核(移植)linux3.4.2移植(1) 简单移植+修改MTD分区+制作jffs2文件系统
一、框架介绍及简单修改 1.1 Bootloader如何引导内核 Bootloader的工作: (1)讲内核读入内存中 (2)存一些内核启动参数到指定位置,内核启动时去解析 (3)启动内核,传入机器ID 1.2、内核的启动流程: 首先 内核的最终目的是挂接根文件系统,并启动应用程序。 想启动应用程序—需要挂接根文件系统—装载驱动程序(flash、网卡)--要解析参数(文件系统在哪)--根据R1判断内核是否支持该ID—支持调用初始化相关函数 每个开发板都有不同的硬件参数 内核移植过程中要决定我这个内核支持哪些硬件开发板 我在内核里针对这个开发板给他一个ID。Uboot启动的时候传入和内核中设置好的匹配
[单片机]
05-<font color='red'>S</font>3C2440学习之内核(移植)linux3.4.2移植(1) 简单移植+修改MTD分区+制作jffs2<font color='red'>文件</font>系统
STM32启动文件分析——startup_stm32f10x_hd.s
一、启动文件的作用 (关于启动代码的作用,前面已经提到过了,这里再啰嗦一下) (1)初始化堆栈指针 SP; (2)初始化程序计数器指针 PC; (3)设置堆、栈的大小; (4)设置异常向量表的入口地址; (5)配置外部 SRAM作为数据存储器(这个由用户配置,一般的开发板可没有外部 SRAM); (6)设置 C库的分支入口__main(最终用来调用 main函数); (7)在 3.5版的启动文件还调用了在 system_stm32f10x.c文件中的SystemIni()函数配置系统时钟。 二、启动文件中提到的汇编指令 指令 作用 EQU 给数字常量取一个符号名,相当于 C 语言中的
[单片机]
基于S3C2440的嵌入式Linux根文件系统构建
  嵌入式Linux早已成为IT界家喻户晓的一个名字,使用Linux进行嵌入式产品开发有一个很大的优势,就是开发资源丰富,且成本低廉,嵌入式Linux操作系统越来越受到重视,其应用也越来越广泛。而文件系统作为操作系统的重要组成部分,用于控制对数据文件及设备的存取,提供对文件和目录的分层组织形式,数据缓冲以及对文件存取权限的控制。根文件系统一直是Linux系统不可或缺的组件,在嵌入式Lin-ux中,内核在启动期间进行的最后操作之一就是安装根文件系统。busybox是构建嵌入式Linux根文件系统的软件,用它制作根文件系统简单、方便,而且设置灵活。    1 根文件   Linux要在一个分区上存放系统启动所必需的文件,如内核
[嵌入式]
ARM 启动代码笔记
1、汇编启动代码之看门狗 看门狗其实就是一个定时器,硬件上就是SOC内部的一个内部外设 看门狗不用分析原理图, 关键性操作寄存器 WTCON(xE270_0000) bit5 是开门狗的开关 1代表开,0代表关 2、汇编写启动代码之设置栈和调用C语言1 1、C语言运行需要和栈的意义 “C语言运行需要” 需要一定的条件,这些条件都是由汇编提供的。 C语言运行需要栈 栈的特点:自动进入,自动退出,C语言的局部变量,都是在栈中运行的。 如果我们汇编部分没有给C设置 合理的栈地址,那么C语言中的局部变量地址就会螺孔,整个程序就死掉了。 2、CPU模式各模式下的栈 每种模式下都有自
[单片机]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
502 Bad Gateway

502 Bad Gateway


openresty
设计资源 培训 开发板 精华推荐

502 Bad Gateway

502 Bad Gateway


openresty
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

502 Bad Gateway

502 Bad Gateway


openresty
502 Bad Gateway

502 Bad Gateway


openresty
502 Bad Gateway

502 Bad Gateway


openresty
随便看看
    502 Bad Gateway

    502 Bad Gateway


    openresty
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
502 Bad Gateway

502 Bad Gateway


openresty