嵌入式第三章课件_第1页
嵌入式第三章课件_第2页
嵌入式第三章课件_第3页
嵌入式第三章课件_第4页
嵌入式第三章课件_第5页
已阅读5页,还剩81页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

3.1Bootloader简介Bootloader是指操作系统的启动加载程序通常引导加载程序包括固化在固件(firmware)中的boot代码(可选),和Bootloader两大部分,是系统加电后运行的第一段软件代码相对于操作系统内核来说,它是一个硬件抽象层3.1Bootloader简介Bootloader是指操作PC机中的引导加载程序两部分组成:BIOS(其本质就是一段固件程序)位于硬盘MBR(MainBootRecord,主引导记录)中的操作系统Bootloader(如LILO和GRUB等)流程:BIOS在完成硬件检测和资源分配后,将硬盘MBR中的Bootloader读到系统的RAM中,然后将控制权交给操作系统BootloaderBootloader的主要运行任务就是将内核映象从硬盘上读到RAM中,然后跳转到内核的入口点去运行,即开始启动操作系统。PC机中的引导加载程序两部分组成:嵌入式系统中引导加载程序嵌入式系统中通常没有BIOS那样的固件程序少数嵌入式CPU也会内嵌一段短小的启动程序系统的加载启动任务就完全由Bootloader来完成例如ARM7TDMI中,系统在上电或复位时从地址0x00000000处开始执行这个地址存放的是BootLoader程序嵌入式系统中引导加载程序嵌入式系统中通常没有BIOS那样的固典型的嵌入式系统BootloaderBlob:Bootloaderobject的缩写开源,遵循GPL,很好的Linuxloader,主要针对ARMU-Boot:universalBootloader的缩写开源,遵循GPL,支持ARM,MIPS,X86,Nios等处理器可启动VxWorks,QNX,Linux等多种操作系统vivi最初是为S3C2410编写的,用于启动Linux,目前版本是0.1.4典型的嵌入式系统BootloaderBootloader的概念

在操作系统内核运行之前运行的一段小程序功能:初始化硬件设备初始化内存空间调整系统的软硬件环境,以便操作系统内核启动Bootloader不通用:依赖于硬件依赖于具体的板级配置不同的CPU有不同的Bootloader有些Bootloader支持多种CPU,如U-Boot支持ARM和MIPSBootloader的概念在操作系统内核运行之前运行的一段Bootloader所处的层次位置Bootloader启动参数内核根文件系统Bootloader所处的层次位置Bootloader启动参3.2Bootloader的启动流程3.2.1进入Bootloader3.2.2Bootloader的输入输出3.2.3Bootloader的启动过程3.2.4Bootloader的操作模式3.2.5Bootloader与主机之间的文件传输3.2Bootloader的启动流程3.2.1进入Boo3.2.1进入Bootloader系统第一条指令51:100h8086:FFFF:0000ARM:地址0x00000000嵌入式系统通常把固态存储设备(比如:ROM、EEPROM或FLASH等)映射到这个预先安排的地址上,而Bootloader就放在这里所以,系统加电后,CPU将首先执行Bootloader程序3.2.1进入Bootloader系统第一条指令嵌入式第三章课件3.2.2Bootloader的输入输出主机和目标机之间一般可通过串口建立连接,没有串口的机器需要通过一条USB转串口的电缆才能完成连接Bootloader执行时通常会通过串口进行I/O输出打印信息到串口从串口读取用户控制字符等串口的参数要事先约定,如115200,n,8,1,无流控3.2.2Bootloader的输入输出主机和目标机之间一3.2.3Bootloader的启动过程一般采用多阶段的Bootloader,它能提供更为复杂的功能,以及更好的可移植性从固态存储设备上启动的Bootloader大多都是2阶段的启动过程,启动过程分为stage1和stage2两部分Bootloader的2部分:汇编部分执行简单的硬件初始化C语言部分负责复制OS数据,设置OS启动参数,通过串口通信显示信息等功能3.2.3Bootloader的启动过程一般采用多阶段的BBOOTLOADER的生命周期:1.初始化硬件,如设置CPU主频,设置RAM刷新频率并检测,设置UART(至少设置一个)等2.设置启动参数,告诉内核硬件的信息,如用哪个启动界面,使用的缺省串口控制台及其波特率3.跳转到操作系统的首地址4.消亡BOOTLOADER的生命周期:3.2.4Bootloader的操作模式1启动加载模式:又叫自主(Autonomous)模式从目标机上的某个固态存储设备上将操作系统加载到RAM中运行Bootloader的正常工作模式,没有外界输入时的缺省模式3.2.4Bootloader的操作模式1启动加载模式:2下载模式:通过串口连接或网络连接等通信手段连接主机(Host),能下载文件,如下载内核映像和根文件系统映像等。从主机下载的文件通常首先被Bootloader保存到目标机的RAM中,然后再被BootLoader写到目标机上的FLASH类固态存储设备中。这种模式通常在第一次安装内核与根文件系统时被使用,当然系统更新也会使用Bootloader的这种工作模式下载模式下通常都会向它的终端用户提供一个简单的命令行接口2下载模式:vivi、Blob或U-Boot等功能强大的Bootloader通常同时支持这两种工作模式,允许用户在这两种工作模式之间进行切换如Blob、uBoot、vivi在启动时都处于正常的启动加载模式,但是会延时(通常为10秒左右)等待终端用户按下任意键以切换到下载模式。如在这段时间内没有用户按键,则继续启动操作系统,如Linuxvivi、Blob或U-Boot等功能强大的Boot3.2.5Bootloader与主机之间

的文件传输通常目标机上的Bootloader通过串口与主机之间进行文件传输串口传输协议(vivi的常用方式,uBoot也支持)通常是xmodem/ymodem/zmodem协议中的一种速度有限,一般传输文件不能太大可通过以太网连接并借助TFTP协议来下载文件(U-Boot的常用方式)解决了串口传输速度有限的问题要求主机提供TFTP服务3.2.5Bootloader与主机之间

的文件传输通常目3.3Bootloader的主要任务stage1

通常包括以下步骤:硬件设备初始化为加载Bootloader的stage2准备RAM空间拷贝Bootloader的stage2到RAM空间中设置好堆栈跳转到stage2的C入口点stage2通常包括以下步骤:初始化本阶段要使用到的硬件设备检测系统内存映射将kernel

映像和根文件系统映像从flash上读到RAM空间中为内核设置启动参数调用内核3.3Bootloader的主要任务stage1

通常包括stage2

的代码通常用C语言来实现(stage1的代码通常用汇编语言来实现),下面的论述针对stage2。要注意代码的可读性和可移植性不能使用glibc库中的任何支持函数没有直接把main地址直接作为stage2的入口点1)无法传递函数参数;2)无法处理函数返回stage2

的代码通常用C语言来实现(stage1的代码通trampoline(弹簧床)编程方式:用汇编语言写一段trampoline小程序,并将这段trampoline小程序来作为stage2可执行映象的执行入口点在trampoline汇编小程序中用CPU跳转指令跳入main()函数中去执行当main()函数返回时,CPU执行路径显然再次回到trampoline程序。用trampoline小程序来作为main()函数的外部包裹(externalwrapper)trampoline(弹簧床)编程方式:blob的trampoline程序示例:

.text .globl_trampoline _trampoline: blmain /*ifmaineverreturnswejustcallitagain*/ b_trampolinevivi的trampoline程序示例:

@getreadtocallCfunctions ldr sp,DW_STACK_START @setupstackpointer movfp,#0 @nopreviousframe,sofp=0 mova2,#0 @setargvtoNULL blmain @callmain; movpc,#FLASH_BASE @otherwise,rebootblob的trampoline程序示例:串口终端调试手段:打印信息到串口终端串口终端显示乱码或根本没有显示(1)Bootloader对串口的初始化设置不正确。(2)运行在host端的终端仿真程序对串口的设置不正确,这包括:波特率、奇偶校验、数据位和停止位等方面的设置串口终端调试手段:打印信息到串口终端基本的硬件初始化

目的:为stage2的执行以及随后的kernel的执行准备好一些基本的硬件环境1.屏蔽所有的中断为中断提供服务通常是OS设备驱动程序的责任,Bootloader的执行全过程中可以不必响应任何中断中断屏蔽可以通过写CPU的中断屏蔽寄存器或状态寄存器(如ARM的CPSR寄存器)来完成2.设置CPU的速度和时钟频率。3.RAM初始化包括正确地设置系统的内存控制器的功能寄存器以及各内存控制寄存器等。基本的硬件初始化目的:为stage2的执行以及随后的ker4.初始化

LED通过GPIO来驱动LED,其目的是表明系统的状态是OK还是Error如板子上没有LED,那么也可以通过初始化UART向串口打印Bootloader的Logo字符信息5.关闭CPU内部指令/数据cache4.初始化

LED为加载stage2准备RAM空间

通常把stage2加载到RAM空间中来执行stage2通常是C语言执行代码,考虑堆栈空间,空间大小最好是存储器页大小(通常是4KB)的倍数一般1MRAM空间已经足够,地址范围可以任意安排如blob就将stage2可执行映像从系统RAM起始地址开始的1M空间内执行将stage2安排到RAM空间的最顶1MB也是一种值得推荐的方法。stage2_end=stage2_start+stage2_size为加载stage2准备RAM空间通常把stage2加载到对所安排的地址范围进行测试必须确保所安排的地址范围为可读写的RAM空间测试方法可以采用类似于blob的方法以存储器的页为被测试单位,测试每个页开始的两个字是否是可读写的对所安排的地址范围进行测试拷贝stage2到RAM中

拷贝时需要用到下列地址:stage2的可执行映象在固态存储设备的存放起始地址和终止地址RAM空间的起始地址。拷贝stage2到RAM中拷贝时需要用到下列地址:设置堆栈指针sp通常把sp的值设置为(stage2_end-4)1MB的RAM空间的最顶端(堆栈向下生长)在设置堆栈指针sp之前,也可以关闭led灯,以提示用户我们准备跳转到stage2设置堆栈指针sp通常把sp的值设置为(stage2_end跳转到stage2的C入口点

最后跳转到Bootloader的stage2去执行如在ARM系统中,这可以通过修改PC寄存器为合适的地址来实现跳转到stage2的C入口点最后跳转到Bootloader初始化本阶段要使用到的硬件设备

初始化至少一个串口,以便终端用户进行I/O输出信息初始化定时器等在初始化这些设备之前,也可以重新把LED灯点亮,以表明我们已经进入main()函数执行设备初始化完成后,可以输出一些打印信息,程序名字字符串、版本号等初始化本阶段要使用到的硬件设备初始化至少一个串口,以便终端检测系统的内存映射确定在物理地址空间中哪些地址范围被分配用来寻址系统的RAM单元如SA-1100中,从0xC0000000开始的512M空间被用作系统的RAM空间在S3C44B0中,从0x0c000000到0x10000000之间的64M地址空间被用作系统的RAM地址空间在S3C2410中,从0x3000,0000到0x4000,0000之间的256M地址空间被用作系统的RAM地址空间检测系统的内存映射确定在物理地址空间中哪些地址范围被分配用来嵌入式系统往往只把CPU预留的全部RAM地址空间中的一部分映射到RAM单元上,而让剩下的那部分预留RAM地址空间处于未使用状态Bootloader的stage2必须检测整个系统的内存映射情况必须知道CPU预留的全部RAM地址空间中的哪些被真正映射到RAM地址单元,哪些是处于"unused"状态的嵌入式系统往往只把CPU预留的全部RAM地址空间中的一部分映加载内核映像和根文件系统映像

规划内存占用的布局内核映像所占用的内存范围根文件系统所占用的内存范围从Flash上拷贝加载内核映像和根文件系统映像规划内存占用的布局设置内核的启动参数

Linux2.4.x以后的内核都以标记列表(taggedlist)的形式来传递启动参数启动参数标记列表以标记ATAG_CORE开始,以标记ATAG_NONE结束每个标记由标识被传递参数的tag_header结构以及随后的参数值数据结构来组成在嵌入式Linux系统中,通常需要由Bootloader设置的常见启动参数:ATAG_CORE、

ATAG_MEM、ATAG_CMDLINE、ATAG_RAMDISK、ATAG_INITRD等设置内核的启动参数Linux2.4.x以后的内核都以标记调用内核

直接跳转到内核的第一条指令处在跳转时,下列条件要满足1.CPU寄存器的设置R0=0;@R1=机器类型ID;@R2=启动参数标记列表在RAM中起始基地址2.CPU模式必须禁止中断(IRQs和FIQs);CPU必须SVC模式(超级用户模式);3.Cache和MMU的设置MMU必须关闭;指令Cache可以打开也可以关闭;数据Cache必须关调用内核直接跳转到内核的第一条指令处3.4几种Bootloader介绍3.4.1WinCE的Bootloader3.4.2Redboot3.4.3Vivi3.4.4U-Boot3.4几种Bootloader介绍3.4.1WinCE的3.4.1WinCE的Bootloader有3种:ROMBootloaderBIOSBootloaderMSDOS+Loadcepc3.4.1WinCE的Bootloader有3种:ROMBootloader又叫RomBoot存放在Flash/EEPROM中,原来BIOS的位置上电后CPU到固定地址执行RomBoot的代码对整个硬件系统进行初始化和检测支持通过网卡从远程机器上下载或者从本地IDE/ATA硬盘的活动分区中寻找nk.bin文件加载优点:引导并且加载速度快,不需要BIOS、MSDOS和Loadcepc了缺点:需要CE开发者读懂它的源码并修改CE提供了RomBoot的所有源码ROMBootloader又叫RomBootBIOSBootloader不需要MSDOS操作系统,但需要BIOS和FAT文件系统系统上电后BIOS执行完硬件初始化和配置后,BIOS检查引导设备的启动顺序,如果引导设备是硬盘、CF卡这类的存储设备,那么就加载这些存储器上的主引导扇区(MasterBootSector)中的实模式代码(MBR)到内存,然后执行这些代码MBR首先在分区表(同样位于主引导扇区)中寻找活动分区,如果存在,就加载位于活动分区的第一个扇区(引导扇区)上的代码到内存,然后执行。引导扇区上的代码的功能是找到并且加载BIOSBootloader,BIOSBootloader再加载nk.bin。对于BIOSBootloader,CE提供了Setupdisk.144和Bootdisk.144两个文件BIOSBootloaderBIOSBootloader不需要MSDOS操作系统,但需BIOSBootloader和MSDOS+Loadcepc两种方式差不多在MSDOS启动后再执行loadcepc.exe,让loadcepc加载nk.bin到内存后再把CPU控制权交给CE内核程序MSDOS+LoadcepcBIOSBootloader和MSDOS+Loadcepc3.4.4U-Boot简介主要功能特点主要目录结构调试方法移植的主要步骤主要命令3.4.4U-Boot简介简介德国DENX软件工程中心的WolfgangDenk全称UniversalBootloader遵循GPL条款的开放源码项目从FADSROM、8xxROM、PPCBOOT发展而来其源码目录、编译形式与Linux内核很相似源码就是相应Linux内核源程序的简化,尤其是设备驱动程序支持:嵌入式Linux/NetBSD/VxWorks/QNX/LynxOS等PowerPC、MIPS、x86、ARM、XScale等对PowerPC系列处理器/对Linux的支持最完善简介德国DENX软件工程中心的WolfgangDenk主要功能主要功能特点①开放源码;②支持多种嵌入式操作系统内核;③支持多个处理器系列;④较高的可靠性和稳定性;⑤高度灵活的功能设置,适合U-Boot调试、操作系统不同引导要求、产品发布等;⑥丰富的设备驱动源码;⑦较丰富的开发调试文档与强大的网络支持。特点①开放源码;主要目录结构Board:目标板相关文件,主要包含SDRAM、FLASH驱动;Common:独立于处理器体系结构的通用代码,如内存大小探测与故障检测;Cpu:与处理器相关的文件。如mpc8xx子目录下含串口、网口、LCD驱动及中断初始化等文件;Driver:通用设备驱动,如CFIFLASH驱动(目前对INTELFLASH支持较好)Doc:U-Boot的说明文档;主要目录结构Board:目标板相关文件,主要包含SDRAM、Include:U-Boot头文件;尤其configs子目录下与目标板相关的配置头文件是移植过程中经常要修改的文件;lib_xxx:处理器体系相关的文件,如lib_ppc,lib_arm目录分别包含与PowerPC、ARM体系结构相关的文件;net:与网络功能相关的文件目录,如bootp,nfs,tftp;Post:上电自检文件目录。尚有待于进一步完善;Tools:用于创建U-BootS-RECORD和BIN镜像文件的工具;Rtc:RTC驱动程序。Include:U-Boot头文件;尤其configs子目录调试方法大致分为两种:先用仿真器创建目标板初始运行环境,将U-Boot镜像文件U-Boot.bin下载到目标板RAM中的指定位置,然后进行跟踪调试好处:不用将Uboot镜像文件烧写到Flash中去弊端:对移植开发人员的移植调试技能要求较高,调试器的配置文件较为复杂用调试器先将U-Boot镜像文件烧写到Flash中去,然后用GDB调试器调试所用的调试器配置文件较为简单,调试过程与U-Boot移植后运行过程相吻合U-Boot先从Flash中运行,再重载至RAM中相应位置,并从那里正式投入运行需要不断烧写Flash调试方法大致分为两种:移植的主要步骤以S3C2410为例,说明U-Boot的主要移植步骤:1.修改Makefile文件 whhit2410_config

:

unconfig

@./mkconfig$(@:_config=)armarm920twhhit2410NULLs3c24x0各项的意思如下:arm:CPU的架构(ARCH)arm920t:CPU的类型(CPU),其对应于cpu/arm920t子目录。whhit2410:开发板的型号(BOARD),对应于board/whhit2410目录。NULL:开发者/或经销商(vender)。s3c24x0:片上系统(SOC)。移植的主要步骤以S3C2410为例,说明U-Boot的主要移2.建立board/whhit2410目录,拷贝board/smdk2410下的文件到board/whhit2410目录,将smdk2410.c更名为whhit2410.c3.cpinclude/configs/smdk2410.hinclude/configs/whhit2410.h4.将arm-linux-gcc的目录加入到PATH环境变量中5.测试编译能否成功:

makewhhit2410_config

makeallARCH=arm

生成U-Boot.bin就OK了2.建立board/whhit2410目录,拷贝board6.依照你自己开发板的内存地址分配情况修改board/whhit2410/memsetup.S文件7.在board/whhit2410加入NANDFlash读函数,建立nand_read.c。8.修改board/whhit2410/Makefile9.修改cpu/arm920t/start.S文件10.修改include/configs/whhit2410.h文件11.重新编译U-Boot

makeallARCH=arm12.通过jtag将U-Boot烧写到flash6.依照你自己开发板的内存地址分配情况修改board/wh主要命令打印环境变量列表:

printenv设置tftp服务器的ip地址

setenvserverip6设置本机(开发板)的ip地址

setenvipaddr1保存前面对环境变量所做的修改

saveenv通过tftp下载内核(串口下载命令为loady)

tftp0x30008000uImage nanderase0x800000x200000 nandwrite0x300080000x800000x200000主要命令打印环境变量列表:

printenv3.4.2RedbootRedhat公司随eCos发布的一个开源BOOT支持:ARM,MIPS,MN10300,PowerPC,RenesasSHx,v850,x86使用X-modem或Y-modem协议经由串口下载,也可以经由以太网口通过BOOTP/DHCP服务获得IP参数,使用TFTP方式下载程序映像文件,常用于调试支持和系统初始化Redboot可以通过串口和以太网口与GDB进行通信,调试程序,能中断被GDB运行的应用程序Redboot提供了一个交互式命令行接口,用来从TFTP服务器或者从Flash下载映像文件、加载系统的引导脚本文件,它保存在Flash上3.4.2RedbootRedhat公司随eCos发布的3.4.3vivivivi是由韩国mizi公司设计为ARM处理器系列设计的一个bootloader,支持使用串口和主机通信。vivi与其它Bootloader相比,增加了对分区的命令支持vivi程序流程编译vivivivi的使用3.4.3vivivivi是由韩国mizi公司设计为A系统复位禁止看门狗关闭中断初始化系统时钟跳到stage2入口执行输出vivi版本号开发板初始化内存映射并拷贝vivi代码到SDRAM中初始化堆栈初始化MTD设备初始化私有数据初始化内置命令启动vivi-boot_or_vivi系统复位禁止看门狗关闭中断初始化系统时钟跳到stage2入口编译vivi首先,进入vivi源代码目录:#cd/vivi然后配置和编译它,执行:#makemenuconfig,实际上,你不需要自己手工选择配置它,已经配置好了,只需装载一个缺省的配置文件即可,使用这个配置文件生成的vivi正好适合于目标板,这个配置文件在vivi/arch/def-configs目录中,该目录包含了一些适合于各种板的配置文件。装载“arch/def-configs/smdk2410”后保存该设置,并执行#make命令编译vivi#cd/vivi#makemenuconfig将出现下面窗口:编译vivi首先,进入vivi源代码目录:#cd/viv在跳出的窗口中选择“LoadonAlternateConfigurationFile”菜单,然后输入“arch/def-configs/smdk2410”。在跳出的窗口中选择“LoadonAlternateC再选择“OK”,前一个界面又会出现一次,这时选择退出,然后选择“Yes”保存刚才的配置。再选择“OK”,前一个界面又会出现一次,这时选择退出,然后选保存完毕,执行以下命令:#make如果编译过程顺利,将会在当前目录下生成vivi二进制映象文件保存完毕,执行以下命令:vivi的使用Vivi的使用可以查看mizi公司的vivi使用手册,下面会介绍其中几个经常使用的命令使用JTAG接口下载vivivivi的load命令参数设定命令vivi的使用Vivi的使用可以查看mizi公司的vivi使使用JTAG接口下载vivi使用JTAG接口下载程序需要JTAG小板、连接电缆和烧写程序。把JTAG小板和电缆连接S3C2410开发板和主机的并口,然后打开目标板电源开关烧写程序有2种:PC端windows环境下的烧写程序PC端linux环境下的烧写程序Mizi公司提供了下载软件,Jflash是Linux的下载程序在Linux下执行以下命令可以查看Jflash的使用方法: #./Jflash–s3c2410--help使用JTAG接口下载vivi使用JTAG接口下载程序需要对应不同类型的Flash,Jflash程序使用不同的选项参数,如使用64M三星NandFlash,则“/t=5”,可执行以下命令开始烧写vivi。 #./Jflash-s3c2410vivi/t=5对应不同类型的Flash,Jflash程序使用不同的选项当vivi烧入Flash,并能正常启动,连接好串口,运行minicom终端程序,就会进入vivi的命令提示符下。当vivi烧入Flash,并能正常启动,连接好串口,运行m嵌入式第三章课件vivi的load命令命令格式如下: loadflashkernelx其中:load–vivi的下载命令flash–把文件下载到flash中kernel–要下载的文件是kernel类型,和分区参数同名,还可以是vivi,rootx–使用超级终端的xmdoem协议下载。使用mincom时,先按下“Ctrl”,不要松开,再按下“a”键,然后同时松开,再按下“s”键,进入下载模式,选择xmodem协议方式下载。vivi的load命令命令格式如下:嵌入式第三章课件嵌入式第三章课件按回车,再按回车输入要下载的文件,注意最好把要下载的文件复制到/root目录。按回车,再按回车输入要下载的文件,注意最好把要下载的文件复制嵌入式第三章课件发送文件结束,vivi将自动保存所下载的文件到flash中此时,如果输入“boot”命令,vivi将会启动刚刚下载的内核发送文件结束,vivi将自动保存所下载的文件到flash参数设定命令paramsetlinuxcommandlineis:"noinitrdroot=/dev/mtdblock/0init=/linuxrcconsole=ttyS0"paramsetlinuxcommandlineis:"noinitrdroot=/dev/bon/2init=/linuxrcconsole=ttyS0"paramsetlinux_cmd_line“console=ttyS0root=/dev/nfsnfsroot=:/hit/rootip=9::::localhost:eth0:off"paramshowparamsave参数设定命令paramsetlinuxcommand3.5终端仿真一般嵌入式操作系统在调试开发的时候,没有像PC那样的VGA输出,一般都是通过串口来查看信息,在嵌入式Linux中,这被称作“串口终端”。主要

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论