linux启动流程分析---内核解压缩过程.doc

上传人:sk****8 文档编号:3520240 上传时间:2019-06-01 格式:DOC 页数:2 大小:33.50KB
下载 相关 举报
linux启动流程分析---内核解压缩过程.doc_第1页
第1页 / 共2页
linux启动流程分析---内核解压缩过程.doc_第2页
第2页 / 共2页
亲,该文档总共2页,全部预览完了,如果喜欢就下载吧!
资源描述

1、linux 启动流程分析-内核解压缩过程内核压缩和解压缩代码都在目录kernel/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),只不过没有和初始化文件及解压文件链接而已;vml

2、inux 是(没有lw:zImage 是压缩过的内核) 压缩过的内核,就是由piggy.o、head.o、misc.o、head-xscale.o 组成的。在 BootLoader 完成系统的引导以后并将 Linux 内核调入内存之后,调用 bootLinux(),这个函数将跳转到 kernel 的起始位置。如果 kernel 没有压缩,就可以启动了。如果 kernel 压缩过,则要进行解压,在压缩过的 kernel 头部有解压程序。压缩过得 kernel 入口第一个文件源码位置在 arch/arm/boot/compressed/head.S。它将调用函数 decompress_kernel

3、(),这个函数在文件 arch/arm/boot/compressed/misc.c 中,decompress_kernel()又调用 proc_decomp_setup(),arch_decomp_setup()进行设置,然后使用在打印出信息“Uncompressing Linux.”后,调用 gunzip()。将内核放于指定的位置。以下分析 head.S 文件:(1)对于各种 Arm CPU 的 DEBUG 输出设定,通过定义宏来统一操作。(2)设置 kernel 开始和结束地址,保存 architecture ID。(3)如果在 ARM2 以上的 CPU 中,用的是普通用户模式,则升到超

4、级用户模式,然后关中断。(4)分析 LC0 结构 delta offset,判断是否需要重载内核地址(r0 存入偏移量,判断 r0 是否为零)。这里是否需要重载内核地址,我以为主要分析arch/arm/boot/Makefile、arch/arm/boot/compressed/Makefile和 arch/arm/boot/compressed/vmlinux.lds.in 三个文件,主要看 vmlinux.lds.in 链接文件的主要段的位置,LOAD_ADDR(_load_addr)0xA0008000,而对于 TEXT_START(_text、_start)的位置只设为 0,BSS_S

5、TART(_bss_start)ALIGN(4)。对于这样的结果依赖于,对内核解压的运行方式,也就是说,内核解压前是在内存(RAM)中还是在 FLASH 上,因为这里,我们的 BOOTLOADER 将压缩内核(zImage)移到了 RAM 的 0xA0008000 位置,我们的压缩内核是在内存(RAM)从 0xA0008000 地址开始顺序排列,因此我们的 r0 获得的偏移量是载入地址 (0xA0008000)。接下来的工作是要把内核镜像的相对地址转化为内存的物理地址,即重载内核地址。(5)需要重载内核地址,将 r0 的偏移量加到 BSS region 和 GOT table 中。(6)清空

6、bss 堆栈空间 r2r3 。(7)建立 C 程序运行需要的缓存,并赋于 64K 的栈空间。(8)这时 r2 是缓存的结束地址,r4 是 kernel 的最后执行地址,r5 是 kernel 境象文件的开始地址。检查是否地址有冲突。将 r5 等于 r2,使 decompress 后的 kernel 地址就在 64K 的栈之后。(9)调用文件 misc.c 的函数 decompress_kernel(),解压内核于缓存结束的地方(r2 地址之后)。此时各寄存器值有如下变化:r0 为解压后 kernel 的大小r4 为 kernel 执行时的地址r5 为解压后 kernel 的起始地址r6 为 C

7、PU 类型值 (processor ID)r7 为系统类型值(architecture ID)(10)将 reloc_start 代码拷贝之 kernel 之后(r5+r0 之后),首先清除缓存,而后执行reloc_start。(11)reloc_start 将 r5 开始的 kernel 重载于 r4 地址处。(12)清除 cache 内容,关闭 cache,将 r7 中 architecture ID 赋于 r1,执行 r4 开始的 kernel 代码。下面简单介绍一下解压缩过程,也就是函数 decompress_kernel 实现的功能:解压缩代码位于 kernel/lib/inflat

8、e.c,inflate.c 是从 gzip 源程序中分离出来的。包含了一些对全局数据的直接引用。在使用时需要直接嵌入到代码中。gzip 压缩文件时总是在前 32K 字节的范围内寻找重复的字符串进行编码, 在解压时需要一个至少为 32K 字节的解压缓冲区,它定义为 windowWSIZE。inflate.c 使用 get_byte()读取输入文件,它被定义成宏来提高效率。输入缓冲区指针必须定义为 inptr,inflate.c 中对之有减量操作。inflate.c 调用 flush_window()来输出 window 缓冲区中的解压出的字节串,每次输出长度用 outcnt 变量表示。在flus

9、h_window()中,还必 须对输出字节串计算 CRC 并且刷新 crc 变量。在调用 gunzip()开始解压之前,调用makecrc()初始化 CRC 计算表。最后 gunzip()返回 0 表示解压成功。我们在内核启动的开始都会看到这样的输出:Uncompressing Linux.done, booting the kernel.这也是由 decompress_kernel 函数内部输出的,它调用了 puts()输出字符串,puts 是在 kernel/include/asm-arm/arch-pxa/uncompress.h 中实现的。执行完解压过程,再返回到 head.S 中,启动内核:call_kernel: bl cache_clean_flushbl cache_offmov r0, #0mov r1, r7 restore architecture numbermov pc, r4 call kernel

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 实用文档资料库 > 策划方案

Copyright © 2018-2021 Wenke99.com All rights reserved

工信部备案号浙ICP备20026746号-2  

公安局备案号:浙公网安备33038302330469号

本站为C2C交文档易平台,即用户上传的文档直接卖给下载用户,本站只是网络服务中间平台,所有原创文档下载所得归上传人所有,若您发现上传作品侵犯了您的权利,请立刻联系网站客服并提供证据,平台将在3个工作日内予以改正。