linux zImage生成过程详解
Image、uImage、zImage、bzImage、vmlinuz和vmlinux的区别
Image、uImage、zImage、bzImage、vmlinuz和vmlinux的区别内核编译(make)之后会生成两个文件,一个Image,一个zImage,其中Image为内核映像文件,而zImage为内核的一种映像压缩文件,Image大约为4M,而zImage不到2M。
uImage是uboot专用的映像文件,它是在zImage之前加上一个长度为64字节的“头”,说明这个内核的版本、加载位置、生成时间、大小等信息;其0x40之后与zImage没区别。
64字节的头结构如下:typedef struct image_header {uint32_tih_magic;uint32_tih_hcrc;uint32_tih_time;uint32_tih_size;uint32_tih_load;uint32_tih_ep;uint32_tih_dcrc;uint8_tih_os;uint8_tih_arch;uint8_tih_type;uint8_tih_comp;uint8_tih_name[IH_NMLEN];} image_header_t;所以,uImage和zImage都是压缩后的内核映像。
而uImage是用mkimage工具根据zImage制作而来的。
mkimage工具介绍如下:u-boot里面的mkimage工具来生成uImage(u-boot源码包/tools/mkimage.c )这里解释一下参数的意义:-A ==> set architecture to 'arch'-O ==> set operating system to 'os'-T ==> set image type to 'type' “kernel或是ramdisk”-C ==> set compression type 'comp'-a ==> set load address to 'addr' (hex)-e ==> set entry point to 'ep' (hex)(内核启动时在此位置查询完整的内核印象)-n ==> set image name to 'name'-d==> use image data from 'datafile'-x ==> set XIP (execute in place,即不进行文件的拷贝,在当前位置执行)对于ARM linux内核映象用法:-A arm -------- 架构是arm-O linux -------- 操作系统是linux-T kernel -------- 类型是kernel-C none/bzip/gzip -------- 压缩类型-a 20008000 ---- image的载入地址(hex),通常为0xX00008000-e 200080XX---- 内核的入口地址(hex),XX为0x40或者0x00 -n linux-XXX --- image的名字,任意-d nameXXX ---- 无头信息的image文件名,你的源内核文件uImageXXX ---- 加了头信息之后的image文件名,任意取原来在这个-C这个参数这里不太理解,因为我觉得既然mkimage是用zImage去制作uImage,而本身zImage就是经过压缩了的,为什么这个地方还要有一个压缩了,后来想了下,觉得可能是这个工具也可以根据最原始的Image去制作uImage,所以就有了这个参数,不深究。
ARM+Linux的启动分析(zImage)
ARM+Linux的启动分析(zImage)基于ARM的Linux的启动分析报告摘要:本文主要分析基于ARM的Linux-2.2.26内核启动过程。
将首先从/arch/arm/Makefile着手,介绍三种不同的启动方案,再剖析典型的压缩内核zImage启动方案的代码结构,最后将详细分析这种方案的启动过程,直到调用start_kernel()为止。
1、Linux内核的启动方案:由/arch/arm/Makefile的代码可以看出,主要有三种启动方案,分别是: echo '* zImage - Compressed kernel image (arch/$ (ARCH)/boot/zImage)'echo ' Image - Uncompressed kernel image (arch/$(ARCH)/boot/Image)'echo ' bootpImage - Combined zImage and initial RAM disk' echo ' (supply initrd image via make variable INITRD=)'Linux内核有两种映像:一种是非压缩内核,叫Image,另一种是它的压缩版本,叫zImage。
根据内核映像的不同,Linux内核的启动在开始阶段也有所不同。
zImage是Image经过压缩形成的,所以它的大小比Image小。
但为了能使用zImage,必须在它的开头加上解压缩的代码,将zImage解压缩之后才能执行,因此它的执行速度比Image要慢。
但考虑到嵌入式系统的存储空容量一般比较小,采用zImage可以占用较少的存储空间,因此牺牲一点性能上的代价也是值得的。
所以一般的嵌入式系统均采用压缩内核的方式(另外bootpImage是编译包含zImage和initrd的映像,可以通过make 变量INITRD=提供initrd映像)。
linux的几个内核镜像格式Image和u-boot启动内核和文件系统时的一些环境变量的设置
linux的几个内核镜像格式Image和u-boot启动内核和文件系统时的一些环境变量的设置关于编译powerpc linux的几个Image参考原文 /s/blog_86a30b0c0100wfzt.html转载▼PowerPC架构 Linux和ARM,X86等平台有些差异,PowerPC平台HW参数不是通过命令行方式传递到Linux,而是通过传递Device tree文件的方式传递参数,所以PowerPC平台Linux需要编译dtb和uImage才能正常加载,另外PowerPC架构linux还提供simpleImage的方式加载,也就是将dtb与uImage或将dtb,uImage 与ramdisk.image.gz多个文件整合生产单个simpleImage文件,这种simpleImage文件加载方式适合于没有bootloader支持的情况下,通过JTAG将simpleImage直接加载到target board内存中运行,对于调试非常方便,下面说说这几种Image文件的编译:1,dtb:dtb文件由dts生成,对于任何一个PowerPC处理器板,都要有对应的dts文件,dts文件主要是对目标板的HW参数进行描述,比如我的目标板是evm440(Powerpc440),我编写了一个evm440.dts文件放到内核arch/powerpc/boot/dts/目录下.编译evm440.dtb文件命令如下:$ make ARCH=powerpc CROSS_COMPILE=/toolchain/freescale-2010.09/bin/powerpc-linux-gnu- evm440.dtb编译成功后会在arch/powerpc/boot/下生成evm440.dtb文件,这就是我们需要的dtb文件.2. uImage:这个Image应该是地球都知道的,这里就不多说了,编译命令如下:$ make ARCH=powerpc CROSS_COMPILE=/toolchain/freescale-2010.09/bin/powerpc-linux-gnu- uImage编译成功后会在arch/powerpc/boot/下生成uImage文件,这就是我们需要的内核Image文件.3. simpleImage.xxxx和simpleImage.initrd.xxxx:这里的xxxx是特定目标板名字,我的目标板是evm440,也就是simpleImage.evm440和simpleImage.initrd.evm440。
9 Linux内核映像的生成与启动
在配置内核前,一般先将内核配置成默认的 例如上节课介绍的方法:
▶cp config_back .config ▶将一个配置文件直接覆盖.config文件;
其他的配置成默认的方法:
▶内核本身提供的很多平台的默认配置文件,这些配置文件保存 在arch/arm/configs目录下: ▶我们看到了s3c2410_defconfig文件,这个文件就是内核提供 的S3C2410平台的默认配置文件; ▶可以通过下面的方式来将其作为内核默认配置:
▶obj-$(CONFIG_USB_NET_DM9601) += dm9601.o
Kconfig文件负责提供菜单,Makefile负责编译 配置和编译通过.config文件来联系
配置结果保存在.config文件中 Makefile包含.config文件来读取用户的配置选项
linux配置系统
linux配置系统
Makefile文件
obj-$(CONFIG_USB_NET_DM9601) += dm9601.o
相当于: obj-y += dm9601.o
▶obj-y的意思是把dm9601.o目标文件编译进内核,dm9601.o目 标文件应该从dm9601.c或dm9601.S文件中编译过来; ▶obj-m 的意思是把目标文件编译成模块
6 将压缩的能够自引导的vmlinux转换成zImage
▶ arm-linux-objcopy -O binary arch/arm/boot/compressed/vmlinux arch/arm/boot/zImage
7 添加uboot头部,生成uImage
▶ mkuboot.sh -A arm -O linux -T kernel -C none -a 0x30008000 -e 0x30008000 -n 'Linux-2.6.32.2bt' -d arch/arm/boot/zImage arch/arm/boot/uImage
s5pv210 生成zImage流程
1、在arch/arm/Makefile 中会定义生成的镜像文件对于zImage 而言,其依赖文件为:zImage Image xipImage bootpImage uImage: vmlinux$(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $(boot)/$@ 如上图所示其中的依赖文件vmlinux 即为顶层目录中的vmlinux命令在210平台中为:2、在/arch/arm/boot/Makefile 中的目标文件zImage从上面的依赖关系可知在arch/arm/boot/目录下:zImage依赖于/compressed/vmlinux/compressed/vmlinux依赖于ImageImage 依赖于顶层目录下vmlinux3、生成第一个依赖文件arch/arm/boot/Image$(call if_changed,objcopy)命令cmd_obcopy在/scripts/Makefile.lib 中定义:quiet_cmd_objcopy = OBJCOPY $@cmd_objcopy = $(OBJCOPY) $(OBJCOPYFLAGS) $(OBJCOPYFLAGS_$(@F)) $< $@其中OBJCOPY 在顶层Makefile中定义:OBJCOPY = $(CROSS_COMPILE)objcopyCROSS_COMPILE ?= /usr/local/arm/4.3.2/bin/arm-none-linux-gnueabi-即OBJCOPY = /usr/local/arm/4.3.2/bin/arm-none-linux-gnueabi- objcopyOBJCOPYFLAGS 在/arch/arm/Makefile 中定义OBJCOPYFLAGS :=-O binary -R .note -R .note.gnu.build-id -R .comment –S OBJCOPYFLAGS_$(@F 可以扩展成OBJCOPYFLAGS_Image所以cmd_objcopy 展开为:即调用objcopy工具从ELF格式的顶层目录下的vmlinux中取出二进制指令在arch/arm/boot目录下生成Image。
Linux内核源码分析--内核启动之zImage自解压过程
Linux内核源码分析--内核启动之zImage⾃解压过程阅读⽬录(Content)参考:⽂档下载地址:关于内核⾃解压完毕后,执⾏start_kernel的分析,参见:内核版本:3.0.8相关⽂件:arch/arm/boot/compressed/head.Sarch/arm/boot/compressed/vmlinux.ldsarch/arm/boot/compressed/piggy.gzip这⾥仅对内核⾃解压进⾏简要分析,详细的分析可以阅读参考博客⽂档。
zImage来历顶层vmlinux ---->arch/arm/boot/Image --->arch/arm/boot/compressed/piggy.gz --->arch/arm/boot/compressed/vmlinux --->arch/arm/boot/zImage如果要分析zImage的反汇编反汇编⽂件,可将arch/arm/boot/compressed/vmlinux进⾏反汇编,arm-linux-xxx-objdump –d vmlinux > vmlinux.dis对顶层的vmlinux反汇编得到的是未压缩的内核的反汇编⽂件,这个vmlinux才是真正的Linux内核。
piggy.gz压缩⽂件的特点gzip -f -9 < Image > piggy.gz在piggy.gz的结尾四个字节表⽰的是 Image 镜像的⼤⼩,并且是以⼩端格式存放的。
下⾯我们验证⼀下:可以看到,Image的⼤⼩是6806148B,⼗六进制值就是67DA84,接下来看看piggy.gz的结尾:可以看到,确实是将0x67DA84以⼩端的格式存放在了piggy.gz的结尾四字节中了。
vmlinux.lds1: /*2: * linux/arch/arm/boot/compressed/vmlinux.lds.in3: *4: * Copyright (C) 2000 Russell King5: *6: * This program is free software; you can redistribute it and/or modify7: * it under the terms of the GNU General Public License version 2 as8: * published by the Free Software Foundation.9: */10: OUTPUT_ARCH(arm)11: ENTRY(_start)12: SECTIONS13: {14: /DISCARD/ : {15: *(.ARM.exidx*)16: *(.ARM.extab*)17: /*18: * Discard any r/w data - this produces a link error if we have any,19: * which is required for PIC decompression. Local data generates20: * GOTOFF relocations, which prevents it being relocated independently21: * of the text/got segments.22: */23: *(.data)24: }25:26: . = 0;27: _text = .;28:29: .text : {30: _start = .;31: *(.start)32: *(.text)33: *(.text.*)34: *(.fixup)35: *(.gnu.warning)36: *(.rodata)37: *(.rodata.*)38: *(.glue_7)39: *(.glue_7t)40: *(.piggydata)41: . = ALIGN(4);42: }43:44: _etext = .;45:46: _got_start = .;47: .got : { *(.got) }48: _got_end = .;49: .got.plt : { *(.got.plt) }50: _edata = .;51:52: . = ALIGN(8);53: __bss_start = .;54: .bss : { *(.bss) }55: _end = .;56:57: . = ALIGN(8); /* the stack must be 64-bit aligned */58: .stack : { *(.stack) }59:60: .stab 0 : { *(.stab) }61: .stabstr 0 : { *(.stabstr) }62: .stab.excl 0 : { *(.stab.excl) }63: .stab.exclstr 0 : { *(.stab.exclstr) }64: .stab.index 0 : { *(.stab.index) }65: .stab.indexstr 0 : { *(.stab.indexstr) }66: .comment 0 : { *(.comment) }67: }68:arch/arm/boot/compressed/head.S1: .section ".start", #alloc, #execinstr2: /*3: * 清理不同的调⽤约定4: */5: .align6: .arm @ 启动总是进⼊ARM状态7: start:8: .type start,#function9: .rept 710: mov r0, r011: .endr12: ARM( mov r0, r0 )13: ARM( b 1f )14: THUMB( adr r12, BSYM(1f) )15: THUMB( bx r12 )16: .word 0x016f2818 @ ⽤于boot loader的魔数17: .word start @ 加载/运⾏zImage的绝对地址(编译时确定), 在vmlinux.lds中可以看到,zImage的链接起始地址是018: .word _edata @ zImage结束地址,分析vmlinux.lds可以看到,_edata是 .got 段的结束地址,后⾯紧接的就是.bss段和.stack段 19: THUMB( .thumb )20: 1: mov r7, r1 @ 保存构架ID到r7(此前由bootloader放⼊r1)21: mov r8, r2 @ 保存内核启动参数地址到r8(此前由bootloader放⼊r2)22: #ifndef __ARM_ARCH_2__23: /*24: * 通过Angel调试器启动 - 必须进⼊ SVC模式且关闭FIQs/IRQs25: * (numeric definitions from angel arm.h source).26: * 如果进⼊时在user模式下,我们只需要做这些27: */28: mrs r2, cpsr @ 获取当前模式29: tst r2, #3 @ 判断是否是user模式30: bne not_angel31: mov r0, #0x17 @ angel_SWIreason_EnterSVC32: ARM( swi 0x123456 ) @ angel_SWI_ARM swi会产⽣软中断,会跳⼊中断向量表,这个向量表⽤的是bootloader的,因为在head.S中并没有建⽴新的向量表33: THUMB( svc 0xab ) @ angel_SWI_THUMB34: not_angel:35: mrs r2, cpsr @ 关闭中断36: orr r2, r2, #0xc0 @ 以保护调试器的运作关闭IRQ和FIQ37: msr cpsr_c, r238: #else39: teqp pc, #0x0c000003@ 关闭中断(此外bootloader已设置模式为SVC)40: #endifGOT表是什么?GOT(Global Offset Table)表中每⼀项都是本运⾏模块要引⽤的⼀个全局变量或函数的地址。
Linux内核编译生成bzImage的详细方法步骤及错误解决
Linux内核编译⽣成bzImage的详细⽅法步骤及错误解决什么是bzImagebzImage诚如其名是big image的意思,不是压缩的image。
在⽹络中,不少服务器采⽤的是Linux系统。
为了进⼀步提⾼服务器的性能,可能需要根据特定的硬件及需求重新编译Linux内核。
编译Linux 内核,需要根据规定的步骤进⾏,编译内核过程中涉及到⼏个重要的⽂件。
编译过RedHat Linux内核的⼈对其中的System.map、vmlinuz、initrd-2.4.7-10.img印象可能⽐较深刻,因为编译内核过程中涉及到这些⽂件的建⽴等操作。
那么这些⽂件是怎么产⽣的呢?以vmlinuz为例。
vmlinuz是可引导的、压缩的内核。
“vm”代表“Virtual Memory”。
Linux ⽀持虚拟内存,不像⽼的操作系统⽐如DOS有640KB内存的限制。
Linux能够使⽤硬盘空间作为虚拟内存,因此得名“vm”。
vmlinuz是可执⾏的Linux内核,它位于/boot/vmlinuz,它⼀般是⼀个软链接。
vmlinuz的建⽴有两种⽅式。
⼀是编译内核时通过“make zImage”创建,⼿动拷贝到/boot⽬录下⾯。
zImage适⽤于⼩内核的情况,它的存在是为了向后的兼容性。
⼆是内核编译时通过命令make bzImage创建,然后⼿动拷贝⾄/boot⽬录下。
bzImage是压缩的内核映像,需要注意,bzImage不是⽤bzip2压缩的,bzImage中的bz容易引起误解,bz表⽰“big zImage”。
bzImage中的b是“big”意思。
zImage(vmlinuz)和bzImage(vmlinuz)都是⽤gzip压缩的。
它们不仅是⼀个压缩⽂件,⽽且在这两个⽂件的开头部分内嵌有 gzip解压缩代码。
所以你不能⽤gunzip 或 gzip –dc解包vmlinuz。
内核⽂件中包含⼀个微型的gzip⽤于解压缩内核并引导它。
zImage制作uImage
bootm命令是用来引导经过u-boot的工具mkimage打包后的kernel image的,什么叫做经过u-boot的工具mkimage打包后的kernel image,这个就要看mkimage的代码,看看它做了些什么,虽然我很希望大家不要偷懒,认真地去看看,但是我知道还是有很多人懒得去做这件,那么我就j将分析mkimage代码后得到的总结告诉大家,mkimage做了些什么,怎么用这个工具。
mkimage的用法uboot源代码的tools/目录下有mkimage工具,这个工具可以用来制作不压缩或者压缩的多种可启动映象文件。
mkimage在制作映象文件的时候,是在原来的可执行映象文件的前面加上一个0x40字节的头,记录参数所指定的信息,这样uboot才能识别这个映象是针对哪个CPU体系结构的,哪个OS的,哪种类型,加载内存中的哪个位置,入口点在内存的那个位置以及映象名是什么root@Glym:/tftpboot# ./mkimageUsage: ./mkimage -l image-l ==> list image header information./mkimage -A arch -O os -T type -C comp -a addr -e ep -n name -d data_file[:data_file...] image-A ==> set architecture to 'arch'-O ==> set operating system to 'os'-T ==> set image type to 'type'-C ==> set compression type 'comp'-a ==> set load address to 'addr' (hex)-e ==> set entry point to 'ep' (hex)-n ==> set image name to 'name'-d ==> use image data from 'datafile'-x ==> set XIP (execute in place)参数说明:-A 指定CPU的体系结构:取值表示的体系结构alpha Alphaarm ARMx86 Intel x86ia64 IA64mips MIPSmips64 MIPS 64 Bitppc PowerPCs390 IBM S390sh SuperHsparc SPARCsparc64 SPARC 64 Bitm68k MC68000-O 指定操作系统类型,可以取以下值:openbsd、netbsd、freebsd、4_4bsd、linux、svr4、esix、solaris、irix、sco、dell、ncr、lynxos、vxworks、psos、qnx、u-boot、rtems、artos-T 指定映象类型,可以取以下值:standalone、kernel、ramdisk、multi、firmware、script、filesystem-C 指定映象压缩方式,可以取以下值:none 不压缩gzip 用gzip的压缩方式bzip2 用bzip2的压缩方式-a 指定映象在内存中的加载地址,映象下载到内存中时,要按照用mkimage制作映象时,这个参数所指定的地址值来下载-e 指定映象运行的入口点地址,这个地址就是-a参数指定的值加上0x40(因为前面有个mkimage添加的0x40个字节的头)-n 指定映象名-d 指定制作映象的源文件1)如果我们没用mkimage对内核进行处理的话,那直接把内核下载到0x30008000再运行就行,内核会自解压运行(不过内核运行需要一个tag来传递参数,而这个tag建议是由bootloader提供的,在u-boot下默认是由bootm命令建立的)。
Linux Kernel Image生成过程
我详细解析了bootsect.s,同时阅读了setup.s。
其中bootsect.s存放于磁盘的主引导扇区,bios-startup程序加载该程序(bootsect.s)到内存0x700处,并由此执行bootsect.s来引导Linux kernel。
在bootsect.s中加载setup.s 至内存中,并在执行完它自身后,jump跳至刚刚已读入的setup部份,继续执行。
Linux Kernel Image 生成过程:一. 引导扇区汇编代码bootsect.s被预处理成bbootsect.s或bootsect.s (无论有无D_BIG_KERNEL),当然这取决于编译目标是bzImage还是bImage。
bbootsect.s被汇编,然后被转化成合法的二进制文件,通过调用bbootsect.s。
(或者是bootsect.s被汇编,然后被转化成合法的二进制文件,通过调用bootsect.s。
)二. 启动代码setup.s(include video.s)被预处理成bsetup.s(就bzImage 而言),或者是setup.s(就zImage而言)。
和bootsect.s一样,不同的是bzImage 使用-D_BIG_KERNEL来标志。
结果同样也将被转化成合法的二进制文件,通过调用bsetup.s或setup.s。
三. 进入子目录 arch/i386/boot/compressed 把/usr/src/linux/vmlinux 转变成$tmppiggy.gz(临时文件名,合法的二进制格式)。
删除.note 和.comment 文件,在这个目录arch/ARM/boot/ compressed下的Makefile文件中TEXTADDR (0xC0008000)表示内核起始运行的地址,在这个arch/ARM/boot/目录下arch/i386/boot/下的Makefile中ZRELADDR(0x00008000)是将内核解压到目标板上的地址,四. gzip -9 <$tmppiggy> $tmppiggy.gz。
Linux内核源码分析--内核启动之(1)zImage
Linux内核源码分析--内核启动之(1)zImageLinux内核源码分析--内核启动之(1)zImag(1)zImage e⾃解压过程(Linux-3.0ARMv7)研究内核源码和内核运⾏原理的时候,很总要的⼀点是要了解内核的初始情况,也就是要了解内核启动过程。
我在研究内核的内存管理的时候,想知道内核启动后的页表的放置,页表1......2OUTPUT_ARCH(arm)3ENTRY(_start)4SECTIONS5{6/DISCARD/:{7*(.ARM.exidx*)8*(.ARM.extab*)9/*10*Discard any r/w data-this produces a link error if we have any,11*which is required for PIC decompression.Local data generates12*GOTOFF relocations,which prevents it being relocated independently13*of the text/got segments.14*/15*(.data)16}17.=TEXT_START;18_text=.;19.text:{20_start=.;21*(.start)22*(.text)23......start t arch/arm/boot/compressed/head.S S找到这个star 我们可以在arch/arm/boot/compressed/head.bootloader r ⼊⼝,这样就可以从这⾥开始⽤代码分析的⽅法研究bootloade跳转到压缩内核映像后的⾃解压启动过程:再看到MMU设置的时候,我只研究了armv7的指令。
看这些代码,必须对ARM的MMU有⼀定的了解,建议参考ARMv7的构架⼿册和⽹上的⼀份PDF《ARM MMU中⽂详解》(就是ARM⼿册中MMU部分的翻译)24/*25*linux/arch/arm/boot/compressed/head.S26*27*Copyright(C)1996-2002Russell King28*Copyright(C)2004Hyok S.Choi(MPU support)29*30*This program is free software;you can redistribute it and/or modify31*it under the terms of the GNU General Public License version2as32*published by the Free Software Foundation.33*/34#include35/*36*调试宏37*38*注意:这些宏必须不包含那些⾮100%可重定位的代码39*任何试图这样做的结果是导致程序崩溃40*当打开调试时请选择以下⼀个使⽤41*/42#ifdef DEBUG/*调试宏-中间层*/43#if defined(CONFIG_DEBUG_ICEDCC)/*使⽤内部调试协处理器CP14*/44#if defined(CONFIG_CPU_V6)||defined(CONFIG_CPU_V6K)||defined(CONFIG_CPU_V7)45.macro loadsp,rb,tmp46.endm47.macro writeb,ch,rb48mcr p14,0,\ch,c0,c5,049.endm50#elif defined(CONFIG_CPU_XSCALE)51.macro loadsp,rb,tmp52.endm53.macro writeb,ch,rb54mcr p14,0,\ch,c8,c0,055.endm56#else57.macro loadsp,rb,tmp58.endm59.macro writeb,ch,rb60mcr p14,0,\ch,c1,c0,061.endm62#endif63#else/*使⽤串⼝作为调试通道*/64#include/*包含构架相关的的调试宏的汇编⽂件调试宏-底层*/ 65.macro writeb,ch,rb 66senduart\ch,\rb67.endm68#if defined(CONFIG_ARCH_SA1100)69.macro loadsp,rb,tmp70mov\rb,#0x80000000@physical base address71#ifdef CONFIG_DEBUG_LL_SER372add\rb,\rb,#0x00050000@Ser373#else74add\rb,\rb,#0x00010000@Ser175#endif76.endm77#elif defined(CONFIG_ARCH_S3C2410)78.macro loadsp,rb,tmp79mov\rb,#0x5000000080add\rb,\rb,#0x4000*CONFIG_S3C_LOWLEVEL_UART_PORT 81.endm82#else83.macro loadsp,rb,tmp84addruart\rb,\tmp85.endm86#endif87#endif88#endif/*DEBUG*/89/*调试宏-上层*/90.macro kputc,val/*打印字符*/91mov r0,\val92bl putc93.endm94.macro kphex,val,len/*打印⼗六进制数*/95mov r0,\val96mov r1,#\len97bl phex98.endm99.macro debug_reloc_start/*重定位内核调试宏-开始*/100#ifdef DEBUG101kputc#'\n'102kphex r6,8/*处理器id*/103kputc#':'104kphex r7,8/*构架id*/105#ifdef CONFIG_CPU_CP15106kputc#':'107mrc p15,0,r0,c1,c0108kphex r0,8/*控制寄存器*/109#endif110kputc#'\n'111kphex r5,8/*解压后的内核起始地址*/112kputc#'-'113kphex r9,8/*解压后的内核结束地址*/114kputc#'>'115kphex r4,8/*内核执⾏地址*/116kputc#'\n'117#endif118.endm119.macro debug_reloc_end/*重定位内核调试宏-结束*/ 120#ifdef DEBUG 121kphex r5,8/*内核结束地址*/122kputc#'\n'123mov r0,r4124bl memdump/*打印内核起始处256字节*/125#endif126.endm127.section".start",#alloc,#execinstr128/*129*清理不同的调⽤约定130*/131.align132.arm@启动总是进⼊ARM状态133start:134.type start,#function135.rept7136mov r0,r0137.endr138ARM(mov r0,r0)139ARM(b1f)140THUMB(adr r12,BSYM(1f))141THUMB(bx r12)142.word0x016f2818@⽤于boot loader的魔数143.word start@加载/运⾏zImage的绝对地址(编译时确定)144.word_edata@zImage结束地址145THUMB(.thumb)1461:mov r7,r1@保存构架ID到r7(此前由bootloader放⼊r1)147mov r8,r2@保存内核启动参数地址到r8(此前由bootloader放⼊r2)148#ifndef__ARM_ARCH_2__ 149/*150*通过Angel调试器启动-必须进⼊SVC模式且关闭FIQs/IRQs151*(numeric definitions from angel arm.h source).152*如果进⼊时在user模式下,我们只需要做这些153*/154mrs r2,cpsr@获取当前模式155tst r2,#3@判断是否是user模式156bne not_angel157mov r0,#0x17@angel_SWIreason_EnterSVC158ARM(swi0x123456)@angel_SWI_ARM159THUMB(svc0xab)@angel_SWI_THUMB160not_angel:161mrs r2,cpsr@关闭中断162orr r2,r2,#0xc0@以保护调试器的运作163msr cpsr_c,r2164#else165teqp pc,#0x0c000003@关闭中断(此外bootloader已设置模式为SVC)166#endif167/*168*注意⼀些缓存的刷新和其他事务可能需要在这⾥完成169*-is there an Angel SWI call for this?170*/171/*172*⼀些构架的特定代码可以在这⾥被连接器插⼊,173*但是不应使⽤r7(保存构架ID),r8(保存内核启动参数地址),and r9. 174*/ 175.text176/*177*此处确定解压后的内核映像的绝对地址(物理地址),保存于r4178*由于配置的不同可能有的结果179*(1)定义了CONFIG_AUTO_ZRELADDR180*ZRELADDR是已解压内核最终存放的物理地址181*如果AUTO_ZRELADDR被选择了,这个地址将会在运⾏是确定:182*将当pc值和0xf8000000做与操作,183*并加上TEXT_OFFSET(内核最终存放的物理地址与内存起始的偏移)184*这⾥假定zImage被放在内存开始的128MB内185*(2)没有定义CONFIG_AUTO_ZRELADDR186*直接使⽤zreladdr(此值位于arch/arm/mach-xxx/Makefile.boot⽂件确定)187*/ 188#ifdef CONFIG_AUTO_ZRELADDR189@确定内核映像地址190mov r4,pc191and r4,r4,#0xf8000000192add r4,r4,#TEXT_OFFSET193#else194ldr r4,=zreladdr195#endif196bl cache_on/*开启缓存(以及MMU)*/197restart:adr r0,LC0198ldmia r0,{r1,r2,r3,r6,r10,r11,r12}199ldr sp,[r0,#28]200/*201*我们可能运⾏在⼀个与编译时定义的不同地址上,202*所以我们必须修正变量指针203*/204sub r0,r0,r1@计算偏移量205add r6,r6,r0@重新计算_edata206add r10,r10,r0@重新获得压缩后的内核⼤⼩数据位置207/*208*内核编译系统将解压后的内核⼤⼩数据209*以⼩端格式210*附加在压缩数据的后⾯(其实是“gzip-f-9”命令的结果)211*下⾯代码的作⽤是将解压后的内核⼤⼩数据正确地放⼊r9中(避免了⼤⼩端问题)212*/213ldrb r9,[r10,#0]214ldrb lr,[r10,#1]215orr r9,r9,lr,lsl#8216ldrb lr,[r10,#2]217ldrb r10,[r10,#3]218orr r9,r9,lr,lsl#16219orr r9,r9,r10,lsl#24220/*221*下⾯代码的作⽤是将正确的当前执⾏映像的结束地址放⼊r10222*/223#ifndef CONFIG_ZBOOT_ROM224/*malloc获取的内存空间位于重定向的栈指针之上(64k max)*/225add sp,sp,r0226add r10,sp,#0x10000227#else228/*229*如果定义了ZBOOT_ROM,bss/stack是⾮可重定位的,230*但有些⼈依然可以将其放在RAM中运⾏,231*这时我们可以参考_edata.232*/233mov r10,r6234#endif235/*236*检测我们是否会发⽣⾃我覆盖的问题237*r4=解压后的内核起始地址(最终执⾏位置)238*r9=解压后内核的⼤⼩239*r10=当前执⾏映像的结束地址,包含了bss/stack/malloc空间(假设是⾮XIP执⾏的)240*我们的基本需求是: 241*(若最终执⾏位置r4在当前映像之后)r4-16k页⽬录>=r10->OK242*(若最终执⾏位置r4在当前映像之前)r4+解压后的内核⼤⼩<=当前位置(pc)->OK 243*如果上⾯的条件不满⾜,就会⾃我覆盖,必须先搬运当前映像244*/245add r10,r10,#16384246cmp r4,r10@假设最终执⾏位置r4在当前映像之后247bhs wont_overwrite248add r10,r4,r9@假设最终执⾏位置r4在当前映像之前249ARM(cmp r10,pc)@r10=解压后的内核结束地址250THUMB(mov lr,pc)251THUMB(cmp r10,lr)252bls wont_overwrite253/*254*将当前的映像重定向到解压后的内核之后(会发⽣⾃我覆盖时才执⾏,否则就被跳过)255*r6=_edata(已校正)256*r10=解压后的内核结束地址257*因为我们要把当前映像向后移动,所以我们必须由后往前复制代码,258*以防原数据和⽬标数据的重叠259*/260/*261*将解压后的内核结束地址r10扩展(reloc_code_end-restart),262*并对齐到下⼀个256B边界。
linux内核zImage详解
linux内核zImage详解以下内容基于s5pv210进⾏分析 zImage由head.o,piggy.gzip.o,misc等链接组成,piggy.gzip.o中包含压缩的内核镜像,zImage的作⽤实际上就是对内核进⾏解码。
zImage还是位置⽆关码,它的链接地址为0,可以在任何地址运⾏,因为在对其源⽂件进⾏编译时编译器参数设置了-fpic,通过反汇编看到编译⽣成了.got和.got.plt段。
.dot.plt为空,查看反汇编得知编译器对c语⾔函数的调⽤是通过bl指令实现的,所以c的函数调⽤是位置⽆关码;⽽对于c中全局变量的处理是通过相对寻址找到全局变量⼀⼀对应的.got地址(这⾥的相对寻址是:在每个函数段中如果使⽤了全局变量都会存放.got⾸地址相对运⾏pc的偏移量以及全局变量在.got中的偏移),所以⽆论运⾏地址和链接地址匹不匹配,代码都能正确找到全局变量的.got地址。
.got地址中存放了全局变量的链接地址,所以只要在zImage的初始化c语⾔运⾏环境部分增加对.got部分全局变量的重定位则代码将正确运⾏,因此zImage成为了位置⽆关码 现在开始分析arch/arm/boot/compressed/head.s进⾏代码分析:start:.type start,#function //⽤于指定标号start为函数.rept 8 //指定.endr以前的指令循环8次mov r0, r0.endrb 1f.word 0x016f2818 @魔数⽤于表⽰zImage的⾝份.word start @ zImage的链接地址.word _edata @ zImage的链接结束地址1: mov r7, r1 @ save architecture IDmov r8, r2 @ save atags pointer #ifndef __ARM_ARCH_2__/*⽤于判断是不是angel启动,我们是u-boot启动进来时已经是svc模式了所以直接跳到not_angel */mrs r2, cpsr @ get current modetst r2, #3 @ not user?bne not_angelmov r0, #0x17 @ angel_SWIreason_EnterSVCARM( swi 0x123456 ) @ angel_SWI_ARMTHUMB( svc 0xab ) @ angel_SWI_THUMBnot_angel:mrs r2, cpsr @ turn off interrupts toorr r2, r2, #0xc0 @ prevent angel from runningmsr cpsr_c, r2#elseteqp pc, #0x0c000003 @ turn off interrupts#endif.textadr r0, LC0 //将LC0的运⾏地址加载到r0,ARM( ldmia r0, {r1, r2, r3, r4, r5, r6, r11, ip, sp})/*将r0指定的地址中的数据依次加载到括号⾥的寄存器中:r1 : LC0的链接地址r2 : BSS 起始链接地址r3 : BSS 结束链接地址r4 :内核的链接地址r5 : zImage的链接地址r6 :内核的⼤⼩r11 :.got的起始链接地址,ip :.got的结束链接地址sp :链接下的栈顶r0 : LC0的运⾏运⾏地址*/THUMB( ldmia r0, {r1, r2, r3, r4, r5, r6, r11, ip} ) //⽆效THUMB( ldr sp, [r0, #32] ) //⽆效subs r0, r0, r1 //r0成为运⾏地址与链接地址的偏移量beq not_relocated //运⾏地址与连接地址相同跳转该语句add r5, r5, r0 //r5 : zImage的运⾏地址add r11, r11, r0 //r11:.got的起始运⾏地址add ip, ip, r0 //ip:.got的结束运⾏地址#ifndef CONFIG_ZBOOT_ROMadd r2, r2, r0 //r2 :bss的运⾏起始地址add r3, r3, r0 //r3:bss的运⾏结束地址add sp, sp, r0 //sp:运⾏的栈顶地址/** 将.got中全局变量的链接地址重定位为运⾏地址*/1: ldr r1, [r11, #0] @ relocate entries in the GOTadd r1, r1, r0 @ table. This fixes up thestr r1, [r11], #4 @ C references.cmp r11, ipblo 1b#else/*未编译*/1: ldr r1, [r11, #0] @ relocate entries in the GOTcmp r1, r2 @ entry < bss_start ||cmphs r3, r1 @ _end < entryaddlo r1, r1, r0 @ table. This fixes up thestr r1, [r11], #4 @ C references.cmp r11, ipblo 1b#endifnot_relocated: mov r0, #01: str r0, [r2], #4 @ clear bssstr r0, [r2], #4str r0, [r2], #4str r0, [r2], #4cmp r2, r3blo 1bbl cache_onmov r1, sp //r1 :运⾏的栈顶地址add r2, sp, #0x10000 //r2:堆结束地址64k/*堆的结束地址⼤于内核的起始地址或者内核的结束地址⼤于zImage的运⾏起始地址将发⽣覆盖,我们这边会发⽣覆盖所以不跳转继续往下执⾏*/ cmp r4, r2bhs wont_overwriteadd r0, r4, r6cmp r0, r5bls wont_overwrite/*r0:堆结束的地址r1:堆起始的地址r2:堆结束的地址r3:机器ID*/mov r5, r2 @ decompress after malloc spacemov r0, r5mov r3, r7bl decompress_kernel 这⾥看看 decompress_kernel中的传⼊参数unsigned long decompress_kernel(unsigned long output_start, //r0 解压内核输出地址unsigned long free_mem_ptr_p,//r1 堆起始地址unsigned long free_mem_ptr_end_p,//r2 堆结束地址int arch_id//r3 机器ID)解压后返回到head中继续执⾏add r0, r0, #127 + 128 @ alignment + stackbic r0, r0, #127 @ align the kernel length分析如下:r0为decompress_kernel()函数的返回值,它的返回值最终为Linux内核解压后的长度,这⾥的第⼀条指令完成的功能是在解压后的Linux内核后⾯预留128字节的栈空间,第⼆条指令使最终r0的值为128字节对齐此时我们的内存空间分布如下:| || || ||----------------|----| 128byte | || | || + | || | r0| 解压后的内核 | || | || | ||----------------|<-------r5| 堆64k ||----------------|| 栈4k ||----------------|| || 压缩的内核 || 当前运⾏的代码|| ||----------------|0x30008000 zImage的加载地址| |---------------------/** r0 = decompressed kernel length* r1-r3 = unused* r4 = kernel execution address* r5 = decompressed kernel start* r7 = architecture ID* r8 = atags pointer* r9-r12,r14 = corrupted*/add r1, r5, r0 @ end of decompressed kerneladr r2, reloc_startldr r3, LC1add r3, r2, r31: ldmia r2!, {r9 - r12, r14} @ copy relocation codestmia r1!, {r9 - r12, r14}ldmia r2!, {r9 - r12, r14}stmia r1!, {r9 - r12, r14}cmp r2, r3blo 1bmov sp, r1add sp, sp, #128 @ relocate the stackbl cache_clean_flushARM( add pc, r5, r0 ) @ call relocation codeTHUMB( add r12, r5, r0 )THUMB( mov pc, r12 ) @ call relocation code解析如下:r1 = r5 + r0 = 解压后内核存放的地址 + 内核⼤⼩r2 = 当前reloc_start标签所在的地址r3 = *LC1LC1: .word reloc_end - reloc_start所以r3 为重定位代码段的⼤⼩r3 = r2 + r3 =重定位代码段的结束地址接下来的指令就是将重定位的代码段搬移到解压的Linux内核后⾯并且重定义了栈最后跳转重定义代码| ||----------------|<---sp| 128byte ||----------------|<---r1| || 重定位代码段 || ||----------------|<---pc| 128byte | || | || + | || | r0| 解压后的内核 | || | || | ||----------------|------->r5| 堆64k ||----------------|| 栈4k ||----------------|| || 压缩的内核 || 当前运⾏的代码|| ||----------------|0x30008000 zImage的加载地址| |---------------------/ * r0 = decompressed kernel length* r1-r3 = unused* r4 = kernel execution address* r5 = decompressed kernel start* r7 = architecture ID* r8 = atags pointer* r9-r12,r14 = corrupted*/.align 5reloc_start: add r9, r5, r0 //内核的结束地址sub r9, r9, #128 //减掉栈部分debug_reloc_startmov r1, r41:.rept 4ldmia r5!, {r0, r2, r3, r10 - r12, r14} //⼀次copy28个字stmia r1!, {r0, r2, r3, r10 - r12, r14}.endrcmp r5, r9blo 1bmov sp, r1add sp, sp, #128 @ relocate the stackdebug_reloc_endcall_kernel: bl cache_clean_flushbl cache_offmov r0, #0 @ must be zeromov r1, r7 @ restore architecture numbermov r2, r8 @ restore atags pointermov pc, r4 @ call kernel 以上就是zImage的启动过程,接下来将跳转内核。
zimage与uimage的区别
uImage与zImage的区别内核编译(make)之后会生成两个文件,一个Image,一个zImage,其中Image为内核映像文件,而zImage为内核的一种映像压缩文件,Image大约为4M,而zImage不到2M。
那么uImage又是什么的?它是uboot专用的映像文件,它是在zImage之前加上一个长度为64字节的“头”,说明这个内核的版本、加载位置、生成时间、大小等信息;其0x40之后与zImage没区别。
如何生成uImage文件?首先在uboot的/tools目录下寻找mkimage文件,把其copy 到系统/usr/local/bin目录下,这样就完成制作工具。
然后在内核目录下运行make uImage,如果成功,便可以在arch/arm/boot/目录下发现uImage文件,其大小比zImage多64个字节。
其实就是一个自动跟手动的区别,有了uImage头部的描述,u-boot就知道对应Image的信息,如果没有头部则需要自己手动去搞那些参数。
U-boot的U是“通用”的意思。
zImage是ARM Linux常用的一种压缩映像文件,uImage是U-boot专用的映像文件,它是在zImage之前加上一个长度为0x40的“头”,说明这个映像文件的类型、加载位置、生成时间、大小等信息。
换句话说,如果直接从uImage的0x40位置开始执行,zImage和uImage没有任何区别。
另外,Linux2.4内核不支持uImage,Linux2.6内核加入了很多对嵌入式系统的支持,但是uImage的生成也需要设置,这个以后我会介绍。
几种linux内核文件的区别:1、vmlinux 编译出来的最原始的内核文件,未压缩。
2、zImage 是vmlinux经过gzip压缩后的文件。
3、bzImage bz表示“big zImage”,不是用bzip2压缩的。
两者的不同之处在于,zImage解压缩内核到低端内存(第一个640K),bzImage解压缩内核到高端内存(1M以上)。
Linux操作系统下如何制作Image映像文件4
Linux操作系统下如何制作Image映像⽂件4⼋,集成,刻录下⾯我们把所制作的⽂件全部集成在⼀起iso-》boot -》grub -》grub.confiso-》boot -》grub -》menu.lstiso-》boot -》grub -》stage2_eltoritoiso-》boot -》grub -》vmlinuz-2.6.20iso-》boot -》grub -》initrd.imgvmlinuz-2.6.20,和 initrd.img可以不放在这⾥,若更改了存放路径则grub.conf中也要更改。
mkisofs -R -b boot/grub/stage2_eltorito -no-emul-boot -boot-load-size 4 -boot-info-table -o grub.iso iso////这步的意思是把iso⽂件夹中的内容做成⼀个镜像,-b参数是表⽰做⼀个启动盘,其他的东西我也不太明⽩,如果哪位⾼⼿知道-no-emul-boot -boot-load-size 4 -boot-info-table是什么意思希望mail我。
好了,现在grub.iso就是你所需要的镜像了,我们可以先放到虚拟机的光驱中看看它是不是能够引导系统。
如果不能仔细检查没⼀步。
注意 grub.iso不能⽤winiso制作,原因好像是winiso做的iso⽂件缺少了光盘信息。
但我们可以⽤demotools载⼊grub.iso⽂件,然后⽤全盘复制的⽅式刻录⼀张光盘linux。
九,这⾥我们⽤grub来引导,⽤lilo是⼀样的,只是配置⽂件不同⽽已,⽹上关于lilo的⽂章很多。
⼗:关于ram制作过程中关于ram我很迷惑,现在我的理解是计算机把⼀部分内存模拟成磁盘,所以我们可以对这部分内存进⾏格式化。
这个格式化⼀个真正的磁盘是⼀样的,但是由于这毕竟是虚拟的,所以其中的数据掉电后就会消失。
这部分内存就叫ram。
zImage的生成
内核的配置和编译主机:ubuntu 10.10发行版目标机:FS_S5PC100平台交叉编译工具:arm-none-linux-gnueabi-gcc(4.5.1)•解压内核将linux-2.6.35-farsight.tar.gz拷贝到/home/linux下并解压$tar xvf linux-2.6.35-farsight.tar.gz$ cd linux-2.6.35-farsight.•修改内核顶层目录下的Makefile$ vim Makefile修改:ARCH ?= $(SUBARCH)CROSS_COMPILE ?=CROSS_COMPILE ?= $(CONFIG_CROSS_COMPILE:"%"=%)为:ARCH ?= armCROSS_COMPILE ?= arm-none-linux-gnueabi-•拷贝标准板配置文件$ cp arch/arm/configs/s5pc100_defconfig .config•配置内核$ make menuconfig网络配置:[*] Networking support (NEW) --->Networking options ---><*> Packet socket<*> Unix domain sockets[*] TCP/IP networking[*] IP: multicasting[*] IP: kernel level autoconfiguration[*] IP: BOOTP support网卡驱动配置Device Drivers --->[*] Network device support --->[*] Ethernet (10 or 100Mbit) ---><*> DM9000 support网络文件系统的配置File systems --->[*] Network File Systems ---><*> NFS client suppor[*] NFS client support for NFS version 3[*] NFS client support for the NFSv3 ACL protocol extension[*] Root file system on NFSNand flash驱动的配置$ make menuconfigDevice Drivers ---><*> Memory Technology Device (MTD) support --->[*] MTD partitioning support<*> Caching block device access to MTD devices<*> NAND Device Support ---><*> NAND Flash support for S3C SoC[*] S3C NAND Hardware ECCFile Systems --->Partition Types --->[*] Advanced partition selection[*] PC BIOS (MSDOS partition tables) support[*] BSD disklabel (FreeBSD partition tables) support•编译内核$ make zImage$cp arch/arm/boot/zImage /tftpboot。
ARM+Linux的启动分析(zImage)
基于ARM的Linux的启动分析报告摘要:本文主要分析基于ARM的Linux-2.2.26内核启动过程。
将首先从/arch/arm/Makefile着手,介绍三种不同的启动方案,再剖析典型的压缩内核zImage启动方案的代码结构,最后将详细分析这种方案的启动过程,直到调用start_kernel()为止。
1、Linux内核的启动方案:由/arch/arm/Makefile的代码可以看出,主要有三种启动方案,分别是: echo '* zImage - Compressed kernel image (arch/$(ARCH)/boot/zImage)'echo ' Image - Uncompressed kernel image (arch/$(ARCH)/boot/Image)'echo ' bootpImage - Combined zImage and initial RAM disk'echo ' (supply initrd image via make variable INITRD=<path>)'Linux内核有两种映像:一种是非压缩内核,叫 Image,另一种是它的压缩版本,叫zImage。
根据内核映像的不同,Linux内核的启动在开始阶段也有所不同。
zImage是Image经过压缩形成的,所以它的大小比 Image小。
但为了能使用 zImage,必须在它的开头加上解压缩的代码,将 zImage解压缩之后才能执行,因此它的执行速度比Image要慢。
但考虑到嵌入式系统的存储空容量一般比较小,采用zImage可以占用较少的存储空间,因此牺牲一点性能上的代价也是值得的。
所以一般的嵌入式系统均采用压缩内核的方式(另外bootpImage是编译包含zImage和initrd的映像,可以通过make变量INITRD=<path>提供initrd映像)。
kernel启动过程,uimge,zimage,archarmbootcompressed。。。
kernel启动过程,uimge,zimage,archarmbootcompressed。
这几天因为工作原因,升级 2.6.22.7 的kernel 到 Mavell 的arm 板子上去,遇到一些头疼的问题,不得不分析启动代码,郁闷阿。
zImage是ARM Linux常用的一种压缩映像文件,uImage是U-boot专用的映像文件,它是在zImage之前加上一个长度为0x40的“头”,说明这个映像文件的类型、加载位置、生成时间、大小等信息。
换句话说,如果直接从uImage的0x40位置开始执行,zImage和uImage没有任何区别。
另外, Linux2.4内核不支持uImage,Linux2.6内核加入了很多对嵌入式系统的支持,但是uImage的生成也需要设置。
内核编译完成后会生成zImage内核镜像文件。
关于bootloader加载zImage到内核,并且跳转到zImage开始地址运行zImage的过程,相信大家都很容易理解。
但对于zImage是如何解压的过程,就不是那么好理解了。
本文将结合部分关键代码,讲解zImage的解压过程。
先看看zImage的组成吧。
在内核编译完成后会在arch/arm/boot/下生成zImage。
在arch/armboot/Makefile中:$(obj)/zImage: $(obj)/compressed/vmlinux FORCE$(call if_changed,objcopy)由此可见,zImage的是elf格式的arch/arm/boot/compressed/vmlinux二进制化得到的在arch/armboot/compressed/Makefile中:$(obj)/vmlinux: $(obj)/vmlinux.lds $(obj)/$(HEAD) $(obj)/piggy.o /$(addprefix $(obj)/, $(OBJS)) FORCE$(call if_changed,ld)$(obj)/piggy.gz: $(obj)/../Image FORCE$(call if_changed,gzip)$(obj)/piggy.o: $(obj)/piggy.gz FORCE其中Image是由内核顶层目录下的vmlinux二进制化后得到的。
linux内核源码分析--zimage出生实录(linux-3.0armv7)
Linux内核源码分析--zImage出生实录(Linux-3.0 ARMv7)自己移植编译过内核的朋友都知道:生成的zImage内核的位置在arch/arm/boot目录下。
但是这个映像是怎么产生的?下面简要地分析一下。
内核根目录下的vmlinux映像文件是内核Makefile的默认目标。
这个vmlinux映像的生成可以通过阅读内核Makefile文件得知,简单的说:Makefile 解析内核配置文件.config,递归到各目录下编译出.o文件,最后将其链接成vmlinux。
而这个链接成的vmlinux文件是一个包含内核代码的静态可执行ELF文件,你可以通过file命令来验证这一点。
她不能通过bootloader引导并启动,如果想要使其可引导,必须使用编译工具链中的objcopy命令把这个ELF格式的vmlinux转化为二进制格式才行。
而平常使用的zImage文件就是这个vmlinux文件经过多次的转换得到的。
现在就来仔细研究一下她的生成过程。
(1)arch/$(ARCH)/Makefile首先嵌入式中经常使用的编译目标zImage并不在顶层Makefile文件中,而在被顶层Makefile包含的arch/$(ARCH)/Makefile文件中,对于ARM处理器来说就是arch/arm/Makefile文件。
其中的部分规则如下:……# Default target when executing plain makeifeq ($(CONFIG_XIP_KERNEL),y)KBUILD_IMAGE := xipImageelseKBUILD_IMAGE := zImageendifall: $(KBUILD_IMAGE)boot := arch/arm/bootarchprepare:$(Q)$(MAKE) $(build)=arch/arm/toolsinclude/generated/mach-types.h# Convert bzImage to zImagebzImage: zImagezImage Image xipImage bootpImage uImage: vmlinux $(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $(boot)/$@……从这里可以看出,zImage的依赖是顶层vmlinux文件,下面的命令展开得到:make -f scripts/Makefile.build obj=arch/arm/boot MACHINE=arch/arm/mach-* arch/arm/boot/ zImage可以看出zImage其实是make解析arch/arm/boot目录下的Makefile文件生成的,而参数传递了目标芯片信息和目标“arch/arm/boot/zImage”。
zImage和uImage的区别
一、简介对于Linux内核,编译可以生成不同格式的映像文件,例如:# make zImage# make uImagezImage是ARM Linux常用的一种压缩映像文件,uImage是U-boot专用的映像文件,它是在zImage之前加上一个长度为0x40的“头”,说明这个映像文件的类型、加载位置、生成时间、大小等信息。
换句话说,如果直接从uImage的0x40位置开始执行,zImage和uImage没有任何区别。
另外,Linux2.4内核不支持uImage,Linux2.6内核加入了很多对嵌入式系统的支持,但是uImage的生成也需要设置。
vmlinux 编译出来的最原始的内核文件,未压缩。
zImage是vmlinux经过gzip压缩后的文件。
bzImage bz表示“big zImage”,不是用bzip2压缩的。
两者的不同之处在于,zImage 解压缩内核到低端内存(第一个640K),bzImage解压缩内核到高端内存(1M以上)。
如果内核比较小,那么采用zImage或bzImage都行,如果比较大应该用bzImage。
uImage是U-boot专用的映像文件,它是在zImage之前加上一个长度为0x40的tag。
vmlinuz是bzImage/zImage文件的拷贝或指向bzImage/zImage的链接。
initrd是“initial ramdisk”的简写。
一般被用来临时的引导硬件到实际内核vmlinuz能够接管并继续引导的状态。
vmlinux是内核文件,zImage是一般情况下默认的压缩内核映像文件,压缩vmlinux,加上一段解压启动代码得到,只能从0X0地址运行。
uImage是u-boot使用bootm命令引导的Linux压缩内核映像文件格式,使用工具mkimage对普通的压缩内核映像文件(zImage)加工而得。
可以由bootm命令从任意地址解压启动内核。
由于bootloader一般要占用0X0地址,所以,uImage相比zImage的好处就是可以和bootloader共存。
矿产
矿产资源开发利用方案编写内容要求及审查大纲
矿产资源开发利用方案编写内容要求及《矿产资源开发利用方案》审查大纲一、概述
㈠矿区位置、隶属关系和企业性质。
如为改扩建矿山, 应说明矿山现状、
特点及存在的主要问题。
㈡编制依据
(1简述项目前期工作进展情况及与有关方面对项目的意向性协议情况。
(2 列出开发利用方案编制所依据的主要基础性资料的名称。
如经储量管理部门认定的矿区地质勘探报告、选矿试验报告、加工利用试验报告、工程地质初评资料、矿区水文资料和供水资料等。
对改、扩建矿山应有生产实际资料, 如矿山总平面现状图、矿床开拓系统图、采场现状图和主要采选设备清单等。
二、矿产品需求现状和预测
㈠该矿产在国内需求情况和市场供应情况
1、矿产品现状及加工利用趋向。
2、国内近、远期的需求量及主要销向预测。
㈡产品价格分析
1、国内矿产品价格现状。
2、矿产品价格稳定性及变化趋势。
三、矿产资源概况
㈠矿区总体概况
1、矿区总体规划情况。
2、矿区矿产资源概况。
3、该设计与矿区总体开发的关系。
㈡该设计项目的资源概况
1、矿床地质及构造特征。
2、矿床开采技术条件及水文地质条件。
矿产
矿产资源开发利用方案编写内容要求及审查大纲
矿产资源开发利用方案编写内容要求及《矿产资源开发利用方案》审查大纲一、概述
㈠矿区位置、隶属关系和企业性质。
如为改扩建矿山, 应说明矿山现状、
特点及存在的主要问题。
㈡编制依据
(1简述项目前期工作进展情况及与有关方面对项目的意向性协议情况。
(2 列出开发利用方案编制所依据的主要基础性资料的名称。
如经储量管理部门认定的矿区地质勘探报告、选矿试验报告、加工利用试验报告、工程地质初评资料、矿区水文资料和供水资料等。
对改、扩建矿山应有生产实际资料, 如矿山总平面现状图、矿床开拓系统图、采场现状图和主要采选设备清单等。
二、矿产品需求现状和预测
㈠该矿产在国内需求情况和市场供应情况
1、矿产品现状及加工利用趋向。
2、国内近、远期的需求量及主要销向预测。
㈡产品价格分析
1、国内矿产品价格现状。
2、矿产品价格稳定性及变化趋势。
三、矿产资源概况
㈠矿区总体概况
1、矿区总体规划情况。
2、矿区矿产资源概况。
3、该设计与矿区总体开发的关系。
㈡该设计项目的资源概况
1、矿床地质及构造特征。
2、矿床开采技术条件及水文地质条件。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
矿产资源开发利用方案编写内容要求及审查大纲
矿产资源开发利用方案编写内容要求及《矿产资源开发利用方案》审查大纲一、概述
㈠矿区位置、隶属关系和企业性质。
如为改扩建矿山, 应说明矿山现状、
特点及存在的主要问题。
㈡编制依据
(1简述项目前期工作进展情况及与有关方面对项目的意向性协议情况。
(2 列出开发利用方案编制所依据的主要基础性资料的名称。
如经储量管理部门认定的矿区地质勘探报告、选矿试验报告、加工利用试验报告、工程地质初评资料、矿区水文资料和供水资料等。
对改、扩建矿山应有生产实际资料, 如矿山总平面现状图、矿床开拓系统图、采场现状图和主要采选设备清单等。
二、矿产品需求现状和预测
㈠该矿产在国内需求情况和市场供应情况
1、矿产品现状及加工利用趋向。
2、国内近、远期的需求量及主要销向预测。
㈡产品价格分析
1、国内矿产品价格现状。
2、矿产品价格稳定性及变化趋势。
三、矿产资源概况
㈠矿区总体概况
1、矿区总体规划情况。
2、矿区矿产资源概况。
3、该设计与矿区总体开发的关系。
㈡该设计项目的资源概况
1、矿床地质及构造特征。
2、矿床开采技术条件及水文地质条件。