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映像)。
2、基于zImage的启动方案。
1、zImage的生成过程
1、编译链接vmlinux
2、生成vmlinux.lds链接脚本
3、链接生成zImage
2、zImage的代码结构
在内核编译完成后会在arch/arm/boot/下生成zImage。
#arch/arm/boot/Makefile:
$(obj)/zImage:$(obj)/compressed/vmlinux FORCE
$(call if_changed,objcopy)
@echo '  Kernel: $@ is ready'
由此可见,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)/: $(obj)/../Image FORCE
$(call if_changed,gzip)
伊春空难真正原因
$(obj)/piggy.o:  $(obj)/ FORCE
总结一下zImage的组成,它是由一个压缩后的内核piggy.o,连接上一段初始化及解压功能的代码(head.o misc.o)组成的。
3、zImage的启动过程波伏娃
1. Linux内核的一般启动过程:
1)对于ARM 系列处理器来说,zImage 的入口程序即为 arch/arm/boot/ compressed/head.S。它依次完成以下工作:开启MMU和Cache,调用 decompress_kernel()解压内核,最后通过调用 call_kernel()进入非压缩内核 Image 的启动。
黄永玉的家
Linux 非压缩内核的入口位于文件/arch/arm/kernel/head-armv.S 中的 stext 段。该段的基地址就是压缩内核解压后的跳转地址。如果系统中加载的内核是非压缩的 Image,那么bootloader将内核从 Flash中拷贝到 RAM 后将直接跳到该地址处,从而启动 Linux 内核。
2)执行镜像:解压後/非压缩镜像直接执行(linux/arch/arm/kernel/head-armv.S:ENTRY(stext)-> __
entry->__ret->__switch_data->__mmap_switched->)3)该程序通过查处理器内核类型和处理器类型调用相应的初始化函数,再建立页表,最后跳转到start_kernel()函数开始内核的初始化工作。(linux/init/main.c:start_kernel())
2、zImage的启动过程
1)内核启动地址的确定
1、#/arch/arm/Makefile文件中,设置内核启动的虚拟地址
textaddr-y    := 0xC0008000      这个是内核启动的虚拟地址
TEXTADDR := $(textaddr-y)
2、#/arch/arm/boot/Makefile文件中,设置内核启动的物理地址ZRELADDR    := $(zreladdr-y)李薇日记
PARAMS_PHYS := $(params_phys-y)
3、 #/arch/arm/boot/compressed/Makefile文件中,变频器论文
SEDFLAGS    =
s/TEXT_START/$(ZTEXTADDR)/;s/LOAD_ADDR/$(ZRELADDR)/;s/BSS_START/$ (ZBSSADDR)/
使得TEXT_START = ZTEXTADDR(从flash中启动时),LOAD_ADDR = ZRELADDR
其中TEXT_START是内核ram启动的偏移地址,这个地址是物理地址ZTEXTADDR就是解压缩代码的ram偏移地址,
LOAD_ADDR就是zImage中解压缩代码的ram偏移地址,
ZRELADDR是内核ram启动的偏移地址,
zImage的入口点由# /arch/arm/boot/compressed/vmlinux.lds.in决定:OUTPUT_ARCH(arm)
ENTRY(_start)
SECTIONS
{
. = TEXT_START;
_text = .;
.text : {
_start = .;
*(.start)
*(.text)
……
}
2)内核解压缩过程
内核压缩和解压缩代码都在目录#/arch/arm/boot/compressed,编译完成后将产生vmlinux、head.o、misc.o、head-xscale.o、piggy.o这几个文件,其中head.o:内核的头部文件,负责初始设置;
misc.o:主要负责内核的解压工作,它在head.o之后;
head-xscale.o:主要针对Xscale的初始化,将在链接时与head.o合并;piggy.o:一个中间文件,其实是一个压缩的内核(kernel/vmlinux),只不过没
有和
初始化文件及解压文件链接而已;
vmlinux:没有(zImage是压缩过的内核)压缩过的内核,就是由piggy.o、 head.o、misc.o、head-xscale.o组成的。

本文发布于:2024-09-21 22:18:26,感谢您对本站的认可!

本文链接:https://www.17tex.com/xueshu/264782.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:内核   启动   压缩   地址   代码   解压   文件   方案
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2024 Comsenz Inc.Powered by © 易纺专利技术学习网 豫ICP备2022007602号 豫公网安备41160202000603 站长QQ:729038198 关于我们 投诉建议