Skip to content

Commit d2fb1ee

Browse files
committed
WIP port pkgs from CSS
Signed-off-by: Daniel Maslowski <[email protected]>
1 parent 3819483 commit d2fb1ee

File tree

4 files changed

+122
-0
lines changed

4 files changed

+122
-0
lines changed

pkg/tools/ifd.go

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
package tools
2+
3+
import (
4+
"bytes"
5+
"errors"
6+
"fmt"
7+
8+
"github.com/linuxboot/fiano/pkg/fmap"
9+
"github.com/linuxboot/fiano/pkg/uefi"
10+
"github.com/linuxboot/fiano/pkg/uefi/consts"
11+
)
12+
13+
func getCorebootRegion(image []byte) (uint32, uint32, error) {
14+
in := bytes.NewReader(image)
15+
f, _, err := fmap.Read(in)
16+
if err != nil {
17+
return 0, 0, err
18+
}
19+
i := f.IndexOfArea("COREBOOT")
20+
if i < 0 {
21+
return 0, 0, errors.New("COREBOOT region not found")
22+
}
23+
return f.Areas[i].Offset, f.Areas[i].Size, nil
24+
}
25+
26+
// CalcImageOffset returns the offset of a given uefi flash image
27+
func CalcImageOffset(image []byte, addr uint64) (uint64, error) {
28+
off, size, ifdErr := GetRegion(image, uefi.RegionTypeBIOS)
29+
if ifdErr == nil {
30+
return uint64(off+size) - consts.BasePhysAddr + addr, nil
31+
}
32+
// If no IFD is present we are not dealing with a full image,
33+
// but maybe a BIOS region only image. Attempt to parse coreboot fmap.
34+
var cbErr error
35+
off, size, cbErr = getCorebootRegion(image)
36+
// If it's not a proper coreboot image return the IFD error as this is more generic.
37+
if cbErr != nil {
38+
return 0, ifdErr
39+
}
40+
return uint64(off+size) - consts.BasePhysAddr + addr, nil
41+
}
42+
43+
// GetRegion returns offset and size of the given region type.
44+
func GetRegion(image []byte, regionType uefi.FlashRegionType) (uint32, uint32, error) {
45+
if _, err := uefi.FindSignature(image); err != nil {
46+
return 0, 0, err
47+
}
48+
flash, err := uefi.NewFlashImage(image)
49+
if err != nil {
50+
return 0, 0, err
51+
}
52+
if flash.IFD.Region.FlashRegions[regionType].Valid() {
53+
offset := flash.IFD.Region.FlashRegions[regionType].BaseOffset()
54+
size := flash.IFD.Region.FlashRegions[regionType].EndOffset() - offset
55+
return offset, size, nil
56+
}
57+
return 0, 0, fmt.Errorf("couldn't find region %d", regionType)
58+
}

pkg/uefi/consts/calculate.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package consts
2+
3+
// CalculatePhysAddrFromTailOffset calculates the physical address (address to a
4+
// region mapped from the SPI chip) using an offset towards down, relatively
5+
// to BasePhysAddr.
6+
//
7+
// Examples:
8+
// CalculatePhysAddrFromTailOffset(0x01) == 0xffffffff
9+
// CalculatePhysAddrFromTailOffset(0x40) == 0xffffffc0
10+
func CalculatePhysAddrFromTailOffset(offset uint64) uint64 {
11+
return BasePhysAddr - offset
12+
}
13+
14+
// CalculateTailOffsetFromPhysAddr calculates the offset (towards down, relatively
15+
// to BasePhysAddr) of the physical address (address to a region mapped from
16+
// the SPI chip).
17+
//
18+
// This is the reverse function to CalculatePhysAddrFromTailOffset()
19+
//
20+
// Examples:
21+
// CalculateTailOffsetFromPhysAddr(0xffffffff) == 0x01
22+
// CalculateTailOffsetFromPhysAddr(0xffffffc0) == 0x40
23+
func CalculateTailOffsetFromPhysAddr(physAddr uint64) uint64 {
24+
return BasePhysAddr - physAddr
25+
}
26+
27+
// CalculateOffsetFromPhysAddr calculates the offset within an image
28+
// of the physical address (address to a region mapped from
29+
// the SPI chip).
30+
//
31+
// Examples:
32+
// CalculateOffsetFromPhysAddr(0xffffffff, 0x1000) == 0xfff
33+
// CalculateOffsetFromPhysAddr(0xffffffc0, 0x1000) == 0xfc0
34+
func CalculateOffsetFromPhysAddr(physAddr uint64, imageSize uint64) uint64 {
35+
startAddr := BasePhysAddr - imageSize
36+
return physAddr - startAddr
37+
}

pkg/uefi/consts/consts.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package consts
2+
3+
const (
4+
// BasePhysAddr is the absolute physical address where the firmware image ends.
5+
//
6+
// See Figure 2.1 in https://www.intel.com/content/dam/www/public/us/en/documents/guides/fit-bios-specification.pdf
7+
//
8+
// Note: A firmware image grows towards lower addresses. So an image will be mapped to addresses:
9+
// [ BasePhysAddr-length .. BasePhysAddr )
10+
//
11+
// Note: SPI chip is mapped into this region. So we actually work directly with data of the SPI chip
12+
//
13+
// See also CalculatePhysAddrOfOffset().
14+
BasePhysAddr = 1 << 32 // "4GB"
15+
)

pkg/uefi/consts/hp.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package consts
2+
3+
var (
4+
// HPSignedFileMagic is the magic used to detect if the firmware is actually
5+
// an HP signed container-file (so it's required to extract/find
6+
// the firmware image first).
7+
HPSignedFileMagic = []byte(`--=</Begin HP Signed File Fingerprint\>=--`)
8+
9+
// HPImageMagic is the magic used to find the beginning of the real
10+
// firmware image inside of a HP signed container-file
11+
HPImageMagic = []byte(`HPIMAGE`)
12+
)

0 commit comments

Comments
 (0)