-
Notifications
You must be signed in to change notification settings - Fork 49
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Signed-off-by: Daniel Maslowski <[email protected]>
- Loading branch information
Showing
4 changed files
with
122 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
package tools | ||
|
||
import ( | ||
"bytes" | ||
"errors" | ||
"fmt" | ||
|
||
"github.com/linuxboot/fiano/pkg/fmap" | ||
"github.com/linuxboot/fiano/pkg/uefi" | ||
"github.com/linuxboot/fiano/pkg/uefi/consts" | ||
) | ||
|
||
func getCorebootRegion(image []byte) (uint32, uint32, error) { | ||
in := bytes.NewReader(image) | ||
f, _, err := fmap.Read(in) | ||
if err != nil { | ||
return 0, 0, err | ||
} | ||
i := f.IndexOfArea("COREBOOT") | ||
if i < 0 { | ||
return 0, 0, errors.New("COREBOOT region not found") | ||
} | ||
return f.Areas[i].Offset, f.Areas[i].Size, nil | ||
} | ||
|
||
// CalcImageOffset returns the offset of a given uefi flash image | ||
func CalcImageOffset(image []byte, addr uint64) (uint64, error) { | ||
off, size, ifdErr := GetRegion(image, uefi.RegionTypeBIOS) | ||
if ifdErr == nil { | ||
return uint64(off+size) - consts.BasePhysAddr + addr, nil | ||
} | ||
// If no IFD is present we are not dealing with a full image, | ||
// but maybe a BIOS region only image. Attempt to parse coreboot fmap. | ||
var cbErr error | ||
off, size, cbErr = getCorebootRegion(image) | ||
// If it's not a proper coreboot image return the IFD error as this is more generic. | ||
if cbErr != nil { | ||
return 0, ifdErr | ||
} | ||
return uint64(off+size) - consts.BasePhysAddr + addr, nil | ||
} | ||
|
||
// GetRegion returns offset and size of the given region type. | ||
func GetRegion(image []byte, regionType uefi.FlashRegionType) (uint32, uint32, error) { | ||
if _, err := uefi.FindSignature(image); err != nil { | ||
return 0, 0, err | ||
} | ||
flash, err := uefi.NewFlashImage(image) | ||
if err != nil { | ||
return 0, 0, err | ||
} | ||
if flash.IFD.Region.FlashRegions[regionType].Valid() { | ||
offset := flash.IFD.Region.FlashRegions[regionType].BaseOffset() | ||
size := flash.IFD.Region.FlashRegions[regionType].EndOffset() - offset | ||
return offset, size, nil | ||
} | ||
return 0, 0, fmt.Errorf("couldn't find region %d", regionType) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
package consts | ||
|
||
// CalculatePhysAddrFromTailOffset calculates the physical address (address to a | ||
// region mapped from the SPI chip) using an offset towards down, relatively | ||
// to BasePhysAddr. | ||
// | ||
// Examples: | ||
// CalculatePhysAddrFromTailOffset(0x01) == 0xffffffff | ||
// CalculatePhysAddrFromTailOffset(0x40) == 0xffffffc0 | ||
func CalculatePhysAddrFromTailOffset(offset uint64) uint64 { | ||
return BasePhysAddr - offset | ||
} | ||
|
||
// CalculateTailOffsetFromPhysAddr calculates the offset (towards down, relatively | ||
// to BasePhysAddr) of the physical address (address to a region mapped from | ||
// the SPI chip). | ||
// | ||
// This is the reverse function to CalculatePhysAddrFromTailOffset() | ||
// | ||
// Examples: | ||
// CalculateTailOffsetFromPhysAddr(0xffffffff) == 0x01 | ||
// CalculateTailOffsetFromPhysAddr(0xffffffc0) == 0x40 | ||
func CalculateTailOffsetFromPhysAddr(physAddr uint64) uint64 { | ||
return BasePhysAddr - physAddr | ||
} | ||
|
||
// CalculateOffsetFromPhysAddr calculates the offset within an image | ||
// of the physical address (address to a region mapped from | ||
// the SPI chip). | ||
// | ||
// Examples: | ||
// CalculateOffsetFromPhysAddr(0xffffffff, 0x1000) == 0xfff | ||
// CalculateOffsetFromPhysAddr(0xffffffc0, 0x1000) == 0xfc0 | ||
func CalculateOffsetFromPhysAddr(physAddr uint64, imageSize uint64) uint64 { | ||
startAddr := BasePhysAddr - imageSize | ||
return physAddr - startAddr | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
package consts | ||
|
||
const ( | ||
// BasePhysAddr is the absolute physical address where the firmware image ends. | ||
// | ||
// See Figure 2.1 in https://www.intel.com/content/dam/www/public/us/en/documents/guides/fit-bios-specification.pdf | ||
// | ||
// Note: A firmware image grows towards lower addresses. So an image will be mapped to addresses: | ||
// [ BasePhysAddr-length .. BasePhysAddr ) | ||
// | ||
// Note: SPI chip is mapped into this region. So we actually work directly with data of the SPI chip | ||
// | ||
// See also CalculatePhysAddrOfOffset(). | ||
BasePhysAddr = 1 << 32 // "4GB" | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
package consts | ||
|
||
var ( | ||
// HPSignedFileMagic is the magic used to detect if the firmware is actually | ||
// an HP signed container-file (so it's required to extract/find | ||
// the firmware image first). | ||
HPSignedFileMagic = []byte(`--=</Begin HP Signed File Fingerprint\>=--`) | ||
|
||
// HPImageMagic is the magic used to find the beginning of the real | ||
// firmware image inside of a HP signed container-file | ||
HPImageMagic = []byte(`HPIMAGE`) | ||
) |