ICode9

精准搜索请尝试: 精确搜索
首页 > 系统相关> 文章详细

Arm64-UEFI 启动Linux内核-Image文件-PE格式

2022-03-05 15:01:03  阅读:476  来源: 互联网

标签:kernel WORD Image long header UEFI PE byte


 

背景介绍:

参考:

http://www.wowotech.net/linux_kenrel/UEFI.html

1、UEFI是什么鬼?

BIOS实际上就是IBM PC兼容机(多么古老的一个词汇啊)主板上的固件(firmware),这些固件可以在系统启动过程中初始化硬件,self test,加载bootloader或者OS kernel,并且能为OS提供一些基础的服务。

Intel提出来EFI(Extensible Firmware Interface)来取代BIOS interface。2005年,Intel终止了EFI规范的开发,替代它的是Unified EFI Forum负责的UEFI

 

2、UEFI关ARM什么事?

如果ARM仅仅是将目光放在移动(嵌入式)市场,那么UEFI当然不关ARM什么事情。

但是,在推出ARMv8以及64 bit架构的的处理器之后,ARM的野心已经不满足在移动市场上称王了。

 

3、UEFI如何定义系统的启动过程?

在UEFI规范中定义了BOOT manager,它会根据保存在NVRAM中的参数来决定如何加载 EFI Application

EFI Application 是 PE(Portable Executable )格式的文件。

PE格式 是一种二进制可执行文件的格式(在linux世界中,我们多半熟悉的是ELF格式),由微软开发,广泛应用在Windows平台上。

 

uefi 的boot manager --> PE 格式的 bootloader (Uboot) --> linux kernel ?  这样不够直观。PE 格式的 uboot 只是转接信息。

因此,linux kernel image自身也可以包装成一个EFI  application image,由boot manager直接加载,完成启动过程。

uefi 的boot manager --> PE 格式的 linux kernel .

 

PE格式-Linux内核Image

PE 格式

下面的图片是一个PE文件格式的示意图:

 

 

 

arm64 kernel image 生成PE格式

MS DOS头里面的内容,由 arch/arm64/kernel/head.S 填充。

head.S 内容

        __HEAD
_head:
        /*
         * DO NOT MODIFY. Image header expected by Linux boot-loaders.
         */
#ifdef CONFIG_EFI
        /*
         * This add instruction has no meaningful effect except that
         * its opcode forms the magic "MZ" signature required by UEFI.
         */
        add     x13, x18, #0x16
        b       primary_entry
#else
        b       primary_entry                   // branch to kernel start, magic
        .long   0                               // reserved
#endif
        .quad   0                               // Image load offset from start of RAM, little-endian
        le64sym _kernel_size_le                 // Effective size of kernel image, little-endian
        le64sym _kernel_flags_le                // Informative flags, little-endian
        .quad   0                               // reserved
        .quad   0                               // reserved
        .quad   0                               // reserved
        .ascii  ARM64_IMAGE_MAGIC               // Magic number
#ifdef CONFIG_EFI
        .long   pe_header - _head               // Offset to the PE header.

pe_header:
        __EFI_PE_HEADER
#else
        .long   0                               // reserved
#endif

其中 ARM64_IMAGE_MAGIC 是一个魔数,4 个字节, 其定义如下(代码位于arch/arm64/include/asm/image.h

#define ARM64_IMAGE_MAGIC    "ARM\x64"

上面,从 _head 到 pe_header 之间有  7*8 bytes + 4 bytes + 4bytes 

 

MS DOS 结构体

typedef struct _IMAGE_DOS_HEADER {      // DOS .EXE header
    WORD   e_magic;                     // MZ标记 0x5a4d             2 byte
    WORD   e_cblp;                      // 最后(部分)页中的字节数  2 byte
    WORD   e_cp;                        // 文件中的全部和部分页数  2 byte
    WORD   e_crlc;                      // 重定位表中的指针数   2 byte
    
    WORD   e_cparhdr;                   // 头部尺寸以段落为单位   2 byte
    WORD   e_minalloc;                  // 所需的最小附加段  2 byte
    WORD   e_maxalloc;                  // 所需的最大附加段        2 byte
    WORD   e_ss;                        // 初始的SS值(相对偏移量)         2 byte
    
    
    
    WORD   e_sp;                        // 初始的SP值  2 byte
    WORD   e_csum;                      // 补码校验值   2 byte
    WORD   e_ip;                        // 初始的IP值       2 byte
    WORD   e_cs;                        // 初始的SS值          2 byte
    
    
    
    
    WORD   e_lfarlc;                    // 重定位表的字节偏移量     2 byte
    WORD   e_ovno;                      // 覆盖号                     2 byte
    
    WORD   e_res[4];                    // 保留字                    8 bytes
    WORD   e_oemid;                     // OEM标识符(相对m_oeminfo)   2 byte
    WORD   e_oeminfo;                   // OEM信息                    2 byte
    
    
    WORD   e_res2[10];                  // 保留字                     10 * 2 bytes

    LONG   e_lfanew;                    // NT头(PE标记)相对于文件的偏移地址

  } IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;

这一结构体有  4 + 4 + 2*8 + 2* 8 + 3*8 = 7*8 + 4 + 4 个字节 

 

head.S 的 7*8 + 4 + 4 个字节 可以和 结构体的  7*8 + 4 + 4 个字节 一一匹配。 主要就是  e_lfanew 对应到 head.S 里面的 

 .long   pe_header - _head

 

pe header 和 arch/arm64/kernel/efi-header.S 内容

 

head.S 中 pe_header 后面跟的 __EFI_PE_HEADER 是一个宏定义,在  arch/arm64/kernel/efi-header.S 中,里面的内容和 PE 文件格式一一对应

        .macro  __EFI_PE_HEADER
        .long   PE_MAGIC
coff_header:
        .short  IMAGE_FILE_MACHINE_ARM64                // Machine
        .short  section_count                           // NumberOfSections
        .long   0                                       // TimeDateStamp
        .long   0                                       // PointerToSymbolTable
        .long   0                                       // NumberOfSymbols
        .short  section_table - optional_header         // SizeOfOptionalHeader
        .short  IMAGE_FILE_DEBUG_STRIPPED | \
                IMAGE_FILE_EXECUTABLE_IMAGE | \
                IMAGE_FILE_LINE_NUMS_STRIPPED           // Characteristics

optional_header:
        .short  PE_OPT_MAGIC_PE32PLUS                   // PE32+ format
        .byte   0x02                                    // MajorLinkerVersion
        .byte   0x14                                    // MinorLinkerVersion
        .long   __initdata_begin - efi_header_end       // SizeOfCode
        .long   __pecoff_data_size                      // SizeOfInitializedData
        .long   0                                       // SizeOfUninitializedData
        .long   __efistub_efi_pe_entry - _head          // AddressOfEntryPoint
        .long   efi_header_end - _head                  // BaseOfCode

extra_header_fields:
        .quad   0                                       // ImageBase
        .long   SEGMENT_ALIGN                           // SectionAlignment

……

 

标签:kernel,WORD,Image,long,header,UEFI,PE,byte
来源: https://www.cnblogs.com/zhangzhiwei122/p/15968036.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有