summarylogtreecommitdiffstats
path: root/uak-script
blob: f144c1c3f400deefc9b7cdee7e4ab6cc88c9514d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
#!/bin/bash -e
# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
# ex: ts=8 sw=4 sts=4 et filetype=sh

source /usr/share/makepkg/util/message.sh

# grabbed from mkinitcpio
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:]]+)+'

    # 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")
    [[ $offset = +([0-9]) ]] || return 1

    read kver _ < \
        <(dd if="$1" bs=1 count=127 skip=$(( offset + 0x200 )) 2>/dev/null)

    [[ $kver =~ $re ]] || return 1

    printf '%s' "$kver"
}

function do_uak() {
    msg "uak $*"
    /usr/bin/uak "$@" || return $?
}

ACTION="$1"

if [[ $ACTION == "install-preset" ]]; then
    kernel="$2"
    pkgbase="$3"
    kernel_version="$4"
    
    source "/etc/mkinitcpio.d/${pkgbase}.preset"
        
    for preset in "${PRESETS[@]}"; do
        preset_kernel_version=${kernel_version}-${preset}
        if [[ "$preset" == "default" ]]; then
            preset_kernel_version=${kernel_version}
        fi
        
        preset_initrd=${preset}_image
        
        if ! [[ -f ${!preset_initrd} ]]; then
            warning "No image file specified for preset $preset"
            continue
        fi

        do_uak install "$preset_kernel_version" "$kernel" $(echo /boot/*-ucode.img) "${!preset_initrd}" 
    done

    exit 0
elif [[ $ACTION == "remove-preset" ]]; then
    pkgbase="$2"
    kernel_version="$3"
    
    source "/etc/mkinitcpio.d/${pkgbase}.preset"
        
    for preset in "${PRESETS[@]}"; do
        preset_kernel_version=${kernel_version}-${preset}
        if [[ "$preset" == "default" ]]; then
            preset_kernel_version=${kernel_version}
        fi

        do_uak remove "$preset_kernel_version" || exit 1
    done

    exit 0
fi

ALL=0
KERNELS=()

if [[ $ACTION == "install-all" ]]; then
    ALL=1
    ACTION="install"
elif [[ $ACTION == "remove-all" ]]; then
    ALL=1
    ACTION="remove"
elif [[ $ACTION != "install" ]] && [[ $ACTION != "remove" ]]; then
    error "Unknown action: $ACTION"
    exit 1
else
    while read -r line; do
        kernel="/$line"

        if [[ $kernel != */vmlinuz ]]; then
            # triggers when it's a change to usr/lib/initcpio/*, usr/lib/systemd/boot/efi/linuxx64.efi.stub or boot/*-ucode.img
            if [[ $ACTION == "install" ]]; then
                ALL=1
            fi
            continue
        fi

        if ! read -r pkgbase > /dev/null 2>&1 < "${kernel%/vmlinuz}/pkgbase"; then
            # if the kernel has no pkgbase, we skip it
            continue
        fi

        KERNELS+=("$kernel")
    done
fi

if (( ALL )); then
    KERNELS=()

    for kernel in /usr/lib/modules/*/vmlinuz; do
        if ! read -r pkgbase > /dev/null 2>&1 < "${kernel%/vmlinuz}/pkgbase"; then
            # if the kernel has no pkgbase, we skip it
            continue
        fi
        KERNELS+=("$kernel")
    done
fi

for kernel in "${KERNELS[@]}"; do
    read -r pkgbase < "${kernel%/vmlinuz}/pkgbase";
        
    if ! [[ -f "/etc/mkinitcpio.d/${pkgbase}.preset" ]]; then
        error "Not found mkinitcpio preset for kernel $pkgbase (with image $kernel"
        exit 1
    fi
    
    kernel_version=$(kver "$kernel")
    
    if [[ $ACTION == "install" ]]; then
        "$0" install-preset "$kernel" "$pkgbase" "$kernel_version"
    else
        "$0" remove-preset "$pkgbase" "$kernel_version"
    fi
done