S3C6410的WinCE 6.0启动过程

S3C6410(OK6410开发板介绍) S3C6410(OK6410开发板介绍)     1.   系统资源 A.处理器       Samsung S3C6410处理器,ARM1176JZF-S内核,主频533MHz/667MHz  B.FLASH    1G字节NAND Flash(MLC)    这里nor flash相当于电脑中的固态硬盘,容量小,速度快,价格贵     Nand  flash相当于电脑 阅读详情

以S3C6410为例子,S3C6410的内部SRAM地址为0x0C00 0000 ~ 0x0C00 1FFF,DRAM的Base地址为0x50000000 ,S3C6410支持NAND,SD启动,S3C6410里面有固化的ROM,
当系统上电的时候,将执行固化ROM中的代码,然后检查硬件的GPIO配置,如果配置成NAND 启动,则把NAND的前8K读入内部的SRAM(stepping Stone)中,然后跳转到
Stepping Stone的开头,执行Bootloader1 (也就是下文的stepldr), stepldr负责把eboot从NAND中搬到DRAM中,然后执行eboot( boot loader 2),eboot通过网络下载
NK.bin或者从NAND中把内核搬到DRAM中,然后执行WINCE内核.所以整个启动过程分为三阶段,stepldr -->eboot --> wince kernel .
下面详细地分析各个阶段.
一 bootloader 1 stepldr
从stepldr的startup.s开始.startup.s主要是初始化硬件,中断,配置好C运行的环境,然后跳转到main函数中,执行C代码.
startuo.s 的流程是 :
startup --> Enable I cache -->关闭watchdog ,Interrupt dosable -> 时钟初始化 --> 初始化DRAM控制器 --> 初始化IRQ,SVC stack -->
判断是否睡眠 ---N--> Clear DRAM -->main
--Y-> 跳到NK的开头 (也就是DRAM + 0x100000的地方)

main.c :
UART初始化 --> nand 初始化 -> 从NAND中把eboot搬到DRAM中 -->跳转到 eboot的开头

我们看代码有2个全局变量。
ROMHDR * volatile const pTOC = (ROMHDR *)-1; 这个在ROMImage里面会赋值。
static BOOL g_bLargeBlock = FALSE; // For Large Block Check
这两个全局变量的位置为:500F0000 根据stepldr.bib

二 bootloader 2 eboot
startup.s
startup --> Enable I cache -->关闭watchdog ,Interrupt dosable -> 时钟初始化 --> Disable VIC --> enable 中断 -->CLEAR DRAM(从1M到128M地址的DRAM,因为低1M地址
空间目前放的是eboot ) --> 初始化MMU Table (根据g_oalAddressTable,把DRAM的Base地址0x50000000映射到0x80000000,此后地址都用虚拟地址) --> 初始化IRQ,SVC stack -->
-->main


main.c
main --> BootloaderMain

BootloaderMain的流程:
KernelRelocate -->OEMDebugInit(初始化串口,这样就可以打印信息了) -->OEMPlatformInit -->OEMPreDownload -->DownloadImage-->OEMLaunch (切换到ce内核了)
OEMPlatformInit :
InitializeDisplay --> 初始化中断 -->NAND Flash驱动 初始化 --> MainMenu (一些选项,比如设置IP) -->ethernet 驱动初始化

OEMPreDownload : get IP , initialize TFTP
DownloadImage :
先用OEMReadData读7位头,然后根据这7位判断是bin 还是 nb0 等
假如是bin , 调用 DownloadBin


三 wince OS
wince os 的启动我们也可以换分为2个阶段,第一个阶段,初始化OAL,一直到FirstSchedule开始调度,第二阶段,开始对文件系统,注册表,driver的
初始化和加载。
(1)初始化 OAL

1.startup.s

初始化一些硬件外设 --> KernelStart

2.KernelStart
在PRIVATE\WINCEOS\COREOS\NK\LDR\ARM\armstart.s中
根据OALAddress Table初始化页表 , 打开MMU和初始化Cache和中断向量
初始化stack
调用ArmInit
mov r12, r0
ldr r0, =KData
mov pc, r12 ; jump to entry of kernel.dll
3 ArmInit
在PRIVATE\WINCEOS\COREOS\NK\LDR\ARM\arminit.c中
LPVOID ARMInit (struct KDataStruct *pKData)
{
/* Initialize kernel globals */
KernelRelocate (pTOC);

/* The only argument passed to the entry point of kernel.dll is the address */
/* of KData, we need to put everything we need to pass to in in KData. */
pKData->dwTOCAddr = (DWORD) pTOC;
pKData->dwOEMInitGlobalsAddr = (DWORD) OEMInitGlobals;

SetOsAxsDataBlockPointer(pKData);

return FindKernelEntry (pTOC);
}
主要是内核重定位 .返回kernel.dll的入口位置.
在上面的KernelStart函数中,mov pc, r12指令跳转到kernel.dll的入口位置.

4 FindKernelEntry找到NKStartup
在PRIVATE\WINCEOS\COREOS\NK\KERNEL\ARM\mdarm.c中
调用 ARMSetup (PRIVATE\WINCEOS\COREOS\NK\KERNEL\ARM\mdarm.c)to perform addition setup for CPU (vector table, 1st-level PT mappings, etc)
调用OEMInitDebugSerial 以及 OEMInit

5 OEMInit
在\PLATFORM\SMDK6410\SRC\OAL\OALLIB\init.c中

OALCacheGlobalsInit();
.....
OALArgsInit((BSP_ARGS *)IMAGE_SHARE_ARGS_UA_START);// Check and Initialize the BSP Args area
.....
if (!OALIntrInit())// Initialize Interrupts
{
OALMSG(OAL_ERROR, (L"[OAL:ERR] OEMInit() : failed to initialize interrupts\n"));
}
.......
OALTimerInit(RESCHED_PERIOD, (OEM_COUNT_1MS ), 0);// Initialize System Clock
.......
KITLIoctl(IOCTL_KITL_STARTUP, NULL, 0, NULL, 0, NULL); // Initialize the KITL connection if required

6、KernelSstart函数:
这里的KernelStart函数与前面的KernelStart函数的属于两个完全不同的函数,NKStartup函数中调用的KernelStart 函数为
$(_PRIVATEROOT)\WINCEOS\COREOS\NK\KERNEL\ARM\armtrap.s文件中的KernelStart 函数,
主要完成调用内核初始化函数KernelInit,并跳转到操作系统的第一个启动的任务。
LEAF_ENTRY KernelStart
ldr r4, =KData ; (r4) = ptr to KDataStruct
ldr r0, =APIRet
str r0, [r4, #pAPIReturn] ; set API return address
mov r1, #SVC_MODE
msr cpsr_c, r1 ; switch to Supervisor Mode w/IRQs enabled
CALL KernelInit ; initialize scheduler, etc.
mov r0, #0 ; no current thread
mov r1, #ID_RESCHEDULE
b FirstSchedule
ENTRY_END

7、KernelInit函数:
Windows CE 6.0的内核初始化函数同其他版本的内核初始化函数基本相近,主要完成在启动第一个线程前对内核进行初始化,主要包括API函数集初始化、堆的初始化、初始化内存池、进程初始化、线程初始化和文件映射初始化等操作。
void KernelInit (void)
{
#ifdef DEBUG
g_pNKGlobal->pfnWriteDebugString (TEXT("Windows CE KernelInit\r\n"));
#endif
APICallInit ();// setup API set
HeapInit ();// setup kernel heap
InitMemoryPool ();// setup physical memory
PROCInit ();// initialize process
VMInit (g_pprcNK);// setup VM for kernel
THRDInit ();// initialize threadsv
MapfileInit ();
#ifdef DEBUG
g_pNKGlobal->pfnWriteDebugString (TEXT("Scheduling the first thread.\r\n"));
#endif
}

8、FirstSchedule:
FirstSchedule函数为Windows CE操作系统启动过程中最后无条件跳转的一个函数,windows CE进行第一个调度,实际为一个空闲线程,因为windows CE系统还没有完成启动,只有当windows CE完全启动并进入稳定状态,然后启动文件系统filesys.dll,设备管理device.dll,窗体图像子系统gews.dll和shell程序 explore.exe。

(2)系统的其它部分初始化

2.1 FirstSchedule --〉SystemStartupFunc
2.2 而在SystemStartupFunc中,会创立一个内核线程
CreateKernelThread (RunApps,0,THREAD_RT_PRIORITY_NORMAL,0)
这样就执行线程的函数RunApps
2.3 在RunApps中,NKLoadLibraryEx (L"filesys.dll", MAKELONG (LOAD_LIBRARY_IN_KERNEL, LLIB_NO_PAGING), NULL);
进行filesys.dll的加载,
2.4 然后启动一个线程,执行filesys.dll的 WinMain
2.5 等待filesys.dll 的event SYSTEM/FSReady
2.6 收到后:
InitMUILanguages();// Initialize MUI-Resource loader (requires registry)

InitSystemSettings (); // Read system settings from registry

我们再来看看 FILESYS.DLL 。它相当于Windows CE以前版本中的FILESYS.EXE,负责初始化文件系统、对象存储、注册表、CEDB数据库、设备通知以及其它一些工作。

1 Filesys.dll 检测是冷启动还是热启动
如果是冷启动,对象存储内存将被初始化并映射给Filesys.dll.对于热启动,不用初始化而直接映射给Filesys.dll
2 Filesys.dll 从ROM中加载 OEM的 Certification DLL .

3 对于热启动,如果系统必须冷启动, Filesys.dll调用OAL函数pNotifyForceCleanboot.

4 对于冷启动, Filesys.dll 初始化RTC,通过调用OEMIoControl函数,控制号为IOCTL_HAL_INIT_RTC I/O.
5 Filesys.dll 按照顺序初始化下列APIs:
Database APIs
File system APIs
Point-to-point message queue APIs
Event log APIs
Registry APIs
对于冷启动, Filesys.dll初始化注册表数据.数据初始化过程取决于是hive注册表还是RAM注册表.
如果在注册表里指定了缺省的用户Profile, Filesys.dll加载缺省用户的profile并初始化 HKEY_CURRENT_USER下的数据.

6 如果Device.dll 没有启动并且HKEY_LOCAL_MACHINE\System\StorageManager 指向一个可以加载的DLL, Filesys.dll加载存储管理器.
如果存储管理器加载了, Filesys.dll创建一个线程来初始化它.

7 Filesys.dll 初始化NLS数据(national language support).
8 对于一个干净的启动,Filesys.dll查阅Initobj.dat文件,然后从ROM中拷贝这些文件到根文件系统.
比如Initobj.dat内容为:
root:-Directory("Program Files")
root:-Directory("My Documents")
Directory("\Windows"):-Directory("Desktop")
Directory("\Windows"):-Directory("Programs")
Directory("\Windows"):-Directory("Recent")
Directory("\Windows\Desktop"):-File("Media Player.lnk", "\Windows\ceplayer.lnk")
Directory("\Windows\Programs"):-File("Media Player.lnk", "\Windows\ceplayer.lnk")
Directory("\Windows\Desktop"):-File("Messenger.lnk", "\Windows\msmsgs.lnk")
Directory("\Windows\Programs"):-File("Messenger.lnk", "\Windows\msmsgs.lnk")
它的意思是:
先用root命令在根目录\下面建立2个文件夹,分别叫Program Files和My Documents.
然后在\Windows下面建立3个文件夹Desktop,Program,Recent
最后把Media Player的链接ceplayer.lnk,msmsgs.lnk拷贝到\windows\Desktop,Programs目录下,命名为Media Player.lnk,Messenger.lnk.

9 如果需要的话,Filesys.dll初始化时区并设置夏令时 (daylight saving time ,DST).
10 对于冷启动, Filesys.dll为用数据库引擎设置区域,对于EDB数据库,通过调用CeChangeDatabaseLCID (EDB)而对于CEDB数据库调用CeChangeDatabaseLCID (CEDB).
此外,对于冷启动,Filesys.dll从Initdb.ini文件中加载数据来填充对象存储数据库.

11 Filesys.dll告诉kernel:Filesys.dll已经好了. Filesys.dll然后等待kernel通知去启动OS的其他部分.

12 Filesys.dll根据HKEY_LOCAL_MACHINE\System\Events注册表创建命名的事件. 这些事件被拥有他们的进程设置.

13 Filesys.dll 启动HKEY_LOCAL_MACHINE\Init所列的应用
如果Device.dll在HKEY_LOCAL_MACHINE\Init中,而它又已经被启动,Filesys.dll会去打开SYSTEM/BOOTPHASE2事件,并会向Device.dll发信号。
该动作使得Device.dll会去重读注册表,并完成最后阶段的驱动初始化。任何驱动都可以去等待该同样的事件,这样驱动就可以去再读一次注册表。

在正常的启动过程中,Filesys.dll建立了一些文件并把他们存储在user storage中. 这些文件将占用 1.8 MB的可用的user storage.

下列文件在启动过程中被创建:

System.hv \Documents and Settings\system.hv 345 KB 系统注册表hive文件
User.hv \Documents and Settings\default\user.hv 345 KB 缺省用户的用户注册表hive文件

对于filesys.dll启动过程,参见 http://msdn.microsoft.com/en-us/library/aa912276.aspx

再来看Device.dll,它被加载后,将读取 HKLM\Drivers\BuildIn下面的信息,然后一个一个驱动被加载,加载后相应地在 HKLM\Drivers\Active下面创立相应的键.

armplayer/android6410/android 6410/wince/linux/ubuntu/s3c6410/arm11 开发板 <br />店主:嵌入式系统工程师<br />联系方式:<br /> QQ:1141256841/774295611  <br />技术qq群:<br />40605090    大连嵌入式商城群<br />121393599   android6410(一)群<br />16667174      android6410(二)群<br />103775766     android6410(三)群<br />121399050   android6410(四)群<br />手机:1532615352 阅读详情

相关推荐

Wince 6.0 开机自启动 总结

最近在做基于Wince6.0的应用程序的开发,应用程序基本开发完毕,需要把程序烧写进内核。经过一段时间折腾,算是完成了任务,先总结如下: wince6.0的应用程序烧写进内核方法与wince5.0修改的地方基本一致。这里需要说明,在\WINCE600\OSDesigns\S3C6410_DEM0\RelDir\Samsung_SMDK6410_Release里的操作前提是已经编译生成NK.bin

5211

Windows CE 5.0启动过程分析

分析WinCE5.0的启动过程对了解和掌握Windows CE操作系统比较重要,下面主要分析Win CE5.0的启动过程,在后续的文章中将分析WinCE6.0的启动过程。     1、CPU加电,跳转到复位向量; 2、执行引导程序Startup();OAL中的Startup(); •         完成最小的CPU和硬件初始化; •         关闭中断、缓存(Cache)和

wince--linux的专栏 1234

armplayer/android6410/s3c6410/arm11 开发板+4.3寸TFT+22DVD

店主:嵌入式系统工程师联系方式: QQ:1141256841/774295611  技术qq群:40605090    大连嵌入式商城群121393599   android6410(一)群16667174      android6410(二)群103775766     android6410(三)群121399050   android6410(四)群手机:15326153526  MSN:lovexuemei@hotmail.com 旺旺:victorzhangl此产品为armplayer

arm开发板,linux,wince,android技术专栏 2889

WINCE启动流程

WINCE实际上是由一些运行中的进程组成的,当系统启动时,至少会创建以下4个进程:1> NK.exe:提供内核服务,是操作系统核心部分。2> GWES.exe:提供用户界面服务和消息管理机制。3> Device.exe:加载和维护系统设备驱动程序。4> Filesys.exe:加载和管理文件系统。由于运行WINCE的硬件平台较

lgb571的专栏 2575

S3C2410下WinCE的启动过程详解及编程示例

引导加载程序是一个位于芯片内部或外部存储器中的小型程序,负责初始化硬件、加载操作系统镜像并将控制权转交给操作系统。加载操作系统镜像的过程包括从存储器中读取镜像数据,并将其加载到内存中的适当位置。在引导加载程序中,需要对S3C2410芯片上的硬件进行初始化。在完成硬件初始化和操作系统镜像加载之后,引导加载程序将控制权转交给操作系统。控制权的转交意味着引导加载程序停止执行,并将程序的控制权交给操作系统内核。请注意,以上示例代码仅为演示目的,实际的引导加载程序和操作系统镜像加载过程可能更为复杂。

2301_79326254的博客 189

wince开机自启动方法

描述WINCE自动启动应用程序的方法11111111111111111111111111111111111111111111

Windows CE 6.0 启动过程分析(转)

在Windows CE 6.0中,内核(Kenerl)和OEM代码被分成oal.exe、kernel.dll和kitl.dll三个部分,其中启动代码(startup)和 OAL层的实现部分不再与内核链接生成NK.exe,取而代之的是启动代码(startup)和硬件相关且独立于内核的OAL层的实现部分编译成 oal.exe,而与内核相关且独立于硬件的OAL层代码包含在kernel.dll中;内核无关

梦中江湖——vcleaner 4118

我的wince设备的启动过程录像

我的wince设备的启动过程录像,含bootloader画面和进度条,最后进入到桌面。

wince6.0启动

以S3C6410为例子,S3C6410的内部SRAM地址为0x0C00 0000 ~ 0x0C00 1FFF,DRAM的Base地址为0x50000000 ,S3C6410支持NAND,SD启动,S3C6410里面有固化的ROM, 当系统上电的时候,将执行固化ROM中的代码,然后检查硬件的GPIO配置,如果配置成NAND 启动,则把NAND的前8K读入内部的SRAM(stepping Stone)...

金家兴无 1035

WINCE6.0的启动过程

WINCE 的eboot代码分析,看完了对wince的启动过程会有个较清晰地认识。

wince6.0开机自启动应用程序及方法

wince6.0开机自启动应用程序及方法,测试通过可行的方法

S3C6410 SD Card一键烧写 WINCE 6.0

S3C6410 SD Card一键烧写 WINCE 6.0 下载地址:S3C 6410 烧写工具及 SD Card 启动镜像 提取码:i2z1 下载地址:S3C6410 WINCE 6.0 系统镜像文件 提取码:r0cd PC 上打开 DNW 软件 PC 上右键 此电脑 设备管理器–>> 端口(COM 和 LP) 烧写时所需要的镜像文件及说明 编号 镜像文件 说明 1 STEPLDR.nb0 Steplooder 上电时最先加载,用于引导 Eboot 2 STEPLDR

clay_xiaoyu的博客 4287

2025年VSCode AI插件实战:如何用Devika+Continue+Tabby三件套10倍提升开发效率

本文详细介绍了2025年VSCode AI插件Devika、Continue和Tabby的三件套组合,如何通过智能开发工作流10倍提升开发效率。从项目架构生成到上下文感知辅助,再到本地化智能编码,这套方案实现了从需求分析到代码生成的全流程自动化,特别适合中大型项目开发。

weixin_26911099的博客 270

WINCE6.0+S3C6410基于SD卡启动

1.  基于IROM SD/MMC启动方式的原理 我们知道S3C6410支持IROM启动(internal ROM Booting),IROM启动是指从OneNAND、SD/MMC卡和NAND Flash存储设备启动的方式,见下图: 图1 IROM启动流程 上图是系统基于IROM方式启动的工作流程图,下面简要描述此流程主要的工作: 1)  处理器上电后,当OM[4:1]=1111时,执行IR

无语僧 947

Greenplum基础

CREATE DATABASE 是 SQL 命令,用于创建一个新的数据库。name 是你要创建的数据库的名称。这个名称是必须的,并且在同一个数据库服务器上必须是唯一的。可选项,OWNER 指定了新数据库的所有者,如果未指定,新数据库的所有者默认是执行该命令的用户。dbowner 是数据库所有者的用户名。可选项,TEMPLATE 指定了用于创建新数据库的模板。在 PostgreSQL 和 GreenPlum 中,通常有一个名为 template1 的默认模板。如果不指定,就会使用这个默认模板。

m0_57697768的博客 1206

2025.1.16——五、LoveSQL1 sqlmap文件类|万能密码

题目来源:BUUCTF[极客大挑战2019]LoveSQL1。

2402_87387800的博客 1067

WINCE6.0+S3C6410睡眠和唤醒的实现

原文:http://cky0612.blog.163.com/blog/static/27478916201161011450822/ WINCE6.0+S3C6410睡眠和唤醒的实现 ********************************LoongEmbedded***************** 作者:LoongEmbedded(kandi) 时间:2011.07.1

孤独长跑者的专栏 1423

S32DS IDE调试技巧:如何用条件断点精准捕获汽车电子MCU的硬件状态变化

本文详细介绍了S32DS IDE中条件断点功能在汽车电子MCU开发中的应用技巧。通过精准捕获硬件状态变化,工程师可以高效调试外设寄存器异常、时序敏感型交互等复杂场景,大幅提升汽车电子系统的开发效率。文章还提供了多种实战案例和性能优化建议,帮助开发者充分利用S32DS的调试功能。

CAT789的专栏 207

wince+s3c6410 SD卡启动

欢迎加入Wince技术讨论群QQ#326444254 1.  基于IROM SD/MMC启动方式的原理 我们知道S3C6410支持IROM启动(internal ROM Booting),IROM启动是指从OneNAND、SD/MMC卡和NAND Flash存储设备启动的方式,见下图: 图1 IROM启动流程 上图是系统基于IROM方式启动的工作流程图,下面简要

u011610939的专栏 1062

PVE(Proxmox VE)添加VMware Esxi并迁移虚拟机

跨平台迁移虚拟机:从VMware虚拟化平台迁移虚拟机到PVE平台。

VEGETA的博客 7714

学Simulink--基于多物理场耦合与系统集成的储能系统场景实例:压缩空气储能(CAES)系统的热力学建模与效率分析

本文提供了一个基于Simulink的压缩空气储能(CAES)系统热力学建模教程。通过多物理场耦合方法,详细演示了从系统架构设计到仿真测试的全过程,包括多级压缩机/膨胀机系统搭建、显热蓄热系统设计以及效率分析。文章重点强调了热管理对提升CAES效率的关键作用,并给出了68%电-电效率的优化案例。最后提出了变工况建模、不同蓄热介质对比等高级优化方向,为开发零碳大容量储能系统提供了实用工具和方法。

amy_mhd的博客 131

S3C6410 IROM启动

IROM启动(internal ROM Booting),IROM启动是指从OneNAND、SD/MMC卡和NANDFlash存储设备启动的方式,见下图,描述了6410支持的启动模式。 ." title="S3C6410的IROM启动模式 ." height="497" width="690"> 图1   1.IROM启动方式的图解 ." title="S3C6410的IROM启

1549

开源项目evo2安装教程

Evo 2 是一种先进的 DNA 语言模型,用于长上下文建模和设计。Evo 2 使用 StripedHyena 2 架构在单核苷酸分辨率下对 DNA 序列进行建模,上下文长度可达 100 万碱基对。Evo 2 使用 Savanna 进行预训练,并在 OpenGenome2 数据集上进行自回归训练,该数据集包含来自所有生命领域的 8.8 万亿个标记。

猿小白的博客 927

S3C6410的WinCE系统烧录

//=====================================================================//TITLE://    S3C6410的WinCE系统烧录//AUTHOR://    norains//DATE://    Tuesday 13- April-2010//Environment://    DMA6410//============

norains的专栏 5958

CE电流法测试中的dBμV负值解析

传导发射(CE)电流法测试中出现的dBμV负值现象表明被测设备干扰电平低于1μV参考基准。这源于对数计算特性(小于1μV的电压转换后为负值)、设备优良的EMC设计(如滤波效果显著)及测试环境的影响(LISN隔离、屏蔽室低噪声)。负值虽不代表实际负电压,但反映干扰水平优于标准限值,为系统集成预留电磁裕度。工程应用中需结合设备灵敏度、环境背景噪声等因素综合分析,避免误判,这类数据可用于评估EMI设计冗余度。

硬核科技 298

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

上一篇: linux下文件拷贝的例子
下一篇: 提示No Launcher activity found
道客优
博客等级 码龄14年 24粉丝 40原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值