




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、嵌入式系统及其软件工具,第七章构建自己的嵌入式Linux Linux移植,“操作系统移植”指使一个操作系统能够在某个微处理器平台上运行。,什么是操作系统移植?,在OS“移植”前必须清楚两个问题:,1、目标平台:目标平台包括了核心处理器和处理器以外的外围设备,核心处理器也整合了一些部件。如:定时器、计数器等。,2、地址管理机制和MMU:,单一的程序模型 应用程序在物理内存的同一个地址开始运行,一个时刻只能有一个应用程序被加载,现代操作系统中很少用了。,多程序模型 多个应用程序共享相同的物理地址,当应用程序被操作系统加载后,根据其加载的位置改变程序中和地址相关的部分指令,让其可以在指定的物理地址运
2、行。,硬件地址转换的内存管理模型 应用程序使用虚拟地址,CPU实际执行程序的地址是物理地址,从虚拟地址到物理地址的转换需要操作系统和MMU硬件的支持,这样应用程序可以在自己的虚拟地址中运行,不需要考虑系统的实际内存情况。,操作系统对内存的管理模型,内存管理机制:,大体上来说,嵌入式系统所用到的内存管理机制主要有以下两种: 虚拟内存管理机制: 有一些嵌入式处理器提供了MMU,在MMU具备内存地址映射和寻址功能,它使操作系统的内存管理更加方便。如果存在MMU ,操作系统会使用它完成从虚拟地址到物理地址的转换, 所有的应用程序只需要使用虚拟地址寻址数据。 这种使用虚拟地址寻址整个系统的主存和辅存的方
3、式在现代操作系统中被称为虚拟内存。MMU 便是实现虚拟内存的必要条件。 虚拟内存的管理方法使系统既可以运行体积比物理内存还要大的应用程序,也可以实现“按需调页”策略,既满足了程序的运行速度,又节约了物理内存空间。 在L inux系统中,虚拟内存机制的实现实现为我们提供了一个典型的例子:在不同的体系结构下, 使用了三级或者两级页式管理,利用MMU 完成从虚拟地址到物理地址之间的转换。基于虚拟内存管理的内存最大好处是:由于不同进程有自己单独的进程空间,十分有效的提高了系统可靠性和安全性。,内存管理机制:,非虚拟内存管理机制 在实时性要求比较高的情况下,很多嵌入式系统并不需要虚拟内存机制:因为虚拟内
4、存机制会导致不确定性的 I/O阻塞时间, 使得程序运行时间不可预期,这是实时嵌入式系统的致命缺陷;另外,从嵌入式处理器的成本考虑,大多采用不装配MMU 的嵌入式微处理器。所以大多嵌入式系统采用的是实存储器管理策略。因而对于内存的访问是直接的,它对地址的访问不需要经过MMU,而是直接送到地址线上输出,所有程序中访问的地址都是实际的物理地址;而且,大多数嵌入式操作系统对内存空间没有保护,各个进程实际上共享一个运行空间。一个进程在执行前,系统必须为它分配足够的连续地址空间,然后全部载入主存储器的连续空间。 由此可见,嵌入式系统的开发人员不得不参与系统的内存管理。从编译内核开始,开发人员必须告诉系统这
5、块开发板到底拥有多少内存;在开发应用程序时,必须考虑内存的分配情况并关注应用程序需要运行空间的大小。另外,由于采用实存储器管理策略,用户程序同内核以及其它用户程序在一个地址空间,程序开发时要保证不侵犯其它程序的地址空间,以使得程序不至于破坏系统的正常工作,或导致其它程序的运行异常;因而,嵌入式系统的开发人员对软件中的一些内存操作要格外小心。 UCOS就是使用非虚拟内存管理的一个例子,在UCOS中,所有的任务共享所有的物理内存,任务之间没有内存保护机制,这样能够提高系统的相应时间,但是任务内存操作不当,会引起系统崩溃。,将虚拟地址转换为物理地址 物理地址是处理器地址总线连接的地址; 虚拟地址是程
6、序运行所访问的地址。,控制内存的访问权限 不同段、页运行不同的进程,并为段、页设定访问权限,称为“域”,依据权限检验算法严格管理每个域。,MMU的作用,本章提要,嵌入式Linux,PART1,PART2,7.1 嵌入式Linux系统的构建流程,PART3,bin:包含基本的用户命令工具; sbin:包含基本的系统管理程序; boot:包含内核映像及启动相关的文件 etc:包含系统配置文件和脚本 lib:包含系统库和内核模块 user:用户程序及库文件目录 home:用户主目录 root:root用户主目录 dev:设备文件目录,每个文件代表一个设备 opt:额外软件包所在目录 mnt:文件系统
7、临时挂装目录 var:包含运行时候改变的文件 proc:内核创建和使用的虚拟文件系统,存放运行时系统信息 tmp:临时文件目录,内核启动后,需要加载根文件系统。为了让目标系统上的根文件系统能够正常使用,需要完成以下工作: $ cd $ TARGET_ROOT /root $ makedir bin dev etc lib proc sbin tmp usr var $ chmod 1777 tmp $ mkdir user/bin user/lib user/sbin $ mkdir var/lib var/lock var/run var/tmp $ chmod 1777 var/tmp,L
8、 I N U X 根 文 件 系 统,7.1.1 BootLoader程序原理,对于PC系统,引导加载程序由BIOS(固件程序)和位于磁盘MBR(主引导记录)中系统引导程序(LILO和GRUB等)一起组成。BIOS完成硬件检测和资源分配后,将硬盘MBR中的引导程序读到系统的内存中,然后将控制权交给引导程序。引导程序的主要任务就是将内核映像从硬盘上读到内存中,然后跳转到内核的入口点去运行,即开始启动操作系统。 在嵌入式系统中,主要使用flash作为系统的存储煤介,很少用磁盘,因此整个系统的加载启动任务就完全由引导程序(也称为Bootloader)来完成。,bootloader是在操作系统内核运行
9、之前运行的一段小程序。通过这段小程序,可以初始化硬件设备、建立内存空间的映射图,从而将系统的软硬件环境带到一个合适的状态,以便为最终调用操作系统内核准备好正确的环境。,嵌入式系统中的bootloader概念,Bootloader的功能,1.硬件设备初始化(CPU的主频、SDRAM、中断、串口等) 2.内核启动参数 3.启动内核 4.与主机进行交互,从串口、USB口或者网络口下载映象文件,并可以对FLASH等存储设备进行管理,Bootloader特点,1.依赖于硬件:每种不同的CPU体系结构都有不同的bootloader 2.bootloader还依靠具体的嵌入式板级设备的配置,Boot Loa
10、der 的安装媒介,1. 系统加电或复位后,所有的处理器通常都从某个预先安排的地址上取指令。比如,ARM在复位时从地址0 x0取指。 2. 嵌入式系统中通常都有某种类型的固态存储设备(比如:ROM、EEPROM 或 FLASH 等)被映射到这个预先安排的地址上。因此在系统加电后,处理器将首先执行 Boot Loader 程序 3. Bootloader是最先被系统执行的程序,固态存储设备的典型空间分配结构,Boot Loader的控制方式,1. 主机和目标机之间一般通过串口建立连接,Boot Loader 软件在执行时通常会通过串口来进行通讯,比如:输出打印信息到串口,从串口读取用户控制字符
11、2. 也可以通过JTAG等其他接口通讯,Boot Loader 的操作模式,大多数 Boot Loader 都包含两种不同的操作模式: 1.启动加载模式 2.下载模式 从最终用户的角度看,Boot Loader 的作用就是用来加载操作系统,而并不存在所谓的启动加载模式与下载工作模式的区别,启动加载模式 启动加载模式,称为“自主”(Autonomous)模式 Boot Loader 从目标机上的某个固态存储设备上将操作系统加载到 RAM 中运行,整个过程并没有用户的介入。这种模式是 Boot Loader 的正常工作模式,因此在嵌入式产品发布的时侯,Boot Loader 显然必须工作在这种模式
12、下。,Boot Loader 的操作模式,下载模式 在下载模式下,目标机上的 Boot Loader 将通过串口连接或网络连接等通信手段从主机下载文件,如:下载内核映像和根文件系统映像等 从主机下载的文件通常首先被 Boot Loader 保存到目标机的 RAM 中,然后再被 Boot Loader 写到目标机上的FLASH 类固态存储设备中。 这种模式通常在第一次安装内核与根文件系统时被使用;此外,以后的系统更新也会使用 Boot Loader 的这种工作模式。 工作于这种模式下的 Boot Loader 通常都会向它的终端用户提供一个简单的命令行接口。,Boot Loader 的操作模式,
13、BL的典型结构框架,大多数 Boot Loader 都分为 stage1 和 stage2 两大部分。 依赖于处理器体系结构和板级初始化的代码,通常都放在 stage1 中,用汇编语言实现 而 stage2 则通常用C语言来实现,这样可以实现更复杂的功能,而且代码会具有更好的可读性和可移植性。,Boot Loader 的 stage1 通常包括以下步骤(以执行的先后顺序): 硬件设备初始化。 为加载 Boot Loader 的 stage2 准备 RAM 空间。 拷贝 Boot Loader 的 stage2 到 RAM 空间中。 设置好堆栈 跳转到 stage2 的 C 入口点。 Stage
14、1主要工作是硬件初始化,并准备第二阶段的C语言运行环境,BL的典型结构框架,Boot Loader 的 stage2 通常包括以下步骤(以执行的先后顺序): 初始化本阶段要使用到的硬件设备。 检测系统内存映射(memory map)。 将 kernel 映像和根文件系统映像从 flash 上读到 RAM 空间中。 为内核设置启动参数。 调用内核。 stage2 的代码通常用 C 语言来实现,以便于实现更复杂的功能和取得更好的代码可读性和可移植性。与普通 C 语言应用程序不同的是,在编译和链接 boot loader 这样的程序时,我们不能使用 glibc 库中的任何支持函数。 Stage2的主
15、要目的是运行Linux内核,在此之前需要完成硬件和内存初始化工作。,BL的典型结构框架,在标准的Linux向ARM体系的移植中,Linux的大部分代码和PC-Linux的相同,只需要完成ARM体系特有的代码和具体处理器特定的代码的移植工作。,7.2 基于ARM-withMMU的Linux移植,7.2.1 Linux源文件结构,配 置 脚 本 Config Makefile 等,选择体系结构、 处理器、驱动程序、编译时必须的宏定义,内核 镜像文件,模 块,编译链接,make zImage,压缩内核汇编入口 (ARM汇编),解压缩内核 ( C语言),跳转到内核真正入口 (ARM汇编),非压缩内核入
16、口 (ARM汇编),创建页表、开启MMU (ARM汇编),跳转入C入口start-kernel (ARM汇编),start-kernel() (ARM汇编),Linux2.xarcharmbootcompressedhead.S入口文件,linux2.xarcharmbootcompressedmisc.c解压缩内核,linux2.xarcharmkernelhaead.S或者linuxarcharmkernelhaead-armv.S,Linux2.xinitmain.c,Linux内核阶段,传递命令行参数到内核,压缩内核的启动,非压缩内核的启动,Bootloader第一阶段,Bootloa
17、der第二阶段,Bootloader阶段,7.2.2 ARM Linux系统初始化过程,标准Linux只能在有内存管理单元的处理器上运行,uCLinux是针对无内存管理单元处理器的Linux系统; 标准Linux和uCLinux最大的差异就体现在内存管理上。,7.3 基于ARM-noMMU的Linux移植,(1)虚拟内存 uCLinux没有内存保护,因此应用程序的实际权限增大了;另外由于uCLinux不能实现虚拟内存,也不能实现进出内存的页面交换。,7.3.1 uCLinux和标准Linux主要区别,(2)Flat(扁平)机制 uCLinux下的可执行程序不能使用通用的ELF格式,而需要使用新
18、的Flat文件格式。,7.3.1 uCLinux和标准Linux主要区别,(4)位置无关代码 在uCLinux中,由内核所加载的程序必须能够独立运行,与他们在内存中的位置无关。其方法是产生只使用相对寻址的代码,也就是位置无关代码(Position Independent Code : PIC),(3)堆栈管理 由于没有MMU,uCLinux不能实现可自动生长的堆栈,也就没有malloc(void *)、brk(void *)系统调用。,7.3.1 uCLinux和标准Linux主要区别,(5)多进程管理 uCLinux和标准Linux最大的不同就是不能使用fork(),只能只用vfork()。
19、当父进程调用vfork()创建了子进程,这俩个进程共享内存空间。,7.3.2 uCLinux移植概述,内核其他部分 linux 2.xkernel linux 2.xipc linux 2.xmm linux 2.xfs linux 2.xnet linux 2.xinit,驱动程序部分 linux 2.xdrivers,体系结构和处理器相关 linux 2.xarcharm公共代码 linux 2.xarcharmmach-XXX,内存管理部分 linux 2.xmmnommu,体系结构和处理器相关 linux 2.xarcharmnommu公共代码 linux 2.xarcharmnimm
20、umach-XXX,ARM-uCLinux源文件,uCLinux移植步骤,1.建立开发环境 2.编译uClinux内核 3.uClinux内核建立过程 4.手工生成ROMFS文件系统,1 建立开发环境,作为uClinux系统的移植和开发的主机最好使用Linux操作系统,如果选择Windows平台作为开发平台则需要Cygwin软件包的支持。在这里 我们选用的开发平台是Fedora Core 2,内核版本为2.4.x。在进行uClinux的移植和开发之前,我们需要建立系统的交叉编译环境,因为做为主机我们使用的是IA32体系结构的处理 器,而开发板我们才用的是ARM体系结构的处理器。ARM平台的交叉
21、编译工具可以从uClinux的官方网站获得()。在这里我们采用的是arm-elf-tools-20030314.sh,该文件是一个自解压文件,可以直接执行程序安装。 #./arm-elf-tools-20030314.sh 如果不能执行该文件,则需要修改一下文件的可执行属性 #chmod 755 arm-elf-tools-20030314.sh 然后再执行程序的安装。可执行文件按会被默认安装在/usr/local/bin目录下。,2 编译uClinux内核,uClinux是一款支持无MMU单元的嵌入式操作系统,我们可以从其官方网站获取最新版本的内核文件(www.
22、)。 我们将下载的uClinux内核文件放入我们的工作目录(/home/jelly/kernel/),然后使用tar工具解压内核文件。 $cd /home/jelly/kernel/ $tar xvzf uClinux-dist-200 xxxxx.tar.gz 经过一段时间的解压后将在工作目录下会生成uClinux-dist文件夹。,2 编译uClinux内核,在编译内核之前我们首先要做的是配置内核,常用的配置方式有如下几种: make xconfig: X Windows图形界面的配置选项 make menuconfig: Console图形界面的配置选项 make
23、config: 命令接口的配置选项 在这里需要注意的是uClinux是不支持loadable modules的,因此应该取消对该模块的支持。 $cd uClinux-dist/ $make menuconfig 配置你需要的选项,比如处理器类型,开发板类型,内核版本等。配置好之后选择Saving and Exiting保存退出。,2.4.X 版本内核xconfig 配置菜单:,2.4.X 版本内核menuconfig 配置菜单 :,2.6.X 版本内核 xconfig配置菜单 :,2 编译uClinux内核,编译uClinux内核的常用选项有: make distclean 该命令将清除以前编
24、译时候产生的文件,包括.config文件,所有目标文件以及内核映象文件。 make clean 该命令与make distclean相似,也是清除之前编译时候产生的文件 make dep 这个只需要在第一次编译的时候执行,为了是建立文件之间的依赖关系,make命令会根据这个依赖关系来确定哪些文件需要重新编译,哪些文件可以跳过。 make lib_only 编译uClibc库,2 编译uClinux内核,make user_only 编译用户制定的应用程序,比如初始化进程init,bash,以及集成了很多常用工具的嵌入式软件包busybox。 make romfs uClinux经常才用romf
25、s(只读文件系统)来作为系统的根文件系统,所以首先需要将之前编译的很多应用程序以uClinux所需要的目录格式存放 起来。比如将可执行文件放在bin目录下,将配置文件放在etc目录下。该命令执行后会在uClinux-dist目录下生成一个romfs的目录,并且 将文件系统所需要的文件组织起来,以便之后生成fomfs的映象文件。 make image 生成romfs文件系统的映象文件,以及linux的映象文件。该linux的映象文件是elf格式的,是不能直接下载到开发板上执行的(里面包含了大量 的调试信息,elf文件执行前的环境建立信息等内容。该文件可以使用arm-elf-objcopy工具来生
26、成可以直接在RAM中执行的binary文 件)。,2 编译uClinux内核,make linux 执行该命令之后将生成linux内核文件。 make zImage 建立经过gzip算法压缩过的内核映象文件,通常zImage产生的内核映象文件无法超过512KB大小。 make modules 建立内核模块 注:有些uClinux版本提供了更多的编译方式,比如make linux.bin。关于其他的编译方式可以参看内核源码目录里的Makefile文件。,2 编译uClinux内核,在介绍完常用的几个内核编译命令后,我们可以使用如下的几个命令来建立我们所需要的内核以及文件系统: make dep
27、make clean make all 这样在uClinux-dist/linux-2.x.x目录下会生成linux, System.map,在uClinux-dist/images/目录下会生成image.bin, linux.bin, image.ram, image.rom, romfs.img, linux.text, linux.data等文件。 其中image.ram是直接可以下载到ram中执行的文件。在调试阶段我们就可以使用该文件。 image.rom是一个zImage文件,可以自解压的内核,该文件需要少写到FLASH里,而不能直接放入RAM中执行,3 uClinux内核建立过程
28、,建立内核首先是建立单独的内核模块和内核子系统,一旦这些建立好了之后将通过连接文件将多个文件连接在一起。该连接文件一般在arch/$(ARCH)/ $(PLATFORM)/$(BOARD)/$(MODEL).ld。连接器使用该连接文件生成linux文件: LD -T (MODUEL).ld crt0_$(MODUEL).o objs -o linux 连接文件定义了内核如何组织内存段。 System.map文件是通过linux文件产生的,用于调试使用。通过该文件可以方便的确定函数的位置。该文件是通过如下方式产生: NM $(LINUX) | grep -v (compiled)|(.o$)|(
29、a) | sort System.map,3 uClinux内核建立过程,linux.data文件是包含内核所有数据段的代码,是通过移除linux文件中所有只读段和其他不需要的段得到的,该文件可以通过arm-elf-objcopy来产生,如: OBJCOPY -O binary -remove-section=.romvec -remove-section=.text -remove-section=.ramvec -remove-section=.bss -remove-section.eram linux linux.data linux.text文件包含了所有文本段代码,是去除数据段后的
30、代码 OBJCOPY -O binary -remove-section=.ramvec -remove-section=.bss -remove-section-.data -remove-section=.eram -set-section-flags=.romvec=CONTENTS,ALLOC,LOAD,READONLY,CODE linux linux.text,3 uClinux内核建立过程,linux.bin文件,是可以实际载入内存中执行的文件,他的建立是通过linux.text和linux.data两个文件连接得到的,如: cat linux.text linux.data l
31、inux.bin 该文件只是内核,并没有包含文件系统。我们可以使用如下方式将文件系统和内核文件连接起来生成image.bin映象文件: cat linux.bin romfs.img image.bin,4 手工生成ROMFS文件系统,建立ROMFS文件系统之前应该手工建立文件系统树,例如通常ROMFS包含如下目录: /bin /dev /etc /lib /proc /sbin /tmp /usr /var 然后我们可以将交叉编译好的应用程序放入/bin目录中,之后使用genromfs工具来建立文件系统的映象,如: genromfs -v -V ROM Disk -f romfs.img -
32、d romfs romfs.map 最后,可以与内核文件连接在一起,然后烧入Flash中。 cat linux.bin romfs.img image.bin,1、根目录 只需要修改Makefile文件。Makefile作用:定义编译的规则。顶层 Makefile,是整个内核配置、编译的总体控制文件。 a:指定目标平台before: ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/)after:ARCH := armb:指定交叉编译器before:
33、 CROSS_COMPILE =after:CROSS_COMPILE = /opt/host/armv4l/bin/armv4l-unknown-linux-,7.4 s3c2410系统的Linux移植,2、arch目录 这里存放着和体系结构相关部分的内核代码。其中每一个目录代表一种硬件平台。 2.1 archarmMakefile文件 手动add: ifeq ($(CONFIG_ARCH_S3C2410),y) TEXTADDR = 0 xC0008000 MACHINE = s3c2410endif 要点:/ TEXTADDR 决定内核开始运行的地址,即image的地址。根据自己的硬件电
34、路设置TEXTADDR 变量。,7.4 s3c2410系统的Linux移植,2.2 archarmconfig.in配置文件 a.添加CONFIG_ARCH_S3C2410子选项if $CONFIG_ARCH_S3C2410 = y ; thencomment S3C2410 Implementationdep_bool SMDK (MERI TECH BOARD) CONFIG_S3C2410_SMDK $CONFIG_ARCH_S3C2410dep_bool change AIJI CONFIG_SMDK_AIJIdep_tristate S3C2410 USB function supp
35、ort CONFIG_S3C2410_USB $CONFIG_ARCH_S3C2100dep_tristate Support for S3C2410 USB character device emulation CONFIG_S3C2410_USB_CHAR $CONFIG_S3C2410_USB,7.4 s3c2410系统的Linux移植,2.2 archarmconfig.in配置文件 b.其它选项if $CONFIG_FOOTBRIDGE_HOST = y -o $CONFIG_ARCH_SHARK = y -o $CONFIG_ARCH_CLPS7500 = y -o $CONFIG
36、_ARCH_EBSA110 = y -o $CONFIG_ARCH_CDB89712 = y -o $CONFIG_ARCH_EDB7211 = y -o $CONFIG_ARCH_S3C2400 = y -o $CONFIG_ARCH_S3C2410 = y -o $CONFIG_ARCH_SA1100 = y ; then define_bool CONFIG_ISA yelse define_bool CONFIG_ISA n 移植要点:config文件决定了menuconfig菜单的内容。把使用的平台加在需要的地方,这样在配置linux内核时就能够选择是否支持你的平台了。,7.4 s3
37、c2410系统的Linux移植,3、archarmboot目录 编译出来的内核存放在这个目录下。这里将指定内核解压到目标板的地址,所以内核无法正常启动,很有可能是这里的地址指定错误。 3.1 archarmbootMakefile文件 ifeq ($(CONFIG_ARCH_S3C2410),y)ZTEXTADDR = 0 x30008000ZRELADDR = 0 x30008000endif 要点:/ ZTEXTADDR 决定内核解压后数据输出的地址。 / ZRELADDR为bootloader压缩内核文件烧入flash /的起始地址。即从哪个位置开始执行bootloader。,7.4 s3c2410系统的Linux移植,3.2 archarmbootcompressedMakefile文件 通过这个文件将从vmlinux创建一个压缩的vmlinuz镜像 ifeq ($(CONFIG_ARCH_S3C2410),y)OBJS += head-s3c2410.oendif 要点:/加入head-s3c2410.o,为Linux的目标镜像。,7.4 s3c2410系统
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年水质监测系统合作协议书
- 2025年烧伤整形科手术器械项目发展计划
- 2025年户用和村用风光互补发电系统控制器及逆变器项目发展计划
- 企业如何借助科技力量推广垃圾分类
- 2025年特种设备检验检测项目发展计划
- 智慧城市公共设施信息安全管理方案
- 教育心理学在艺术教育中的价值体现
- 教育心理学的激励理论在教育中的应用
- 教育心理学的反馈机制与学习效果提升研究
- 中职数学函数课件
- 杭州转贷基金管理办法
- 老北京胡同文化课件
- 公司安全隐患排查记录表
- 粮食的形态与化学组成第二节粮食的主要化学成分下64课件
- 儿科护士考试试题及答案
- 创新社区管乐团活动方案
- 中国农田水利行业发展前景及发展策略与投资风险研究报告2025-2028版
- 鸵鸟养殖场管理制度
- 余料使用管理制度
- 金氏五行升降中医方集
- 前列腺癌根治术护理查房课件
评论
0/150
提交评论