mirror of
https://github.com/siderolabs/talos.git
synced 2025-10-26 14:01:39 +01:00
This time use `eg` from `x/tools` repo tool to do this. Signed-off-by: Dmitriy Matrenichev <dmitry.matrenichev@siderolabs.com>
70 lines
1.5 KiB
Go
70 lines
1.5 KiB
Go
// This Source Code Form is subject to the terms of the Mozilla Public
|
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
|
package uki
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/binary"
|
|
"errors"
|
|
"os"
|
|
"strings"
|
|
)
|
|
|
|
// DiscoverKernelVersion reads kernel version from the kernel image.
|
|
//
|
|
// This only works for x86 kernel images.
|
|
//
|
|
// Based on https://www.kernel.org/doc/html/v5.6/x86/boot.html.
|
|
func DiscoverKernelVersion(kernelPath string) (string, error) {
|
|
f, err := os.Open(kernelPath)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
defer f.Close() //nolint:errcheck
|
|
|
|
header := make([]byte, 1024)
|
|
|
|
_, err = f.Read(header)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
// check header magic
|
|
if string(header[0x202:0x206]) != "HdrS" {
|
|
return "", errors.New("invalid kernel image")
|
|
}
|
|
|
|
setupSects := header[0x1f1]
|
|
versionOffset := binary.LittleEndian.Uint16(header[0x20e:0x210])
|
|
|
|
if versionOffset == 0 {
|
|
return "", errors.New("no kernel version")
|
|
}
|
|
|
|
if versionOffset > uint16(setupSects)*0x200 {
|
|
return "", errors.New("invalid kernel version offset")
|
|
}
|
|
|
|
versionOffset += 0x200
|
|
|
|
version := make([]byte, 256)
|
|
|
|
_, err = f.ReadAt(version, int64(versionOffset))
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
idx := bytes.IndexByte(version, 0)
|
|
if idx == -1 {
|
|
return "", errors.New("invalid kernel version")
|
|
}
|
|
|
|
versionString := string(version[:idx])
|
|
versionString, _, _ = strings.Cut(versionString, " ")
|
|
|
|
return versionString, nil
|
|
}
|