From de5f76c8837898ee4005dee5df58b7aba09a3d3a Mon Sep 17 00:00:00 2001 From: George Hopkins Date: Sun, 18 Aug 2024 16:15:51 +0200 Subject: [PATCH] Support i386/x86 platforms (#75) --- internal/packer/packer.go | 18 ++++++++++++------ internal/packer/packer_test.go | 2 +- internal/packer/testdata/kernel.386 | Bin 0 -> 1024 bytes packer/packer.go | 11 +++++++++-- 4 files changed, 22 insertions(+), 9 deletions(-) create mode 100644 internal/packer/testdata/kernel.386 diff --git a/internal/packer/packer.go b/internal/packer/packer.go index 146e9c8..b7e639b 100644 --- a/internal/packer/packer.go +++ b/internal/packer/packer.go @@ -1861,7 +1861,7 @@ func (pack *Pack) logic(programName string) error { } // kernelGoarch returns the GOARCH value that corresponds to the provided -// vmlinuz header. It returns one of "arm64", "arm", "amd64", or the empty +// vmlinuz header. It returns one of "arm", "arm64", "386", "amd64" or the empty // string if not detected. func kernelGoarch(hdr []byte) string { // Some constants from the file(1) command's magic. @@ -1873,17 +1873,23 @@ func kernelGoarch(hdr []byte) string { arm64Magic = 0x644d5241 arm64MagicOffset = 0x38 // x86: https://github.com/file/file/blob/65be1904/magic/Magdir/linux#L137-L152 - x86Magic = 0xaa55 - x86MagicOffset = 0x1fe + x86Magic = 0xaa55 + x86MagicOffset = 0x1fe + x86XloadflagsOffset = 0x236 ) if len(hdr) >= arm64MagicOffset+4 && binary.LittleEndian.Uint32(hdr[arm64MagicOffset:]) == arm64Magic { return "arm64" } - if len(hdr) >= arm64MagicOffset+4 && binary.LittleEndian.Uint32(hdr[arm32MagicOffset:]) == arm32Magic { + if len(hdr) >= arm32MagicOffset+4 && binary.LittleEndian.Uint32(hdr[arm32MagicOffset:]) == arm32Magic { return "arm" } - if len(hdr) >= arm64MagicOffset+2 && binary.LittleEndian.Uint16(hdr[x86MagicOffset:]) == x86Magic { - return "amd64" // we'll assume 386 is unsupported + if len(hdr) >= x86XloadflagsOffset+2 && binary.LittleEndian.Uint16(hdr[x86MagicOffset:]) == x86Magic { + // XLF0 in arch/x86/boot/header.S + if hdr[x86XloadflagsOffset]&1 != 0 { + return "amd64" + } else { + return "386" + } } return "" } diff --git a/internal/packer/packer_test.go b/internal/packer/packer_test.go index d836505..e5a18e5 100644 --- a/internal/packer/packer_test.go +++ b/internal/packer/packer_test.go @@ -6,7 +6,7 @@ import ( ) func TestKernelGoarch(t *testing.T) { - for _, arch := range []string{"arm", "arm64", "amd64"} { + for _, arch := range []string{"386", "arm", "arm64", "amd64"} { t.Run(arch, func(t *testing.T) { k, err := os.ReadFile("testdata/kernel." + arch) if err != nil { diff --git a/internal/packer/testdata/kernel.386 b/internal/packer/testdata/kernel.386 new file mode 100644 index 0000000000000000000000000000000000000000..3859b78520c530054895505492c0e251014b11f7 GIT binary patch literal 1024 zcmaFG%5Z?a=S1I)z5{(144?e|vrm^{jlzKv&Mkbq*%{6Xy#8c(;H=nL$yXo#Gkgdw zPE|-$NXpMIQOL_!2kc!j11?3nSrkO|DS;&bk*xDkCdWdekQQ91RfYOFfueSFbJTy z@_`S8`~Uy{daxWXP&Ye@5{613cguGZWI;wS$6y(lI$~+c&;v|le|j!i9_oBlBDU*+ z*EcpnriK!hZZQ?6#zPD&#Y~2mnjifsW#0AYf8T{P{_T%`%VjKPI-S;N7hxW{Dk`c} ze1C%Z&c|M9h6gl%9(>94Ic;^?i?cw-r0uv1^ikT24?wHFy#8y!_MfSQbWM z_!sc6NK0sbqtkh<^Z8D0hR@9!_ii!BxtWwgcz}p!JV|0hHGHAnnCvaR!F; z<1Q)!>|jcQkslT~ik=A)Rt@#k^n-vNroN1jO(mHRwd(DyNS@QYwgxB}dKrV_-ivzkQ80e1lH2!_e zEeA@t(wx&?!~o5E{T3*DnB6a5p*Xdqv_PRaGd(Y{q_ikiAuYc&F9nzxxfs%REofr| E08O3w+5i9m literal 0 HcmV?d00001 diff --git a/packer/packer.go b/packer/packer.go index ee6fc10..611662c 100644 --- a/packer/packer.go +++ b/packer/packer.go @@ -262,6 +262,7 @@ func (p *Pack) writeGPT(w io.Writer, devsize uint64, primary bool) error { partitionTypeLinuxFilesystemData = "0FC63DAF-8483-4772-8E79-3D69D8477DE4" partitionTypeLinuxRootPartitionAMD64 = "4F68BCE3-E8CD-4DB1-96E7-FBCAF984B709" partitionTypeLinuxRootPartitionARM64 = "B921B045-1DF0-41C3-AF44-4C6F280D3FAE" + partitionTypeLinuxRootPartitionX86 = "44479540-f297-41b2-9af7-d131d5f0458a" ) type partitionEntry struct { @@ -284,10 +285,16 @@ func (p *Pack) writeGPT(w io.Writer, devsize uint64, primary bool) error { partition3First := partition2Last + 1 partition3Last := partition3First + uint64(permSize(p.FirstPartitionOffsetSectors, devsize)) - 1 - rootType := mustParseGUID(partitionTypeLinuxRootPartitionARM64) - if os.Getenv("GOARCH") == "amd64" { + var rootType [16]byte + switch os.Getenv("GOARCH") { + case "386": + rootType = mustParseGUID(partitionTypeLinuxRootPartitionX86) + case "amd64": rootType = mustParseGUID(partitionTypeLinuxRootPartitionAMD64) + default: + rootType = mustParseGUID(partitionTypeLinuxRootPartitionARM64) } + partitionEntries := []partitionEntry{ { TypeGUID: mustParseGUID(partitionTypeEFISystemPartition),