stupid! if it does not exist, dd it!
[outofuni/dib.git] / build.sh
1 #!/bin/bash
2
3 # debian image build tool
4 # author hackbard@hackdaworld.org
5
6 function check_prereq() {
7         # read config
8         [ -f ./build.config ] && . ./build.config
9         # check
10         tc="gcc-`echo $MAKEOPT | sed 's/.*\ CROSS_COMPILE=\(.*\)-.*/\1/'`"
11         deps=0
12         for deb in debootstrap binfmt-support qemu-user-static $tc; do
13                 ip=`dpkg -l | grep $deb | awk '{ print $2 }'`
14                 if [ -z "$ip" ]; then
15                         echo "package $deb required but not installed"
16                         deps=1
17                 fi
18         done
19         if [ "$deps" = "1" ]; then
20                 echo "install prerequisites"
21                 exit 1
22         fi
23 }
24
25 function umount_if_mounted() {
26         mnt=$1
27         rpath="`realpath $PWD`"
28         mntpt=`mount | grep $rpath/$mnt | awk '{ print $3 }'`
29         if [ ! -z "$mntpt" ]; then
30                 echo "umounting $mntpt"
31                 umount $mntpt
32         fi
33 }
34
35 function build_all {
36         # read config
37         [ -f ./build.config ] && . ./build.config
38         # build stage 1
39         if [ -f .build_stage1 ]; then
40                 echo "stage one already done, skipping ..."
41         else
42                 echo "building debian image, first stage ..."
43                 # image
44                 if [ -f ./rootfs.img ]; then
45                         size=`ls -al ./rootfs.img | awk '{ print $5/1048576 }'`
46                         if [ "$size" = "$IMGSIZE" ]; then
47                                 echo "rootfs.img exists"
48                         else
49                                 echo "creating rootfs.img"
50                                 dd if=/dev/zero of=./rootfs.img \
51                                         bs=1M count=$IMGSIZE
52                         fi
53                 else
54                         echo "creating rootfs.img"
55                         dd if=/dev/zero of=./rootfs.img \
56                                 bs=1M count=$IMGSIZE
57                 fi
58                 # make fs and mount
59                 umount_if_mounted rootfs.mnt
60                 FORCEFS="-F"
61                 [ "$ROOTFS" = "xfs" ] && FORCEFS="-f"
62                 mkfs.${ROOTFS} $FORCEFS -L rootfs ./rootfs.img
63                 rm -rf rootfs.mnt
64                 mkdir rootfs.mnt
65                 modprobe loop
66                 mount -o loop ./rootfs.img ./rootfs.mnt
67                 # debootstrap first part
68                 debootstrap --verbose --arch $ARCH --variant=minbase \
69                         --foreign $SUITE rootfs.mnt $DEBMIRROR
70                 # copy emulator
71                 cp -v `which $EMU` ./rootfs.mnt/usr/bin
72                 touch .build_stage1
73         fi
74         # copy myself
75         cp -v ./build.sh ./rootfs.mnt
76         cp -v ./build.config ./rootfs.mnt
77         mkdir -p ./rootfs.mnt/post_routines
78         cp -v ./post_routines/$NAME/* ./rootfs.mnt/post_routines
79         mkdir -p ./rootfs.mnt/files
80         cp -rv ./files/$NAME/* ./rootfs.mnt/files
81         if [ ! -f .build_stage2 ]; then
82                 # prepare/run second stage
83                 modprobe binfmt_misc
84                 mnts="rootfs.mnt/dev/pts rootfs.mnt/proc"
85                 for mnt in $mnts; do 
86                         umount_if_mounted $mnt
87                 done
88                 mount -t proc proc ./rootfs.mnt/proc
89                 mkdir -p ./rootfs.mnt/dev/pts
90                 mount -t devpts devpts ./rootfs.mnt/dev/pts
91                 chroot ./rootfs.mnt /build.sh chroot
92                 #
93                 # running build_stage2()
94                 #
95                 for mnt in $mnts; do 
96                         umount_if_mounted $mnt
97                 done
98                 touch .build_stage2
99                 # cleanup
100                 rm -v ./rootfs.mnt/build.sh
101                 rm -v ./rootfs.mnt/build.config
102                 rm -rfv ./rootfs.mnt/post_routines
103                 rm -rfv ./rootfs.mnt/files
104         fi
105         # final things
106         echo
107         echo -en "build completed! want me to umount everything? [Y,n]: "
108         read answer
109         if [ "$answer" != "n" ]; then
110                 mnts="rootfs.mnt/dev/pts rootfs.mnt/proc rootfs.mnt"
111                 for mnt in $mnts; do
112                         umount_if_mounted $mnt
113                 done
114         fi
115 }
116
117 function build_in_chroot {
118         # read config
119         [ -f ./build.config ] && . ./build.config
120         # build second stage
121         echo "building debian image, second stage ..."
122         [ -f /debootstrap/debootstrap ] && \
123                 /debootstrap/debootstrap --second-stage
124         # additional packages + configuration
125         echo "deb ${DEBMIRROR}/ $SUITE main contrib non-free" > \
126                 /etc/apt/sources.list
127         echo "deb-src ${DEBMIRROR}/ $SUITE main contrib non-free" >> \
128                 /etc/apt/sources.list
129         # run apt
130         apt-get update
131         apt-get -y install $PKGS
132         # locales
133         locale-gen --purge en_US.UTF-8
134         echo 'LANG="en_US.UTF-8"' > /etc/default/locale
135         echo 'LANGUAGE="en_US:en"' >> /etc/default/locale
136         # network
137         echo -en "auto lo\niface lo inet loopback\n" > /etc/network/interfaces
138         echo -en "auto eth0\niface eth0 inet dhcp\n" >> /etc/network/interfaces
139         echo -en "auto usb0\niface usb0 inet dhcp\n" >> /etc/network/interfaces
140         # hostname
141         echo $NAME > /etc/hostname
142         # root
143         echo "/dev/root / $ROOTFS defaults 0 1" > /etc/fstab
144         # determine init type
145         if [ "`file /sbin/init | awk '{ print $2 }'`" = "symbolic" ]; then
146                 symlink=`ls -al /sbin/init | awk -F'->' '{ print $2 }'`
147                 inittype=`basename $symlink`
148         else
149                 inittype=sysvinit
150         fi
151         # serial console
152         num=`echo $GETTY | sed 's/\([a-zA-Z].*\)\([0-9].*\)/\2/'`
153         case "$inittype" in
154                 systemd)
155                         # nothing required to enable serial console
156                         ;;
157                 sysvinit)
158                         echo -en "T${num}:2345:respawn:/sbin/getty -L " >> \                                    /etc/inittab
159                         echo -en "$GETTY 115200 linux" >> /etc/inittab;;
160                 *)
161                         echo "unsupported init system: $inittype";;
162         esac
163         # more boot scripts     
164         echo -en "\nHWCLOCKACCESS=no\n" >> /etc/default/rcS
165         echo "CONCURRENCY=shell" >> /etc/default/rcS
166         # additional packages
167         apt-get -y install $ADDPKGS
168         # (un)set passwd
169         passwd -d root
170         # profile
171         echo -en "\nalias l='ls -al --color'\n\n" >> /etc/profile
172         # post install hooks
173         for file in `ls /post_routines`; do
174                 . /post_routines/$file
175         done
176 }
177
178 #
179 # post chroot tasks
180 #
181
182 function build_uboot() {
183         echo "building u-boot ..."
184         echo "  argv: $@"
185         nopatch=0
186         noget=0
187         update=0
188         nocheckout=0
189         noclean=0
190         no2all=0
191         while [ "$1" ]; do
192                 case "$1" in
193                         -nopatch)       nopatch=1; shift;;
194                         -noget)         noget=1; shift;;
195                         -update)        update=1; shift;;
196                         -nocheckout)    nocheckout=1; shift;;
197                         -noclean)       noclean=1; shift;;
198                         -no2all)        no2all=1; shift;;
199                         *) shift;;
200                 esac
201         done
202         if [ "$no2all" = "1" ]; then
203                 nopatch=1
204                 noget=1
205                 nocheckout=1
206                 noclean=1
207         fi
208         [ -f ./build.config ] && . ./build.config
209         if [ "$noget" = "0" ]; then
210                 rm -rf u-boot
211                 git clone $UBSRC
212         fi
213         if [ "$update" = "1" ]; then
214                 cd u-boot
215                 git pull
216                 cd ..
217         fi
218         cd u-boot
219         if [ "$nocheckout" = "0" ]; then
220                 if [ ! -z "$UBVER" ]; then
221                         git checkout $UBVER
222                 fi
223         fi
224         if [ "$nopatch" = "0" ]; then
225                 if [ ! -z "$UBPATCH" ]; then
226                         for patch in $UBPATCH; do
227                                 patch -Nfp1 < ../patches/$NAME/$patch
228                         done
229                 fi
230         fi
231         if [ "$noclean" = "0" ]; then
232                 make $MAKEOPT distclean
233         fi
234         make $MAKEOPT $UBCONF
235         make $MAKEOPT
236         cd ..
237 }
238
239 function build_kernel() {
240         nopatch=0
241         noget=0
242         nohook=0
243         noclean=0
244         no2all=0
245         while [ "$1" ]; do
246                 case "$1" in
247                         -nopatch)       nopatch=1; shift;;
248                         -noget)         noget=1; shift;;
249                         -nohook)        nohook=1; shift;;
250                         -noclean)       noclean=1; shift;;
251                         -no2all)        no2all=1; shift;;
252                         *) shift;;
253                 esac
254         done
255         if [ "$no2all" = "1" ]; then
256                 nopatch=1
257                 noget=1
258                 nohook=1
259                 noclean=1
260         fi
261         [ -f ./build.config ] && . ./build.config
262         KV=`echo $KERVER | awk -F. '{
263                 if($1=="3") print "3.x"
264                 else print$1 "." $2
265         }'`
266         if [ "$noget" = "0" ]; then
267                 rm -rf linux-${KERVER}*
268                 KERSRC="https://www.kernel.org/pub/linux/kernel/"
269                 KERSRC="$KERSRC/v$KV/linux-${KERVER}.tar.bz2"
270                 wget $KERSRC
271                 tar xfj linux-${KERVER}.tar.bz2
272         fi
273         cd linux-$KERVER
274         if [ "$nopatch" = "0" ]; then
275                 if [ ! -z "$KERPATCH" ]; then
276                         for patch in $KERPATCH; do
277                                 patch -Nfp1 < ../patches/$NAME/$patch
278                         done
279                 fi
280         fi
281         if [ "$noclean" = "0" ]; then
282                 make $MAKEOPT mrproper
283         fi
284         if [ "$nohook" = "0" ]; then
285                 if [ ! -z "$KERHOOKS" ]; then
286                         for hook in $KERHOOKS; do
287                                 . ../hooks/$hook
288                         done
289                 fi
290         fi
291         if [ ! -z "$KERCONF" ]; then
292                 make $MAKEOPT $KERCONF
293         fi
294         make $MAKEOPT zImage
295         make $MAKEOPT modules
296         make $MAKEOPT INSTALL_MOD_PATH=../rootfs.mnt modules_install
297         cd ..
298 }
299
300 function build_sdcard() {
301         echo "creating sdcard ..."
302 }
303
304 #
305 # main
306 #
307
308 # configuration 
309 if [ ! -f ./build.config ]; then
310         echo "no configuration found, aborting ..."
311 else
312         . ./build.config
313 fi
314
315 # debootstrap
316 if [ -z $1 ]; then
317         check_prereq
318         build_all | tee ./build.log 2>&1
319 elif [ "$1" = "chroot" ]; then
320         build_in_chroot | tee ./build_in_chroot.log 2>&1
321 elif [ "$1" = "uboot" ]; then
322         check_prereq
323         build_uboot $@ | tee ./build_uboot.log 2>&1
324 elif [ "$1" = "kernel" ]; then
325         check_prereq
326         build_kernel $@ | tee ./build_kernel.log 2>&1
327 else 
328         echo "unknown option: '$1'"
329 fi
330