Message ID | 1403918735-30027-16-git-send-email-roy.franz@linaro.org |
---|---|
State | New |
Headers | show |
On Sat, 2014-06-28 at 02:25 +0100, Roy Franz wrote: > This patch adds a simple PE/COFF header in head.S. PE/COFF linker support > is not available for arm64, so a native build is not possible. Also, this > allows the binary to be both a PE/COFF EFI application, and a normal Image > file bootable like a Linux kernel. The arm and arm64 Linux kernels use the > same methodology to create a single image that is both an EFI application and > a zImage/Image file. This looks good to me. A few minor comments: Some of the whitespace is off (please use space and not hard tabs throughout) I think we could perhaps get rid of CONFIG_EFI_STUB at least at the arm64 subarch level. We don't in general support the same level of configurability in Xen as Linux -- it's mostly just a single configuration for everyone. It'd need to be retain at the arch level to cope with arm32 not doing efi, but removing it here would make things simpler I think? Would it be possible to find sort of link/reference to a spec for the header structs which you are adding and stick them in comments before each one please. > > Signed-off-by: Roy Franz <roy.franz@linaro.org> > --- > xen/arch/arm/arm64/head.S | 118 +++++++++++++++++++++++++++++++++++++++++++++- > xen/arch/arm/xen.lds.S | 1 + > 2 files changed, 117 insertions(+), 2 deletions(-) > > diff --git a/xen/arch/arm/arm64/head.S b/xen/arch/arm/arm64/head.S > index 2a13527..9b88aeb 100644 > --- a/xen/arch/arm/arm64/head.S > +++ b/xen/arch/arm/arm64/head.S > @@ -84,7 +84,7 @@ > #endif /* !CONFIG_EARLY_PRINTK */ > > /*.aarch64*/ > - > +#define CONFIG_EFI_STUB > /* > * Kernel startup entry point. > * --------------------------- > @@ -100,12 +100,24 @@ > */ > > .global start > +efi_stub_entry: /* Dummy symbol so we can compile before actual stub added */ > start: > +#ifdef CONFIG_EFI_STUB > /* > * DO NOT MODIFY. Image header expected by Linux boot-loaders. > */ > - b real_start /* branch to kernel start, magic */ > +efi_head: > + /* > + * This add instruction has no meaningful effect except that > + * its opcode forms the magic "MZ" signature of a PE/COFF file > + * that is required for UEFI applications. > + */ > + add x13, x18, #0x16 I love this hack ;-) Ian.
On Wed, Jul 2, 2014 at 5:02 AM, Ian Campbell <Ian.Campbell@citrix.com> wrote: > On Sat, 2014-06-28 at 02:25 +0100, Roy Franz wrote: >> This patch adds a simple PE/COFF header in head.S. PE/COFF linker support >> is not available for arm64, so a native build is not possible. Also, this >> allows the binary to be both a PE/COFF EFI application, and a normal Image >> file bootable like a Linux kernel. The arm and arm64 Linux kernels use the >> same methodology to create a single image that is both an EFI application and >> a zImage/Image file. > > This looks good to me. A few minor comments: > > Some of the whitespace is off (please use space and not hard tabs > throughout) I'll clean that up. > > I think we could perhaps get rid of CONFIG_EFI_STUB at least at the > arm64 subarch level. We don't in general support the same level of > configurability in Xen as Linux -- it's mostly just a single > configuration for everyone. It'd need to be retain at the arch level to > cope with arm32 not doing efi, but removing it here would make things > simpler I think? I agree. I don't think the arm64 stub needs to be configurable, as it should not affect non-stub users when it is enabled, and should be a fairly small amount of code. It will need to be disabled for arm32. > > Would it be possible to find sort of link/reference to a spec for the > header structs which you are adding and stick them in comments before > each one please. I will try to track down some documentation to link to. It may end up being a single link to a PDF (or even a microsoft Word document, since it is a Microsoft spec.) > >> >> Signed-off-by: Roy Franz <roy.franz@linaro.org> >> --- >> xen/arch/arm/arm64/head.S | 118 +++++++++++++++++++++++++++++++++++++++++++++- >> xen/arch/arm/xen.lds.S | 1 + >> 2 files changed, 117 insertions(+), 2 deletions(-) >> >> diff --git a/xen/arch/arm/arm64/head.S b/xen/arch/arm/arm64/head.S >> index 2a13527..9b88aeb 100644 >> --- a/xen/arch/arm/arm64/head.S >> +++ b/xen/arch/arm/arm64/head.S >> @@ -84,7 +84,7 @@ >> #endif /* !CONFIG_EARLY_PRINTK */ >> >> /*.aarch64*/ >> - >> +#define CONFIG_EFI_STUB >> /* >> * Kernel startup entry point. >> * --------------------------- >> @@ -100,12 +100,24 @@ >> */ >> >> .global start >> +efi_stub_entry: /* Dummy symbol so we can compile before actual stub added */ >> start: >> +#ifdef CONFIG_EFI_STUB >> /* >> * DO NOT MODIFY. Image header expected by Linux boot-loaders. >> */ >> - b real_start /* branch to kernel start, magic */ >> +efi_head: >> + /* >> + * This add instruction has no meaningful effect except that >> + * its opcode forms the magic "MZ" signature of a PE/COFF file >> + * that is required for UEFI applications. >> + */ >> + add x13, x18, #0x16 > > I love this hack ;-) > > Ian. >
diff --git a/xen/arch/arm/arm64/head.S b/xen/arch/arm/arm64/head.S index 2a13527..9b88aeb 100644 --- a/xen/arch/arm/arm64/head.S +++ b/xen/arch/arm/arm64/head.S @@ -84,7 +84,7 @@ #endif /* !CONFIG_EARLY_PRINTK */ /*.aarch64*/ - +#define CONFIG_EFI_STUB /* * Kernel startup entry point. * --------------------------- @@ -100,12 +100,24 @@ */ .global start +efi_stub_entry: /* Dummy symbol so we can compile before actual stub added */ start: +#ifdef CONFIG_EFI_STUB /* * DO NOT MODIFY. Image header expected by Linux boot-loaders. */ - b real_start /* branch to kernel start, magic */ +efi_head: + /* + * This add instruction has no meaningful effect except that + * its opcode forms the magic "MZ" signature of a PE/COFF file + * that is required for UEFI applications. + */ + add x13, x18, #0x16 + b real_start /* branch to kernel start */ +#else + b real_start /* branch to kernel start */ .long 0 /* reserved */ +#endif .quad 0 /* Image load offset from start of RAM */ .quad 0 /* reserved */ .quad 0 /* reserved */ @@ -116,7 +128,109 @@ start: .byte 0x52 .byte 0x4d .byte 0x64 +#ifdef CONFIG_EFI_STUB + .long pe_header - efi_head /* Offset to the PE header. */ +#else .word 0 /* reserved */ +#endif + +#ifdef CONFIG_EFI_STUB + .align 3 +pe_header: + .ascii "PE" + .short 0 +coff_header: + .short 0xaa64 // AArch64 + .short 2 // nr_sections + .long 0 // TimeDateStamp + .long 0 // PointerToSymbolTable + .long 1 // NumberOfSymbols + .short section_table - optional_header // SizeOfOptionalHeader + .short 0x206 // Characteristics. + // IMAGE_FILE_DEBUG_STRIPPED | + // IMAGE_FILE_EXECUTABLE_IMAGE | + // IMAGE_FILE_LINE_NUMS_STRIPPED +optional_header: + .short 0x20b // PE32+ format + .byte 0x02 // MajorLinkerVersion + .byte 0x14 // MinorLinkerVersion + .long __init_end_efi - real_start // SizeOfCode + .long 0 // SizeOfInitializedData + .long 0 // SizeOfUninitializedData + .long efi_stub_entry - efi_head // AddressOfEntryPoint + .long real_start - efi_head // BaseOfCode + +extra_header_fields: + .quad 0 // ImageBase + .long 0x200000 // SectionAlignment (2MByte) + .long 0x8 // FileAlignment + .short 0 // MajorOperatingSystemVersion + .short 0 // MinorOperatingSystemVersion + .short 0 // MajorImageVersion + .short 0 // MinorImageVersion + .short 0 // MajorSubsystemVersion + .short 0 // MinorSubsystemVersion + .long 0 // Win32VersionValue + + .long __init_end_efi - efi_head // SizeOfImage + + // Everything before the kernel image is considered part of the header + .long real_start - efi_head // SizeOfHeaders + .long 0 // CheckSum + .short 0xa // Subsystem (EFI application) + .short 0 // DllCharacteristics + .quad 0 // SizeOfStackReserve + .quad 0 // SizeOfStackCommit + .quad 0 // SizeOfHeapReserve + .quad 0 // SizeOfHeapCommit + .long 0 // LoaderFlags + .long 0x6 // NumberOfRvaAndSizes + + .quad 0 // ExportTable + .quad 0 // ImportTable + .quad 0 // ResourceTable + .quad 0 // ExceptionTable + .quad 0 // CertificationTable + .quad 0 // BaseRelocationTable + + // Section table +section_table: + + /* + * The EFI application loader requires a relocation section + * because EFI applications must be relocatable. This is a + * dummy section as far as we are concerned. + */ + .ascii ".reloc" + .byte 0 + .byte 0 // end of 0 padding of section name + .long 0 + .long 0 + .long 0 // SizeOfRawData + .long 0 // PointerToRawData + .long 0 // PointerToRelocations + .long 0 // PointerToLineNumbers + .short 0 // NumberOfRelocations + .short 0 // NumberOfLineNumbers + .long 0x42100040 // Characteristics (section flags) + + + .ascii ".text" + .byte 0 + .byte 0 + .byte 0 // end of 0 padding of section name + .long __init_end_efi - real_start // VirtualSize + .long real_start - efi_head // VirtualAddress + .long __init_end_efi - real_start // SizeOfRawData + .long real_start - efi_head // PointerToRawData + + .long 0 // PointerToRelocations (0 for executables) + .long 0 // PointerToLineNumbers (0 for executables) + .short 0 // NumberOfRelocations (0 for executables) + .short 0 // NumberOfLineNumbers (0 for executables) + .long 0xe0500020 // Characteristics (section flags) + .align 5 +#endif real_start: msr DAIFSet, 0xf /* Disable all interrupts */ diff --git a/xen/arch/arm/xen.lds.S b/xen/arch/arm/xen.lds.S index be55dad..62b9d5b 100644 --- a/xen/arch/arm/xen.lds.S +++ b/xen/arch/arm/xen.lds.S @@ -135,6 +135,7 @@ SECTIONS *(.xsm_initcall.init) __xsm_initcall_end = .; } :text + __init_end_efi = .; . = ALIGN(STACK_SIZE); __init_end = .;
This patch adds a simple PE/COFF header in head.S. PE/COFF linker support is not available for arm64, so a native build is not possible. Also, this allows the binary to be both a PE/COFF EFI application, and a normal Image file bootable like a Linux kernel. The arm and arm64 Linux kernels use the same methodology to create a single image that is both an EFI application and a zImage/Image file. Signed-off-by: Roy Franz <roy.franz@linaro.org> --- xen/arch/arm/arm64/head.S | 118 +++++++++++++++++++++++++++++++++++++++++++++- xen/arch/arm/xen.lds.S | 1 + 2 files changed, 117 insertions(+), 2 deletions(-)