public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: Rafael Machado <rafaelrodrigues.machado@gmail.com>
To: "Kinney, Michael D" <michael.d.kinney@intel.com>,
	Andrew Fish <afish@apple.com>
Cc: "edk2-devel@lists.01.org" <edk2-devel@lists.01.org>
Subject: Re: Sec and Reset vector
Date: Fri, 04 Nov 2016 22:19:26 +0000	[thread overview]
Message-ID: <CACgnt79oZZqgTDDDx=CcXuM6XjEwnP7OzAcsybAosy837ew0AQ@mail.gmail.com> (raw)
In-Reply-To: <E92EE9817A31E24EB0585FDF735412F564840A09@ORSMSX113.amr.corp.intel.com>

All the answers were really detailed and I agree with Andrew. These answers
are a great help when we are learning.

Thanks a lot guys. I learn a lot with this community.

Thanks and regards
Rafael

Em sex, 4 de nov de 2016 19:28, Kinney, Michael D <
michael.d.kinney@intel.com> escreveu:

> Rafael,
>
> The first instruction executed for IA32 SEC phase is typically 16-bytes
> from
> the end of the Firmware Device (FD) image generated by a build.
>
> If you look at QuarkPlatformPkg/Quark.dsc as an example build, it generates
> an 8MB  file called Quark.FD.  The reset vector is 16-bytes from the end of
> that file.  The reset vector and rest of SEC code are all in a special FFS
> file
> known at the Volume Top File(VFT).
>
> The source code for the reset vector is in the file:
>
>         UefiCpuPkg/SecCore/Ia32/ResetVector.nasmb
>
> This source file contains the code that fills the last 0x40 bytes of the
> VTF
> which is also the last 0x40 bytes of Quark.FD.
>
> The build tools do some special fixups on this file, so 16-bit relative JMP
> instruction at line 79 is fixed up to jump to the symbol _ModuleEntryPoint.
>
>         ResetHandler:
>             nop
>             nop
>         ApStartup:
>             ;
>             ; Jmp Rel16 instruction
>             ; Use machine code directly in case of the assembler
> optimization
>             ; SEC entry point relative address will be fixed up by some
> build tool.
>             ;
>             ; Typically, SEC entry point is the function
> _ModuleEntryPoint() defined in
>             ; SecEntry.asm
>             ;
>             DB      0e9h
>             DW      -3
>
> For Quark.FD, _ModuleEntryPoint is from the PlatformSecLib library at:
>
>         QuarkPlatformPkg/Library/PlatformSecLib
>
> Specifically Line l5 of the file:
>
>         QuarkPlatformPkg/Library/PlatformSecLib/Ia32/Flat32.asm
>
> _ModuleEntryEntryPoint starts in 16-bit real mode and transitions to
> 32-bit protected mode, initializes ESRAM to be used as a stack, and
> transfers control to the C function PlatformSecLibStartup() at line 220.
> The goal is to minimize the amount of assembly code and get into C code
> as quickly as possible.
>
> The PlatformSecLibStartup() function implementation is in the same
> PlatformSecLib library at line 68 of the file:
>
>         QuarkPlatformPkg/Library/PlatformSecLib/PlatformSecLib.c
>
> Best regards,
>
> Mike
>
> > -----Original Message-----
> > From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] On Behalf Of
> Rafael Machado
> > Sent: Friday, November 4, 2016 12:34 PM
> > To: Andrew Fish <afish@apple.com>
> > Cc: edk2-devel@lists.01.org
> > Subject: Re: [edk2] Sec and Reset vector
> >
> > Hi Andrew
> >
> > Maybe my question was not clear.
> > But thanks for the information you provided.
> >
> > I think we can simplify what I need based on your last comment. You told:
> >
> > *"The .com file contains the hardware real mode reset vector
> (0xFFFFFFF0).
> > So execution starts up high. The 1st far jmp you do gets you running in
> the
> > 0x000F**** range (the ROM is aliased to the old PC address)"*
> >
> > How could I find the .com file inside the dump of a bios (I have used
> > DediProg to get the dump)?
> > I'm hunting the first far jump the firmware has.
> >
> > Thanks
> > Rafael
> >
> > Em sex, 4 de nov de 2016 às 16:50, Andrew Fish <afish@apple.com>
> escreveu:
> >
> > > On Nov 4, 2016, at 10:48 AM, Rafael Machado <
> > > rafaelrodrigues.machado@gmail.com> wrote:
> > >
> > > Hi everyone
> > >
> > > Thanks Andrew and Marvin for the clarification.
> > > Now things start to make sense.
> > >
> > > But I was still not able to understand were things start on a real
> binary
> > >
> > >
> > > Rafeal,
> > >
> > > I'm not sure what you are asking?
> > >
> > > The .com file contains the hardware real mode reset vector
> (0xFFFFFFF0).
> > > So execution starts up high. The 1st far jmp you do gets you running
> in the
> > > 0x000F**** range (the ROM is aliased to the old PC address). The .com
> file
> > > is patched with the entry point of the PE/COFF (or TE) .efi and just
> jumps
> > > into that code. At some point early in the processes the code
> transitions
> > > to protected mode and starts executing up high again (only a small
> part of
> > > the ROM is aliased down low).
> > >
> > > The SEC PE/COFF  (or TE) .efi image entry point can be found in the
> > > PE/COFF (or TE) header that is part of that image. This is how the PEI
> Core
> > > passes control to PEIMs, and it is also what the PEI/DXE/SMM cores use
> to
> > > pass control to images that are loaded into memory.
> > >
> > > There is a library that given a PE/COFF or TE image will return the
> entry
> > > point.
> > >
> > >
> > >
> >
> https://github.com/tianocore/edk2/blob/master/MdePkg/Library/BasePeCoffGetEntryPointL
> > ib/PeCoffGetEntryPoint.c#L44
> > > RETURN_STATUS
> > > EFIAPI
> > > PeCoffLoaderGetEntryPoint (
> > > IN VOID *Pe32Data,
> > > OUT VOID **EntryPoint
> > > )
> > > {
> > > EFI_IMAGE_DOS_HEADER *DosHdr;
> > > EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr;
> > > ASSERT (Pe32Data != NULL);
> > > ASSERT (EntryPoint != NULL);
> > > DosHdr = (EFI_IMAGE_DOS_HEADER *)Pe32Data;
> > > if (DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE) {
> > > //
> > > // DOS image header is present, so read the PE header after the DOS
> image
> > > header.
> > > //
> > > Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)((UINTN) Pe32Data + (UINTN)
> > > ((DosHdr->e_lfanew) & 0x0ffff));
> > > } else {
> > > //
> > > // DOS image header is not present, so PE header is at the image base.
> > > //
> > > Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)Pe32Data;
> > > }
> > > //
> > > // Calculate the entry point relative to the start of the image.
> > > // AddressOfEntryPoint is common for PE32 & PE32+
> > > //
> > > if (Hdr.Te->Signature == EFI_TE_IMAGE_HEADER_SIGNATURE) {
> > > *EntryPoint = (VOID *)((UINTN)Pe32Data +
> (UINTN)(Hdr.Te->AddressOfEntryPoint
> > > & 0x0ffffffff) + sizeof(EFI_TE_IMAGE_HEADER) - Hdr.Te->StrippedSize);
> > > return RETURN_SUCCESS;
> > > } else if (Hdr.Pe32->Signature == EFI_IMAGE_NT_SIGNATURE) {
> > > *EntryPoint = (VOID *)((UINTN)Pe32Data +
> (UINTN)(Hdr.Pe32->OptionalHeader.
> > > AddressOfEntryPoint & 0x0ffffffff));
> > > return RETURN_SUCCESS;
> > > }
> > > return RETURN_UNSUPPORTED;
> > > }
> > >
> > >
> > > Thanks,
> > >
> > > Andrew Fish
> > >
> > > On the attached image ResetVectorCoreboot.png we have the entry point
> on a
> > > coreboot image.
> > > What I would like to do is to find something similar to this on a UEFI
> Bios
> > > image.
> > >
> > > Based on Marvin's idea, I got the UEFI Tool and star to check the
> image I
> > > have.
> > > On the attached image TopFileInfo.png we can see to Top File mentioned
> by
> > > Andrew.
> > > The details about the Top File are these:
> > >
> > >  Offset: FF8018h
> > >
> > >  File GUID: 1BA0062E-C779-4582-8566-336AE8F78F09
> > >
> > >  Type: 03h
> > >
> > >  Attributes: 08h
> > >
> > >  Full size: 7FE8h (32744)
> > >
> > >  Header size: 18h (24)
> > >
> > >  Body size: 7FD0h (32720)
> > >
> > >  Tail size: 0h (0)
> > >
> > >  State: F8h
> > >
> > >  Header checksum: 99h, valid
> > >
> > >  Data checksum: AAh, valid
> > >
> > >  Header memory address: FFFF8018h
> > >
> > >  Data memory address: FFFF8030h
> > >
> > >  Compressed: No
> > >
> > >  Fixed: No
> > >
> > >
> > > I tried to find something similar to what I see at the coreboot image,
> but
> > > didn't find anything. Neither on the PE Image section, not on the Raw
> image
> > > sections.
> > >
> > >
> > > Any idea about how could I find the entry point of sec in this case?
> > >
> > > Thanks and Regards
> > > Rafael R. Machado
> > >
> > >
> > > Em sáb, 22 de out de 2016 às 16:19, Andrew Fish <afish@apple.com>
> > > escreveu:
> > >
> > > On Oct 22, 2016, at 10:03 AM, Marvin H?user <
> Marvin.Haeuser@outlook.com>
> > > wrote:
> > >
> > > Hey Rafael,
> > >
> > > There actually is some generic SEC code in UefiCpuPkg you might want to
> > > take a look at. It's generic because it does not have "Intel NDA" code,
> > > such as CAR (Cache-As-RAM) etc.
> > > The Reset Vector may or may not be part of SecCore. It's either
> embedded
> > > within the SecCore module, or a separate file in the FFS. You can
> check the
> > > start/end address of the modules (e.g. with UEFITool) and find the
> Reset
> > > Vector file that way.
> > >
> > >
> > > Rafael,
> > >
> > > There is some strange construction things going on with the SEC for
> X86.
> > >
> > > If you look in the FDF file you will see that the SEC is a PE/COFF (or
> TE)
> > > image and a raw binary for the 16-bit real mode reset vector code.
> > >
> > >
> > >
> > >
> >
> https://github.com/tianocore/edk2/blob/master/Vlv2TbltDevicePkg/PlatformPkg.fdf#L876
> > > [Rule.Common.SEC]
> > > FILE SEC = $(NAMED_GUID) RELOCS_STRIPPED {
> > > PE32 PE32 Align = 8 $(INF_OUTPUT)/$(MODULE_NAME).efi
> > > RAW BIN Align = 16 |.com
> > > }
> > >
> > > The .com files are constructed from *.nasmb, *.asm16, or *.S16 files.
> > > https://github.com/tianocore/edk2/tree/master/UefiCpuPkg/SecCore/Ia32
> > >
> > > Special extensions are needed to have special build rules. The build
> rules
> > > are here:
> > >
> > >
> > >
> >
> https://github.com/tianocore/edk2/blob/master/BaseTools/Conf/build_rule.template#L480
> > > Look at the [Masm16-Code-File] and [Nasm-to-Binary-Code-File] rules.
> > >
> > > The build tools also do some magic to stitch the .com and PE/COFF (TE)
> > > file together.
> > >
> > >
> > >
> >
> https://github.com/tianocore/edk2/blob/master/UefiCpuPkg/SecCore/Ia32/ResetVec.nasmb#
> > L46
> > > ;
> > > ; Pointer to the entry point of the PEI core
> > > ; It is located at 0xFFFFFFE0, and is fixed up by some build tool
> > > ; So if the value 8..1 appears in the final FD image, tool failure
> occurs.
> > > ;
> > > PeiCoreEntryPoint: DD 87654321h
> > >
> > >
> > > The reason you need special build rules is it is really hard to get
> code
> > > at the end of a PE/COFF file, so you need a stripped binary for the
> reset
> > > vector.
> > >
> > > The next problem is how do you get the FV File to be at the end of the
> FV
> > > (that is usually free space). The PI spec defines that if an FFS file
> has
> > > the File GUID of gEfiFirmwareVolumeTopFileGuid then it gets place at
> the
> > > end of the FV. Thus the X86 SEC must have this file guid. This also
> > > triggers the magic behavior to stitch the .com and PE/COFF together.
> > >
> > >
> > >
> https://github.com/tianocore/edk2/blob/master/UefiCpuPkg/SecCore/SecCore.inf#L25
> > > FILE_GUID = 1BA0062E-C779-4582-8566-336AE8F78F09
> > >
> > >
> > >
> > > For ARM things are much simpler. The FV reserves 16-bytes at the start
> of
> > > the volume for the reset vector. If the build tools see an FV has an
> ARM
> > > SEC it can patch in a branch to the SEC PE/COFF (TE) entry point (going
> > > from memory hopefully I did not botch that).
> > >
> > >
> > >
> > >
> >
> https://github.com/tianocore/edk2/blob/master/MdePkg/Include/Pi/PiFirmwareVolume.h#L1
> > 10
> > > ///
> > > /// The first 16 bytes are reserved to allow for the reset vector of
> > > /// processors whose reset vector is at address 0.
> > > ///
> > > UINT8 ZeroVector[16];
> > >
> > >
> > >
> > > PS.: Seems like inline images are not supported by the mailing list
> (or is
> > > it my error?). Either way, I do not see the image in my mail client
> > > (Outlook 2016).
> > >
> > >
> > > I don't see the image in my macOS Mail client.
> > >
> > > Thanks,
> > >
> > > Andrew Fish
> > >
> > >
> > > Regards,
> > > Marvin.
> > >
> > > -----Original Message-----
> > > From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org
> > > <edk2-devel-bounces@lists.01.org>] On Behalf Of
> > > Rafael Machado
> > > Sent: Saturday, October 22, 2016 6:28 PM
> > > To: edk2-devel@lists.01.org
> > > Subject: [edk2] Sec and Reset vector
> > >
> > > Hi eveyrone
> > >
> > > I'm doing some studies on edk2 and coreboot, but I'm having some
> questions
> > > that I believe you can help.
> > >
> > > On the journey to try to understand things since the beginning, so they
> > > make
> > > sense in future, I'm trying to understand how does the Initial phases
> of
> > > UEFI
> > > / PI firmware work. To do that I got a bios image and start to reverse
> it
> > > to
> > > check the modules and everything present at that bios. Now I
> understand, at
> > > least the basics, about DXE and PEI phase.
> > >
> > > The main question that I have now is about the SEC phase.
> > > To try to understand the SEC phase I tried to reverse this firmware so
> I
> > > could
> > > check the reset vector's first jump or something like that.
> > > The surprise I have is that I was not able to find this code.
> > >
> > > To be sure I was reversing on the correct way I generated a coreboot
> image.
> > > On the image below we can see the initial code of a firmware generated
> > > using coreboot
> > >
> > > [image: pasted1]
> > >
> > > But at the UEFI firmware I'm studying I'm not able to find anything
> > > similar to
> > > that.
> > > My guess before starting this was that at least the SEC initial code
> > > should be
> > > similar to the legacy way of doing things, a jmp at 0xfff:fff0 and
> after
> > > that the
> > > magic should get started with all uefi phases.
> > >
> > > Could someone please give me some light on that?
> > >
> > >
> > > Thanks and Regards
> > > Rafael R. Machado
> > > _______________________________________________
> > > edk2-devel mailing list
> > > edk2-devel@lists.01.org
> > > https://lists.01.org/mailman/listinfo/edk2-devel
> > >
> > > _______________________________________________
> > > edk2-devel mailing list
> > > edk2-devel@lists.01.org
> > > https://lists.01.org/mailman/listinfo/edk2-devel
> > >
> > >
> > > _______________________________________________
> > > edk2-devel mailing list
> > > edk2-devel@lists.01.org
> > > https://lists.01.org/mailman/listinfo/edk2-devel
> > >
> > >
> > _______________________________________________
> > edk2-devel mailing list
> > edk2-devel@lists.01.org
> > https://lists.01.org/mailman/listinfo/edk2-devel
>


  reply	other threads:[~2016-11-04 22:19 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-10-22 16:28 Sec and Reset vector Rafael Machado
2016-10-22 17:03 ` Marvin H?user
2016-10-22 18:19   ` Andrew Fish
2016-11-04 17:48     ` Rafael Machado
2016-11-04 17:50       ` Rafael Machado
2016-11-04 18:50       ` Andrew Fish
2016-11-04 19:33         ` Rafael Machado
2016-11-04 19:59           ` Laszlo Ersek
2016-11-04 21:18             ` Andrew Fish
2016-11-04 21:28           ` Kinney, Michael D
2016-11-04 22:19             ` Rafael Machado [this message]
2017-03-29 19:05               ` Rafael Machado

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-list from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CACgnt79oZZqgTDDDx=CcXuM6XjEwnP7OzAcsybAosy837ew0AQ@mail.gmail.com' \
    --to=devel@edk2.groups.io \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox