#!/bin/sh # # kprune: An interactive script that allows selective pruning # of the kernel source tree, based on user input, and # on the information contained in the ".config" file. # # Options: # -a Automatic prune mode based on .config file data. # -d Debug mode, don't delete anything. (implies "-t") # -h Give help # -t Keep a tally/total of kB deleted. # -q quiet delete mode (implies "-a") # # The v2.0 kernel tree is now about 23MB in total and I hacked up # this script to address that. It only targets whole directories and # a handful of large (>50k) drivers. If that isn't good enough then # you can do additional pruning by hand, or buy another hard disk. :) # Use at own risk, no warranty, distributed under GPL, etc. etc. # # Paul Gortmaker VERBOSE=y AUDIT=n AUTO=n DEBUG=n DISKSPACE=0 NAME=kprune # Are we using bash (Can we *not* be ?) if [ -z "$BASH" ];then echo "$NAME requires bash" 1>&2 exit 1 fi # Report some hocus-pocus usage message with optional error message to stderr usage () { if [ -n "$1" ];then echo $NAME: Illegal option \"$1\" 1>&2 EXITVAL=1 else EXITVAL=0 fi echo "Usage: $NAME [-a] [-d] [-q] [-t]" echo Prunes kernel of unused source based on user input and .config file. echo -e \\t\-a\\tauto mode, delete only based on \".config\" file info. echo -e \\t\-d\\tdebug mode, only report what would have been deleted. echo -e \\t\-h\\tprint this help message. echo -e \\t\-q\\tquiet mode, implies non-interactive \"-a\" mode. echo -e \\t\-t\\ttally mode, report on total kB of files deleted. exit $EXITVAL } # Delete funciton with auditing ability. # DEBUG is for testing the script w/o untarring the kernel 50 times... # usage: delete file1 [file2] [file3] ... [fileN] # function delete () { if [ "$AUDIT" = "y" ]; then SAVING=`du -csk $* 2> /dev/null | tail -n1 | sed 's/[ ]total//'` DISKSPACE=$[$DISKSPACE+$SAVING] fi if [ "$DEBUG" = "y" ];then echo Debug mode, would have deleted "$SAVING"kB in file\(s\): for i in $* do echo -e \\t $i done echo Currently tagged "$DISKSPACE"kB of files. echo else rm -rf $@ fi } # Grab some user input. # usage: readln prompt default # function readln () { if [ "$AUTO" = "y" ]; then if [ "$VERBOSE" = "y" ]; then echo -e "$1":\\tDefault="$2" fi ans=$2 else case "$2" in "y") defprompt="Y/n" ;; "n") defprompt="N/y" ;; esac echo -n "$1" [$defprompt] IFS='@' read ans &2 exit 1 fi # See what the user has enabled at the moment source .config # The "make dep" step will barf if we prune the tree before it # is run, so we make sure that is done before pruning as well. if [ ! -f .depend ]; then echo You must run \"make depend\" before using $NAME. 1>&2 exit 1 fi # This implictly assumes that the asm dirs have the name "asm-$ARCH" ARCHDIRS="alpha i386 m68k mips ppc sparc" # There is no magic CONFIG_XXX that will give us the arch as easy as this. # Using "uname -m" is ugly because it can be i[3456]86, etc. unalias ls 2> /dev/null ARCH=`ls -l include/asm | sed 's/^.*asm-//'` # Lists of big architechture specific files that *aren't* tied to a # CONFIG_XXX option. Nothing for some of these guys at the moment. FILES_i386="" FILES_mips="" FILES_ppc="" FILES_alpha="drivers/char/tga.c" FILES_sparc="drivers/sbus" FILES_m68k="\ drivers/block/amiflop.c \ drivers/block/ataflop.c \ drivers/scsi/atari_* " comment "Unused Processor Architecture Specific Files" for i in $ARCHDIRS do if [ $i != $ARCH ]; then ARCH_LIST=FILES_$i ARCH_FILES=$(eval echo "\${$ARCH_LIST}") readln "Delete files for $i architecture" y if [ $ans = "y" ]; then delete arch/"$i" include/asm-"$i" $ARCH_FILES fi fi done # Various unused filesystems can be deleted as well FSLIST="\ CONFIG_AFFS_FS;fs/affs \ CONFIG_FAT_FS;fs/msdos \ CONFIG_EXT_FS;fs/ext \ CONFIG_EXT2_FS;fs/ext2 \ CONFIG_HPFS_FS;fs/hpfs \ CONFIG_ISO9660_FS;fs/isofs \ CONFIG_MINIX_FS;fs/minix \ CONFIG_NFS_FS;fs/nfs \ CONFIG_PROC_FS;fs/proc \ CONFIG_SMB_FS;fs/smbfs \ CONFIG_UMSDOS_FS;fs/umsdos \ CONFIG_VFAT_FS;fs/vfat \ CONFIG_XIA_FS;fs/xiafs " comment "Unused file systems" walklist $FSLIST # Can also nuke SCSI or at least some large drivers if not being used. # Only the real monsters are targeted at the moment SCSIDRVRS="\ CONFIG_BLK_DEV_SD;drivers/scsi/sd.c \ CONFIG_CHR_DEV_ST;drivers/scsi/st.c \ CONFIG_BLK_DEV_SR;drivers/scsi/sr.c \ CONFIG_CHR_DEV_SG;drivers/scsi/sg.c \ CONFIG_SCSI_ADVANSYS;drivers/scsi/advansys.* \ CONFIG_SCSI_BUSLOGIC;drivers/scsi/BusLogic.* \ CONFIG_SCSI_NCR53C7xx;drivers/scsi/53c[78]* \ CONFIG_SCSI_AIC7XXX;drivers/scsi/aic7xxx* \ CONFIG_SCSI_AM53C974;drivers/scsi/AM53C974.* \ CONFIG_SCSI_QLOGIC_ISP;drivers/scsi/qlogicisp* " comment "Unused SCSI support/drivers" if [ -z "$CONFIG_SCSI" ];then walklist "CONFIG_SCSI;drivers/scsi" else walklist $SCSIDRVRS fi # drivers/char is a mess. (i.e. no subdirs). Target large files anyway. CHARDRVRS="\ CONFIG_BAYCOM;drivers/char/baycom.c \ CONFIG_CYCLADES;drivers/char/cyclades.c \ CONFIG_DIGI;drivers/char/pcxx*;drivers/char/digi* \ CONFIG_FTAPE;drivers/char/ftape \ CONFIG_ISTALLION;drivers/char/istallion.c \ CONFIG_RISCOM8;drivers/char/riscom8* \ CONFIG_SCC;drivers/char/scc.c \ CONFIG_SERIAL;drivers/char/serial.c \ CONFIG_STALLION;drivers/char/stallion.c \ CONFIG_QIC02_TAPE;drivers/char/tpqic02.c " comment "Unused Character Devices" walklist $CHARDRVRS # drivers/block is a mess. (i.e. no subdirs). Target large files anyway. BLKDRVRS="\ CONFIG_BLK_DEV_FD;drivers/block/floppy.c \ CONFIG_BLK_DEV_IDE;drivers/block/ide.* \ CONFIG_BLK_DEV_IDECD;drivers/block/ide-cd.c \ CONFIG_BLK_DEV_IDETAPE;drivers/block/ide-tape.* " comment "Unused Block Drivers" walklist $BLKDRVRS # drivers/net is a mess. (i.e. no subdirs). Target large files anyway. # The dgrs firmware is good for 1/2 MB!! NETDRVRS="\ CONFIG_ARCNET;drivers/net/arcnet.c \ CONFIG_DE4X5;drivers/net/de4x5.* \ CONFIG_DEPCA;drivers/net/depca.* \ CONFIG_DGRS;drivers/net/dgrs* \ CONFIG_EWRK3;drivers/net/ewrk3.* \ CONFIG_PPP;drivers/net/ppp.c \ CONFIG_PT;drivers/net/pt.* \ CONFIG_SMC9194;drivers/net/smc9194.* \ CONFIG_SK_G16;drivers/net/sk_g16.* \ CONFIG_WAVELAN;drivers/net/wavelan.* " comment "Unused Network Device Drivers" if [ -z "$CONFIG_NETDEVICES" ];then walklist "CONFIG_NETDEVICES;drivers/net" else walklist $NETDRVRS fi # drivers/cdrom is a mess. (i.e. no subdirs). Target large files anyway. CDROMDRVRS="\ CONFIG_AZTCD;drivers/cdrom/aztcd.c \ CONFIG_CDU31A;drivers/cdrom/cdu31a.c \ CONFIG_CDU535;drivers/cdrom/sonycd535.c \ CONFIG_MCDX;drivers/cdrom/mcdx.c \ CONFIG_OPTCD;drivers/cdrom/optcd.c \ CONFIG_SBPCD;drivers/cdrom/sbpcd.c " comment "Unused CD-ROM Drivers (non IDE/SCSI)" if [ -z "$CONFIG_CD_NO_IDESCSI" ];then walklist "CONFIG_CD_NO_IDESCSI;drivers/cdrom" else walklist $CDROMDRVRS fi # ISDN is nice and tidy with drivers in subdirs :-) ISDNDRVRS="\ CONFIG_ISDN_DRV_TELES;drivers/isdn/teles \ CONFIG_ISDN_DRV_ICN;drivers/isdn/icn \ CONFIG_ISDN_DRV_PCBIT;drivers/isdn/pcbit " comment "Unused ISDN Drivers" if [ -z "$CONFIG_ISDN" ];then walklist "CONFIG_ISDN;drivers/isdn" else walklist $ISDNDRVRS fi # Unused net protocols, etc NETPROTS="\ CONFIG_ATALK;net/appletalk \ CONFIG_AX25;net/ax25 \ CONFIG_BRIDGE;net/bridge \ CONFIG_INET;net/ipv4 \ CONFIG_IPX;net/ipx \ CONFIG_NET;net/802 \ CONFIG_NETROM;net/netrom " comment "Unused Networking Protocols/Functionality" walklist $NETPROTS # Nuke other driver subdirs as an all or nothing approach. comment "Misc. Other Drivers, documentation, etc." walklist "CONFIG_SOUND;drivers/sound" walklist "CONFIG_PCI;drivers/pci" # Don't blast the Documentation dir unless user explicitly says "y" # Also offer to clean up misc README files, Changelog, etc. readln "Delete Documentation directory and all README/Changelog files" n if [ $ans = "y" ];then delete Documentation READMES=`find . -name 'README*' -print` if [ -n "$READMES" ];then delete $READMES fi CHANGELOG=`find . -name 'Change*' -print` if [ -n "$CHANGELOG" ];then delete $CHANGELOG fi fi if [ "$AUDIT" = "y" ];then echo; echo "There was a total of "$DISKSPACE"kB of deleted files." fi if [ "$VERBOSE" = "y" ];then echo echo "After compiling and installing the kernel, you may wish to do:" echo -e \\t"rm -f vmlinux" echo -e \\t"rm -f arch/i386/boot/compressed/piggy.o" echo -e \\t"rm -f arch/i386/boot/compressed/vmlinux" echo -e \\t"rm -f arch/i386/boot/zImage" echo -e \\t"rm -f core \`find . -name '*.a' -print\`" echo "to recover 2 -> 3MB without sacrificing future rebuild times." echo fi