#!/bin/bash # buildrootfilesystem v0.2 10/23/01 # www.embeddedlinuxinterfacing.com # # The original location of this script is # http://www.embeddedlinuxinterfacing.com/chapters/04/buildrootfilesystem # # Copyright (C) 2001 by Craig Hollabaugh # # This program is free software; you can redistribute it and/or modify it under # the terms of the GNU Library General Public License as published by the Free # Software Foundation; either version 2 of the License, or (at your option) any # later version. # # This program is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more # details. # # You should have received a copy of the GNU Library General Public License # along with this program; if not, write to the Free Software Foundation, Inc., # 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # umask 022 SRCFILELOC=/root/cross BUILDLOC=$SRCFILELOC/builds case "$1" in "ppc" ) ARCH=powerpc TARGET=powerpc-linux #MVRPMLOC=ftp://ftp.mvista.com/pub/Journeyman/cd2/ppc_8xx/apps/ MVRPMLOC=http://www.embeddedlinuxinterfacing.com/ftp.mvista.com/pub/Journeyman/cd2/ppc_8xx/apps/ TEMPFSLOC=$BUILDLOC/$ARCH-rootrpms/opt/hardhat/devkit/ppc/8xx/target/ ;; "arm" ) ARCH=arm TARGET=arm-linux #MVRPMLOC=ftp://ftp.mvista.com/pub/Journeyman/cd1/arm_sa_le/apps/ MVRPMLOC=http://www.embeddedlinuxinterfacing.com/ftp.mvista.com/pub/Journeyman/cd1/arm_sa_le/apps/ TEMPFSLOC=$BUILDLOC/$ARCH-rootrpms/opt/hardhat/devkit/arm/sa_le/target/ ;; "i386" ) ARCH=i386 TARGET=i386 #MVRPMLOC=ftp://ftp.mvista.com/pub/Journeyman/cd1/x86_586/apps/ MVRPMLOC=http://www.embeddedlinuxinterfacing.com/ftp.mvista.com/pub/Journeyman/cd1/x86_586/apps/ TEMPFSLOC=$BUILDLOC/$ARCH-rootrpms/opt/hardhat/devkit/x86/586/target/ ;; * ) echo -n "Usage " `basename $0` echo " i386|arm|ppc [ramdisk]" exit 1 ;; esac # # Step 1 - Determine what packages to download # echo Step 1 - Determine what packages to download PACKAGES="glibc-2 bash procps textutils fileutils shellutils sysvinit netbase libncurses libstdc mount telnet-client net-tools ping gdbserver modutils" echo packages are $PACKAGES echo Step 1 - Complete echo # # Step 2 - Create build and new target root filesystem directories # echo Step 2 - Create build and new target root filesystem directories if [ ! -e /tftpboot ] then mkdir /tftpboot fi if [ ! -e $SRCFILELOC ] then mkdir $SRCFILELOC fi if [ ! -e $BUILDLOC ] then mkdir $BUILDLOC fi ROOTFSLOC=/tftpboot/$ARCH-rootfs echo Creating root file system for $ARCH rm -rf $ROOTFSLOC mkdir $ROOTFSLOC if [ ! -e $BUILDLOC/$ARCH-rootrpms ] then mkdir $BUILDLOC/$ARCH-rootrpms fi cd $ROOTFSLOC mkdir dev etc etc/init.d bin sbin lib usr usr/bin proc tmp chmod 755 . dev etc etc/init.d bin sbin lib usr usr/bin proc tmp echo Step 2 - Complete echo # # Step 3 - Download the packages # echo Step 3 - Download the packages cd $BUILDLOC/$ARCH-rootrpms lynx -dump $MVRPMLOC | grep ftp > /tmp/rpmlist for i in $PACKAGES do a=`grep $i /tmp/rpmlist` rpmurl=`echo $a | cut -d " " -f 2` # echo $rpmurl rpm=`basename $rpmurl` # echo $rpm if [ ! -f $BUILDLOC/$ARCH-rootrpms/$rpm ] then echo Getting $rpm wget $rpmurl else echo Have $rpm fi done echo Step 3 - Complete echo # # Step 4 - Extract the package's contents into a temporary directory # echo Step 4 - Extract the package/'s contents into a temporary directory cd $BUILDLOC/$ARCH-rootrpms # this is the old way, too slow because it converts rpms everytime #alien -t *rpm #find . -name "*tgz" -exec tar zxvf {} /; #rm -rf *tgz IFS=' ' for rpm in `ls *rpm` do if [ ! -f $rpm.extracted ] then alien -t $rpm tgz=`ls *tgz` tar zxvf $tgz rm -rf $tgz touch $rpm.extracted fi done echo Step 4 - Complete echo # # Step 5 - Copy the required programs # echo Step 5 - Copy the required programs echo #lib files cd $TEMPFSLOC/lib cp -av ld* $ROOTFSLOC/lib cp -av libc-* $ROOTFSLOC/lib cp -av libc.* $ROOTFSLOC/lib cp -av libutil* $ROOTFSLOC/lib cp -av libncurses* $ROOTFSLOC/lib cp -av libdl* $ROOTFSLOC/lib cp -av libnss_dns* $ROOTFSLOC/lib cp -av libnss_files* $ROOTFSLOC/lib cp -av libresolv* $ROOTFSLOC/lib cp -av libproc* $ROOTFSLOC/lib cp -av librt* $ROOTFSLOC/lib cp -av libpthread* $ROOTFSLOC/lib #libm and libstdc are needed by telnet-client cp -av libm* $ROOTFSLOC/lib cd $ROOTFSLOC/usr ln -s ../lib lib cd $TEMPFSLOC/usr/lib cp -av libstdc* $ROOTFSLOC/usr/lib #sbin files cd $TEMPFSLOC/sbin cp -av init ifconfig route *mod $ROOTFSLOC/sbin #bin files cd $TEMPFSLOC/bin cp -av bash cat ls mount umount ps $ROOTFSLOC/bin cp -av df kill ping chmod touch rm $ROOTFSLOC/bin cp -av echo $ROOTFSLOC/bin cd $ROOTFSLOC/bin ln -s bash sh #usr/bin files cd $TEMPFSLOC/usr/bin cp -av telnet gdbserver $ROOTFSLOC/usr/bin #helloworld cd $ROOTFSLOC/tmp cat > helloworld.c << ENDOFINPUT #include <stdio.h> int main(void) { int i; for (i = 1; i < 10; i++) { printf("Hello world %d times!/n",i); } } ENDOFINPUT if [ $ARCH == "i386" ] then gcc -g -o helloworld-$TARGET helloworld.c else $TARGET-gcc -g -o helloworld-$TARGET helloworld.c fi file helloworld-$TARGET chown -R root.root $ROOTFSLOC/* echo Step 5 - Complete echo # # Step 6 - Strip the required programs # echo Step 6 - Strip the required programs echo # strip it, strip it good if [ $ARCH == "i386" ] then strip -s -g $ROOTFSLOC/lib/* strip -s -g $ROOTFSLOC/bin/* strip -s -g $ROOTFSLOC/sbin/* strip -s -g $ROOTFSLOC/usr/bin/* strip -s -g $ROOTFSLOC/usr/lib/* else $TARGET-strip -s -g $ROOTFSLOC/lib/* $TARGET-strip -s -g $ROOTFSLOC/bin/* $TARGET-strip -s -g $ROOTFSLOC/sbin/* $TARGET-strip -s -g $ROOTFSLOC/usr/bin/* $TARGET-strip -s -g $ROOTFSLOC/usr/lib/* fi echo Step 6 - Complete echo # # Step 7 - Create configuration files # echo Step 7 - Create configuration files echo #etc files cd $TEMPFSLOC/etc cp -av protocols services $ROOTFSLOC/etc cd $ROOTFSLOC/etc cat > fstab << endofinput # <file system> <mount point> <type> <options> <dump> <pass> proc /proc proc defaults 0 0 endofinput if [ $# == 2 ] && [ $2 == "ramdisk" ] then echo "/dev/ram / ext2 defaults 0 0" >> fstab else echo "192.168.1.11:/tftpboot/$ARCH-rootfs / nfs defaults 1 1" >> fstab fi cat > inittab << endofinput id:2:initdefault: l2:2:wait:/etc/init.d/rcS 1:2:respawn:/bin/bash 2:6:wait:/etc/init.d/umountfs endofinput cat > init.d/rcS << endofinput #!/bin/bash /bin/mount -n -o remount,rw / # clear out mtab >/etc/mtab /bin/mount -a echo Starting Network /sbin/ifconfig lo 127.0.0.1 netmask 255.0.0.0 broadcast 127.255.255.255 /sbin/route add -net 127.0.0.0 netmask 255.0.0.0 lo endofinput case "$ARCH" in "powerpc" ) cat >> init.d/rcS << endofinput /sbin/ifconfig eth0 192.168.1.22 netmask 255.255.255.0 /sbin/route add default gw 192.168.1.254 eth0 endofinput ;; "arm" ) cat >> init.d/rcS << endofinput /sbin/ifconfig eth0 192.168.1.21 netmask 255.255.255.0 /sbin/route add default gw 192.168.1.254 eth0 endofinput ;; "i386" ) cat >> init.d/rcS << endofinput /sbin/ifconfig eth0 192.168.1.23 netmask 255.255.255.0 /sbin/route add default gw 192.168.1.254 eth0 endofinput ;; esac chmod 755 init.d/rcS cat > init.d/umountfs << endofinput /bin/echo umounting filesystems and remounting / as readonly /bin/umount -f -a -r /bin/mount -n -o remount,ro / endofinput chmod 755 init.d/umountfs cat > resolv.conf << endofinput domain trailblazerdev nameserver 192.168.1.1 endofinput echo Step 7 - Complete echo # # Step 8 - Create devices in /dev directory # echo Step 8 - Create devices in /dev directory #dev files cd $ROOTFSLOC/dev mknod -m 0666 tty c 5 0 mknod -m 0666 tty0 c 4 0 mknod -m 0666 ttyS0 c 4 64 ln -s ttyS0 console mknod -m 0666 null c 1 3 mknod -m 660 ram b 1 1 chown root.disk ram echo Step 8 - Complete echo # # Step 9 - Prepare the root filesystem for operation on the target board # echo Step 9 - Prepare the root filesystem for operation on the target board if [ $# == 2 ] then if [ $2 == "ramdisk" ] then echo Building $ARCH root filesystem ramdisk rm -rf /tmp/tmpmnt mkdir /tmp/tmpmnt rm -rf /tmp/ramrootfs dd if=/dev/zero of=/tmp/ramrootfs bs=1k count=8192 mke2fs -F -m 0 -i 2000 /tmp/ramrootfs mount -o loop -t ext2 /tmp/ramrootfs /tmp/tmpmnt cd /tmp/tmpmnt cp -av $ROOTFSLOC/* . cd /tmp umount /tmp/tmpmnt cat /tmp/ramrootfs | gzip -9 > /tftpboot/$ARCH-ramdisk.gz if [ $ARCH == "powerpc" ] then cp /tftpboot/$ARCH-ramdisk.gz /usr/src/$TARGET/arch/ppc/boot/images/ramdisk.image.gz echo Copying /tftpboot/$ARCH-ramdisk.gz to /usr/src/$TARGET/arch/ppc/boot/images/ramdisk.image.gz fi rm -rf /tmp/ramrootfs rm -rf /tmp/tmpmnt echo Your $ARCH root filesystem ramdisk is /tftpboot/$ARCH-ramdisk.gz fi fi if [ $ARCH == "i386" ] then echo echo -n This script is about to work with your /dev/hdc1 partition, is this OK? yes/no?" " read hdc1ok if [ $hdc1ok == "yes" ] then mkdir $ROOTFSLOC/boot #dev files cd $ROOTFSLOC/dev rm -rf console mknod console c 5 1 chmod 666 console mknod hda b 3 0 mknod hda1 b 3 1 mknod hda2 b 3 2 chmod 666 hda* #/boot files cp /boot/boot.b $ROOTFSLOC/boot cp /usr/src/linux/arch/i386/boot/bzImage $ROOTFSLOC/boot/bzImage TMPMOUNT=/tmp/tmpmnt cat > /tmp/lilo.conf.1 << ENDOFINPUT # this is a special lilo.conf file used to install lilo on the /dev/hdc drive # when the machine is booted from the /dev/hda drive. Don't run lilo with this # conf file if you booted the machine from this second drive. disk=/dev/hdc bios=0x80 # This tells LILO to treat hdc as hda #disk=/dev/hdc # bios=0x80 # cylinders=612 # this is experimenting with 40MB SanDisk flash card # heads=4 # sectors=32 #linear #append="hd=612/4/32" boot=/dev/hdc # install boot on hdc map=$TMPMOUNT/boot/map # location of the map file install=$TMPMOUNT/boot/boot.b # boot file to copy to boot sector prompt # show LILO boot: prompt timeout=1 # wait a second for user input image=$TMPMOUNT/boot/bzImage # kernel location label=linux # kernel label root=/dev/hda1 # root image location after you finalize disk location read-only # mount root as read only ENDOFINPUT cat > $ROOTFSLOC/etc/fstab << endofinput # <file system> <mount point> <type> <options> <dump> <pass> /dev/hda1 / ext2 defaults,errors=remount-ro 0 1 proc /proc proc defaults 0 0 endofinput e2fsck -y /dev/hdc1 rm -rf $TMPMOUNT mkdir $TMPMOUNT mount -t ext2 /dev/hdc1 $TMPMOUNT echo -n "Do you want to erase the /dev/hdc1 partition, continue yes/no? " read deleteall if [ $deleteall == "yes" ] then # this deletes everything on your partition, WATCH OUT!! rm -rf $TMPMOUNT/* mkdir $TMPMOUNT/lost+found fi cp -av $ROOTFSLOC/* $TMPMOUNT /sbin/lilo -C /tmp/lilo.conf.1 cd / umount $TMPMOUNT rm -rf $TMPMOUNT e2fsck -y /dev/hdc1 fi #hdc1ok fi echo Step 9 - Complete echo echo Your $ARCH root filesystem is $ROOTFSLOC