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 23D=tools/testing/selftests/rcutorture 24 25# Prerequisite checks 26[ -z "$D" ] && echo >&2 "No argument supplied" && exit 1 27if [ ! -d "$D" ]; then 28 echo >&2 "$D does not exist: Malformed kernel source tree?" 29 exit 1 30fi 31if [ -s "$D/initrd/init" ]; then 32 echo "$D/initrd/init already exists, no need to create it" 33 exit 0 34fi 35 36T=${TMPDIR-/tmp}/mkinitrd.sh.$$ 37trap 'rm -rf $T' 0 2 38mkdir $T 39 40cat > $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 53a4="a a a a" 54a16="$a4 $a4 $a4 $a4" 55a64="$a16 $a16 $a16 $a16" 56a192="$a64 $a64 $a64" 57while : 58do 59 q= 60 for i in $a192 61 do 62 q="$q $i" 63 done 64 sleep 1 65done 66__EOF___ 67 68# Try using dracut to create initrd 69if command -v dracut >/dev/null 2>&1 70then 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 82fi 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. 87echo "Could not find dracut, attempting C initrd" 88cd $D 89mkdir -p initrd 90cd initrd 91cat > init.c << '___EOF___' 92#ifndef NOLIBC 93#include <unistd.h> 94#include <sys/time.h> 95#endif 96 97volatile unsigned long delaycount; 98 99int 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. 128if 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 136else 137 ${CROSS_COMPILE}gcc -s -static -Os -o init init.c 138fi 139 140rm init.c 141echo "Done creating a statically linked C-language initrd" 142 143exit 0 144