Merge branch 'for-linus-5.1-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git...
[linux-2.6-microblaze.git] / tools / testing / selftests / rcutorture / bin / mkinitrd.sh
1 #!/bin/bash
2 #
3 # Create an initrd directory if one does not already exist.
4 #
5 # This program is free software; you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; either version 2 of the License, or
8 # (at your option) any later version.
9 #
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 # GNU General Public License for more details.
14 #
15 # You should have received a copy of the GNU General Public License
16 # along with this program; if not, you can access it online at
17 # http://www.gnu.org/licenses/gpl-2.0.html.
18 #
19 # Copyright (C) IBM Corporation, 2013
20 #
21 # Author: Connor Shu <Connor.Shu@ibm.com>
22
23 D=tools/testing/selftests/rcutorture
24
25 # Prerequisite checks
26 [ -z "$D" ] && echo >&2 "No argument supplied" && exit 1
27 if [ ! -d "$D" ]; then
28     echo >&2 "$D does not exist: Malformed kernel source tree?"
29     exit 1
30 fi
31 if [ -s "$D/initrd/init" ]; then
32     echo "$D/initrd/init already exists, no need to create it"
33     exit 0
34 fi
35
36 T=${TMPDIR-/tmp}/mkinitrd.sh.$$
37 trap 'rm -rf $T' 0 2
38 mkdir $T
39
40 cat > $T/init << '__EOF___'
41 #!/bin/sh
42 # Run in userspace a few milliseconds every second.  This helps to
43 # exercise the NO_HZ_FULL portions of RCU.  The 192 instances of "a" was
44 # empirically shown to give a nice multi-millisecond burst of user-mode
45 # execution on a 2GHz CPU, as desired.  Modern CPUs will vary from a
46 # couple of milliseconds up to perhaps 100 milliseconds, which is an
47 # acceptable range.
48 #
49 # Why not calibrate an exact delay?  Because within this initrd, we
50 # are restricted to Bourne-shell builtins, which as far as I know do not
51 # provide any means of obtaining a fine-grained timestamp.
52
53 a4="a a a a"
54 a16="$a4 $a4 $a4 $a4"
55 a64="$a16 $a16 $a16 $a16"
56 a192="$a64 $a64 $a64"
57 while :
58 do
59         q=
60         for i in $a192
61         do
62                 q="$q $i"
63         done
64         sleep 1
65 done
66 __EOF___
67
68 # Try using dracut to create initrd
69 if command -v dracut >/dev/null 2>&1
70 then
71         echo Creating $D/initrd using dracut.
72         # Filesystem creation
73         dracut --force --no-hostonly --no-hostonly-cmdline --module "base" $T/initramfs.img
74         cd $D
75         mkdir -p initrd
76         cd initrd
77         zcat $T/initramfs.img | cpio -id
78         cp $T/init init
79         chmod +x init
80         echo Done creating $D/initrd using dracut
81         exit 0
82 fi
83
84 # No dracut, so create a C-language initrd/init program and statically
85 # link it.  This results in a very small initrd, but might be a bit less
86 # future-proof than dracut.
87 echo "Could not find dracut, attempting C initrd"
88 cd $D
89 mkdir -p initrd
90 cd initrd
91 cat > init.c << '___EOF___'
92 #ifndef NOLIBC
93 #include <unistd.h>
94 #include <sys/time.h>
95 #endif
96
97 volatile unsigned long delaycount;
98
99 int main(int argc, int argv[])
100 {
101         int i;
102         struct timeval tv;
103         struct timeval tvb;
104
105         for (;;) {
106                 sleep(1);
107                 /* Need some userspace time. */
108                 if (gettimeofday(&tvb, NULL))
109                         continue;
110                 do {
111                         for (i = 0; i < 1000 * 100; i++)
112                                 delaycount = i * i;
113                         if (gettimeofday(&tv, NULL))
114                                 break;
115                         tv.tv_sec -= tvb.tv_sec;
116                         if (tv.tv_sec > 1)
117                                 break;
118                         tv.tv_usec += tv.tv_sec * 1000 * 1000;
119                         tv.tv_usec -= tvb.tv_usec;
120                 } while (tv.tv_usec < 1000);
121         }
122         return 0;
123 }
124 ___EOF___
125
126 # build using nolibc on supported archs (smaller executable) and fall
127 # back to regular glibc on other ones.
128 if echo -e "#if __x86_64__||__i386__||__i486__||__i586__||__i686__" \
129            "||__ARM_EABI__||__aarch64__\nyes\n#endif" \
130    | ${CROSS_COMPILE}gcc -E -nostdlib -xc - \
131    | grep -q '^yes'; then
132         # architecture supported by nolibc
133         ${CROSS_COMPILE}gcc -fno-asynchronous-unwind-tables -fno-ident \
134                 -nostdlib -include ../../../../include/nolibc/nolibc.h \
135                 -lgcc -s -static -Os -o init init.c
136 else
137         ${CROSS_COMPILE}gcc -s -static -Os -o init init.c
138 fi
139
140 rm init.c
141 echo "Done creating a statically linked C-language initrd"
142
143 exit 0