On Jun 16, 2014, at 5:11 AM, Laszlo Ersek <ler...@redhat.com> wrote:

> On 06/16/14 08:14, Michael Casadevall wrote:
>> Hey all,
>> 
>> I've been working on porting TianoCore to KVM on AArch64, and I've
>> recently run into an issue which I'm hoping someone can help me to
>> debug. Recent proposed changes to KVM place the address space for
>> BootROMs and persistent storage from 0x0-0x8000000, with the early boot
>> code for Tiano startng at 0x0.
> 
> Looks like a spectacularly bad idea. The C standard guarantees that any
> pointer to a function, and any pointer to an object, will compare
> unequal to a null pointer. On edk2 platforms, null pointers have
> all-bits-zero representation. If you place an object at address zero,
> then the above guarantee is breached.
> 

Well PCs (and lots of other devices) have memory/ROM at address zero. In this 
case it is an assembly branch instruction that lives at zero, so no harm done 
to the C language. 

Dereferencing NULL is undefined behavior in C. While it is not pedantically 
defined in C a volatile variable can be used to write to address zero. There 
may be a real reason to do this, like to init the ECC. 

This is a good description of undefined behavior in C. 
http://blog.llvm.org/2011/05/what-every-c-programmer-should-know.html

Clang is very aggressive about dumping undefined behavior in the optimizer. 
~/work/Compiler>cat null.c
// test()
int test ()
{
   int *x = (int *)0;
  *x = 2;
   return *x;
}

~/work/Compiler>clang -S -Os null.c
~/work/Compiler>cat null.S
        .section        __TEXT,__text,regular,pure_instructions
        .globl  _test
_test:                                  ## @test
        .cfi_startproc
## BB#0:
        pushq   %rbp
Ltmp2:
        .cfi_def_cfa_offset 16
Ltmp3:
        .cfi_offset %rbp, -16
        movq    %rsp, %rbp
Ltmp4:
        .cfi_def_cfa_register %rbp
        ud2
        .cfi_endproc


.subsections_via_symbols

As you can see the compiler just punts and places a trap in the code. 


>> My problem is that when the FDF is set to
>> generate an image for this load location, it appears to create a
>> malformed FD file.
>> 
>> Under normal circumstances, the very first bits of the .fd file are a
>> branch instruction to the start of the PEI. This generates correctly
>> when the FDF is set to any BaseAddress that != 0x0.
>> 
>> For example:
>> 
>> Here's a known good image
>> $ hexdump
>> Build/AArch64Virtualization-KVM/DEBUG_ARMLINUXGCC/FV/KVM_EFI.fd | head
>> 0000000 01e2 1400 0000 0000 0000 0000 0000 0000
>> 0000010 e578 8c8c 8a3d 4f1c 3599 6189 c385 d32d
>> 
>> The same code, compiled with my updated FDF generates the following:
>> $ hexdump
>> Build/AArch64Virtualization-KVM/DEBUG_ARMLINUXGCC/FV/KVM_EFI.fd | head
>> 0000000 0000 0000 0000 0000 0000 0000 0000 0000
>> 0000010 e578 8c8c 8a3d 4f1c 3599 6189 c385 d32d
> 
> (In the second line of each of these dumps, you can see
> EFI_FIRMWARE_FILE_SYSTEM2_GUID. But this is just a side note, not
> particularly important.)
> 
>> 
>> I've tried and failed to locate the code responsible for writing out the
>> initial branch statement, so I'm hoping somewhere here can get me a
>> pointer on where to look. The relevant bit of my FDF is inline below.
>> 

https://svn.code.sf.net/p/edk2/code/trunk/edk2/BaseTools/Source/C/GenFv/GenFvInternalLib.c
 UpdateArmResetVectorIfNeeded()

This code patches the zero vector at the start of the FV. There is an assembly 
branch instruction to the SEC entry point, followed by the address of the PEI 
Core entry point. 

Thanks,

Andrew Fish

>> [FD.KVM_EFI]
>> BaseAddress   = 0x0000000|gArmTokenSpaceGuid.PcdFdBaseAddress  # KVM
>> assigns 0 - 0x8000000 for a BootROM
>> Size          = 0x8000000|gArmTokenSpaceGuid.PcdFdSize         # The
>> size in bytes of the FLASH Device
>> ErasePolarity = 1
>> 
>> # This one is tricky, it must be: BlockSize * NumBlocks = Size
>> BlockSize     = 0x00001000
>> NumBlocks     = 0x8000
>> 
>> As best I can tell, GenFds appears to be the relevant utility, but
>> nothing in the code jumps out as relevent, and I admit I'm completely
>> unfamiliar with this area of the tree.
> 
> Please save your build log and upload it somewhere. My guess is the
> following -- see "BaseTools/UserManuals/GenFds_Utility_Man_Page.rtf" --
> GenFv is likely called with --baseaddr=0 (equivalently, with -r 0),
> which leads the code to believe that --baseaddr has not been passed at
> all. See:
> 
> $ GenFv --help
> 
>  -r Address, --baseaddr Address
>                    Address is the rebase start address for drivers that
>                    run in Flash. It supports DEC or HEX digital format.
>                    If it is set to zero, no rebase action will be taken
> 
> And/or, please see GenVtf ("generate volume top file") too:
> 
> $ GenVtf --help
> 
>  -r BaseAddress,  --baseaddr BaseAddress
>                  BaseAddress is the starting address of Firmware Volume
>                  where Boot Strapped Image will reside.
> 
> main() in "BaseTools/Source/C/GenVtf/GenVtf.c" parses the value into
> "StartAddress1" and "StartAddress2" (which are set to zero initially),
> and passes them to GenerateVtfImage(). That function checks for zero
> values (at least in case of StartAddress2.)
> 
> GenFds (BaseTools/Source/Python/GenFds) seems to be a Python program
> that invokes both GenFv and GenVtf, and it appears to pass "-r" to both.
> 
> The above are not the exact cause of course, but I think they illustrate
> that storing the boot code such that the null pointer points to it is a
> Bad Idea (TM). I'm not sure about the alignment requirements (word?
> page?) -- can you try at the next "granule" above zero?
> 
> Thanks
> Laszlo
> 
> ------------------------------------------------------------------------------
> HPCC Systems Open Source Big Data Platform from LexisNexis Risk Solutions
> Find What Matters Most in Your Big Data with HPCC Systems
> Open Source. Fast. Scalable. Simple. Ideal for Dirty Data.
> Leverages Graph Analysis for Fast Processing & Easy Data Exploration
> http://p.sf.net/sfu/hpccsystems
> _______________________________________________
> edk2-devel mailing list
> edk2-devel@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/edk2-devel

------------------------------------------------------------------------------
HPCC Systems Open Source Big Data Platform from LexisNexis Risk Solutions
Find What Matters Most in Your Big Data with HPCC Systems
Open Source. Fast. Scalable. Simple. Ideal for Dirty Data.
Leverages Graph Analysis for Fast Processing & Easy Data Exploration
http://p.sf.net/sfu/hpccsystems
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/edk2-devel

Reply via email to