首页 > 其他分享 >zImage的位置对于ARM32内核解压的影响

zImage的位置对于ARM32内核解压的影响

时间:2023-08-29 18:14:24浏览次数:49  
标签:解压 end DTB Image appended ARM32 bss zImage

  ARM32内核解压流程简单总结了解压流程,这里给出zImage加载位置和Image解压位置的不同组合下,zImage,Image和可能存在的重定位zImage在内存上的位置分布。

  因为解压过程中的判断是根据zImage和解压后Image的相对位置来进行不同处理,在以下的分析中,可以认为Image位置是固定的,但是zImage的位置在不断地向低地址方向移动。 示意图中,地址是从上方向下方递增的。下面是示意图中各个箭头所表示的意义。

  • Page_table_start:解压过程中页表的起始地址。
  • Kernel_start:未压缩内核Image的起始地址,实际上是相对于内存起始地址偏移为TEXT_OFFSET的地址。
  • Kernel_end:未压缩内核Image的结束地址。
  • Kernel_bss_end:未压缩内核Image使用的bss段结束地址。
  • start:zImage中的start段,这部分代码只在重定位前会运行。
  • check_page_table:检查是否可以创建页表的代码位置。
  • restart:代码自有的restart标签所在位置。
  • check_overlap:检查Image是否和zImage有重叠的代码位置。如果没有重叠的话,就跳转到wont_overwrite。
  • wont_overwrite:代码自有的wont_overwrite标签位置。运行到这里时,表示zImage和Image一定不会重叠了。一种情况是不需要重定位,直接跳转到这里。一种是需要重定位,运行到这里时,已经进行过重定位,并且是重定位后所在的位置。
  • not_relocated:代码自有not_relocated标签所在位置。如果zImage运行地址和链接时指定的VMA相同,可以直接跳转到这里。否则,就要修正GOT等数据才能执行到这里。
  • cache_flush:缓存操作相关代码的起始位置,这部分代码在重定位跳转前,和重定位跳转后都需要运行。
  • _edata:zImage链接脚本指定的符号,表示data段的结束地址。如果有appended DTB的话,会根据appended DTB的大小进行调整。
  • _end:zImage的bss段结束地址。如果有appended DTB的话,会根据appended DTB的大小进行调整。
  • .L_user_stack_end:zImage栈空间的结束地址。如果有appended DTB的话,会根据appended DTB的大小进行调整。
  • Heap_end:zImage堆的结束地址。如果有appended DTB的话,会根据appended DTB的大小进行调整。
  • Headroom_end:zImage预估结束地址,和实际结束地址可能不一致。基于appended DTB大小不会很大的假设,预估的结束地址一定会大于实际结束地址。否则,页表就有可能覆盖掉appended DTB。

Kernel_end小于等于wont_overwrite

  这种情况下,zImage用于解压Image的代码在较高地址,Image在较低地址,两者没有重叠,不需要重定位zImage,同时可以在重定位前就创建页表,并使能缓存。注意的是,在上面的示意图中,虽然内核和zImage部分代码有重叠,但是这部分代码在解压内核过程中不会使用,因此没有影响。如果zImage和Image完全没有重叠,也属于这种情况。

  虚线右半部分是zImage不带有appended DTB的情况。

  虚线左半部分是zImage支持appended DTB,并且带有appended DTB的情况。此时,Image的bss不会覆盖到appended DTB,也不需要重定位。如果进一步细分的话,这里还有两种情况。代码里是比较Image的bss段大小和_edata与wont_overwrite的差,来决定是否要调整kernel_end的值。一种情况是bss段大小较小,不需要调整,kernel_end自然小于wont_overwrite。另外一种情况是bss段大小较大,需要增加。但是这种情况下,即使有所增加,kernel_end也一定会仍然小于wont_overwrite。

  如果内核的bss会覆盖掉appended DTB,就会变成如下所示。这里虚线右半部分是不带有appended DTB,还是和上一幅图一样,不受影响。

代码会对内核结束地址进行调整,也就是加上图中所示的extra space for bss的大小。之后再根据extra space for bss的结束地址是否大于wont_overwrite来确定是否要重定位zImage。在这种情况下,一定会得到要重定位zImage的结论。调整时计算extra space for bss的大小,使用的是wont_overwrite。之后重定位zImage并拷贝时,是从restart处开始拷贝,因此重定位后的appended DTB起始地址实际上会大于kernel_bss_end。

  另外,这里还有一块空间是extra space for reloc code。可以看出,如果没有这一块空间,重定位后的代码就有可能覆盖掉cache_flush之后的部分代码。而cache_flush之后的部分代码在跳转到浅色部分zImage前,还会被执行。因此,增加这块空间将重定位后zImage的位置向高地址移动了。

Kernel_end大于wont_overwrite,Kernel_start小于check_page_table

  此时,页表和zImage还没有重叠,可以在最开始就创建页表。但是,Image代码会覆盖掉zImage用于解压的代码,因此,需要将zImage拷贝到Image结束地址之后的高地址范围内,也就是上图中浅色部分zImage。重定位完成之后,就在浅色部分所在地址上运行代码了。

  对于带有appended DTB的情况,当kernel_end大于wont_overwrite时,一定会对zImage进行重定位。虽然图示中显示的内核的bss不会覆盖appended DTB。但是,还是存在这种可能。如果会覆盖的话,就会在kernel_end后面增加若干空间extra space for bss,用于保证重定位后的appended DTB不会被覆盖。如果不会覆盖appended DTB,就不会有extra space for bss这一块空间。

  之后要讨论的情形,kernel_end会一直大于wont_overwrite,需要考虑的是kernel_start和zImage的相对关系了。

Kernel_start大于check_page_table,page_table_start小于Heap_end

  随着zImage和Image进一步靠近,zImage进而和页表范围也有重叠了。因此,在重定位过程中,不会创建页表,也就是灰色页表的意义。在重定位完成之后,执行浅色部分的zImage代码时,就会创建页表,也就是浅色页表的意义。页表的位置没有变化,只是由于重定位之前,需要用到这一块的数据,因此不能创建页表。

  这里extra space for bss是否存在也是取决于内核bss大小。想象上图中kernel_bss_end往下移动,还是有可能覆盖掉重定位后,也就是浅色的appended DTB。但是代码在拷贝zImage之前,会根据kernel BSS的大小调整extra space for bss的大小,保证浅色的appended DTB不会被覆盖。

  一般来说,解压后的Image应该会比zImage要大得多。因此,这种情况下,重定位后的代码一般不会覆盖cache_flush之后的代码了,但是代码实现上还是总会加上extra space for reloc code这一段。

Page_table_start大于等于heap_end,kernel_start小于headroom_end

  此时,Image使用的空间和zImage已经没有重叠了,因此不需要重定位zImage。虽然页表和zImage实际上没有重叠了,但是因为在最开始判断是否能够创建页表时,使用的是估计范围headroom_end和kernel_start进行比较,所以还是没有创建页表。在后面获得zImage的准确范围后,使用heap_end和kernel_start进行比较,所以就不用重定位了,也可以放心地创建页表。

Kernel_start大于headroom_end

  此时,页表和zImag的预估范围也已经没有重叠了。最开始就可以创建页表,也不用重定位zImage。

标签:解压,end,DTB,Image,appended,ARM32,bss,zImage
From: https://www.cnblogs.com/watsondd/p/17665351.html

相关文章

  • 实用指令_文件目录类_压缩和解压指令
    压缩和解压类gzip/gunzip指令基本语法gzip文件1文件2....(功能描述,压缩文件,只能将文件压缩为*.gz文件)gunzip文件.gz(功能描述,解压缩文件命令)应用实例###eg1:gzip压缩,将/home下的文件hello.txt文件进行压缩gziphello.txt##注意权限要够###eg2:gu......
  • 使用gr.inputs.File(type="fille")输入一个zip包,这个zip包是个图片文件夹,解压并提取其
    要在Gradio中使用 gr.inputs.File(type="file") 输入一个包含图片的Zip文件,并在函数中解压并提取其中的图片,您可以按照以下步骤进行操作:在您的函数中使用Python的zipfile模块来解压上传的Zip文件。从解压后的文件夹中获取图像文件,并进行处理。以下是一个示例代码......
  • CentOS安装rar、unrar解压缩软件的方法
         闲话不说,centos上如何安装rar、unrar在线解压缩软件呢?如果您的centos是32位的,执行如下命令:wget http://www.rarsoft.com/rar/rarlinux-3.9.3.tar.gztar -zxvf rarlinux-3.9.3.tar.gzcd rarmake看见下面这些信息就是安装成功了:mkdir -p /usr/local/bi......
  • Python教程:Gzip解压缩
    我们将介绍Python中的gzip解压。我们还将介绍如何使用gzip解压来解压压缩的内容。Python中的Gzip解压在Python中为压缩和解压目的建立了许多库,但我们将介绍Gzip库。它是一个流行的数据压缩工具。我们可以使用gzip,通过对数据进行特殊格式的编码来减少文件的大小,这种格式不......
  • 如何用WinRAR解压文件zip.001
    要合并“分卷.zip.001”~“分卷.zip.018”,步骤如下:新建文本文档,输入:copy/B分卷.zip.*a.zip(如果需要合并的文件为aaaa.zip.001……aaaa.zip.018,就输入copy/Baaaa.zip.*a.zip)将文档保存为批处理文件(如:合并分卷.bat),由于命令中有中文字符,需要保存为ANSI格式  将批处......
  • Linux:tar、压缩、解压
    压缩文件扩展名:.tar:tar程序打包的数据,没经过压缩.tar.gz:tar程序打包,并经过gzip压缩.tgz.gz:gzip程序压缩的文件.Z:Compress程序压缩的文件.bz2:bzip2程序压缩的文件.xz:xz程序压缩的文件Linux上最常见的压缩指令为gzip、bzip2、最新的xz;Windows上最常用的是zi......
  • 解决乌班图下zip文件解压后中文乱码问题
    解决乌班图下zip文件解压后中文乱码问题unzip如果没安装需要安装一下apt-getinstallzip解压:这个需要注意的是你解压的不能跟你的文件名称一致,刚开始以为是文件有空格导致的,后来点进去zip文件一看里面文件名跟外面文件名一样导致解压失败。unzip-Ocp936xx.zip......
  • 文件解压 //problem/2928 or /contest/1709/problem/3
    字符串套递归#include<bits/stdc++.h>usingnamespacestd;chars[1005];intn,i;stringwork(){stringp;intt=0;while(++i<=n){if(s[i]>='0'&&s[i]<='9'){t=s[i]-'0......
  • exe压缩文件解压后自动运行某一文件,如vbs、cmd、bat
    支持sfx自解压功能的压缩软件一般可以实现标题所示需求,推荐Bandizip(标准版即可),下载安装就是标准版:http://www.bandisoft.com/bandizip/以解压MySoft.exe后自动执行pre_install.vbs为例:1、全选下图文件后,鼠标右键——添加到压缩文件(Bandzip) 2、自解压设置,填写完毕后点击“开......
  • Linux解压/压缩文件命令
    1、.tar解包:tarxvfFileName.tar打包:tarcvfFileName.tarDirName(注:tar是打包,不是压缩!)2、.gz解压1:gunzipFileName.gz解压2:gzip-dFileName.gz压缩:gzipFileName3、.tar.gz和.tgz解压:tarzxvfFileName.tar.gz压缩:tarzcvfFileName.tar.gzDirName4、.bz2解压1:bzip2-dFile......