Skip to content

Commit

Permalink
Recognize Linux kernel ARM64 boot executable Image
Browse files Browse the repository at this point in the history
Some unikernels are using a specific binary format for aarch64 binaries.
An example of such unikernels is Unikraft. The used format is neither an
elf nor a PE, but can be recognized through its magic as a Linux kernel
ARM64 boot executable Image. For that purpose, we add support to
recognize this binary format.

Signed-off-by: Charalampos Mainas <cmainas@Nubificus.co.uk>
Reviewed-by: Anastassios Nanos <ananos@nubificus.co.uk>
Reviewed-by: Georgios Ntoutsos <gntouts@nubificus.co.uk>
Approved-by: Anastassios Nanos <ananos@nubificus.co.uk>
Approved-by: Georgios Ntoutsos <gntouts@nubificus.co.uk>
PR: #33
  • Loading branch information
cmainas authored and gntouts committed Feb 28, 2024
1 parent 43e50bf commit 8b81c9d
Showing 1 changed file with 28 additions and 3 deletions.
31 changes: 28 additions & 3 deletions internal/image/image.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ package image
import (
"encoding/json"
"fmt"
"os"
"path/filepath"
"strings"

Expand Down Expand Up @@ -270,10 +271,10 @@ func (i *BimaImage) extractIUnikernelArch() error {
return fmt.Errorf("unikernel defined by annotation was not copied in image rootfs")
}

file, err := elf.Open(unikernelPath)
elfFile, err := elf.Open(unikernelPath)
if err == nil {
defer file.Close()
switch file.Machine {
defer elfFile.Close()
switch elfFile.Machine {
case elf.EM_ARM:
i.arch = "arm64"
return nil
Expand All @@ -290,6 +291,8 @@ func (i *BimaImage) extractIUnikernelArch() error {
return fmt.Errorf("unknown architecture")
}
}

// We are not dealing with an elf binary. Maybe we can try PE
peFile, err := pe.Open(unikernelPath)
if err == nil {
defer peFile.Close()
Expand All @@ -305,6 +308,28 @@ func (i *BimaImage) extractIUnikernelArch() error {
}
}

// We are not dealing with an elf or PE binary.
// Let's check if it is Linux kernel ARM64 boot executable Image
file, err := os.Open(unikernelPath)
if err != nil {
return err
}
defer file.Close()

var dosheader [64]byte

if _, err = file.ReadAt(dosheader[0:], 0); err != nil {
return err
}
if dosheader[0] == 'M' && dosheader[1] == 'Z' {
if dosheader[56] == 'A' && dosheader[57] == 'R' {
if dosheader[58] == 'M' && dosheader[59] == 'd' {
i.arch = "arm64"
return nil
}
}
}

return err
}

Expand Down

0 comments on commit 8b81c9d

Please sign in to comment.