# TWEAK:Trim unused exported kernel symbols IF extern modules

## CaptainBlood

IMHO interesting post for those with kernel external modules whishing to shrink kernel.

Likely not for the faint-hearted.

Thks 4 ur attention.Last edited by CaptainBlood on Tue Mar 31, 2020 9:04 am; edited 6 times in total

----------

## Ionen

Interesting, it's something I've thought about before (it's an option I wanted to enable given my minimalist kernel), but then I'm (also) stuck with using nvidia proprietary.

Doesn't sound like it'd be hard to integrate in my build scripts and automate, may set it up later. Thanks for bringing it up  :Smile: 

Formerly I did want to just build in nvidia (was the only modules I had at all, then I could disable module support), but lately I'm happy with them being modules because it's easier to unload them for GPU passthrough (on that note, if I do the trim, I guess I'll be getting even more warnings from portage which _really_ wants me to enable CONFIG_ZONE_DMA for nvidia drivers, but no! I'm using IOMMU, no thanks  :Cool: ).

----------

## CaptainBlood

Cdemu stack kernel integration issued the concern here.

No Nvidia, so nothing to share in this regard.

i965 instead. Maybe not so out of scope....

Haven't figured that out, yet.

Thks 4 ur attention, interest & support.

----------

## CaptainBlood

```
-rw-r--r--  1 root root 7987760 mars  27 20:11 vmlinuz-5.4.28-gento

-rw-r--r--  1 root root 8110640 mars  27 15:14 vmlinuz-5.4.28-gentoo.old

```

```
lsmod

Module                  Size  Used by

snd_aloop              28672  3

vhba                   20480  0 # <=external module

pcspkr                 16384  0
```

Thks 4 ur attention.Last edited by CaptainBlood on Sat Mar 28, 2020 11:51 pm; edited 2 times in total

----------

## CaptainBlood

```
-rw-r--r-- 1 root root 7352368 mars  29 00:12 /boot/vmlinuz-4.19.97-gentoo-classic

-rw-r--r-- 1 root root 7467056 mars  29 00:11 /boot/vmlinuz-4.19.97-gentoo-classic.old
```

```
lsmod

Module                  Size  Used by

vhba                   20480  0 # <=external module

snd_aloop              24576  3

pcspkr                 16384  0
```

Thks 4 ur attention.

----------

## CaptainBlood

A couple of scripts & files for those willing to try an 'easier way':

Calling script:

```
#!/bin/bash

# parameters

# @1 mandatory kernel version

# @2 mandatory config versionSsed

# debug

#set -x

krn_pth=$1

if [[ ! -z $2 ]];then

    krn_pth+=-$2

fi

dst_dir=/usr/src/linux-$krn_pth

if [[ ! -d $dst_dir || ! -f $dst_dir/.config ]];then

    echo syntax: $0 \'kernel version\', mandatory, [\'config version\'], optional

    echo \'kernel version\', mandatory e.g. 5.6.2 or 5.6.2-gentoo for sys-kernel/gentoo-sources package class user

    echo "[\'config version\'], optional e.g. classic as here kernel is configured in /usr/src/linux-5.5.13-gentoo-classic/]"

    echo kernel config file must exist in directory $dst_dir

else

    cd $dst_dir

    if ! grep -q "# CONFIG_TRIM_UNUSED_KSYMS is not set" .config;then

        echo kernel already configured for unused ksyms trimming, cancelling...

        unset dst_dir

    else

        # test kernel config defined module compression & type, hence gunzip or unxz commands in PATH

        unset GUNZIP

        unset UNXZ

        # dirty testing with fuzzy values of y or yes

        if grep -q "CONFIG_MODULE_COMPRESS=y" .config;then

            if grep -q "CONFIG_MODULE_COMPRESS_GZIP=y" .config;then

                krn_mdl_cmprss=gunzip

                echo kernel module GUNZIP compression detected

            elif grep -q "CONFIG_MODULE_COMPRESS_XZ=y" .config;then

                krn_mdl_cmprss=unxz

                echo kernel module XZ compression detected

            else

                echo kernel module compression type not found in config file, please check, continuing...

            fi

        fi

        unset dst_dir

        unset rrr_flg

        # test all cases executables in PATH [gunzip], patch, sed, sort & [unxz]

        for cmd in $krn_mdl_cmprss patch readlink sed sort

        do

            command -v $cmd>/dev/null 2>&1||(echo>&2 "required $cmd command not in PATH";rrr_flg=0;)

        done

        unset krn_mdl_cmprss

        # binutils's nm has aliases from other packages, hence a # detection

        if [[ ! -x $(readlink -e "$( command -v nm)") ]];then

            echo binutils\'s required nm command not in PATH, cancelling... && rrr_flg=0

        elif ! nm -V | grep -q "GNU nm";then

            echo detected nm command doesn\'t hold GNU signature, cancelling... && rrr_flg=0

        fi

        if [[ -z $rrr_flg ]];then

            # user dependent location, update according to local settings

            path_to_kernel_unused_ksyms_trim_patch_root_dir=/home/luc/src/git/kernel-trim-external-modules/

            if [[ ! -d $path_to_kernel_unused_ksyms_trim_patch_root_dir ]];then

                echo failed to find kernel patch root dir $path_to_kernel_unused_ksyms_trim_patch_root_dir, cancelling...

            else

                kernel_unused_ksyms_trim_patch_filename=/support-trim-unused-ksyms-for-external-modules.patch

                krn_vrs_nmb=$(echo $1|sed -En "s/([[:digit:]].[[:digit:]]*.[[:digit:]]*)(.*)/\1/p")

                

                krn_vrs_nmb_suffix=.x

                full_path_to_kernel_unused_ksyms_trim_patch=$path_to_kernel_unused_ksyms_trim_patch_root_dir$krn_vrs_nmb$kernel_unused_ksyms_trim_patch_filename

                while [[ $krn_vrs_nmb =~ \. ]] && [[ ! -f $full_path_to_kernel_unused_ksyms_trim_patch ]];do

                    krn_vrs_nmb=${krn_vrs_nmb%.*}

                    full_path_to_kernel_unused_ksyms_trim_patch=$path_to_kernel_unused_ksyms_trim_patch_root_dir$krn_vrs_nmb$krn_vrs_nmb_suffix$kernel_unused_ksyms_trim_patch_filename

                done

                unset path_to_kernel_unused_ksyms_trim_patch

                unset kernel_unused_ksyms_trim_patch_filename

                unset krn_vrs_nmb

                unset krn_vrs_nmb_suffix

                

                if [[ ! -f $full_path_to_kernel_unused_ksyms_trim_patch ]];then

                    echo patch file $full_path_to_kernel_unused_ksyms_trim_patch not found, cancelling...

                else

                    # calling external bash script

                    extern-ksym-2 $krn_pth>include/generated/autoksyms.h.extern

                    unset krn_pth 

                    cat include/generated/autoksyms.h.extern

                    # test patch only

                    if ! patch --dry-run -p1<$full_path_to_kernel_unused_ksyms_trim_patch;then

                        echo patch test of kernel file failed, cancelling...

                    else

                        # backup file & apply patch

                        if ! patch -b -p1<$full_path_to_kernel_unused_ksyms_trim_patch;then

                            echo kernel config file patching with backup failed, cancelling...

                        else

                            echo -\> prepached original kernel file backuped as scripts/adjust_autoksyms.sh.orig

                            # manual setting

                            #make nconfig # enable CONFIG_TRIM_UNUSED_KSYMS

                            #make menuconfig

                            

                            # automatic setting

                            # test existing .conf.sed[::digit::] to avoid sed backuo feature to overwrite & setting index variable accordingly

                            unset sed_bck_ext_ndx

                            while [[ -f .config.sed$sed_bck_ext_ndx ]];do

                                  #((sed_bck_ext_ndx++));

                                  # shorter form;

                                  sed_bck_ext_ndx+=1;

                            done

                            if ! sed -i.sed$sed_bck_ext_ndx 's/# CONFIG_TRIM_UNUSED_KSYMS is not set/CONFIG_TRIM_UNUSED_KSYMS=y/g' .config;then

                                echo error activating TRIM_UNUSED_KSYMS in kernel config file with sed, cancelling...

                            else

                                echo TRIM_UNUSED_KSYMS activated in kernel config file

                                # sets MAKOPTS variable if according defintion file exists, i.e. Gentoo portage style there, e.g. MAKEOPTS="-j3 -l3".

                                if [[ -f /etc/portage/env/makeopts-but.conf ]];then

                                    echo detected Gentoo portage type specifc file: /etc/portage/env/makeopts-but.conf

                                    if ! MAKEOPTS_BUT=$(grep '^[[:space:]]*MAKEOPTS="[[:space:]]*-j[0]*[1-9]*[0-9]*[[:space:]]*-l[0]*[1-9]*[0-9]*[[:space:]]*"[[:space:]]*$' /etc/portage/env/makeopts-but.conf| tail -n1); then

                                          MAKEOPTS_BUT=$(grep '^[[:space:]]*MAKEOPTS="[[:space:]]*-j[0]*[1-9]*[0-9]*[[:space:]]*"[[:space:]]*$' /etc/portage/env/makeopts-but.conf| tail -c1)

                                    fi

                                fi

                                [[ ! -z $MAKEOPTS_BUT ]] && MAKEOPTS=${MAKEOPTS_BUT#MAKEOPTS=} && unset MAKEOPTS_BUT || MAKEOPTS="-j1 -l1"

                                echo executing \'make ${MAKEOPTS//\"}\'

                                if ! make ${MAKEOPTS//\"};then

                                    echo error building TRIM_UNUSED_KSYMS featured kernel

                                else

                                    echo Installing kernel

                                    if ! make install; then

                                        echo error installing TRIM_UNUSED_KSYMS featured kernel

                                    fi

                                fi

                                # restoring initial environment, e.g. files

                                

                                # SUSPENDED reversing initial sed inline substitution

                                #sed -i 's/CONFIG_TRIM_UNUSED_KSYMS=y/# CONFIG_TRIM_UNUSED_KSYMS is not set/g' .config

                                # ACTIVE restore initial file with sed generated backup file 

                                if [[ ! -f .config.sed$sed_bck_ext_ndx ]];then

                                    echo sed originated backup of original kernel config file [e.g. .config.sed$sed_bck_ext_ndx] not found, continuing...

                                elif mv .config.sed$sed_bck_ext_ndx .config;then

                                    echo kernel original config file restored

                                else

                                    echo error restoring .config.sed$sed_bck_ext_ndx as original kernel config file, please check & proceed manually, continuing...

                                fi

                                unset sed_bck_ext_ndx

                                # SUSPENDED reverse patch method to restore prepatch hernel file

                                #if patch -p1 -R < $full_path_to_kernel_unused_ksyms_trim_patch;then

                                #    echo prepatch kernel file restored

                                #else

                                #   echo error reversing patched file scripts/adjust_autoksyms.sh

                                #fi

                                # ACTIVE overwrite patched file by renaming backuped one instead

                                if mv scripts/adjust_autoksyms.sh.orig scripts/adjust_autoksyms.sh;then

                                    echo prepatch kernel file restored from scripts/adjust_autoksyms.sh.orig

                                else

                                    echo error restoring prepatch kernel file scripts/adjust_autoksyms.sh.orig

                                fi

                            fi

                        fi

                    fi

                    if ! rm include/generated/autoksyms.h.extern;then

                        echo error deleting include/generated/autoksyms.h.extern

                    fi

                fi

                unset full_path_to_kernel_unused_ksyms_trim_patch

            fi

        fi

        unset rrr_flg

    fi

fi
```

Called script, renamed because of slight change with original, check 1st post.

```
ls /usr/local/sbin/extern-ksym-2 -la

-rwxr----- 1 root root 1331 mars   1 11:43 /usr/local/sbin/extern-ksym-2
```

```
cat /usr/local/sbin/extern-ksym-2

#!/bin/bash

#parameter: $1 

list_required_ksyms() {

    case ${1##*.} in

        ko)

            cmd="nm $1"

            ;;

        gz)

            gunzip -c $1>a.out

            cmd="nm"

            ;;

        xz)

            unxz -c $1>a.out

            cmd="nm"

            ;;

        *)

            exit

            ;;

    esac

    eval $cmd |

        sed -n 's/^ \+U //p' |

        sed -ns -e '{s/ /\n/g;/^$/!p;}' |

        sort -u |

        while read sym; do

            if [[ -n "$CONFIG_HAVE_UNDERSCORE_SYMBOL_PREFIX" ]]; then

                sym="${sym#_}"

            fi

            echo "#define __KSYM_${sym} 1"

        done

}

if [[ linux-$1 != $(basename $PWD) ]]; then # test current directory matches kernel version[-config directory name']

    echo "syntax: $0 'kernel version'[-'config version']"

else

    # calling matching kernel script

    . ./include/config/auto.conf

    

    # Find all external modules

    mod_dir_list=$(find /lib/modules/$1 -mindepth 1 -maxdepth 1 -type d  \! -name 'kernel' | xargs)

    for mod_dir in $mod_dir_list; do

        for ko in ${mod_dir}/*.ko*; do

            list_required_ksyms ${ko}

        done

    done | sort -u

    [[ -f ./a.out ]] && rm ./a.out

fi
```

patch tree:

```
tree /home/user/src/git/kernel-trim-external-modules/

/home/user/src/git/kernel-trim-external-modules/

├── 4.14.x

│   └── support-trim-unused-ksyms-for-external-modules.patch

├── 4.19.x

│   └── support-trim-unused-ksyms-for-external-modules.patch

└── 5.x

    └── support-trim-unused-ksyms-for-external-modules.patch
```

```
cat /home/user/src/git/kernel-trim-external-modules/4.14.x/support-trim-unused-ksyms-for-external-modules.patch 

--- ./scripts/adjust_autoksyms.sh.ori   2020-03-16 07:48:55.196492298 +0300

+++ ./scripts/adjust_autoksyms.sh   2020-03-29 01:50:56.150936670 +0300

@@ -22,6 +22,7 @@

 

 cur_ksyms_file="include/generated/autoksyms.h"

 new_ksyms_file="include/generated/autoksyms.h.tmpnew"

+ext_ksyms_file="include/generated/autoksyms.h.extern"

 

 info() {

    if [ "$quiet" != "silent_" ]; then

@@ -66,7 +67,11 @@

       sym="${sym#_}"

    fi

    echo "#define __KSYM_${sym} 1"

-done >> "$new_ksyms_file"

+done >> "$new_ksyms_file".tmp

+

+# Merge external and new ksym files

+sort -u "$new_ksyms_file".tmp "$ext_ksyms_file" >> "$new_ksyms_file"

+rm -f "$new_ksyms_file".tmp

 

 # Special case for modversions (see modpost.c)

 if [ -n "$CONFIG_MODVERSIONS" ]; then

@@ -99,7 +104,8 @@

    # Replace the old list with tne new one

    old=$(grep -c "^#define __KSYM_" "$cur_ksyms_file" || true)

    new=$(grep -c "^#define __KSYM_" "$new_ksyms_file" || true)

-   info "KSYMS" "symbols: before=$old, after=$new, changed=$changed"

+    ext=$(grep -c "^#define __KSYM_" "$ext_ksyms_file" || true)

+    info "KSYMS" "symbols: before=$old, after=$new, external=$ext, changed=$changed"

    info "UPD" "$cur_ksyms_file"

    mv -f "$new_ksyms_file" "$cur_ksyms_file"

    # Then trigger a rebuild of affected source files
```

```
cat /home/user/src/git/kernel-trim-external-modules/4.19.x/support-trim-unused-ksyms-for-external-modules.patch 

--- ./scripts/adjust_autoksyms.sh.ori   2018-10-22 09:37:37.000000000 +0300

+++ ./scripts/adjust_autoksyms.sh   2020-03-28 23:09:34.933620716 +0300

@@ -22,6 +22,7 @@

 

 cur_ksyms_file="include/generated/autoksyms.h"

 new_ksyms_file="include/generated/autoksyms.h.tmpnew"

+ext_ksyms_file="include/generated/autoksyms.h.extern"

 

 info() {

    if [ "$quiet" != "silent_" ]; then

@@ -62,7 +63,11 @@

 done | sort -u |

 while read sym; do

    echo "#define __KSYM_${sym} 1"

-done >> "$new_ksyms_file"

+done >> "$new_ksyms_file".tmp

+

+# Merge external and new ksym files

+sort -u "$new_ksyms_file".tmp "$ext_ksyms_file" >> "$new_ksyms_file"

+rm -f "$new_ksyms_file".tmp

 

 # Special case for modversions (see modpost.c)

 if [ -n "$CONFIG_MODVERSIONS" ]; then

@@ -95,7 +100,8 @@

    # Replace the old list with tne new one

    old=$(grep -c "^#define __KSYM_" "$cur_ksyms_file" || true)

    new=$(grep -c "^#define __KSYM_" "$new_ksyms_file" || true)

-   info "KSYMS" "symbols: before=$old, after=$new, changed=$changed"

+    ext=$(grep -c "^#define __KSYM_" "$ext_ksyms_file" || true)

+    info "KSYMS" "symbols: before=$old, after=$new, external=$ext, changed=$changed"

    info "UPD" "$cur_ksyms_file"

    mv -f "$new_ksyms_file" "$cur_ksyms_file"

    # Then trigger a rebuild of affected source files
```

```
cat /home/user/src/git/kernel-trim-external-modules/5.x/support-trim-unused-ksyms-for-external-modules.patch 

--- ./scripts/adjust_autoksyms.sh.ori   2019-11-25 03:32:01.000000000 +0300

+++ ./scripts/adjust_autoksyms.sh   2020-03-27 19:54:21.572733145 +0300

@@ -19,6 +19,7 @@

 

 cur_ksyms_file="include/generated/autoksyms.h"

 new_ksyms_file="include/generated/autoksyms.h.tmpnew"

+ext_ksyms_file="include/generated/autoksyms.h.extern"

 

 info() {

    if [ "$quiet" != "silent_" ]; then

@@ -49,7 +50,11 @@

 sed 's/ko$/mod/' modules.order |

 xargs -n1 sed -n -e '2{s/ /\n/g;/^$/!p;}' -- |

 sort -u |

-sed -e 's/\(.*\)/#define __KSYM_\1 1/' >> "$new_ksyms_file"

+sed -e 's/\(.*\)/#define __KSYM_\1 1/' >> "$new_ksyms_file".tmp

+

+# Merge external and new ksym files

+sort -u "$new_ksyms_file".tmp "$ext_ksyms_file" >> "$new_ksyms_file"

+rm -f "$new_ksyms_file".tmp

 

 # Special case for modversions (see modpost.c)

 if [ -n "$CONFIG_MODVERSIONS" ]; then

@@ -82,7 +87,8 @@

    # Replace the old list with tne new one

    old=$(grep -c "^#define __KSYM_" "$cur_ksyms_file" || true)

    new=$(grep -c "^#define __KSYM_" "$new_ksyms_file" || true)

-   info "KSYMS" "symbols: before=$old, after=$new, changed=$changed"

+   ext=$(grep -c "^#define __KSYM_" "$ext_ksyms_file" || true)

+    info "KSYMS" "symbols: before=$old, after=$new, external=$ext, changed=$changed"

    info "UPD" "$cur_ksyms_file"

    mv -f "$new_ksyms_file" "$cur_ksyms_file"

    # Then trigger a rebuild of affected source files
```

All three patches have been tested, with xzipped modules here.

Hoping it's good enough for some of you to try & succeed.

Thks 4 ur attention, interest and supportLast edited by CaptainBlood on Thu Apr 09, 2020 10:11 pm; edited 4 times in total

----------

## CaptainBlood

Fixed & tested with single parameter.

Thks 4 ur attention, interest & support

----------

## CaptainBlood

Fine with 5.6.0 here, without any change.

```
uname -r

5.6.0-gentoo-classic
```

```
ls /boot/vmlinuz-5.6.0-gentoo-classic* -ll

-rw-r--r-- 1 root root 8153136 mars  31 01:43 /boot/vmlinuz-5.6.0-gentoo-classic

-rw-r--r-- 1 root root 8300592 mars  31 01:12 /boot/vmlinuz-5.6.0-gentoo-classic.old
```

```
lsmod

Module                  Size  Used by

snd_aloop              32768  2

vhba                   20480  0 # <= external module

pcspkr                 16384  0
```

Thks 4 ur attention, interest & support.

----------

## CaptainBlood

Dry-run patch test & cancellation added in calling script, i.e. updated above.

NOK and OK cases verified.

Thks 4 ur attention, interest & support.

----------

## CaptainBlood

Calling script updated:

-Reordered tasks

-Hopefully easier reading

-Check & report availability of requested external commands

-Most command failures detected & reported.

-Kernel config file named .config.sed remains preserved if exists prior to execution

-Patched files are restored upon success.

-Kernel compilation, which is defaulted to -j1 -l1 optionally supports /etc/portage/env/makeopts_but.conf defined here as

```
cat /etc/portage/env/makeopts-but.conf 

MAKEOPTS="-j3 -l3"
```

Called script unchanged:

-Supports compressed modules

Kernel patch tree & files unchanged.

Tested ok here with latest 5.6.3.

Likely quite near to beta.

TODO:

- Integration of called script within calling one.

- Debug mode as command line parameter

- Redefinition of default mode ouputs

- SIlent output mode

- Decorated mode option for both of the above.

- Some variables name length shortening, e.g. for a smaller filesize/512 ratio

- Simpler way to parse & integrate  MAKEOPTS="-i[[:digit:]] [-l[[:digit:]]]

- Patched files restored in most failure cases.

- check kernel has already been build, as a prerequisite.

- Check compatibility with kernel named with revision suffix such as 5.6.3-r1 or 5.6.3-gentoo-r1

Thks 4 ur attention, interest & support.Last edited by CaptainBlood on Mon Apr 13, 2020 12:44 am; edited 3 times in total

----------

## CaptainBlood

Single script, i.e. not calling external script:

```
ll /usr/local/sbin/kermak-extern-ksym2

-rwxr----- 1 root root 13984 avril 11 02:13 /usr/local/sbin/kermak-extern-ksym2
```

```
#!/bin/bash

# parameters

# @1 mandatory kernel version

# debug

#set -x

dst_dir=/usr/src/linux-$1

if [[ ! -d $dst_dir || -z  $1 ]];then

    echo syntax: $0 \'kernel version\', mandatory, e.g. 5.6.3 or 5.63-gentoo for sys-kernel/gentoo-sources package class user

elif ! cd $dst_dir;then

    echo error directory $dst_dir not found

elif [[ ! -f $dst_dir/.config ]];then

    echo kernel config file missing: $dst_dir/.config

elif ! grep -q "# CONFIG_TRIM_UNUSED_KSYMS is not set" .config;then

    echo kernel already configured for unused ksyms trimming, cancelling...

else

    # test kernel config defined module compression & type, hence gunzip or unxz commands in PATH

    unset GUNZIP UNXZ

    # dirty testing with fuzzy values of y or yes

    # TODO clarify allowance of # concurrent kernel module compression types

    if grep -q "CONFIG_MODULE_COMPRESS=y" .config;then

        if grep -q "CONFIG_MODULE_COMPRESS_GZIP=y" .config;then

            krn_mdl_cmprss=gunzip

            echo kernel module GUNZIP compression detected

        elif grep -q "CONFIG_MODULE_COMPRESS_XZ=y" .config;then

            krn_mdl_cmprss=unxz

            echo kernel module XZ compression detected

        else

            echo kernel module compression type not found in config file, please check, continuing...

        fi

    fi

    unset dst_dir rrr_flg

    # test all cases executables in PATH [gunzip], patch, sed, sort & [unxz]

    for cmd in $krn_mdl_cmprss patch readlink sed sort

    do

        command -v $cmd>/dev/null 2>&1||(echo>&2 "required $cmd command not in PATH";rrr_flg=0;)

    done

    unset krn_mdl_cmprss

    # binutils's nm has aliases from other packages, hence a # detection

    if [[ ! -x $(readlink -e "$( command -v nm)") ]];then

        echo binutils\'s required nm command not in PATH, cancelling... && rrr_flg=0

    elif ! nm -V | grep -q "GNU nm";then

        echo detected nm command doesn\'t hold GNU signature, cancelling... && rrr_flg=0

    fi

    if [[ ! -z $rrr_flg ]];then

        unset rrr_flg

    else

        # user dependent location, update according to local settings

        path_to_kernel_unused_ksyms_trim_patch_root_dir=/home/luc/src/git/kernel-trim-external-modules/

        if [[ ! -d $path_to_kernel_unused_ksyms_trim_patch_root_dir ]];then

            echo failed to find kernel patch root dir $path_to_kernel_unused_ksyms_trim_patch_root_dir, cancelling...

        else

            kernel_unused_ksyms_trim_patch_filename=/support-trim-unused-ksyms-for-external-modules.patch

            krn_vrs_nmb=$(echo $1|sed -En "s/([[:digit:]].[[:digit:]]*.[[:digit:]]*)(.*)/\1/p")

            

            krn_vrs_nmb_suffix=.x

            full_path_to_kernel_unused_ksyms_trim_patch=$path_to_kernel_unused_ksyms_trim_patch_root_dir$krn_vrs_nmb$kernel_unused_ksyms_trim_patch_filename

            while [[ $krn_vrs_nmb =~ \. ]] && [[ ! -f $full_path_to_kernel_unused_ksyms_trim_patch ]];do

                krn_vrs_nmb=${krn_vrs_nmb%.*}

                full_path_to_kernel_unused_ksyms_trim_patch=$path_to_kernel_unused_ksyms_trim_patch_root_dir$krn_vrs_nmb$krn_vrs_nmb_suffix$kernel_unused_ksyms_trim_patch_filename

            done

            unset path_to_kernel_unused_ksyms_trim_patch kernel_unused_ksyms_trim_patch_filename krn_vrs_nmb krn_vrs_nmb_suffix

            

            if [[ ! -f $full_path_to_kernel_unused_ksyms_trim_patch ]];then

                echo patch file $full_path_to_kernel_unused_ksyms_trim_patch not found, cancelling...

            else

                # kernel out of tree file generation, i.e. required by above patched kernel script

                echo kernel out of the tree file generation: include/generated/autoksyms.h.extern...

                # calling kernel script

                # TODO explain purpose

                . ./include/config/auto.conf

                # find all external modules

                mod_dir_list=$(find /lib/modules/$1 -mindepth 1 -maxdepth 1 -type d  \! -name 'kernel'|xargs)

                if [[ 0 -ne $? ]];then

                    echo error generating module directory internal list

                else

                    for mod_dir in $mod_dir_list;do

                        # catching all files matching *.ko*

                        # TODO composite list instead of a single one, i.e. *.ko, *.ko.gz & *.ko.xz

                        for ko in ${mod_dir}/*.ko*;do

                            cmd=nm

                            case ${ko##*.} in

                                ko)

                                    cmd=$cmd\ $ko

                                    ;;

                                gz)

                                    # parameter free nm runs against a.out file from current directory, i.e. generated above

                                    if ! gunzip -c $ko>a.out;then

                                        echo error decompressing $ko, cancelling...

                                        rrr_flg=0

                                        exit

                                    fi

                                    ;;

                                xz)

                                    # parameter free nm runs against a.out file from current directory, i.e. generated above

                                    if ! unxz -c $ko>a.out;then

                                        echo error decompressing $ko, cancelling...

                                        rrr_flg=0

                                        exit

                                    fi

                                    ;;

                                *)

                                    # TODO raise error

                                    echo error anomaly decompressing $k, cancelling...                    

                                    rrr_flg=0

                                    exit

                                    ;;

                            esac

                            eval $cmd|

                                sed -n 's/^ \+U //p'|

                                sed -ns -e '{s/ /\n/g;/^$/!p;}'|

                                sort -u|

                                while read sym;do

                                    if [[ -n "$CONFIG_HAVE_UNDERSCORE_SYMBOL_PREFIX" ]];then

                                        sym="${sym#_}"

                                    fi

                                    echo "#define __KSYM_${sym} 1"

                                done

                        done

                    done|sort -u>include/generated/autoksyms.h.extern

                    if [[ 0 -ne $? ]];then

                        rrr_flg=0

                    fi

                    if [[ ! -f include/generated/autoksyms.h.extern ]];then

                        echo kernel out of the tree generated file not found: include/generated/autoksyms.h.extern   

                    elif [[ ! -z $rrr_flg ]];then

                        echo kernel out of the tree file generation failed, cancelling...                            

                    else

                        # generated file display

                        echo kernel out of the tree generated file display:

                        cat include/generated/autoksyms.h.extern

                        # test patch

                        if ! patch --dry-run -p1<$full_path_to_kernel_unused_ksyms_trim_patch;then

                            echo patch test of kernel file failed, cancelling...

                        else

                            # apply patch with backup

                            if ! patch -b -p1<$full_path_to_kernel_unused_ksyms_trim_patch;then

                                echo kernel config file patching with backup failed, cancelling...

                            else

                                echo kernel original file backup: scripts/adjust_autoksyms.sh.orig

                                # manual setting

                                #make nconfig # enable CONFIG_TRIM_UNUSED_KSYMS

                                #make menuconfig

                                

                                # automatic setting

                                # test existing .conf.sed[::digit::] to avoid sed backuo feature to overwrite & setting index variable accordingly

                                unset sed_bck_ext_ndx

                                while [[ -f .config.sed$sed_bck_ext_ndx ]];do

                                    #((sed_bck_ext_ndx++));

                                    # shorter form;

                                    sed_bck_ext_ndx+=1;

                                done

                                if ! sed -i.sed$sed_bck_ext_ndx 's/# CONFIG_TRIM_UNUSED_KSYMS is not set/CONFIG_TRIM_UNUSED_KSYMS=y/g' .config;then

                                    echo error activating TRIM_UNUSED_KSYMS in kernel config file with sed, cancelling...

                                else

                                    echo TRIM_UNUSED_KSYMS activated in kernel config file

                                    # sets MAKOPTS variable if according defintion file exists, i.e. Gentoo portage style there, e.g. MAKEOPTS="-j3 -l3".

                                    if [[ -f /etc/portage/env/makeopts-but.conf ]];then

                                        echo Gentoo portage type specific file detected: /etc/portage/env/makeopts-but.conf

                                        if ! MAKEOPTS_BUT=$(grep '^[[:space:]]*MAKEOPTS="[[:space:]]*-j[0]*[1-9]*[0-9]*[[:space:]]*-l[0]*[1-9]*[0-9]*[[:space:]]*"[[:space:]]*$' /etc/portage/env/makeopts-but.conf| tail -n1);then

                                              MAKEOPTS_BUT=$(grep '^[[:space:]]*MAKEOPTS="[[:space:]]*-j[0]*[1-9]*[0-9]*[[:space:]]*"[[:space:]]*$' /etc/portage/env/makeopts-but.conf| tail -c1)

                                        fi

                                    fi

                                    [[ ! -z $MAKEOPTS_BUT ]] && MAKEOPTS=${MAKEOPTS_BUT#MAKEOPTS=} && unset MAKEOPTS_BUT && echo Gentoo portage type specific file validated || MAKEOPTS="-j1 -l1"

                                    if echo -e "kernel build started...\n"make ${MAKEOPTS//\"} && ! make ${MAKEOPTS//\"};then

                                        echo error building TRIM_UNUSED_KSYMS featured kernel, cancelling...

                                    elif echo -e "kernel builded\nkernel install started...\n"make ${MAKEOPTS//\"} install && make ${MAKEOPTS//\"} install;then

                                        echo TRIM_UNUSED_KSYMS enabled kernel installed

                                    else

                                        echo error installing TRIM_UNUSED_KSYMS featured kernel

                                    fi

                                    

                                    # restoring initial environment, e.g. files

                                    echo restoring unpatched files:

                                    # SUSPENDED reversing initial sed inline substitution

                                    #sed -i 's/CONFIG_TRIM_UNUSED_KSYMS=y/# CONFIG_TRIM_UNUSED_KSYMS is not set/g' .config

                                    # ACTIVE restore initial file with sed generated backup file 

                                    if [[ ! -f .config.sed$sed_bck_ext_ndx ]];then

                                        echo sed originated backup of original kernel config file [e.g. .config.sed$sed_bck_ext_ndx] not found, continuing...

                                    elif mv .config.sed$sed_bck_ext_ndx .config;then

                                        echo TRIM_UNUSED_KSYMS deactivated in restored kernel config file

                                    else

                                        echo error restoring .config.sed$sed_bck_ext_ndx as original kernel config file, please check & proceed manually, continuing...

                                    fi

                                    unset sed_bck_ext_ndx

                                    # SUSPENDED reverse patch method to restore prepatch hernel file

                                    #if patch -p1 -R < $full_path_to_kernel_unused_ksyms_trim_patch;then

                                    #    echo prepatch kernel file restored

                                    #else

                                    #   echo error reversing patched file scripts/adjust_autoksyms.sh

                                    #fi

                                    # ACTIVE overwrite patched file by renaming backuped one instead

                                    if mv scripts/adjust_autoksyms.sh.orig scripts/adjust_autoksyms.sh;then

                                        echo prepatch kernel file restored from scripts/adjust_autoksyms.sh.orig

                                    else

                                        echo error restoring prepatch kernel file scripts/adjust_autoksyms.sh.orig

                                    fi

                                fi

                            fi

                        fi

                        echo remove temporary files:

                        echo deleting temporary file: include/generated/autoksyms.h.extern && ( rm include/generated/autoksyms.h.extern || echo error deleting include/generated/autoksyms.h.extern, please check manually, continuing... )

                    [[ -f ./a.out ]] && ( echo deleting kernel module compression related temporary file: a.out && rm a.out || echo error deleting file a.out, please check manually, continuing... )

                    fi

                fi

            fi

        fi

        unset full_path_to_kernel_unused_ksyms_trim_patch

    fi

fi

[[ ! -z ${dst_dir=+x} ]] && unset dst_dir
```

Should be saved with a # name to preserve previous script set, if required.

Changes:

-Called scriot integration, i.e. not required anymore.

-Single command line argument, not two with optional second as before.

-Better restored kernel directory, i.e patched files restored & temporary files removed.

TODO: Plz read previous post.

Thks 4 ur attention, interest & support.

----------

