summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGiancarlo Razzolini <grazzolini@archlinux.org>2021-11-29 08:15:01 -0300
committerGiancarlo Razzolini <grazzolini@archlinux.org>2021-11-29 08:15:01 -0300
commit93325dd7802238359405e4decb601650efc61d22 (patch)
treed8c621ad9d351d866674db37db9911a7b961e5d6
parentaee76f6c4253f5003979f445374e47a7449c9462 (diff)
parent73982d12aa773a505271dceeb07905167e2330d3 (diff)
Merge branch 'Depau-master'v31
-rw-r--r--functions43
-rwxr-xr-xmkinitcpio12
2 files changed, 41 insertions, 14 deletions
diff --git a/functions b/functions
index 7f3c382..48cfd7a 100644
--- a/functions
+++ b/functions
@@ -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"
diff --git a/mkinitcpio b/mkinitcpio
index a3a1e12..549f381 100755
--- a/mkinitcpio
+++ b/mkinitcpio
@@ -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
}