diff options
author | Giancarlo Razzolini <grazzolini@archlinux.org> | 2021-11-29 08:15:01 -0300 |
---|---|---|
committer | Giancarlo Razzolini <grazzolini@archlinux.org> | 2021-11-29 08:15:01 -0300 |
commit | 93325dd7802238359405e4decb601650efc61d22 (patch) | |
tree | d8c621ad9d351d866674db37db9911a7b961e5d6 | |
parent | aee76f6c4253f5003979f445374e47a7449c9462 (diff) | |
parent | 73982d12aa773a505271dceeb07905167e2330d3 (diff) |
Merge branch 'Depau-master'v31
-rw-r--r-- | functions | 43 | ||||
-rwxr-xr-x | mkinitcpio | 12 |
2 files changed, 41 insertions, 14 deletions
@@ -133,23 +133,50 @@ parseopts() { return 0 } -kver() { - # this is intentionally very loose. only ensure that we're - # dealing with some sort of string that starts with something - # resembling dotted decimal notation. remember that there's no - # requirement for CONFIG_LOCALVERSION to be set. - local kver re='^[[:digit:]]+(\.[[:digit:]]+)+' - +kver_x86() { # scrape the version out of the kernel image. locate the offset # to the version string by reading 2 bytes out of image at at # address 0x20E. this leads us to a string of, at most, 128 bytes. # read the first word from this string as the kernel version. - local offset=$(hexdump -s 526 -n 2 -e '"%0d"' "$1") + local kver offset=$(hexdump -s 526 -n 2 -e '"%0d"' "$1") [[ $offset = +([0-9]) ]] || return 1 read kver _ < \ <(dd if="$1" bs=1 count=127 skip=$(( offset + 0x200 )) 2>/dev/null) + printf '%s' "$kver" +} + +kver_generic() { + # For unknown architectures, we can try to grep the uncompressed + # image for the boot banner. + # This should work at least for ARM when run on /boot/Image. On + # other architectures it may be worth trying rather than bailing, + # and inform the user if none was found. + + # Loosely grep for `linux_banner`: + # https://elixir.bootlin.com/linux/v5.7.2/source/init/version.c#L46 + local kver= + + read _ _ kver _ < <(grep -m1 -aoE 'Linux version .(\.[-[:alnum:]]+)+' "$1") + + printf '%s' "$kver" +} + +kver() { + # this is intentionally very loose. only ensure that we're + # dealing with some sort of string that starts with something + # resembling dotted decimal notation. remember that there's no + # requirement for CONFIG_LOCALVERSION to be set. + local kver re='^[[:digit:]]+(\.[[:digit:]]+)+' + + local arch=$(uname -m) + if [[ $arch == @(i?86|x86_64) ]]; then + kver=$(kver_x86 "$1") + else + kver=$(kver_generic "$1") + fi + [[ $kver =~ $re ]] || return 1 printf '%s' "$kver" @@ -113,12 +113,6 @@ resolve_kernver() { return 0 fi - arch=$(uname -m) - if [[ $arch != @(i?86|x86_64) ]]; then - error "kernel version extraction from image not supported for \`%s' architecture" "$arch" - return 1 - fi - if [[ ! -e $kernel ]]; then error "specified kernel image does not exist: \`%s'" "$kernel" return 1 @@ -128,6 +122,12 @@ resolve_kernver() { error "invalid kernel specified: \`%s'" "$1" + arch=$(uname -m) + if [[ $arch != @(i?86|x86_64) ]]; then + error "kernel version extraction from image not supported for \`%s' architecture" "$arch" + error "there's a chance the generic version extractor may work with a valid uncompressed kernel image" + fi + return 1 } |