From b08ab7600c8f624db08f8ce0455f08c209df88f6 Mon Sep 17 00:00:00 2001 From: Euan Kemp Date: Sun, 4 Oct 2020 23:22:18 -0700 Subject: [PATCH] Add partial support for arm64 This is enough support that `pixiecore quick debian testing --arch arm64` is able to successfully boot a raspberry pi 4 that's using the experimental edk2 raspberry pi UEFI firmware. It does not seem to work with the built-in eeprom pxe booting the raspberry pi 4 includes, but the eeprom pxe implementation is severely lacking, so I'm not surprised. --- cmd/pixiecore/main.go | 1 + go.sum | 5 +++++ pixiecore/cli/quickcmd.go | 2 +- pixiecore/dhcp.go | 11 +++++++++-- pixiecore/http.go | 2 +- pixiecore/pixiecore.go | 6 ++++++ pixiecore/pxe.go | 2 ++ 7 files changed, 25 insertions(+), 4 deletions(-) diff --git a/cmd/pixiecore/main.go b/cmd/pixiecore/main.go index cb637934..1e2b4fb8 100644 --- a/cmd/pixiecore/main.go +++ b/cmd/pixiecore/main.go @@ -26,6 +26,7 @@ func main() { cli.Ipxe[pixiecore.FirmwareEFI32] = ipxe.MustAsset("third_party/ipxe/src/bin-i386-efi/ipxe.efi") cli.Ipxe[pixiecore.FirmwareEFI64] = ipxe.MustAsset("third_party/ipxe/src/bin-x86_64-efi/ipxe.efi") cli.Ipxe[pixiecore.FirmwareEFIBC] = ipxe.MustAsset("third_party/ipxe/src/bin-x86_64-efi/ipxe.efi") + cli.Ipxe[pixiecore.FirmwareEFIArm64] = ipxe.MustAsset("third_party/ipxe/src/bin-arm64-efi/ipxe.efi") cli.Ipxe[pixiecore.FirmwareX86Ipxe] = ipxe.MustAsset("third_party/ipxe/src/bin/ipxe.pxe") cli.CLI() } diff --git a/go.sum b/go.sum index c05d2f16..ab4ececb 100644 --- a/go.sum +++ b/go.sum @@ -2,7 +2,9 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= +github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc h1:cAKDfWh5VpdgMhJosfJnn5/FoN2SRZ4p7fJNX58YPaU= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf h1:qet1QNfXsQxTZqLG4oE62mJzwPIB8+Tee4RNCL9ulrY= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= @@ -82,12 +84,14 @@ github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDf github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= +github.com/prometheus/common v0.4.0 h1:7etb9YClo3a6HjLzfl6rIQaU+FDfi0VSX39io3aQ+DM= github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= +github.com/sirupsen/logrus v1.2.0 h1:juTguoYk5qI21pwyTXY3B3Y5cOTH3ZUyZCg1v/mihuo= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= @@ -169,6 +173,7 @@ google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9Ywl google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= diff --git a/pixiecore/cli/quickcmd.go b/pixiecore/cli/quickcmd.go index 278c788c..765e27fe 100644 --- a/pixiecore/cli/quickcmd.go +++ b/pixiecore/cli/quickcmd.go @@ -299,7 +299,7 @@ func netbootRecipe(parent *cobra.Command) { Long: `https://network.xyz allows to boot multiple operating systems and useful system utilities.`, Run: func(cmd *cobra.Command, args []string) { - kernel := "https://boot.netboot.xyz/ipxe/netboot.xyz.lkrn" + kernel := "https://boot.netboot.xyz/ipxe/netboot.xyz-packet-arm64.efi" fmt.Println(staticFromFlags(cmd, kernel, []string{}, "").Serve()) }, } diff --git a/pixiecore/dhcp.go b/pixiecore/dhcp.go index fdfe3af2..4eb440e5 100644 --- a/pixiecore/dhcp.go +++ b/pixiecore/dhcp.go @@ -115,8 +115,15 @@ func (s *Server) validateDHCP(pkt *dhcp4.Packet) (mach Machine, fwtype Firmware, case 9: mach.Arch = ArchX64 fwtype = FirmwareEFIBC + case 11: + // Not in the original rfc, but in + // https://www.ietf.org/assignments/dhcpv6-parameters/dhcpv6-parameters.xml#processor-architecture + // In practice, used by edk2 + // https://github.com/tianocore/edk2/blob/ef5dcba975ee3b4c29b19ad0b23d371a2cd9d60a/MdePkg/Include/IndustryStandard/Dhcp.h#L258-L272 + mach.Arch = Arm64 + fwtype = FirmwareEFIArm64 default: - return mach, 0, fmt.Errorf("unsupported client firmware type '%d' (please file a bug!)", fwtype) + return mach, 0, fmt.Errorf("unsupported client firmware type '%d' (please file a bug!)", fwt) } // Now, identify special sub-breeds of client firmware based on @@ -210,7 +217,7 @@ func (s *Server) offerDHCP(pkt *dhcp4.Packet, mach Machine, serverIP net.IP, fwt resp.Options[43] = bs resp.BootFilename = fmt.Sprintf("tftp://%s/%s/%d", serverIP, mach.MAC, fwtype) - case FirmwareEFI32, FirmwareEFI64, FirmwareEFIBC: + case FirmwareEFI32, FirmwareEFI64, FirmwareEFIBC, FirmwareEFIArm64: // In theory, the response we send for FirmwareX86PC should // also work for EFI. However, some UEFI firmwares don't // support PXE properly, and will ignore ProxyDHCP responses diff --git a/pixiecore/http.go b/pixiecore/http.go index cfc0e98c..bbda4782 100644 --- a/pixiecore/http.go +++ b/pixiecore/http.go @@ -74,7 +74,7 @@ func (s *Server) handleIpxe(w http.ResponseWriter, r *http.Request) { } arch := Architecture(i) switch arch { - case ArchIA32, ArchX64: + case ArchIA32, ArchX64, Arm64: default: s.debug("HTTP", "Bad request %q from %s, unknown architecture %q", r.URL, r.RemoteAddr, arch) http.Error(w, "unknown architecture", http.StatusBadRequest) diff --git a/pixiecore/pixiecore.go b/pixiecore/pixiecore.go index 19bef463..8fab541c 100644 --- a/pixiecore/pixiecore.go +++ b/pixiecore/pixiecore.go @@ -51,6 +51,9 @@ const ( ArchIA32 Architecture = iota // ArchX64 is a 64-bit x86 machine (aka amd64 aka X64). ArchX64 + // ARM aarch64, go calls it 'arm64' in its cross toolchain, so stick with + // that. + Arm64 ) func (a Architecture) String() string { @@ -59,6 +62,8 @@ func (a Architecture) String() string { return "IA32" case ArchX64: return "X64" + case Arm64: + return "ARM64" default: return "Unknown architecture" } @@ -147,6 +152,7 @@ const ( FirmwareEFI32 // 32-bit x86 processor running EFI FirmwareEFI64 // 64-bit x86 processor running EFI FirmwareEFIBC // 64-bit x86 processor running EFI + FirmwareEFIArm64 // 64-bit arm processor (aarch64), running EFI FirmwareX86Ipxe // "Classic" x86 BIOS running iPXE (no UNDI support) FirmwarePixiecoreIpxe // Pixiecore's iPXE, which has replaced the underlying firmware ) diff --git a/pixiecore/pxe.go b/pixiecore/pxe.go index 01c5d3a4..33cef923 100644 --- a/pixiecore/pxe.go +++ b/pixiecore/pxe.go @@ -103,6 +103,8 @@ func (s *Server) validatePXE(pkt *dhcp4.Packet) (fwtype Firmware, err error) { fwtype = FirmwareEFI64 case 9: fwtype = FirmwareEFIBC + case 11: + fwtype = FirmwareEFIArm64 default: return 0, fmt.Errorf("unsupported client firmware type '%d' (please file a bug!)", fwt) }