自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(263)
  • 资源 (23)
  • 收藏
  • 关注

原创 14. Linux-riscv内存管理66-71问

写时复制(Copy-On-Write,COW)是一种内存管理技术,它用于优化操作系统中进程的内存分配和管理。在使用COW的操作系统中,当一个进程需要复制一个已经存在的内存页时,不会直接复制,而是将新的内存页映射到同一个物理页框中,只有当其中一个进程需要修改这个页面时,才会复制出一个新的物理页框来,并将修改后的数据写入其中。缺页异常是操作系统中的一个机制,用于处理程序访问的内存页面不在物理内存中的情况。

2025-12-08 15:21:21 29

原创 13. Linux-riscv内存管理62-65问

这里给出答案,懂得人可以略过,主要是因为虚拟地址和物理地址的映射关系并没有建立,我们知道Linux进程访问一块内存实际上使用的是虚拟内存,必须把对应虚拟地址空间和物理页面进行了映射才能够正常访问,那么vma结构体实际仅仅表示一个虚拟地址空间,必须把内核中Page Cache中的物理地址与进程vma虚拟地址空间进行映射才能正常被进程访问到。在do_page_fault中回去检查这个地址是否有对应的vma,如果有对应的vma,表示此异常地址时可以修复的。编号为13的读内存异常,编号为15的是写内存异常。

2025-12-01 10:16:50 27

原创 12. Linux-riscv内存管理61-61问

为了能够以简短和快速的展示此函数核心功能,去掉的宏定义有:CONFIG_VMAP_STACK、CONFIG_TRACE_IRQFLAGS、CONFIG_CONTEXT_TRACKING、CONFIG_RISCV_M_MODE。上图解释:假设当前用户进程发起系统调用,此时栈底存放的就是当前的用户进程的寄存器信息,在系统调用过程中函数的局部变量也会保存到进程的内核栈上,发生了中断,则要保存当前内核状态的信息到栈上,即第二个pt_regs。通常异步异常指的是中断,而同步异常指的是异常。可以先看2.34.2。

2025-11-19 15:16:37 69

原创 11. Linux-riscv内存管理54-60问

以避免被交换出去。FOLL_WRITE:当flags参数的有此参数时,需要pte_write或者((flags & FOLL_FORCE) && (flags & FOLL_COW) && pte_dirty(pte))FOLL_TOUCH:表示在follow_page的时候需要调用一次mark_page_accessed()函数,还要设置page为dirty。follow_page()函数的核心函数为follow_page_mask,在get_user_pages函数中也会调用此函数。

2025-11-17 09:00:53 83

原创 10. Linux-riscv内存管理47-53问

这时问题出来了,这些页面可能会被换出,get_user_pages并没有做任何事情比如锁住页面以保证页面不被换出,在页面换出的时候,用户映射的页表项的存在位会被清除,但是这可能不会通知该页面的内核映射的页表项,如果内核继续读写该页面,那么结果将是错误的,因此,内核不应该长时间的保持get_user_pages的映射。vm_normal_page()函数返回普通映射页面的page数据结构,一些特殊映射的页面是不会返回page数据结构的,这些页面不希望参与与内存管理的一些活动,如页面回收、页面迁移和ksm等。

2025-11-13 09:26:46 44

原创 9. Linux-riscv内存管理41-46问

从protection_map数组的转换可以看出,其只关心VM_READ|VM_WRITE|VM_EXEC|VM_SHARED 这四个属性。需要设置当前页表有效(_PAGE_PRESENT),设置_PAGE_ACCESSED,需要硬件自动去设置对pte的访问,_PAGE_USER需要u模式有访问权限。在创建一个新的vma时使用vm_get_page_prot()函数可以把vm_flags标志位转换成具体的页表项的硬件标志位。insert_vm_struct()是内核提供的插入vma的核心接口函数。

2025-11-11 17:16:05 205

原创 8. Linux-riscv内存管理35-40问

假设新创建的slab描述符my_object的本地对象缓冲池中没有空闲对象(ac-avail = 0),那么在cache_alloc_refill()->cache_grow_begin()函数中会创建一个slab分配器。迁移完成之后,slab分配器中的对象0和对象1变成了不活跃的对象,而其他4个都是活跃对象。本地对象缓冲池存放的事obj的地址,而不是编号,根据obj地址、slab分配器的起始地和obj的size,可以计算出obj的编号,计算函数为:obj_to_index()

2025-11-11 17:07:35 82

原创 7. Linux-riscv内存管理28-34问

早期Linux内核采用$$2^n$$字节的内存块分配机制,虽然减少浪费但效率不高。slab分配器通过对象缓存池、保留释放对象和多层缓冲池等机制,有效解决了内存碎片和效率问题。slab分配器为每个CPU设置本地缓冲池,避免锁争用,并通过着色区优化缓存访问。当空闲对象过多时,会将对象从本地池移至共享池。对象缓存池即kmem_cache结构中的obj数组,用于快速分配和释放小内存块。

2025-11-07 09:34:43 51

原创 6. Linux-riscv内存管理25-27问

释放页面的核心功能是把空闲页面添加到伙伴系统中合适的空闲链表中。在释放内存块时,会检查后面相邻的内存块是否空闲,如果空闲,就将其合并成一个大的内存块,放置到高一阶的空闲链表中。如果还能继续合并邻近的内存块,就会继续合并,转到到更高的空闲链表中,这个过程会一直重复下去,直到所有可能合并的内存块都已经合并。释放页面的API:释放页面的核心函数:__free_one_page假设现在要释放一个内存块A,大小为两个页面,内存中页面的开始页帧号是0x10,order为1,通过函数__find_buddy_pfn(

2025-11-07 09:27:13 369

原创 openwrt出现rootfs只读原因

从新编译openwrt软件。openwrt启动时出现。rootfs未对齐。

2024-09-24 17:58:28 848

原创 OrangePi AIpro 性能测试以及使用体验

OrangePi AIpro是一款单板计算机,主要用于人工智能应用。它的优点可以简单概述如下:强大的性能:OrangePi AIpro配备了高性能的处理器和GPU,能够处理复杂的人工智能任务和计算密集型应用。丰富的接口:它提供了丰富的接口,包括多个USB接口、网口、HDMI接口等,便于连接外部设备和扩展功能。支持多种人工智能框架:OrangePi AIpro支持多种流行的人工智能框架,如TensorFlow、PyTorch等,方便开发人员进行模型训练和推理。

2024-05-27 19:41:20 1262

原创 0. linux-riscv内存管理120问大纲

内存管理之预备知识1.1 请简述内存架构中UMA和NUMA的区别1.2 CPU访问各级存储结构的速度是否一样?1.3 请绘制内存管理常用的数据结构的关系图,如mm_struct、VMA、vaddr、page、PFN、PTE、zone、paddr和pg_data等,并思考如下转换关系1.3.1 如何由mm_struct和vaddr找到对应的vma?1.3.2 如何由page和VMA找到vaddr?1.3.3 如何由page找到所有映射的VMA?1.3.4 如何由VMA和vaddr找出相应的p

2023-09-13 10:22:15 780

原创 5. Linux-riscv内存管理21-24问

MIN水位以下的内存,只能被紧急情况下的用户申请到,最著名的紧急用户莫过于PF_MEMALLOC用户,task_struct设置了这个标记表示忽略MIN水位。在__alloc_pages函数中如果进入慢速分配路径( __alloc_pages_slowpath()函数),在__alloc_pages_slowpath()函数中,会调用。在__zone_watermark_ok函数中,由于ATOMIC有表示ALLOC_HIGH,并且会设置ALLOC_HARDER, 则会触及到5/8*min的内存。

2023-09-12 09:57:37 562

原创 4. Linux-riscv内存管理17-20问

由于在prepare_alloc_pages()函数中会根据gfp-mask选取出合适的zone,在遍历zone时,会从刚选择的zone开始扫描zone,一般按照这个方向遍历ZONE_DEVICE->ZONE_MOVABLE->ZONE_HIGHMEM->ZONE_NORMAL->ZONE_DMA32->ZONE_DMA。zone有哪些类型:ZONE_DMA、ZONE_DMA32、ZONE_NORMAL、ZONE_HIGHMEM、ZONE_MOVABLE、ZONE_DEVICE。

2023-09-11 10:46:23 555

原创 2.5 opensbi: riscv: opensbi源码解析

从sbi_trap_handler()函数中,我们可以看到其中处理的中断只有IRQ_M_TIMER和IRQ_M_SOFT,处理函数分别为sbi_timer_process()和sbi_ipi_process()。函数作用:设置所有hart状态为SBI_HSM_STATE_STARTED。函数位置:lib/sbi/sbi_timer.c。函数位置:lib/sbi/sbi_hart.c。函数位置:lib/sbi/sbi_hsm.c。函数位置:lib/sbi/sbi_ipi.c。

2023-09-06 09:27:14 731

原创 riscv-linux中的多核启动流程

在注册sbi_ipi_event_create的时候ipi_ops_array[0]为ipi_smode_ops,ipi_ops_array[1]为ipi_halt_ops,异常处理函数sbi_trap_handler,判断为IRQ_M_SOFT,则调用软中断处理函数sbi_ipi_process,根据SBI_EXT_HSM和SBI_EXT_HSM_HART_START可以在opensbi找到对应的回调函数。找到cpu_ops_sbi结构体:sbi_cpu_start是我想找到的启动第二个核的函数。

2023-08-30 17:43:50 1004

原创 2.4 opensbi: riscv: opensbi源码解析

当编程timer中断到来时,陷入m模式的异常,进入_trap_handler汇编函数,调用sbi_trap_handler()->sbi_timer_process(),在sbi_timer_process函数中触发一个s模式的timer中断,真正的timer中断处理函数是在s模式处理的。在aclint_mtimer_cold_init()函数中会初始化time_rd以及time_wr回调函数,64位系统为mtimer_time_rd64()函数和mtimer_time_wr64()函数。

2023-08-29 09:30:14 509

原创 2.3 opensbi: riscv: opensbi源码解析

设置hart 的状态,如果是冷启动hart设置为PENDING,其他的hart设置为STOPPED,状态信息放在hsm_data的state字段中。sbi_platform_early_init(plat, TRUE) 函数,调用对应平台设置的回调函数,一般都没有设置。冷启动的hart为每个hart的extra space空间分配一个struct sbi_hsm_data结构体。如果热启动的hart则开启ipi,并且判断字节的状态不是PENDING的话则进入wfi状态。

2023-08-21 11:01:40 575

原创 2.2 opensbi: riscv: opensbi源码解析

函数位置:firmware/fw_base.S函数作用:重置寄存器 除了ra, a0, a1 和a2关闭和清理所有中断设置每个hartid的栈地址设置mscratch指向sbi_scatch结构体设置异常处理函数_trap_handler(所有hart 都会去设置)设置参数为sbi_scatch结构体,调用sbi_init/*1. 重置寄存器 除了ra, a0, a1 和a2*/li ra, 0/*2. 关闭和清理所有中断*//*3. 设置每个hartid的栈地址*/

2023-07-25 20:45:36 785

原创 3. Linux-riscv内存管理17-24问

由于在prepare_alloc_pages()函数中会根据gfp-mask选取出合适的zone,在遍历zone时,会从刚选择的zone开始扫描zone,一般按照这个方向遍历ZONE_DEVICE->ZONE_MOVABLE->ZONE_HIGHMEM->ZONE_NORMAL->ZONE_DMA32->ZONE_DMA。在__alloc_pages函数中如果进入慢速分配路径( __alloc_pages_slowpath()函数),在__alloc_pages_slowpath()函数中,会调用。

2023-07-20 13:31:26 204

原创 2.1 opensbi: riscv: opensbi源码解析

在spl跳转到opensbi执行的时候,携带了三个参数,分别保存在a0,a1,a2,三个参数的含义:hartid、fdt地址(u-boot的dtb文件)和struct fw_dynamic_info结构体地址。在这里我们使用的是dynamic负载,所有fw_boot_hart汇编函数位于firmware/fw_dynamic.S。opensbi第一条执行的指令是从_start开始(firmware/fw_base.S).代码如下。在执行make的时候可以指定是否开启FW_PIC,,如果开启FW_PIC,

2023-07-19 18:26:51 1866

原创 2. Linux-riscv内存管理13-16问

从下表可以看出内核映像文件是被映射到了0xffffffff80000000-0xffffffffffffffff此区域范围内,因为内核映射,可以能随机映射到这个范围的任意地方。linux启动后回去扫描dts文件中的所有节点,其中也包括dts文件中定义的物理内存大小。0xffffffc000000000-0xffffffffffffffff为内核空间,0x0000000000000000- 0xffffffbfffffffff为用户空间。

2023-07-17 13:45:22 471 1

原创 1.2 SPL:riscv:uboot-spl源码解析

问题:如何根据struct spl_image_loader *drv找到对应的代码加载u-boot答:在common/spl/spl_mmc.c中,可以看到宏会将每个驱动函数定义的struct spl_image_loader结构体链接到__u_boot_list_2_spl_image_loader_1和__u_boot_list_2_spl_image_loader_3段中间。分析展开**SPL_LOAD_IMAGE_METHOD()**宏。

2023-07-16 09:29:27 1366

原创 1.1 SPL: riscv: u-bool-spl源码解析

riscv spl分两部分,这是其中第一部分。

2023-07-15 13:26:38 836

原创 1. Linux-riscv内存管理1-11问

在匿名页面中:page->index表示在vma中的第几个物理页面(单位是PAGE_SIZE)。可能将vma->vm_pgoff 想成0的话,更好理解。

2023-07-11 09:41:47 696

原创 macbook m2 安装riscv-elf-gdb

macbook m2上远程单步调试linux内核。

2023-02-24 13:39:53 840

原创 进程基本概念

进程的运行状态程序计数器CPU寄存器,保存上下文内存管理信息统计信息文件相关的信息。

2022-09-25 20:09:54 1583

原创 Linux之进程管理

vfork()函数通过系统调用进入到linux内核,然后通过do_fork()函数来实现。clone()函数通过系统调用进入到Linux内核,然后通过do_fork()函数来实现。exit()系统调用吧退出码转换成内核要求的格式并且调用do_exit()函数来处理。vfork父进程会一直阻塞,知道子进程调用exit()或exec()为止。子函数会从复函数继承进程地址空间,包括。do_fork()函数有5个参数。fn就是线程的回调函数。clone()函数用来。常用的clone标志位。

2022-09-24 15:30:46 832

原创 yocto bsp-开发人员指南

对于每个配方,您可以在名为 LICENSE_FLAGS_ACCEPTED 的 local.conf 变量中指定匹配的许可证字符串。指定匹配的许可证字符串表示您同意该许可证。因此,构建系统可以构建相应的配方并将组件包含在映像中。如果您像往常一样构建,而不在 LICENSE_FLAGS_ACCEPTED 变量中指定任何配方,则构建将停止并为您提供您尝试包含在需要 LICENSE_FLAGS_ACCEPTED 变量中条目的映像中的配方列表。在其中输入适当的许可证标志后,重新启动构建以从中断处继续。

2022-09-02 17:41:11 2458

原创 risc-v 栈分析

下面查看该进程的内存映射(memory map),要查看GDB attach了的进程的内存映像,可以执行一下命令,执行该命令后,GDB就会显示与被调试的进程相对应的/proc//maps的信息。它表示栈空间,栈空间的顶端是0x3fff800000。然而,刚看到的栈指针的值却是0x3fff7ffff0,超出了栈的范围。访问地址超出了栈的范围,也就是说,发生了栈溢出。GDB等调试器的backtrace功能是通过搜索栈中保存的 信息来实现的。LR_c 指的是父函数调用子函数时,返回子函数的pc值。......

2022-08-26 12:40:21 1841

原创 riscv ELF bss段解析

在调试risc-v-bm的时候,实现malloc函数后,risc-v-bm出现错误。原因是在exec中,没有实现对bss段的初始化。怎么找到这个问题的呢?malloc代码_block_head变量是全局定义为0的。编译器将其放在了bss段。使用readelf可以读取每个段的信息。bss的type为NOBITS,flags为WA, WA意思是可写、需要分配内存,size为8,sh程序只定义了一个全局变量,变量值为0。注意:只有全局变量,且值为0才会放在bss段。读取bss的代码。......

2022-07-13 09:34:17 922

原创 riscv ASID疑问

最近几天调试自己写的risc-v的裸机操作系统,在写完malloc程序后,调用malloc程序分配内存时,最终调用到了sbrk,sbrk中分配vma或者扩大vma的容量。在程序真正是用内存时,触发缺页异常,映射真正的内存。free的时候,使用brk释放内存。在反复malloc/free的时候出现了程序跑飞了。经过不断的gdb和printk debug,发现释放的内存还可以被访问,而不是访问新映射的内存。经过测试,需要刷tlb。在每次map/unmap的时候刷新tlb。代码链接在risc-v-bm程序中

2022-07-13 09:17:15 742

原创 risc-v “access fault“和“page fault“区别

access fault简单的说access fault发生在PMP检测时。意味着处理器使用没有权限的内存。发生在至少有user模式的机器上,因为在machine模式下,处理器可以访问所有的内存。因此只有 M 模式的处理器可能无法通过 PMP 检查。此外,access fault可能是由于 PMA(物理内存属性)检查失败而导致的,这也适用于 M 模式。page fault当处理器试图使用它可能有权限使用的内存,但内存块尚未可用时,通常会产生page fault。page fault只能发生在具有

2022-05-26 17:39:27 3503

转载 RISCV WMO和TSO具体解决什么问题

本文给人解释RISCV的WMO和TSO模型具体解决什么问题。多核CPU的Cache问题很麻烦。多核不复杂,就是有多个执行体,各有各的动作而已。Cache也不复杂,就是访问内存的时候留一份下来,下次访问的时候直接从Cache(通常是SRAM之类更快的内存)中取而已。但把这两个简单的概念都放进来,这个问题就复杂了:在你的Cache中的数据,怎么能够让其他人知道呢?其他人按什么顺序知道呢?定义指令的时候这是个非常复杂的问题,规矩复杂了,代码没法写。规矩简单了,硬件做不出效率来。为此,我们先定义两个基本的概

2022-04-19 08:58:16 987

原创 12. 自制操作系统: risc-v ACLINT

ACLINT全称: Advanced Core LocalInterruptor1.介绍这个RISC-V ACLINT规范定义了一组内存映射设备,这些设备在一个多HART RISC-V平台上为每个HART提供处理器间中断(IPI)和定时器功能。这些hart级的IPI和定时器功能是在多hart RISC-V平台上运行的操作系统、引导加载程序和固件所必需的。SiFive核心本地中断器(CLINT)在RISC-V世界中被广泛采用,以提供机器级IPI和定时器功能。不幸的是,SiFive CLINT对于.

2022-04-15 15:15:47 1848

原创 11. 自制操作系统: risc-v Svnapot/Svpbmt标准扩展

Svnapot“Svnapot” Standard Extension forNAPOT Translation Contiguity,Version 1.0在Sv39、Sv48和Sv57中,当PTE的N位等于1时,此时的PTE表示一个区域内的连续虚拟地址到物理地址的转换,并且这个区域的PTE[5:0]比特位均相同,说明这个需要连续转换的页面的属性相同。此类范围必须是自然对齐的 2的N次方 (NAPOT) 粒度,大于基本页面大小。Svnapot扩展依赖于Sv39在地址转换...

2022-04-13 11:18:29 3759

原创 10.4 自制操作系统: risc-v 虚拟内存系统

Sv32全称: Page-Based 32-bit Virtual-Memory Systems当Sv32是被写入到satp.MODE时,s-mode是在一个32-bit的虚拟内存系统。在这种模式下,supervisor和user虚拟地址通过遍历基树页表转换为supervisor物理地址。当 SXLEN=32 时支持 Sv32,并且旨在包含足以支持现代基于 Unix 的操作系统的机制。Addressing and Memory Protection(寻址和内存保护)Sv32 实现支持

2022-04-12 10:35:35 3627 2

原创 10.3 自制操作系统: risc-v Supervisor寄存器satp

satp全称 Supervisor Address Translation and Protection Registersupervisor模式下的地址翻译和保护寄存器satp是一个SXLEN-bit 读写寄存器,控制s-mode下地址转换和地址保护。格式如下:此寄存器保存root page table的物理地址编号(PPN),例如supervisor物理地址被分割为4KiB;地址空间标识符(ASID),方便在每个地址空间的基础上进行地址转换。MODE字段,选择当前的地址.

2022-04-11 14:28:38 4426 1

原创 10.2 自制操作系统: risc-v Supervisor寄存器sscratch/sepc/scause/stval/senvcfg

Supervisor Scratch Register (sscratch)sscratch是一个SXLEN-bit 读写寄存器,在supervisor下使用。通常,在hart执行user代码时,sscratch是用于保存一个指向本地 supervisor上下文的地址。在trap处理开始时,sscratch与user 寄存器交换,提供一个初始的working寄存器。Supervisor Exception Program Counter (sepc)管理者异常程序计数器sepc是一个SXLEN-bi

2022-04-10 19:14:53 5319

原创 10.1 自制操作系统: risc-v Supervisor寄存器 timers/performace counters/scounteren

Supervisor Timers and Performance Counters管理器软件使用与用户模式软件相同的硬件性能监视工具,包括time、cycle和instret CSRs。具体实现中会提供修改counter值的机制。在实现中,必须依据real-time counter, time提供调度timer中断。Counter-Enable Register (scounteren)counter-enable寄存器scounteren是一个32位寄存器,它控制u模式下硬件性能监控计数器的可

2022-04-08 20:35:11 1044

ARM64架构面试20题目答案.pdf

ARMv8/ARM64架构20道面试题以及答案

2021-08-03

LCD_x35电路图

LCD—x35 索尼3.5寸屏幕电路图,好资源共享

2012-11-18

mini2440无盘启动(服务器配置-内核编译-文件系统制作-u-boot烧写)

mini2440无盘启动,包含了服务器NFS配置,支持NFS内核编译,根文件系统制作,u-boot参数设置,u-boot烧写,一气呵成。

2012-11-30

linux内核驱动笔记-尚观

由浅入深 了解驱动 内核 是个好东西 给大家分享哈

2012-12-02

mini2440无盘启动(服务器NFS配置-支持NFS内核编译-根文件构建-u-boot烧写)

mini2440无盘启动,配置NFS服务器,编译支持NFS内核,u-boot烧写,全部讲解

2012-12-04

Linux_init进程详解

免费好资料 不用说 看了就知道

2013-09-20

tcp/ip详解卷1卷2卷3高清pdf

tcp/ip详解卷1卷2卷3高清pdf

2014-10-15

sd卡驱动框架.pdf

高清sd卡驱动框架思维导图pdf

2021-07-29

TCP拥塞算法reno_bic_cubic概述与对比.pdf

TCP拥塞算法reno/bic/cubic概述与对比

2021-07-28

rtp2jpegAndjpeg-9a

rtp2jpegAndjpeg-9a.rtp传输jpeg图片到vlc实时播放

2015-01-08

索尼LCD_X35时序图手册

索尼LCD_X35时序图手册

2012-11-18

linux下tcp穿透NAT源代码(git提交信息)

运行服务器程序./server 然后运行client 输入server Ip 输入client名字(不能超过10字符) 然后输入hole [另一个client的名字,名字后面必须加一个空格,不然程序崩溃]。

2014-09-16

tcp_header_state.pdf

一图看懂TCP协议头和TCP各种状态

2021-07-29

module_param

module_param内核函数的意思

2012-11-06

编译好的mini2440-uboot

编译好的mini2440-u-boot

2013-01-19

索尼LCD_X35电路图

索尼——LCD_3.5寸屏幕电路图。。。。。。。。。。

2012-11-18

基于P2P网络应用的NAT穿越方案的分析与设计

需要安装caj程序才能看。基于P2P网络应用的NAT穿越方案的分析与设计

2014-09-27

基于H_264的嵌入式无线视频传输系统的设计(硕士论文 )

需要安装caj程序才能看。基于H_264的嵌入式无线视频传输系统的设计(硕士论文 )

2014-09-27

busybox-1.13.3-mini2440

busybox-1.13.3 mini2440

2012-11-30

寄存器位查看小工具

寄存器位查看小工具,二进制十进制,十六进制转换必备工具

2012-11-18

Linux+新手最全10本培训书籍集-到高手必备

Linux+新手最全10本培训书籍集-到高手必备,看了就知道

2012-11-18

SSH Secure Shell Client 3.2.9

不需要注册码,安全的secureCRT+cutefpt,一次安装就可以用两个软件。

2012-11-18

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除