[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

RFS scrubbing scripts [was: package requests for grip]




I thought I would give this topic a better heading, in case it's missed by interested parties.

I didn't understand all of Neil's comments with regards to including more scrubbing in grip itself, but  i did want to answer the call to provide scripts that are being used.  I attach mine. If it fails to get to the list as an attachment I will insert in a next message.

I don't think I am doing anything you guys havent already thought of. Looking at the first part of my script,  I essentially do the following:

    if rm -rf usr/share/doc  \
&& rm -rf usr/share/man   \
&& rm -rf usr/share/doc-base  \
&& rm -rf var/cache/apt  \
&& rm -rf var/cache/man \
&& rm -rf var/cache/debconf \
&& rm -rf var/lib/apt/lists  \
&& rm -rf var/lib/dpkg/      \
&& rm -rf var/log/installer/cdebconf \
&& $SUDO rm -rf var/log/news/*

and remove perl:

 rm -rf usr/share/perl

Also, after my first (NFS based) boot, I apt-get the purgelocale package and run that to clean out all language locales except English.  Then I remove purgelocale itself again.

The above lines blow away about 50% of a standard debian minimal install,  bringing it in the 100MB range I think (uncompressed).

The next part of the script removes some stuff that I found causes problems (such as udev and things that shouldn't be inherited across machines) and then I start installing our own RFS changes ( serial boot console, network setup,  rc.local, passwd files etc) that can be ignored. Finally I create the jffs2 images (one containing the summary file).

I think the issue of how far one needs to go with minimalizing obviously depends on the size of the flash you intent to use.  Given the market trend, I limited my efforts to producing <64MB filesystems and called it a day.  With a 256MB flash at ~$12 or so,  I have plenty of room to send out future flash upgrades that can be installed side by side. In end, whether I install packages that have /usr/man removed per package or whether I blow away /usr/man at the end doesnt matter.

With regards to board (vendor) specific changes,  I would hesitate to spend too much time in incorporating such a mechanism in Emdebian.  Its a game where you are always catching up to whats in the market place and at some point everyone is going to have to write some scripts to modify an RFS anyway. I also noticed some calls for ready-to-run kernels within this project: I would hesitate there too. We use an at91sam9260 (and G20). I am sure no generic ARM kernel would even boot. Even 9260 specific kernels probably wouldnt boot because all these chip mulitplex their hardware on I/O lines and depending on whose board you buy, you have different hardware available.  I got myself in a bad muddle once when a serial port I/O pin got programmed to be used as an SPI interface in a newer kernel release and a dataflash driver was loaded when there was none.

For completeness, and in case anyone in interested, I put a copy of my own notes on how to create a Debian RFS at the bottom here.  It only applies of you start on Debian based i86 and are able to boot & complete the debootstrap process on your actual target board, with the RFS NFS mounted. I realize this isnt really appropiate for this mailing list.



====================================================================

RootFS creation instructions (ARM,  9260 processor)
--------------------------------------------------------------------------------
my working folder is /arm/debootstrap/nfs

#1st stage:
mkdir /arm/debootstrap/nfs
cd /arm/debootstrap/nfs
debootstrap --foreign --arch armel  --verbose  lenny  $PWD

# make sure we can log in !
cp /etc/passwd etc/passwd
cp /etc/shadow etc/shadow
cp /etc/group etc/group
echo "proc /proc proc defaults 0 0" > etc/fstab
echo "192.168.0.3:/arm/debootstrap/nfs / nfs defaults 0 1" >> etc/fstab

#Make sure the root account uses /bin/bash as the shell, since tcsh will not be on the bare Debian install !
 
#Must create dev/console and dev null or dont get a prompt:
cd /arm/debootstrap/nfs/dev
mknod -m 660 console c 5 1
mknod -m 660 null c 1 3
mknod  ttyS0 c 4 64
mknod  ttyS1 c 4 65

#Now boot the kernel with: (at u-boot)
setenv bootargs console=ttyS0  root=/dev/nfs rw ip=dhcp nfsroot=192.168.0.3:/arm/debootstrap/nfs init=/bin/bash
bootd

#kernel now boots to bash prompt....
#Next commands are on the ARM board:
mount -n -o remount,rw /
mount /proc

# 2nd stage of debootstrap, within the guest system, to finalise the installation:
cd /
export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
./debootstrap/debootstrap --second-stage

(if you get lots of errors installing certain packages do dpkg --configure -a to see which ones. One of them was debconf but a dpkg-reconfigure debconf solved that)
Note: passwd and shadow files must not contain blank lines at the end of the files.
and add (on Debian i86 host, with an editor)

T0:23:respawn:/sbin/getty -L ttyS0 115200 vt100 to /etc/inittab.

#reboot without the init=/bin/bash statement in the u-boot variable
#if the deboostrap 2nd staged failed, you have manually install everything in here, since it didnt #get done
 cd /var/cache/apt/archives/
 dpkg -i -R $PWD

#manually correct the apt/source.list - it seems hosed. Do this on Debian i86  with an editor
deb http://ftp.us.debian.org/debian/ lenny main
deb-src http://ftp.us.debian.org/debian/ lenny main
deb http://security.debian.org/ lenny/updates main
deb-src http://security.debian.org/ lenny/updates main

#and do a apt-get update  on the board
apt-get update
#Wrap up with

apt-get install dropbear file tcsh hostname ifupdown nano mount

The result RFS is what I use as the input to the (hopefully) attached script.

Cheers,


Gertjan

















#!/bin/bash
# do NOT run this as root !


# 19.03.2006
# Gertjan Hofman
# mostly geared to Debian SID now (unstable)
# July 2009: added sumtool to add JFFS2 block info to device and speed up boot times



case $# in
3)    echo ; echo Creating jffs2 image from $1. Expanding to rootfs;;
*)    echo "Usage: add_rfs_mod <name of folder containing rfs> <hostname> <eabi/oabi>"
     exit 1 ;;
esac


# set up variables:

# =================== START OF  DEFINITIONS ====================
SUDO="sudo"

# where the input  root filesystem is:
ROOT_IN=$1

# where the output root filesystem is:
ROOT=${PWD}/rootfs

# store present working dir
STARTPWD=${PWD}

# where our files are:
POST_INSTALL_COMMON=$PWD/post_install_common

if   [ $3 = "oabi" ] ; then
   POST_INSTALL_BINARY=$PWD/post_install_oabi
elif [ $3 = "eabi" ] ; then
   POST_INSTALL_BINARY=$PWD/post_install_eabi
else
   echo "Illegal ABI $3"
   exit 1
fi


# location of OpenEmbedded created binaries (needed for mkfs)
JFFS2_BIN=/usr/sbin/

# =================== END OF DEFINITIONS ====================


echo -n "Removing old rootfile system..............................."
if $SUDO rm -rf ${ROOT}
then
   echo "OK"
else
   echo "Can not copy the file system to ${ROOT}"
   exit
fi


echo -n "Copying rootfile system...................................."
if $SUDO cp -a ${ROOT_IN} ${ROOT}
then
   echo "OK"
else
   echo "Can not copy the file system to ${ROOT}"
   exit
fi



# change the owner to me:
$SUDO chown -R ${USER}:users ${ROOT}

# ok - going into folder:
cd ${ROOT}
#$SUDO tar -xf ../$1


#before we remove apt, lets get a listing of installed packages
echo -n "Storing list of APT packages..............................."
if [ -x  /usr/bin/dpkg ]  && dpkg --get-selections --admindir=${ROOT}/var/lib/dpkg > ${ROOT}/etc/apt/packages.list
then
   echo  "OK"
else
   echo  "FAILED"
   exit
fi


# remove docs
echo -n "Removing doc/man pages....................................."
if rm -rf usr/share/doc  \
&& rm -rf usr/share/man   \
&& rm -rf usr/share/doc-base  \
&& rm -rf var/cache/apt  \
&& rm -rf var/cache/man \
&& rm -rf var/cache/debconf \
&& rm -rf var/lib/apt/lists  \
&& rm -rf var/lib/dpkg/      \
&& rm -rf var/log/installer/cdebconf \
&& $SUDO rm -rf var/log/news/*
then
   echo "OK"
else
   echo "Failed"
fi

# remove Perl
echo -n "Removing Perl (!).................. ......................."
if rm -rf usr/share/perl
then
   echo "OK"
else
   echo "Failed"
fi




# save some locales (which one are we using ?)
# note: this is now done by using apt-get install localepurge on the host
# and running localepurge
echo -n "Purging Locales............................................"
if rm -rf usr/share/locale/fr \
&& rm -rf usr/share/locale/de \
&& rm -rf usr/share/locale/ru \
&& rm -rf usr/share/locale/pl \
&& rm -rf usr/share/locale/sv \
&& rm -rf usr/share/locale/es \
&& rm -rf usr/share/locale/ca \
&& rm -rf usr/share/locale/ja \
&& rm -rf usr/share/locale/tr \
&& rm -rf usr/share/locale/vi \
&& rm -rf usr/share/locale/cs \
&& rm -rf usr/share/locale/nl \
&& rm -rf usr/share/locale/hu
then
   echo "OK"
else
   echo "Failed"
fi

echo -n "Removing mystery .nfs files ..............................."
if find $ROOT -name ".nfs*" -print | xargs rm -f
then
   echo "OK"
else
   echo "Failed"
fi


echo -n "Empty sys and proc........................................."
# empty sys and proc
#rm -rf sys/*
rm -rf proc/*
echo "OK"


echo -n "Removing udev ............................................."
# remove dev udev remnants
if rm -fr dev/.udev
then
   echo "OK"
else
   echo "Failed"
fi

echo -n "Removing dnsmasq start up link in rcX.d...................."
# remove dev udev remnants
if rm -fr  etc/rc2.d/S15dnsmasq
then
   echo "OK"
else
   echo "Failed"
fi


echo -n "Removing/creating  lib modules............................."
# remove kernel mods, we have none:
if rm -rf lib/modules/* &&  \
  mkdir -p lib/modules &&  \
  cp -a ${POST_INSTALL_BINARY}/lib/modules/*  lib/modules/
then
   echo "OK"
else
   echo "Failed"
fi



echo -n "Removing timezone info ...................................."
# remove timezone info we dont need:
du -a usr/share/zoneinfo/ | grep -v America | awk '{print $2}' | xargs rm -rf
echo "OK"

#entropy is low, so random blocks, but urandom never does...
#echo "replacing dev/random with urandom"
#rm dev/random
#ln -s urandom dev/random


# re-instate some folder structures for apt in case we ever use apt-get
mkdir -p var/cache/apt
mkdir -p var/lib/apt/lists/partial
mkdir -p var/cache/apt/archives/partial


echo -n "Creating xauth dunmmy......................................"
# create a dummy xauth file -login errors ?
mkdir -p usr/X11R6/bin
cp ${POST_INSTALL_COMMON}/usr/X11R6/bin/xauth usr/X11R6/bin
echo "OK"



echo -n "Updating etc files........................................."
cp -a ${POST_INSTALL_COMMON}/etc/*  etc/
echo "OK"

echo -n "Updating Webserver files..................................."
cp -a ${POST_INSTALL_COMMON}/usr/local/apache  usr/local/
echo "OK"

echo -n "Updating usr/edaq/ (*should be in usr-local*..............."
cp -a ${POST_INSTALL_COMMON}/usr/edaq  usr/
echo "OK"

echo -n "Updating usr/bin/ (*should be in usr-local*................"
cp -a ${POST_INSTALL_COMMON}/usr/bin/*  usr/bin/
echo "OK"





echo -n "Creating mount points......................................"
# create mount points
test -d pc_home     || mkdir pc_home
test -d arm         || mkdir arm
test -d permanent   || mkdir permanent
test -d mnt/flash01 || mkdir mnt/flash01
test -d mnt/flash02 || mkdir mnt/flash02
test -d mnt/flash03 || mkdir mnt/flash03
test -d mnt/flash04 || mkdir mnt/flash04
test -d evolution_info || mkdir evolution_info
echo "OK"



echo -n "Creating additional dev files.............................."
test -a dev/mtdblock0 || $SUDO mknod dev/mtdblock0 b 31 0
test -a dev/mtdblock1 || $SUDO mknod dev/mtdblock1 b 31 1
test -a dev/mtdblock2 || $SUDO mknod dev/mtdblock2 b 31 2
test -a dev/mtdblock3 || $SUDO mknod dev/mtdblock3 b 31 3
test -a dev/mtdblock4 || $SUDO mknod dev/mtdblock4 b 31 4
# the major=misc=10, the minor is from ./include/linux/miscdevice.h
test -a dev/watchdog  || $SUDO mknod dev/watchdog  c 10 130

test -a dev/mtd0   || $SUDO mknod dev/mtd0 c 90 0
test -a dev/mtd1   || $SUDO mknod dev/mtd1 c 90 2
test -a dev/mtd2   || $SUDO mknod dev/mtd2 c 90 4
test -a dev/mtd3   || $SUDO mknod dev/mtd3 c 90 6
test -a dev/mtd4   || $SUDO mknod dev/mtd4 c 90 8
test -a dev/ttyS0  || $SUDO mknod dev/ttyS0 c 4 64
test -a dev/ttyS1  || $SUDO mknod dev/ttyS1 c 4 65
test -a dev/ttyS2  || $SUDO mknod dev/ttyS2 c 4 66
test -a dev/ttyS3  || $SUDO mknod dev/ttyS3 c 4 67


echo "OK"



echo -n "Copying EDAQ program files................................."
if cp -a ${POST_INSTALL_COMMON}/usr/local/edaq usr/local/
then
   echo "OK"
else
   echo "Failed"
fi


echo -n "Creating usr/local/bin and populating......................"
if \
mkdir -p usr/local/bin && \
cp  ${POST_INSTALL_COMMON}/usr/local/bin/*    usr/local/bin/
then
   echo "OK"
else
   echo "Failed"
fi


# note: in future, eliminate usr/bin and put everything in usr/local
echo -n "Creating arch dep  usr/{local}/bin and populating.........."
if \
mkdir -p usr/local/bin && \
cp  ${POST_INSTALL_BINARY}/usr/local/bin/*  usr/local/bin/ && \
cp  ${POST_INSTALL_BINARY}/usr/bin/*  usr/bin/
then
   echo "OK"
else
   echo "Failed"
fi

echo -n "Creating binary usr/local/lib and populating..............."
if \
mkdir -p usr/local/lib && \
cp -a ${POST_INSTALL_BINARY}/usr/local/lib/* usr/local/lib
then
   echo "OK"
else
   echo "Failed"
fi

echo -n "Creating script usr/local/lib and populating..............."
if \
cp -a ${POST_INSTALL_COMMON}/usr/local/lib/* usr/local/lib
then
   echo "OK"
else
   echo "Failed"
fi




#3/2/2008: decided to have /usr/local run off devel host.
echo -n "Note: Moving Usr_Local to symlink.........................."
if \
mv  usr/local usr/local.LOCAL && \
ln -s /arm/edaq_usr_local usr/local
then
   echo "OK"
else
   echo "Failed"
fi


echo -n "Setting hostname .........................................."
if rm -f etc/hostname && echo $2 > etc/hostname
then
   echo "OK"
else
   echo "Failed"
fi



# link tcl lib - not sure why this is missing:
#echo -n "Creating TCL dynlib symlink................................"
#if cd  usr/lib && \
#    ln -s  libtcl8.5.so.0  libtcl8.5.so && \
#    cd - >>/dev/null
#then
#    echo "OK"
#else
#    echo "Failed"
#fi
#if cd usr/lib && ln -s libtcl8.5.so.0 libtcl8.5.so && cd - > /dev/null
#then
#    echo "OK"
#else
#    echo "Failed"
#fi


echo -n "Adding LD_LIBRARY_PATH=/usr/local/lib ....................."
if echo "export LD_LIBRARY_PATH=/usr/local/lib" >> etc/profile &&
  echo "setenv LD_LIRARTY_PATH /usr/local/lib" >> etc/csh.cshrc
then
   echo "OK"
else
   echo "Failed"
fi



echo -n "Copying root user files  .................................."
if cp -a ${POST_INSTALL_COMMON}/root/.ssh  root/
then
   echo "OK"
else
   echo "Failed"
fi


echo -n "Clean up SVN files ........................................"
if find ${ROOT} -name .svn | xargs rm -rf
then
   echo "OK"
else
   echo "Failed"
fi


# does the version number file exist ?
if ! [ -r "${STARTPWD}/rfs_version_number" ] ; then
   echo "Note: RFS version file not there, creating"
   echo $(date) >  ${STARTPWD}/rfs_version_number
   echo 1000    >> ${STARTPWD}/rfs_version_number
fi

# open the file. First line is a date, the second line is the version number. I am
# not sure why the \n does get into the version_info variable.
# the $NF gets the last field

version_info=$(cat ${STARTPWD}/rfs_version_number)
version_num=$(echo $version_info | awk '{printf $NF}')

#  increment the version.
let version_num=version_num+1

# write back to local SVN'ed file:
echo $(date)        >  ${STARTPWD}/rfs_version_number
echo $version_num   >> ${STARTPWD}/rfs_version_number

# write it to the rootfile system
echo $(date)        >  etc/rfs_version_number
echo $version_num   >> etc/rfs_version_number



#=================== done =========================
# return to up directory.

cd ..


# finally, create RFS image



OUTNAME=`date +%H-%M-%S-%F`
OUTNAME=`date +%Y-%m-%d-%H-%M`


rm -f $OUTNAME.jffs2

echo Creating filesystem
# changed from -x lzo in OE to -x zlib in Ubuntu

# -x - remove compressor
# -root build RFS from root=
# --faketime change all file times to zero
# --pad to end of erase block
# -n no clean markers to every erase block

$SUDO ${JFFS2_BIN}/mkfs.jffs2 \
  -x rtime  \
 --root=${ROOT} \
 --faketime \
 --output=$OUTNAME.jffs2 \
 --pad \
 --little-endian \
 --eraseblock=0x20000 \
 -n  \
 --squash-uids

# --compression-mode=none
$SUDO ${JFFS2_BIN}/sumtool --eraseblock=0x20000 -n -p -i $OUTNAME.jffs2 -o ${OUTNAME}_sum.jffs2

echo Created $OUTNAME.jffs2 filesystem and sum version ${OUTNAME}_sum.jffs2






Reply to: