首页 > 其他分享 >zImage的压缩、解压以及性能对比

zImage的压缩、解压以及性能对比

时间:2023-05-17 12:46:30浏览次数:32  
标签:解压 data 压缩 boot compressed zImage arch arm piggy

关键词:Image,zImage,piggy,gzip,lzo,xz,lzma等等。

1. zImage的压缩

zImage是Image经过压缩后,加上解压缩头后生成的文件:Image -> piggy_data -> piggy.o ->vmlinux(compressed) -> zImage。

Image经过压缩生成piggy_data:

cmd_arch/arm/boot/compressed/piggy_data := { cat arch/arm/boot/compressed/../Image | lzop -9; printf \\070\\266\\126\\000; } > arch/arm/boot/compressed/piggy_data

piggy.o包含了piggy_data数据:

/* SPDX-License-Identifier: GPL-2.0 */
    .section .piggydata,#alloc
    .globl    input_data
input_data:
    .incbin    "arch/arm/boot/compressed/piggy_data"
    .globl    input_data_end
input_data_end:

cpmpressed/vmlinux包含了piggy.o:

cmd_arch/arm/boot/compressed/vmlinux := arm-none-linux-gnueabihf-ld  -EL   --defsym _kernel_bss_size=100900 --no-undefined -X
-T arch/arm/boot/compressed/vmlinux.lds
arch/arm/boot/compressed/head.o
arch/arm/boot/compressed/piggy.o
arch/arm/boot/compressed/misc.o
arch/arm/boot/compressed/decompress.o
arch/arm/boot/compressed/string.o
arch/arm/boot/compressed/hyp-stub.o
arch/arm/boot/compressed/lib1funcs.o
arch/arm/boot/compressed/ashldi3.o
arch/arm/boot/compressed/bswapsdi2.o
-o arch/arm/boot/compressed/vmlinux

从compressed/vmlinux.lds可以看出piggydata段放在rodata之后:

OUTPUT_ARCH(arm)
ENTRY(_start)
SECTIONS
{
  /DISCARD/ : {
    *(.ARM.exidx*)
    *(.ARM.extab*)
    *(.data)
  }
  . = 0;
  _text = .;
  .text : {
    _start = .;
    *(.start)
    *(.text)
    *(.text.*)
    *(.fixup)
    *(.gnu.warning)
    *(.glue_7t)
    *(.glue_7)
  }
  .table : ALIGN(4) {
    _table_start = .;
    LONG((2))
    LONG((0x5a534c4b))
    LONG((__piggy_size_addr - _start))
    LONG((_kernel_bss_size))
    LONG(0)
    _table_end = .;
  }
  .rodata : {
    *(.rodata)
    *(.rodata.*)
    *(.data.rel.ro)
  }
  .piggydata : {
    *(.piggydata)
    __piggy_size_addr = . - 4;
  }
  . = ALIGN(4);
  _etext = .;
  .got.plt : { *(.got.plt) }
  _got_start = .;
  .got : { *(.got) }
  _got_end = .;
  .pad : { BYTE(0); . = ALIGN(8); }
  _edata = .;
  .image_end (NOLOAD) : {
    _edata_real = .;
  }
  _magic_sig = (0x016f2818);
  _magic_start = (_start);
  _magic_end = (_edata);
  _magic_table = (_table_start - _start);
  . = ALIGN(8);
  __bss_start = .;
  .bss : { *(.bss) }
  _end = .;
  . = ALIGN(8);
  .stack : { *(.stack) }
...
}
ASSERT(_edata_real == _edata, "error: zImage file size is incorrect");

从compressed/vmlinux中拷贝zImage:

cmd_arch/arm/boot/zImage := arm-none-linux-gnueabihf-objcopy -O binary -R .comment -S  arch/arm/boot/compressed/vmlinux arch/arm/boot/zImage

2. zImage的解压

 由compressed/vmlinux.lds可知,zImage启动从arch/arm/boot/compressed/head.S中start开始:

start
  ->__hyp_stub_install
  ->not_angel
  ->restart   ->wont_overwrite     ->not_relocated--清空bss段,并配置好C执行环境。r0-kernel输出起始地址;r1/r2-分配内存的其实和结束地址;r3-架构类型ID。     ->decompress_kernel--对内核进行解压。       ->arch_decomp_setup       ->do_decompress         ->__decompress           ->unlzo--调用对应的解压缩算法进行解压。 ->cache_clean_flush--刷新并清空cache。 ->cache_off--关闭cache。 ->__enter_kernel--准备好寄存器跳转到解压后的内核。

decompress_kernel是解压Image入口:

  • output_start是指向zImage起始地址+TEXT_OFFSET的地址,对于0x80000000来说即为0x80008000。
  • free_mem_ptr_p和free_mem_ptr_end_p指向分配的一段64KB空间起始和结束地址,给compressed中malloc/free使用。
  • arch_id为架构ID,此为0x80004000。
void
decompress_kernel(unsigned long output_start, unsigned long free_mem_ptr_p,
        unsigned long free_mem_ptr_end_p,
        int arch_id)
{
    int ret;

    output_data        = (unsigned char *)output_start;
    free_mem_ptr        = free_mem_ptr_p;
    free_mem_end_ptr    = free_mem_ptr_end_p;
    __machine_arch_type    = arch_id;

    arch_decomp_setup();

    putstr("Uncompressing Linux...");
    ret = do_decompress(input_data, input_data_end - input_data,
                output_data, error);--input_data和input_data_end实在piggy.S中定义的piggy_data起始和结束地址。此处将piggy_data解压到TEXT_OFFSET之下那个的地方。
    if (ret)
        error("decompressor returned an error");
    else
        putstr(" done, booting the kernel.\n");
}

__enter_kernel未进入内核做准备,然后跳转到解压结果首地址。

r0为0,;r1架构编号;r2位atags指针。r4保存解压后内核跳转地址,最后跳转到解压后的内核。

__enter_kernel:
        mov    r0, #0            @ must be 0
        mov    r1, r7            @ restore architecture number
        mov    r2, r8            @ restore atags pointer
 ARM(        mov    pc, r4        )    @ call kernel
 M_CLASS(    add    r4, r4, #1    )    @ enter in Thumb mode for M class
 THUMB(        bx    r4        )    @ entry point is always ARM for A/R classes

3. 不同算法性能对比

在一FPGA环境下测试不同解压算法的耗时:

解压类型 Gzip LZMA XZ LZO LZ4
镜像大小 Image 17966904
zImage 7320936
Image 17966904
zImage 5037832
Image 17966904
zImage 4883408
Image 17966904
zImage 79859524
Image 17966904

zImage 8538088
耗时(秒) 188 1812 1146 56 142
由上可知,在解压速度慢的FPGA环境下,LZO是最合适的算法。如果对于占用空间要求较高,XZ和LZMA比较合适。

标签:解压,data,压缩,boot,compressed,zImage,arch,arm,piggy
From: https://www.cnblogs.com/arnoldlu/p/17408102.html

相关文章

  • dpkg命令用法、Ubuntu下deb包的解压、打包、安装、卸载及常用命令参数
    dpkg命令的用法不带图简装:https://blog.csdn.net/wanghuohuo13/article/details/78916821?ops_request_misc=&request_id=&biz_id=102&utm_term=dpkg&utm_medium=distribute.pc_search_result.none-task-blog-2allsobaiduweb~default-6-.first_rank_v2_pc_rank_v29&am......
  • C# 使用7z压缩
    项目中,直接获取7z的项目Install-PackageSevenZipSharp-Version0.64.0然后,下载7z.dll https://github.com/gdoujkzz/7zdll 然后,项目会用SevenZipSharp的方法调用,7z.dll,实现对文件的7z算法压缩。///<summary>///7z压缩///</summary>publicclassR7z{......
  • C#支持格式最多的解压缩开源库SharpCompress
    stringarchivePath="path/to/";stringextractPath="path/to/extract/folder";string[]filesRar=Directory.GetFiles(archivePath,"*.RAR");foreach(variteminfilesRar){using(St......
  • tomcat 启用Gzip 压缩进行优化
    <Connector...compression="1400"noCompressionUserAgents="gozilla,traviata"compressableMimeType="text/html,text/xml,text/plain,text/css,text/javascript"/>[url]http://stackoverflow.com/questions/11486745/referencing-......
  • Delphi XE2 新增 System.Zip 单元, 可用一句话压缩整个文件夹了
    单元内主要就是TZipFile类,最方便使用的是它的类方法:TZipFile.ExtractZipFile()   //解压Zip文件到指定文件夹TZipFile.IsValid()       //判断指定文件是否是有效的Zip文件TZipFile.ZipDirectoryContents()//压缩指定路径下的所有文件测试:u......
  • 关于 Delphi 中流的使用 压缩与解压缩的函数
    unitUnit1;interfaceuses Windows,Messages,SysUtils,Variants,Classes,Graphics,Controls,Forms, Dialogs,StdCtrls;type TForm1=class(TForm)  Button1:TButton;  Button2:TButton;  procedureButton1Click(Sender:TObject); ......
  • Windows的Mysql5.7社区版的安装详细操作,从无到有,安装配置一条龙服务。(压缩包自行安装,
    换了一个电脑,所有软件、环境都得重新来安装一次,安装到Mysql的时候,发现网上有两种安装方式,一种是Mysql的压缩包安装方式,这种方式直接到官网下载Mysql的压缩包,解压之后做些配置就可以了,另一种是Mysql的Installer一站式的安装,这种方法步骤相对来说少点,但是要先安装个Installer在......
  • 代码压缩
    JS代码压缩有哪些策略去除换行,去除空白字符长变量变成短变量预计算见terser更多策略配置webpack中使用terser-webpack-plugin进行代码压缩tersercompress:{ drop_console:true//去除打包以后代码中的console}......
  • java笔记_10_文件压缩Zip并加密(Zip4j)
    1、添加依赖Maven仓库地址:https://mvnrepository.com/artifact/net.lingala.zip4j/zip4j<!--压缩--><dependency><groupId>net.lingala.zip4j</groupId><artifactId>zip4j</artifactId>......
  • Vue2没有`public`文件夹,该怎么建资源文件,编译后不被压缩
    在Vue2项目中,如果没有`public`文件夹,可以在项目根目录下创建一个`static`文件夹来存放静态资源文件,如JS、CSS、图片等。 如果你想在打包后不压缩JS文件,并且这个JS文件是在HTML中通过`script`标签引用的,可以按照以下步骤进行操作: 1.在`static`文件夹下创建一个`js`文件夹,并......